/* BlueArgos landing page — 브랜드 색상은 docs/UI_SPEC.md·lib/features/driving/view/driving_visual_tuning.dart 실제 값과 일치시킴 */

:root {
  --bg: #000000;
  --bg-elevated: #0a0d14;
  --panel: #10141c;
  --panel-border: #1f2530;
  --ring: #5ea8ff;
  --ring-dim: #8a93a2;
  --text: #f7f9fc;
  --text-dim: #aab2c0;
  --text-faint: #6b7180;
  --accent-red: #e8383f;
  --radius-lg: 28px;
  --radius-md: 18px;
  --max-width: 1080px;
  color-scheme: dark;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  overflow-x: hidden;
  background: var(--bg);
  color: var(--text);
  font-family: "Pretendard", -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo", "Segoe UI", Roboto, sans-serif;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

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

a { color: inherit; }

.br-mobile { display: none; }

/* ---------- Nav ---------- */

.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(0, 0, 0, 0.72);
  /* iOS Safari는 접두사 없는 backdrop-filter를 오래 지원 안 했다 —
     -webkit- 없이는 조용히 무시되거나(구버전) sticky와 겹쳐 합성이
     불안정해지는 경우가 있었다("햄버거 버튼이 흐릿하게 보이고 안 눌림"
     피드백의 원인 중 하나). */
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.nav-inner {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 16px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
}

/* 예전엔 radial-gradient로 흉내 낸 원이었는데, 실제 앱 아이콘(no-mad-max/
   assets/icon/app_icon.png — "블루 링" 그 자체를 그린 진짜 대표 아이콘)을
   그대로 써 달라는 요청으로 <img>로 교체. 파비콘/og:image는 이미 같은
   파일을 쓰고 있었다(index.html <head> 참고) — 이제 네비/푸터 브랜드
   마크도 같은 소스로 통일. */
.brand-mark {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}

.brand-name {
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -0.01em;
}

.nav-links {
  display: flex;
  gap: 28px;
}

.nav-links a {
  color: var(--text-dim);
  text-decoration: none;
  font-size: 14px;
  font-weight: 500;
  transition: color 0.15s ease;
  -webkit-tap-highlight-color: transparent;
}

.nav-links a:hover { color: var(--text); }

/* nav-inner는 space-between으로 brand↔오른쪽 그룹만 벌린다 — nav-links와
   lang-toggle을 이 래퍼로 묶어야 셋을 각각 벌리지 않고(중간에 끼임)
   기존처럼 오른쪽에 나란히 붙는다. */
.nav-right {
  display: flex;
  align-items: center;
  gap: 20px;
}

.lang-toggle {
  appearance: none;
  border: 1px solid rgba(94, 168, 255, 0.3);
  background: rgba(94, 168, 255, 0.1);
  color: var(--ring);
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 5px 11px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.lang-toggle:hover {
  background: rgba(94, 168, 255, 0.18);
  border-color: rgba(94, 168, 255, 0.5);
}

/* 모바일 nav 메뉴 토글(햄버거) — 데스크톱에선 안 보이다가, 아래
   @media(max-width:520px)에서 .nav-links가 접히는 대신 이 버튼으로
   펼쳐지는 드롭다운으로 바뀐다("모바일에선 메뉴가 안 보여" 피드백 수정 —
   예전엔 그냥 display:none으로 숨기기만 하고 대안이 없었다). */
.nav-toggle {
  display: none;
  appearance: none;
  background: transparent;
  border: none;
  color: var(--text);
  cursor: pointer;
  align-items: center;
  justify-content: center;
  /* iOS에서 "흐릿하게 보이고 안 눌림" 신고 대응 — 아이콘 버튼 특유의
     iOS Safari 문제 세 가지를 한 번에 고친다:
     1) 44×44px 미만 터치 타겟은 손가락으로 정확히 누르기 어렵다(애플
        HIG 최소 권장치가 44pt) — min-width/height로 확보.
     2) 기본 회색 탭 하이라이트가 어두운 헤더 위에서 얼룩(흐릿함)처럼
        보인다 — 투명하게.
     3) touch-action 없이는 iOS가 탭을 확대/더블탭 후보로 잠깐 보류하며
        300ms 지연이 생겨 "눌러도 반응이 없다"처럼 느껴질 수 있다. */
  min-width: 44px;
  min-height: 44px;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  position: relative;
  z-index: 2;
}

.nav-toggle svg {
  width: 22px;
  height: 22px;
  /* svg 자체가 탭을 가로채 버튼의 클릭 이벤트가 새지 않게(중첩 SVG를
     직접 탭했을 때 iOS WebKit에서 간헐적으로 버튼까지 안 이어지는
     문제가 있었다) — 탭은 항상 부모 button이 받는다. */
  pointer-events: none;
}

/* ---------- Hero ---------- */

.hero {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 72px 24px 40px;
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: 48px;
  align-items: center;
}

.eyebrow {
  color: var(--ring);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  margin: 0 0 18px;
}

.hero h1 {
  font-size: clamp(32px, 4.4vw, 48px);
  line-height: 1.28;
  letter-spacing: -0.02em;
  margin: 0 0 20px;
  font-weight: 800;
}

.hero-lead {
  color: var(--text-dim);
  font-size: 16px;
  max-width: min(46ch, 100%);
  margin: 0 0 28px;
}

.hero-lead strong { color: var(--text); font-weight: 700; }

.hero-badges {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.pill {
  display: inline-flex;
  align-items: center;
  padding: 7px 14px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  background: rgba(94, 168, 255, 0.12);
  color: var(--ring);
  border: 1px solid rgba(94, 168, 255, 0.28);
  text-decoration: none;
}

.pill-muted {
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-dim);
  border-color: rgba(255, 255, 255, 0.1);
}

/* ---------- Phone visual ---------- */

.hero-visual { display: flex; justify-content: center; }

.phone {
  width: 240px;
  /* 배경 폰 비율 — 처음엔 갤럭시 Z 폴드의 "펼친 메인 화면" 비율을 썼는데,
     사용자가 원한 건 "전면(커버) 디스플레이" 쪽이라 정정. 갤럭시 Z
     Fold8의 실제 커버 디스플레이 스펙(1248×1972px, 공식 10:16 비율,
     Samsung.com/GSMArena 확인)을 그대로 써서 폭:높이 = 10:16 = 0.625:1.
     폭은 그대로 240px로 두고 그 비율대로 높이만 역산(240 ÷ 0.625 =
     384px) — 슬림폰 실물 비율(520px)보다 짧지만 이전 시도(280px)보다는
     길어, 사용자가 말한 "3:4에 가깝다"는 감각(0.75)과 실측 10:16(0.625)
     사이 값으로 정확한 스펙을 우선했다. */
  height: 384px;
  background: #0b0e14;
  border-radius: 38px;
  /* 배경(#000)에 거의 묻히던 예전 값(rgba(36,41,51,.5) 테두리 + 어두운 인셋)이
     너무 흐리다는 피드백 — 테두리를 밝히고 은은한 블루 글로우를 더해 화면과
     경계가 분명히 보이도록 했다. */
  border: 1px solid rgba(148, 163, 184, 0.4);
  box-shadow:
    0 30px 80px -20px rgba(0, 0, 0, 0.85),
    0 0 0 1px rgba(255, 255, 255, 0.08),
    0 0 70px -14px rgba(94, 168, 255, 0.4),
    inset 0 0 0 6px #131722,
    inset 0 1px 0 rgba(255, 255, 255, 0.07);
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
}

.phone-notch {
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  width: 70px;
  height: 16px;
  border-radius: 10px;
  background: #0b0e14;
  border: 1px solid rgba(255, 255, 255, 0.14);
  z-index: 2;
}

/* 하단 애니메이션 단계(경고/과속 결과)에서 화면 전체가 점멸하는 효과 —
   phone-screen 뒤, notch 앞에 깔리는 전용 레이어(script.js가 제어). */
.phone-flash {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: transparent;
  opacity: 0;
  pointer-events: none;
}

/* 2026-09-17 재요청 — 캡션을 "블루 링 바로 아래"가 아니라 "블루 링
   바닥 ~ 폰 하단 사이의 정중앙"에 위치시킨다. 고정 gap 대신, ring-stage
   앞뒤에 늘어나는 빈 flex 아이템 두 개(::before 가상 요소 +
   .phone-caption-zone)를 둬서, 아래쪽 빈 아이템(.phone-caption-zone)
   안에서 캡션을 다시 한 번 가운데 정렬한다 — 그러면 캡션 중심이 정확히
   "ring 바닥~화면 하단" 구간의 중점에 온다. .phone-screen이 .phone의
   전체 높이(384px)를 채워야(height:100%) 이 계산이 성립한다.
   처음엔 두 flex 아이템을 1:1로 둬 ring-stage가 화면 정중앙에 왔는데,
   "블루 링/속도/마커를 더 위로 올려달라"는 재요청으로 1:2까지 올렸다가
   "너무 올라갔다, 좀 내려달라"는 즉시 재조정으로 1:1.5(2:3)로 절충했다
   — 위쪽 spacer(::before)보다 아래쪽(.phone-caption-zone)이 조금 더
   커서 ring-stage가 정중앙보다는 약간 위, 처음 올렸던 위치보다는
   아래에 온다. */
.phone-screen {
  display: flex;
  flex-direction: column;
  align-items: center;
  height: 100%;
}

.phone-screen::before {
  content: "";
  flex: 1 1 0%;
}

.phone-caption-zone {
  flex: 1.5 1 0%;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 지금 재생 중인 데모 단계를 설명하는 캡션(2026-09-09 피드백으로 한 줄
   라벨 하나로 합침, 단계별 문구는 script.js의 PHASE_LABELS) —
   2026-09-15 재요청: "시간 기반 과속 예상 알림" 단계 문구가 두 줄
   (문장 + 남은 시간 안내)로 늘어나며 모바일 폭(폰 목업 내부 238px)을
   넘어서게 됐다. 한 줄+말줄임 방식을 버리고 "최대 N줄"을 기본 레이아웃
   으로 삼는다 — 높이를 고정해(1줄짜리 문구도 이 높이 안에서 상하 중앙
   정렬) 문구가 몇 줄이든 블루 링 위치가 흔들리지 않게 하고, 긴 문구는
   자연스럽게 줄바꿈되게 한다.
   2026-09-16 재요청으로 warning 단계가 "설명 한 줄 + 따옴표 문장"
   구조가 됐는데, 그 따옴표 문장 자체가 216px 폭에서 이미 2줄이라(실측
   약 319px, 폰 목업 폭으로는 줄일 수 없는 길이) 합쳐서 3줄이 필요해져
   높이를 2줄→3줄 기준으로 다시 늘렸다. */
.phone-caption {
  margin: 0;
  /* 항상 최상위 레이어에 그려야 한다는 요청 — position 없이는 z-index가
     먹지 않으므로(static 요소) relative로 승격한 뒤 phone-notch(2)·
     camera-sign(3)보다 확실히 높은 값을 준다. 실제로 겹칠 일은 없는
     위치지만(캡션은 ring-stage 아래 별도 영역) 애매한 페인트 순서에
     기대지 않고 명시적으로 고정한다. */
  position: relative;
  z-index: 10;
  /* 폭은 고정하지 않고 max-width로 상한만 둔다(짧은 문구는 그 안에서
     좁게, 긴 문구는 이 폭에서 줄바꿈) — 높이만 고정이면 세로 위치는
     이미 안정적이라, 폭까지 고정할 필요가 없어졌다. 216px은 "시간 기반
     과속 예상 알림"/"15초 뒤 전방에 100km 카메라.." 두 줄 각각이(실측
     약 178px) 그 폭 안에서 한 줄로 그대로 유지되면서도, 폰 목업 내부
     폭(238px)에 여유(약 11px씩)를 남기는 값이다. */
  max-width: 216px;
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  /* 줄바꿈을 허용하되(auto-wrap), PHASE_LABELS에 명시적으로 넣은 "\n"
     (예: 과속 예상 알림 문구의 문장/남은시간 두 줄 구분)도 그대로
     지켜야 해서 nowrap 대신 pre-line을 쓴다. */
  white-space: pre-line;
  /* 기본값(word-break:normal)은 한글을 음절 단위 아무 데서나 끊어서,
     예를 들어 "있습니다"가 "있습"/"니다"로 단어 중간에 갈라지는 경우가
     생겼다(warning 단계 캡션에서 발견) — keep-all로 띄어쓰기 경계에서만
     줄바꿈되게 한다. */
  word-break: keep-all;
  overflow: hidden;
  font-size: 12px;
  line-height: 1.3;
  font-weight: 700;
  letter-spacing: 0.02em;
  /* 카메라 경고/과속 결과 단계에서 배경 전체가 흰/빨강으로 점멸하는 동안에도
     묻히지 않도록, 배경이 무슨 색으로 깜박이든 상관없이 항상 짙은 검정
     알약 위에 흰 글자로 고정한다(단계별로 글자색을 반전시키는 대신 —
     사용자가 더 단순한 이 방식을 선택). */
  color: var(--text);
  background: rgba(0, 0, 0, 0.82);
  padding: 4px 14px;
  border-radius: 999px;
}

/* approach 단계 캡션의 둘째 줄("카메라가 실제로 말해줄 문구")을 첫째 줄
   (단계 설명)과 구분하려고 따옴표로 감싸고 이탤릭체를 준다(2026-09-15
   재요청). 마크업은 script.js의 PHASE_LABELS.approach 참고. */
.phone-caption-quote {
  font-style: italic;
}

/* 감속 단계는 캡션이 없다(요청 사양) — 하지만 textContent를 진짜 빈
   문자열로 두면 <p>가 줄 상자(line box) 자체를 잃어 padding만 남은 높이가
   되고, .phone의 justify-content:center가 전체를 다시 가운데 맞추면서
   블루 링 위치가 위아래로 움찔거렸다(감속↔반복 전환 시 신고된 버그).
   그래서 script.js는 빈 캡션에도 non-breaking space 한 글자를 채워
   줄 상자 높이를 항상 동일하게 유지하고, 이 클래스로만 시각적으로 지운다
   — 레이아웃에 영향 없이 안 보이게. */
.phone-caption.is-blank {
  visibility: hidden;
}

/* ---------- Blue Ring ---------- */

.ring-stage {
  position: relative;
  width: 120px;
  height: 120px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.ring-stage-lg { width: 220px; height: 220px; }

/* 히어로 폰의 블루 링만 script.js가 매 프레임 직접 제어하는 데모 애니메이션
   (아래 pulse→가속→카메라 경고→과속→감속 시퀀스)으로 대체한다 — 아래
   #ring 섹션의 큰 링(.ring-stage-lg)은 원래의 은은한 breathe 애니메이션을
   그대로 유지(피드백 대상이 히어로 폰 한정이라 여긴 손대지 않음). */
.ring-stage-hero .blue-ring,
.ring-stage-hero .ring-glow {
  animation: none;
}

/* 가운데 블루 링/경고 표시를 기존보다 20% 키워 달라는 요청 — 120px →
   144px. 링 자체 모양(각도별 밝기)은 script.js가 매 프레임 conic-gradient
   로 다시 그리므로 크기와 무관하게 그대로지만, 스트로크 두께를 정하는
   반지름 마스크(mask, 아래)는 고정 px라 커진 만큼 같이 20% 키워야
   상대적으로 더 가늘어 보이지 않는다. */
.ring-stage-hero {
  width: 144px;
  height: 144px;
}

.ring-stage-hero .blue-ring,
.ring-stage-hero .ring-glow {
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 16.8px), #000 calc(100% - 18.6px), #000 100%);
  mask: radial-gradient(farthest-side, transparent calc(100% - 16.8px), #000 calc(100% - 18.6px), #000 100%);
}

.speed-value {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  /* 링(120→144px)과 같은 비율(×1.2)로 키워 커진 링 안에서 숫자가
     상대적으로 작아 보이지 않게 한다. */
  font-size: 36px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

/* #ring 섹션의 정적 "7" 표시 — 처음 36px에서 2.5배(90px)로 키웠더니 너무
   크다는 재요청으로 20% 줄임(90 × 0.8 = 72px). */
.ring-stage-lg .speed-value {
  font-size: 72px;
}

/* 전방 카메라 표지(lib/features/driving/view/speed_sign.dart의 SpeedSign/
   OverspeedSign을 참고한 색 구성) — 평소엔 안 보이다가(opacity 0) 카메라
   접근 단계에서 자라나며 나타난다. inset:0라 ring-stage-hero 크기를
   그대로 따라가고, 테두리·글자만 같은 비율(×1.2)로 맞춰 키운다.
   테두리 굵기는 같은 ring-stage-hero의 .blue-ring 마스크 두께(14px×1.2=
   16.8px, 아래 .ring-stage-hero .blue-ring 참고)와 맞춘 값 — 예전엔
   11px로 따로 놀아서, 속도가 올라가며 블루 링에서 이 표지로 넘어갈 때
   테두리 굵기가 갑자기 얇아져 보였다(디자인 피드백으로 발견, 수정).
   숫자 폰트도 .speed-value와 같은 weight 700 + tabular-nums로 맞춰,
   숫자가 늘어나며 "5" → "100"/"+20"으로 넘어갈 때 자연스럽게 이어지도록
   한다. */
.camera-sign {
  position: absolute;
  inset: 0;
  z-index: 3;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f7f9fc;
  border: 16.8px solid #e8383f;
  color: #17181b;
  font-size: 36px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  opacity: 0;
  box-shadow: 0 8px 20px -4px rgba(0, 0, 0, 0.5);
  transition: background-color 0.2s ease, border-color 0.2s ease;
}

/* 과속 통과 결과(OverspeedSign) — 색 반전: 빨간 바탕·흰 테두리·검정 숫자. */
.camera-sign.is-overspeed {
  background: #e8383f;
  border-color: #f7f9fc;
  color: #17181b;
}

/* "다수 카메라 중 대상 선별" 단계(select, 2026-09-15 피드백)의 후보
   마커 — 실제 앱(radar_markers_layer.dart)에서 최우선으로 뽑히지 않은
   카메라가 화면 가장자리 쪽에 작고 옅게 표시되다가, 대상이 아니면
   사라지는 것을 옮겼다. 대상으로 뽑히는 마커는 새 요소 없이 기존
   .camera-sign을 그대로 재사용(북쪽=12시에서 자라나 approach 단계로
   이어짐, script.js 참고) — 이 두 후보는 화면 중앙까지 오지 못하고
   11시/2시 방향에 머물다 사라지는 쪽만 표현한다. 위치(translate)·
   불투명도·크기는 script.js가 매 프레임 계산해 인라인 스타일로 준다.
   기본 크기(width/height/border)는 2026-09-16 재요청("너무 작다")으로
   26px→40px, 테두리 5px→7px로 키웠다 — script.js의 scale 상한도 함께
   0.55/0.5→0.85/0.75로 올려, 두 값이 곱해진 실제 표시 크기가 눈에 띄게
   커지도록 했다. */
.candidate-marker {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 40px;
  height: 40px;
  margin: -20px 0 0 -20px;
  z-index: 3;
  border-radius: 50%;
  background: #f7f9fc;
  border: 7px solid #e8383f;
  opacity: 0;
  pointer-events: none;
}

/* .ring-core는 삭제했다 — 안쪽 원이 무슨 색이든("링보다 옅은 파란색") 결국
   또렷하게 도드라져 보인다는 지적이 반복돼, 코어 자체를 없애고 안쪽엔
   진짜 배경(폰 화면 배경/섹션 배경)이 그대로 비치게 했다. 대신
   .ring-glow의 블러가 자기 마스크의 안쪽 경계를 넘어 중앙까지 번지던
   문제가 남아 있어(마스크가 필터보다 먼저 적용되므로 블러가 그 경계를
   다시 부드럽게 넘나든다) — 아래 .ring-glow-wrap에서 별도로 처리한다. */

/* 링 도형(개구부 있는 conic-gradient)을 두 겹으로 그린다 — 아래 흐릿한 겹(.ring-glow)은
   앰비언트 발광만 담당하고, 위 또렷한 겹(.blue-ring)이 6시 방향 개구부의 경계를 선명하게
   유지한다. 두 겹을 하나로 합쳐 filter: drop-shadow만 크게 주면 블러가 개구부까지 덮어버려
   C자 모양이 안 보이는 문제가 있었다(스크린샷 검수로 발견, 수정). */

.blue-ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(
    from 285deg,
    var(--ring) 0%,
    var(--ring) 41.7%,
    transparent 66.7%,
    transparent 75%,
    var(--ring) 100%
  );
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 14px), #000 calc(100% - 15.5px), #000 100%);
  mask: radial-gradient(farthest-side, transparent calc(100% - 14px), #000 calc(100% - 15.5px), #000 100%);
  animation: ring-breathe 3.6s ease-in-out infinite;
}

.blue-ring-lg {
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 22px), #000 calc(100% - 24px), #000 100%);
  mask: radial-gradient(farthest-side, transparent calc(100% - 22px), #000 calc(100% - 24px), #000 100%);
}

/* .ring-glow는 마스크 다음에 blur가 적용돼(mask → filter 순서) 자기 마스크의
   안쪽 경계를 블러 반경만큼 다시 넘어 중앙까지 번진다 — 그게 "링보다
   옅은 파란 원"의 실제 원인이었다(.ring-core를 없앤 뒤에도 이 번짐 자체는
   남아 있었다). 블러 없는 이 래퍼에 블루 링과 똑같은 안쪽 경계의(14px/
   22px) 하드 마스크를 한 번 더 걸어, 이미 블러 처리된 결과 중 구멍
   안쪽으로 새어든 부분만 정확히 잘라낸다 — 바깥으로 번지는 앰비언트
   발광은 이 래퍼의 마스크가 그 반경 밖에서는 계속 불투명이라 그대로
   살아있다. */
.ring-glow-wrap {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 14px), #000 calc(100% - 14px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 14px), #000 calc(100% - 14px));
}

.ring-glow-wrap-lg {
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 22px), #000 calc(100% - 22px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 22px), #000 calc(100% - 22px));
}

.ring-glow {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(
    from 285deg,
    var(--ring) 0%,
    var(--ring) 41.7%,
    transparent 66.7%,
    transparent 75%,
    var(--ring) 100%
  );
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 14px), #000 calc(100% - 15.5px), #000 100%);
  mask: radial-gradient(farthest-side, transparent calc(100% - 14px), #000 calc(100% - 15.5px), #000 100%);
  filter: blur(10px);
  opacity: 0.65;
  animation: ring-breathe 3.6s ease-in-out infinite;
}

.ring-glow-lg {
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 22px), #000 calc(100% - 24px), #000 100%);
  mask: radial-gradient(farthest-side, transparent calc(100% - 22px), #000 calc(100% - 24px), #000 100%);
  filter: blur(16px);
}

@keyframes ring-breathe {
  0%, 100% { transform: scale(0.97); opacity: 0.88; }
  50% { transform: scale(1.03); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .blue-ring { animation: none; }
}

/* prefers-reduced-motion일 때 script.js는 루프 자체를 돌리지 않고 정지 화면만
   남긴다(아래 스크립트 참고) — 카메라 표지/화면 점멸은 처음부터 숨겨둔다. */
@media (prefers-reduced-motion: reduce) {
  .camera-sign { display: none; }
  .phone-flash { display: none; }
}

/* ---------- Sections ---------- */

main section {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 88px 24px;
}

.section-head { max-width: 640px; margin: 0 0 48px; }

.section-head h2 {
  font-size: clamp(26px, 3vw, 34px);
  letter-spacing: -0.01em;
  margin: 0 0 12px;
  font-weight: 800;
}

.section-head p {
  color: var(--text-dim);
  font-size: 15px;
  margin: 0;
}

/* ---------- Cards ---------- */

.cards {
  display: grid;
  /* 카드가 4개→5개로 늘면서(경로 설정 없음 카드 추가) 4열이면 마지막 한
     장이 다음 줄에 혼자 남는다 — 3열로 바꿔 3+2로 자연스럽게 줄바꿈. */
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
}

.card {
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-md);
  padding: 26px 22px;
}

.card-icon {
  width: 40px;
  height: 40px;
  border-radius: 12px;
  background: rgba(94, 168, 255, 0.12);
  color: var(--ring);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 18px;
}

.card-icon svg { width: 20px; height: 20px; }

.card h3 {
  font-size: 16px;
  margin: 0 0 8px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.card p {
  color: var(--text-dim);
  font-size: 14px;
  margin: 0;
}

/* ---------- Steps ---------- */

.steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 28px;
}

.steps li {
  display: grid;
  grid-template-columns: 44px 1fr;
  gap: 20px;
  align-items: start;
  padding-bottom: 28px;
  border-bottom: 1px solid var(--panel-border);
}

.steps li:last-child { border-bottom: none; padding-bottom: 0; }

.step-num {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid rgba(94, 168, 255, 0.35);
  color: var(--ring);
  font-weight: 700;
  font-size: 15px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.steps h3 {
  margin: 0 0 6px;
  font-size: 17px;
  font-weight: 700;
}

.steps p {
  margin: 0;
  color: var(--text-dim);
  font-size: 14.5px;
  max-width: min(58ch, 100%);
}

/* 각 단계 오른쪽 여백에 히어로 애니메이션(블루 링 데모)의 해당 장면을
   축약해 재현한 작은 삽화 + 캡션을 배치한다 — 텍스트는 왼쪽에 그대로
   두고, 넓은 화면에서 남는 공간에 붙인다(좁은 화면에서는 줄바꿈되어
   본문 아래로 내려간다). */
.step-body {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
}

.step-text { flex: 1 1 340px; min-width: 0; }

.step-visual {
  flex: 0 0 auto;
  width: 140px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.step-visual .step-caption {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--text-dim);
  text-align: center;
}

/* 실제 표지판 스타일(speed_sign.dart의 SpeedSign) — 흰 바탕·빨간 테두리·
   검정 숫자를 그대로 축소해 옮겼다. 테두리 굵기는 .camera-sign과 같은
   원 지름 대비 비율(블루 링의 스트로크 비율, 7/60 — 120px 기본 링에서
   14px, 144px 히어로 링에서 16.8px로 쓰인 값과 동일 비율)로 맞춘 값
   (72px × 7/60 = 8.4px, 예전엔 6px로 이 비율보다 얇았음). 숫자 폰트도
   .speed-value/.camera-sign과 같은 weight 700 + tabular-nums로 통일해
   과속 애니메이션 전체에서 숫자 두께가 같아 보이게 한다. */
.mini-sign {
  position: relative;
  width: 72px;
  height: 72px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f7f9fc;
  border: 8.4px solid var(--accent-red);
  color: #17181b;
  font-size: 22px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  box-shadow: 0 8px 20px -6px rgba(0, 0, 0, 0.6);
}

/* 1단계: 표지가 "다가온다"는 느낌을 은은한 확산 펄스로 표현(히어로의
   카메라 접근 단계 참고). */
.mini-sign--approach::before {
  content: "";
  position: absolute;
  inset: -14px;
  border-radius: 50%;
  border: 2px solid rgba(232, 56, 63, 0.45);
  animation: mini-approach-pulse 2.2s ease-out infinite;
}

@keyframes mini-approach-pulse {
  0% { transform: scale(0.78); opacity: 0.9; }
  100% { transform: scale(1.35); opacity: 0; }
}

/* 2단계: 히어로의 흰/검 배경 점멸(WarningView)을 표지 둘레의 흰 글로우
   점멸로 축약. */
.mini-sign--flash {
  animation: mini-flash 0.9s steps(2, jump-none) infinite;
}

@keyframes mini-flash {
  50% {
    box-shadow: 0 0 0 8px rgba(247, 249, 252, 0.35), 0 8px 20px -6px rgba(0, 0, 0, 0.6);
  }
}

/* "과속 경고" 단계(2026-09-16 재요청)의 오른쪽 삽화 — 히어로 애니메이션의
   "전방 다수 카메라 중 대상 선별" 장면(select 단계, hero의 11시/2시 후보
   마커)을 축약해 옮겼다. .mini-sign(대상 카메라, 계속 점멸)은 그대로 두고,
   그 둘레에 작은 후보 마커 2개가 서로 다른 타이밍으로 나타났다 사라지길
   반복한다 — 실제 12초 넘게 걸리는 히어로 시퀀스와 달리, 여긴 짧은 무한
   반복 삽화라 두 마커 모두 하나의 루프 안에서 등장/소멸시킨다. */
.mini-radar {
  position: relative;
  width: 72px;
  height: 72px;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 2026-09-17 피드백으로 두 차례 재조정 — "가운데 마커가 최상위, 그 크기는
   줄이고 후보 마커는 키워달라"(1차: 72→58 / 16→20)에 이어 "더 줄이고
   더 키워달라"(2차: 58→50 / 20→24)는 재요청이 왔다. 이 삽화에서만
   .mini-sign을 줄인다(다른 단계의 .mini-sign은 그대로). .mini-radar가
   72px 박스를 유지하며 flex로 가운데 정렬해, 후보 마커의 절대 위치
   (아래 top/left)는 그대로 쓸 수 있다. z-index로 가운데 마커가 항상
   후보보다 위에 오도록 명시했다(원래도 DOM 순서상 위였지만, 이후
   마크업이 바뀌어도 깨지지 않도록). */
.mini-radar .mini-sign {
  width: 50px;
  height: 50px;
  border-width: 5.8px;
  font-size: 15px;
  z-index: 2;
}

.mini-candidate {
  position: absolute;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: #f7f9fc;
  border: 5px solid var(--accent-red);
  opacity: 0;
  z-index: 1;
}

.mini-candidate--a {
  top: -12px;
  left: -14px;
  animation: mini-candidate-a 4.2s ease-in-out infinite;
}

.mini-candidate--b {
  top: -2px;
  right: -18px;
  animation: mini-candidate-b 4.2s ease-in-out infinite;
  animation-delay: 1.6s;
}

/* 2026-09-17 재요청("사라지는 속도를 줄여줘, 지금은 너무 빠르다") —
   전체 주기를 2.8s→4.2s로 늘리고, 정점(peak) 구간을 잠깐 유지한 뒤
   페이드아웃 구간 자체도 27%(756ms)에서 40%(1.68s)로 넓혀 천천히
   사라지게 했다. */
@keyframes mini-candidate-a {
  0%, 8%, 100% { opacity: 0; transform: scale(0.5); }
  28% { opacity: 0.85; transform: scale(1); }
  45% { opacity: 0.85; transform: scale(1); }
  85% { opacity: 0; transform: scale(0.6); }
}

@keyframes mini-candidate-b {
  0%, 8%, 100% { opacity: 0; transform: scale(0.45); }
  28% { opacity: 0.6; transform: scale(0.9); }
  45% { opacity: 0.6; transform: scale(0.9); }
  85% { opacity: 0; transform: scale(0.55); }
}

/* 3단계: 과속 통과 결과(OverspeedSign) — 색 반전(빨간 바탕·흰 테두리·
   검정 숫자)에 짙은 빨강 글로우가 천천히 오간다. */
.mini-sign--overspeed {
  background: var(--accent-red);
  border-color: #f7f9fc;
  color: #17181b;
  animation: mini-overspeed-glow 2.4s ease-in-out infinite;
}

@keyframes mini-overspeed-glow {
  0%, 100% {
    box-shadow: 0 8px 20px -6px rgba(0, 0, 0, 0.6), 0 0 0 0 rgba(232, 56, 63, 0);
  }
  50% {
    box-shadow: 0 8px 20px -6px rgba(0, 0, 0, 0.6), 0 0 0 6px rgba(232, 56, 63, 0.28);
  }
}

/* 4단계: 카메라 위치가 지도 위에 표시되고, 일부는 자동 갱신됐다는 뜻으로
   블루 링 색 배지가 붙는다. */
.mini-map {
  position: relative;
  width: 140px;
  height: 100px;
  border-radius: 14px;
  border: 1px solid var(--panel-border);
  background:
    linear-gradient(rgba(94, 168, 255, 0.08) 1px, transparent 1px) 0 0 / 20px 20px,
    linear-gradient(90deg, rgba(94, 168, 255, 0.08) 1px, transparent 1px) 0 0 / 20px 20px,
    var(--panel);
  overflow: hidden;
}

.mini-map-pin {
  position: absolute;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent-red);
  box-shadow: 0 0 0 3px rgba(232, 56, 63, 0.25);
}

.mini-map-pin:nth-of-type(1) { top: 18%; left: 62%; }
.mini-map-pin:nth-of-type(2) { top: 55%; left: 22%; }
.mini-map-pin:nth-of-type(3) { top: 70%; left: 78%; }
.mini-map-pin:nth-of-type(4) { top: 30%; left: 40%; }

.mini-map-pin.is-updated {
  background: var(--ring);
  box-shadow: 0 0 0 3px rgba(94, 168, 255, 0.3);
}

.mini-map-badge {
  position: absolute;
  top: -6px;
  left: 12px;
  white-space: nowrap;
  background: var(--ring);
  color: #06101f;
  font-size: 9px;
  font-weight: 800;
  padding: 1px 5px;
  border-radius: 999px;
  line-height: 1.5;
}

/* "카메라 DB 보정" 단계 전용 — 아래 5단계(자동 보정 업데이트)의 평범한
   지도와 구분되도록, AI가 지도를 스캔하며 정보를 채우는 느낌을 중앙의
   반짝이는 아이콘 + 확산 펄스로 표현한다. */
.mini-map-ai-icon {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: rgba(94, 168, 255, 0.18);
  border: 1px solid rgba(94, 168, 255, 0.55);
  color: var(--ring);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2;
}

.mini-map-ai-icon svg { width: 13px; height: 13px; }

.mini-map-ai-icon::before {
  content: "";
  position: absolute;
  inset: -9px;
  border-radius: 50%;
  border: 1.5px solid rgba(94, 168, 255, 0.45);
  animation: mini-map-scan 2.4s ease-out infinite;
}

@keyframes mini-map-scan {
  0% { transform: scale(0.6); opacity: 0.9; }
  100% { transform: scale(2.4); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .mini-sign--approach::before,
  .mini-sign--flash,
  .mini-sign--overspeed,
  .mini-map-ai-icon::before,
  .mini-candidate--a,
  .mini-candidate--b {
    animation: none;
  }
}

/* ---------- Ring section ---------- */

.ring-section {
  display: grid;
  grid-template-columns: 0.9fr 1.1fr;
  gap: 56px;
  align-items: center;
  background: radial-gradient(ellipse at 20% 50%, rgba(94, 168, 255, 0.06), transparent 60%);
  border-radius: var(--radius-lg);
}

.ring-section-visual { display: flex; justify-content: center; }

.ring-section-text h2 {
  font-size: clamp(26px, 3vw, 34px);
  font-weight: 800;
  letter-spacing: -0.01em;
  margin: 0 0 18px;
}

.ring-section-text p {
  color: var(--text-dim);
  font-size: 15px;
  max-width: min(52ch, 100%);
  margin: 0 0 14px;
}

.ring-section-text strong { color: var(--text); }

/* ---------- Footer ---------- */

.footer {
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  margin-top: 40px;
}

.footer-inner {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 40px 24px 56px;
}

.footer-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
  margin-bottom: 14px;
}

.footer-note, .footer-copy {
  color: var(--text-faint);
  font-size: 12.5px;
  margin: 0 0 6px;
}

/* ---------- Reveal-on-scroll ---------- */

.reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* ---------- Release notes ---------- */

.releases-head {
  padding-bottom: 24px !important;
}

.releases-head h1 {
  font-size: clamp(28px, 3.4vw, 38px);
  font-weight: 800;
  letter-spacing: -0.01em;
  margin: 0 0 12px;
}

.releases-head-en {
  color: var(--text-faint) !important;
  font-size: 13px !important;
}

.releases-list-section {
  padding-top: 0 !important;
}

.release-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 14px;
}

.release-card {
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-md);
  padding: 22px 24px;
}

.release-meta {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 10px;
}

.release-version {
  font-weight: 700;
  font-size: 15px;
  color: var(--ring);
}

.release-date {
  font-size: 13px;
  color: var(--text-faint);
}

.release-text {
  margin: 0 0 6px;
  font-size: 14.5px;
  line-height: 1.6;
}

.release-text:last-child { margin-bottom: 0; }

.release-text-ko { color: var(--text); }

.release-text-en { color: var(--text-dim); }

.release-loading {
  color: var(--text-faint);
  font-size: 14px;
}

/* ---------- Auto-launch guide page(auto-launch.html) ---------- */

.guide-head { padding-bottom: 24px !important; }

.guide-head h1 {
  font-size: clamp(28px, 3.4vw, 38px);
  font-weight: 800;
  letter-spacing: -0.01em;
  margin: 0 0 12px;
}

.guide-head p {
  color: var(--text-dim);
  font-size: 15px;
  max-width: 62ch;
  margin: 0;
}

.guide-tabs-section { padding-top: 0 !important; }

/* Android/iOS 탭 — 한 번에 한 플랫폼 안내만 보여준다. */
.platform-tabs {
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: 999px;
  margin-bottom: 40px;
}

.platform-tab {
  appearance: none;
  border: none;
  background: transparent;
  color: var(--text-dim);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  padding: 10px 22px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}

.platform-tab:hover { color: var(--text); }

.platform-tab.is-active {
  background: var(--ring);
  color: #06101f;
}

.platform-panel[hidden] { display: none; }

.guide-note {
  background: rgba(94, 168, 255, 0.08);
  border: 1px solid rgba(94, 168, 255, 0.22);
  border-radius: var(--radius-md);
  padding: 14px 18px;
  color: var(--text-dim);
  font-size: 13.5px;
  line-height: 1.6;
  margin: 0 0 32px;
}

.guide-note strong { color: var(--text); }

/* 흐름 다이어그램 — "무엇이 조건이고 무엇이 결과인지"를 글보다 먼저
   그림으로 한눈에 보여준다(요청: "최대한 그림을 활용"). */
.flow-diagram {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 20px;
  padding: 32px 24px;
  margin: 0 0 40px;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-lg);
}

.flow-node {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  width: 130px;
}

.flow-icon {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(94, 168, 255, 0.12);
  border: 1px solid rgba(94, 168, 255, 0.3);
  color: var(--ring);
}

.flow-icon img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
}

.flow-icon svg { width: 26px; height: 26px; }

.flow-node span {
  font-size: 12.5px;
  color: var(--text-dim);
  text-align: center;
  line-height: 1.4;
}

.flow-arrow {
  color: var(--ring);
  font-size: 22px;
  font-weight: 700;
  flex-shrink: 0;
}

.guide-steps {
  list-style: none;
  margin: 0 0 8px;
  padding: 0;
  display: grid;
  gap: 26px;
}

.guide-step {
  display: grid;
  grid-template-columns: 36px 1fr;
  gap: 18px;
  align-items: start;
}

.guide-step-num {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid rgba(94, 168, 255, 0.35);
  color: var(--ring);
  font-weight: 700;
  font-size: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.guide-step h3 {
  margin: 0 0 6px;
  font-size: 16px;
  font-weight: 700;
}

.guide-step p {
  margin: 0;
  color: var(--text-dim);
  font-size: 14px;
  line-height: 1.65;
}

.guide-step p strong { color: var(--text); }

.guide-subhead {
  font-size: 19px;
  font-weight: 800;
  margin: 48px 0 16px;
}

/* 자동 실행 안내의 "선택 사항" 소제목 — guide-subhead 아래 단계로,
   같은 섹션 안에서 본문 흐름을 끊지 않을 만큼만 작게. */
.guide-subhead-sm {
  font-size: 16px;
  font-weight: 700;
  color: var(--text);
  margin: 36px 0 10px;
}

/* ---------- 설정 방법 안내 페이지(setup-guide.html) ---------- */

/* 언어 전환(setup-guide.js)이 <html lang>을 바꾸면, 실제 앱에서 찍은
   한/영 스크린샷 중 해당 언어 쪽만 보이게 한다 — 문구뿐 아니라 화면
   캡처 자체도 언어별로 다르므로 이미지 자체를 통째로 바꿔 끼운다. */
:lang(en) .ko-only { display: none; }
:lang(ko) .en-only { display: none; }

.setup-block {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: 32px;
  align-items: start;
  margin-bottom: 64px;
}

.setup-media { display: flex; justify-content: center; }

/* 실제 기기 스크린샷을 둘러싸는 단순한 폰 프레임 — 히어로의 `.phone`은
   캔버스 애니메이션 전용 구조라 그대로 재사용하기 어려워 새로 만들었다. */
.shot-frame {
  position: relative;
  width: 100%;
  max-width: 220px;
  border-radius: 26px;
  border: 1px solid rgba(148, 163, 184, 0.4);
  box-shadow:
    0 20px 50px -18px rgba(0, 0, 0, 0.8),
    0 0 0 1px rgba(255, 255, 255, 0.06);
  overflow: hidden;
  background: #000;
}

.shot-frame img { width: 100%; display: block; }

/* "여기를 터치하세요" 표시 — 블루 링과 같은 색으로, 화면 중앙에 겹쳐
   그린다(실제 원점 탭 히트 영역과 같은 위치). */
.tap-indicator {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 72px;
  height: 72px;
  transform: translate(-50%, -50%);
  pointer-events: none;
}

.tap-indicator span {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid var(--ring);
  animation: tap-pulse 1.8s ease-out infinite;
}

.tap-indicator span:nth-child(2) { animation-delay: 0.6s; }

@keyframes tap-pulse {
  0% { transform: scale(0.4); opacity: 0.9; }
  100% { transform: scale(1.6); opacity: 0; }
}

.setup-text .guide-step-num { margin-bottom: 12px; }

.setup-text h3 {
  margin: 0 0 10px;
  font-size: 18px;
  font-weight: 700;
}

.setup-text > p {
  margin: 0 0 20px;
  color: var(--text-dim);
  font-size: 14.5px;
  line-height: 1.7;
}

.settings-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 18px;
}

.settings-item.is-sub {
  margin-left: 20px;
  padding-left: 16px;
  border-left: 2px solid var(--panel-border);
}

.settings-item-label {
  font-weight: 700;
  font-size: 14.5px;
  margin-bottom: 4px;
}

.settings-item-desc {
  color: var(--text-dim);
  font-size: 13.5px;
  line-height: 1.6;
}

/* 메뉴 4항목(설정/소개 및 사용법/앱 정보/종료) — settings-item과 같은
   라벨/설명 톤이지만 서브 들여쓰기가 없다. */
.menu-list {
  list-style: none;
  margin: 0 0 20px;
  padding: 0;
  display: grid;
  gap: 16px;
}

/* ---------- Responsive ---------- */

@media (max-width: 860px) {
  .hero { grid-template-columns: 1fr; padding-top: 48px; }
  .hero-visual { order: -1; }
  .br-mobile { display: inline; }
  .cards { grid-template-columns: repeat(2, 1fr); }
  .ring-section { grid-template-columns: 1fr; text-align: left; }
  main section { padding: 64px 20px; }
  .setup-block { grid-template-columns: 1fr; }
  .shot-frame { max-width: 260px; margin: 0 auto; }
}

@media (max-width: 520px) {
  .cards { grid-template-columns: 1fr; }

  /* nav-links는 헤더 아래로 접히는 드롭다운이 되고(.is-open일 때만 펼침),
     그걸 여닫는 햄버거 버튼이 대신 보인다. .nav(sticky)가 이 드롭다운의
     기준 위치가 된다. */
  .nav-toggle { display: flex; }

  .nav-links {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    gap: 0;
    background: rgba(0, 0, 0, 0.94);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    padding: 4px 24px 12px;
  }

  .nav-links.is-open { display: flex; }

  .nav-links a {
    padding: 13px 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  }

  .nav-links a:last-child { border-bottom: none; }

  .steps li { grid-template-columns: 36px 1fr; }

  /* 좁은 화면에서 블루 링/숫자/캡션이 상대적으로 작아 보인다는 피드백(1차
     1.12배로도 부족하다는 재요청) — ring-stage의 마스크·아이콘 두께가
     전부 고정 px라 폰 크기 자체를 키우면 비율이 어긋나므로, .phone
     전체를 transform으로 균일하게 확대한다(내부 conic-gradient·마스크·
     글자 크기가 전부 그대로 비례 커진다).
     transform은 레이아웃 크기에 반영되지 않아 원본 박스(240×384px, 갤럭시
     Z Fold8 커버 디스플레이 비율 10:16로 맞춘 값)보다 커진 만큼 사방으로
     그냥 넘치는데, 1.3배 이상에서는 예전처럼 .hero의 grid gap만으로 세로
     초과분을 못 흡수해 아래 헤드라인 텍스트와 겹친다 — 그래서
     --mobile-phone-scale 커스텀 프로퍼티 하나를 .hero-visual/.phone이
     함께 참조하게 하고, .hero-visual의 min-height를 "원본 높이 × 배율"로
     미리 확보해(+ align-items:center) 넘친 부분이 이 컨테이너 안에서만
     흡수되고 이웃 요소를 침범하지 않게 한다(.phone의 height가 바뀔
     때마다 이 384px도 같이 맞춰야 함). 가로는 body의 overflow-x:hidden이
     뷰포트 경계에서 그냥 잘라주므로(가장 좁은 320px 기기 기준 약
     1.33배까지 안전) 1.3은 그 안에서 여유를 두고 고른 값이다. */
  .hero-visual {
    --mobile-phone-scale: 1.3;
    min-height: calc(384px * var(--mobile-phone-scale));
    align-items: center;
  }
  .phone { transform: scale(var(--mobile-phone-scale)); }

  /* 하단 캡션은 위 .phone 확대(1.3배)를 그대로 따라가지만, "그것만으로는
     아직 작다"는 재요청으로 캡션 자체의 선언 크기도 한 번 더 키웠었다
     (font-size 12→15px). 2026-09-15 재요청으로 캡션이 최대 2줄까지
     늘어나면서, 늘어난 문구의 긴 줄("15초 뒤 전방에 100km 카메라..",
     실측 약 191px)을 15px에서 그대로 쓰면 패딩을 더해 .phone의 로컬
     238px 폭에 거의 닿아버린다(15px 기준 실측 약 217px). 대신 13px로
     한 단계만 낮춰(데스크톱 12px보다는 여전히 크다) 그 문구가 실측 약
     191px에 머물게 하고, 220px 상한에 여유(약 9px씩)를 남겼다.
     2026-09-16 재요청으로 warning 단계가 3줄이 필요해져(위 데스크톱
     규칙 주석 참고) 높이도 2줄→3줄 기준으로 늘렸다. */
  .phone-caption {
    max-width: 220px;
    height: 62px;
    font-size: 13px;
    padding: 5px 12px;
  }
}
