/* IA v2 (SAYO_IA_V2) 전용 스타일시트.
 *
 * 이 파일은 플래그가 ON 인 빌드에서만 dist 로 나가고, 그때만 두 셸
 * (base.html · app/base.html) 의 head 에 <link> 로 실린다. `style.css` 에는 한
 * 바이트도 넣지 않는다 - 그 파일은 OFF 산출물의 정본이라 거기 규칙을 더하면
 * "OFF 빌드 바이트 무변" 오라클이 그 자리에서 죽는다. 고양이 `cat/` · 셸
 * `app-shell/` 과 같은 처분이다.
 *
 * 규율 둘:
 *   - 모든 선택자는 `body.ia-v2` 아래로 스코프한다. 스코프 밖 규칙은 OFF
 *     산출물에는 안 실리지만, ON 에서 v2 가 아닌 표면(법무·어드민 셸)까지
 *     번질 자리를 만든다.
 *   - 값은 `var(--...)` 토큰만 쓴다 (DESIGN 3.6). 색·간격 리터럴 금지.
 */

/* [U2-0] 플래그 스코프. 규칙은 후속 유닛이 채운다. */
body.ia-v2 {
}

/* [U2-1] 경량 크롬 헤더 - 로고(좌) + 대시보드 CTA(우) 한 줄.
 *
 * 탭 레일(`nav.site-nav-links`)도 로그인 UI 도 ON 에서는 DOM 에 없으므로
 * `style.css` 의 그 규칙들은 무효화할 대상 자체가 없다(부재로 닫는다).
 * 여기서 잠그는 것은 남은 두 요소가 좁은 폭에서도 한 줄을 유지하는 것과,
 * CTA 가 "채운 버튼" 으로 읽히는 것 둘뿐이다.
 */
body.ia-v2 .site-header-lite .site-header-inner,
body.ia-v2 .site-header-lite .site-header-actions {
  flex-wrap: nowrap;
}

/* 채운 라운드 버튼. 값은 전부 tokens.css 의 기존 토큰이다 - 새 팔레트 0.
 * 높이 40px 는 Kevin 지시값이고, coarse pointer 의 44px 탭 표면 규칙
 * (`style.css` 의 단 하나뿐인 M-3 블록 안 `.nav-app-open` 선언)이 그 위에
 * 그대로 얹히므로 모바일 히트 영역은 44px 로 남는다. */
body.ia-v2 .site-header-lite .nav-app-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 40px;
  padding: 0 18px;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  box-shadow: var(--shadow-card);
  transition: background-color 120ms ease-out;
}

body.ia-v2 .site-header-lite .nav-app-cta:hover {
  background: var(--accent-strong);
  /* `style.css` 의 `.nav-app-open:hover { color: var(--accent) }` 는 채운 면
   * 위에서 글자를 배경색과 같게 만든다. 채운 버튼에서는 글자색이 안 움직인다. */
  color: var(--accent-ink);
}

body.ia-v2 .site-header-lite .nav-app-cta:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}

/* [IA-V2 LANDING] 랜딩 히어로 상하배열 - 태그라인 -> 리드 -> 검색창 -> 데모.
 *
 * Kevin 2026-09-17 "9k1 처럼 태그라인-검색창-데모 상하배열" + 승인 시안
 * (`ui-critique-20260917/landing-layouts.html` (A) 안, "랜딩 시안 굿").
 *
 * 템플릿은 무접촉이다 - `about.html` 의 DOM 순서가 이미 h1 -> 리드 ->
 * `.hero-search-col`(폼) -> `<aside class="search-preview hdemo">` 다. 2열은
 * `style.css` 의 `.about-hero .about-hero-grid`(2열 그리드)가 만들고 900px
 * 이하에서는 이미 1열로 접힌다. 그러니 여기서 할 일은 그 그리드를 **전 폭에서**
 * 1열로 고정하는 것 하나다 - 데스크톱이 모바일과 같은 순서로 읽힌다.
 *
 * 열 폭은 검색창 폭에 맞춘다: `style.css` 의 `.hero-search-col` 상한
 * 640px [실측] 이 이 지면의 측정 폭이고, 말(제목·리드)과 데모 카드가 그
 * 폭을 공유해야 세 요소가 한 기둥으로 읽힌다. 640 은 토큰에 없는 값이라
 * 리터럴을 흘리는 대신 이 파일 스코프의 변수 하나로 든다(DESIGN 3.6 의
 * "값은 var() 로" 를 지키는 방법 - 새 전역 토큰을 만들지는 않는다).
 */
body.ia-v2 {
  --ia-v2-hero-col: 640px;
}

body.ia-v2 .about-hero .about-hero-grid {
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
  gap: var(--space-6);
}

body.ia-v2 .about-hero .about-hero-main,
body.ia-v2 .about-hero .search-preview.hdemo {
  width: 100%;
  max-width: var(--ia-v2-hero-col);
}

/* 한 기둥이 되었으므로 말은 가운데 정렬이다(2열 시절의 왼쪽 정렬은 오른쪽
 * 카드와 짝을 이루던 조형이다). `style.css` 가 2열을 위해 리드·검색창의
 * 자동 여백을 0 으로 눌러 뒀으므로(`.about-hero .about-hero-grid .hero-lede`
 * 계열) 그것부터 되돌린다 - 안 되돌리면 `text-align: center` 가 리드
 * 상한폭(560px) **안에서만** 글을 가운데로 옮겨, 640px 기둥 안에서 리드
 * 덩어리 자체가 왼쪽에 붙은 채로 남는다. 물리 롱핸드로 쓴다 - 되돌릴 선언이
 * `margin-left`/`margin-right` 라 같은 축으로 겹쳐야 캐스케이드가 자명하다. */
body.ia-v2 .about-hero .about-hero-main {
  text-align: center;
}

body.ia-v2 .about-hero .about-hero-grid .hero-lede,
body.ia-v2 .about-hero .about-hero-grid .hero-search-col {
  margin-left: auto;
  margin-right: auto;
}

/* [IA-V2 FOLD] 첫 화면 완결 - 경량 헤더 높이로 재실측한 3구간.
 *
 * `style.css` 의 `[FOLD-COMPLETE]` 블록(94/61/89)은 5탭 레일이 있던 OFF
 * 헤더의 값이다. IA v2 의 `site-header-lite`(로고 + 대시보드 CTA 한 줄)는
 * 그보다 낮으므로 같은 값을 쓰면 히어로가 필요 이상으로 길어지고 첫 화면
 * 하단에 빈 띠가 남는다. `style.css` 는 한 바이트도 안 만진다(OFF 정본) -
 * 그래서 재실측 값은 여기서 `body.ia-v2` 스코프로 얹는다.
 *
 * 실측(2026-09-18, playwright 헤드리스, .venv-new 1.55, ON 3플래그 빌드,
 * `.site-header` getBoundingClientRect().height, 26개 폭 스윕):
 *   <=640px:    50.234px (320~640 전 폭 동일)
 *   641~720px:  62.828px (641~719), 720px 에서 90.828px
 *   >=721px:    90.828px (721~1920 전 폭 동일)
 * 과소추정(가정 <= 실측)이 유일하게 안전한 방향이다 - 뺄셈 값이 작을수록
 * 히어로가 커져서 다음 절이 폴드 밖으로 더 밀린다(`style.css` 의 같은 블록
 * 주석 그대로). 그래서 50 / 62 / 90 으로 내림한다. 641~720 단이 62 인 것은
 * 그 단의 **최솟값**(62.828, 720px 의 90.828 이 아니라)을 따른 것이다 -
 * OFF 가 61 을 쓴 것과 같은 규율이다.
 *
 * vh 를 먼저, svh 를 뒤에 선언한다 - svh 미지원 브라우저는 뒤 선언이 무효라
 * 앞선 vh 가 캐스케이드에 남는다(선언 **순서**가 계약이다).
 *
 * 헤더 높이가 또 바뀌면 이 세 값을 다시 실측해야 한다.
 */
body.ia-v2 .hero.about-hero {
  min-height: calc(100vh - 50px);
  min-height: calc(100svh - 50px);
}
@media (min-width: 641px) {
  body.ia-v2 .hero.about-hero {
    min-height: calc(100vh - 62px);
    min-height: calc(100svh - 62px);
  }
}
@media (min-width: 721px) {
  body.ia-v2 .hero.about-hero {
    min-height: calc(100vh - 90px);
    min-height: calc(100svh - 90px);
  }
}

/* [IA-V2 HERO SCALE] 표제 한 단 축소 + 히어로 상단 여백 축소.
 *
 * 승인 시안 (A) 안 6항 (2): "헤드라인 48px 상당(현 62px 축소) + 히어로 상단
 * 여백 축소 -> 1280x800 첫 화면에 데모 카드 전체 + 입력 도크까지".
 *
 * [계획서 정정] 62px 은 전역 `.hero-title`(`style.css` 의 clamp 36~62) 이고,
 * **랜딩** 은 이미 `.about-hero .hero-title` 로 clamp 32~52 로 내려와 있다
 * [실측: 1280 에서 52px]. 그래서 이 유닛의 실제 델타는 52 -> 48 이다.
 * 상한만 낮추는 것이 목적이므로 규칙을 641px 이상으로 스코프한다 - 모바일
 * (<=640) 의 26px 은 승인 시안의 폰 캔버스가 그대로 든 값이라 건드리지
 * 않는다(시안 `.phone .m-h1` 환산 ~26px). 전 폭에 걸면 clamp 하한 32px 이
 * 모바일 표제를 26 -> 32 로 **올려** 시안과 어긋나고, 360px 폭에서 표제가
 * 3행으로 접혀 데모 카드의 폴드 수납 여유를 그만큼 먹는다
 * [실측 2026-09-18, 360px 에서 리터럴 clamp 시 h1 67.6 -> 83.2 = +15.6px].
 *
 * 4vw 는 641~1200 구간을 잇는 기울기다 - 1200px 에서 48px 에 닿고 그 위는
 * 상한에 고정된다.
 */
@media (min-width: 641px) {
  body.ia-v2 .about-hero .hero-title {
    font-size: clamp(32px, 4vw, 48px);
  }
}

/* 상단 여백: `style.css` 가 <=640 에 --space-4(16px), >=641 에 --space-6(24px)
 * 을 준다. ON 은 641 이상에서만 --space-2(8px) 로 줄인다 - 모바일은 이미
 * 데모 카드가 폴드 안에 수납돼 있어(오라클 5) 회수할 이유가 없고, 데스크톱만
 * 16px 을 되찾아 데모 카드 + 입력 도크를 첫 화면에 넣는다. 새 토큰 0.
 *
 * 721 이상에서는 `style.css` 의 수직 센터링(`margin-top/bottom: auto`)이
 * 회수분의 절반을 다시 위아래로 배분한다 - 도크가 폴드에 닿을 만큼 빡빡해지면
 * 여기서 한 단 더 줄이는 대신 그 센터링 블록을 다시 읽어야 한다(값만 깎으면
 * 첫 화면이 상단 앵커로 되돌아간 것처럼 보인다). */
@media (min-width: 641px) {
  body.ia-v2 .hero.about-hero {
    padding-top: var(--space-2);
  }
}

/* [IA-V2 DOCK] 데모 입력 도크 - 죽은 어포던스 수리 (K15 채택).
 *
 * Kevin 2026-09-17 "입력 도크는 모양 유지, 죽은 어포던스만 수리 (클릭 시
 * 실제 검색창 포커스). 제거 금지". `style.css` 의 `.hdemo-dock` 은
 * `pointer-events: none` 인 순수 장식 `<div>` 다 - ON 에서는 `about.html` 이
 * 같은 자리를 `<button type="button">` 으로 바꾸고 여기서 UA 기본값을 지운다.
 * **모양은 한 픽셀도 안 바꾼다** - 패딩·배경·윗줄·간격은 전부 `style.css` 의
 * 같은 선언이 계속 진다.
 *
 * [정정 2026-09-18, #1303 리뷰 실측] 이전 판은 `pointer-events: auto` 를
 * `.hdemo-set-primary` 에만 줘 놓고 "회전 세트의 독은 `pointer-events: none`
 * 그대로라 클릭이 통과해 이 버튼에 닿는다 = 어느 프레임에서 눌러도 어포던스가
 * 산다" 고 적었다 - 거짓이다. 회전자가 세트 1 을 `visibility: hidden` 으로
 * 내리는 구간(세트 2 개 · 16s 루프에서 48.5~97%)에는 세트 1 이 히트 테스트
 * 자체에서 빠지므로 "통과해 닿을" 버튼이 없다. 그 좌표의 클릭은 회전 세트의
 * `.hdemo-set` 컨테이너에 잡히고 `activeElement` 는 BODY 로 남았다
 * [실측 2026-09-18: 390x844 · 1280x800 양쪽, activeElement id 빈 값].
 *
 * 그래서 **전 세트의 독**을 켠다. 겹침 충돌은 없다 - `visibility: hidden` 은
 * 포인터 이벤트와 접근성 트리 양쪽에서 빠지는 유일한 값이라(`about.html` 의
 * `@keyframes hdemo-set-*` 주석) 어느 프레임에서든 **보이는 세트의 독 하나**만
 * 히트 테스트에 남는다 - 도크에 뜬 질의와 검색창에 실리는 질의도 늘 같은 세트
 * 것이다(오라클이 실린 질의까지 같이 잰다:
 * `test_dock_click_focuses_the_real_searchbox_in_a_rotating_frame`).
 * 회전 세트는 템플릿이 `tabindex="-1"` 로 **포커스 순서에서만** 뺀다 - 탭
 * 스톱은 여전히 세트 1 하나다(`test_only_one_dock_is_a_tab_stop`).
 * `.hdemo-cta` 앵커는 무접촉이다 - 그쪽 세트별 목적지는 그대로 자기 세트를
 * 따른다.
 *
 * 셀렉터가 `button.hdemo-dock` 인 것은 의도적이다 - 독을 장식 `<div>` 로
 * 되돌리면 `style.css` 의 `pointer-events: none` 이 그대로 남아 어포던스가
 * 히트 테스트 층에서 죽는다(= 사보타주가 오라클의 클릭 경로에서 red).
 */
body.ia-v2 button.hdemo-dock {
  width: 100%;
  border-right: 0;
  border-bottom: 0;
  border-left: 0;
  border-radius: 0;
  font: inherit;
  color: inherit;
  text-align: inherit;
  pointer-events: auto;
  cursor: pointer;
  position: relative;
  z-index: 1;
}

/* 포커스 링은 토큰(`--ring`). `outline-offset` 이 음수인 것은 독이 카드
 * 바닥에 맞물려 있어(아래 모서리 = 카드 모서리) 밖으로 나간 링이 카드 밖으로
 * 삐져나오기 때문이다. */
body.ia-v2 button.hdemo-dock:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: -2px;
}

/* `prefers-reduced-motion: reduce` 에서는 `html.js-demo` 자체가 안 붙는다
 * (`search-preview-demo.mjs` 가 no-preference 에서만 클래스를 준다) -> 회전
 * 세트는 `display: none`, 세트 1 은 질의 전문이 다 쳐진 **정지 프레임**이고
 * 그 독이 이 버튼이다. 즉 여기에 애니메이션을 끄는 규칙을 더할 자리가 없다 -
 * 끌 애니메이션이 애초에 안 걸린다. 그 사실을 오라클
 * (`test_reduced_motion_keeps_a_still_clickable_dock`)이 잰다. */

/* [U2-7 APP-MODE] 앱 모드 - 공개 URL 문서 위 셸 레일 (계획서 §3.5).
 *
 * 술어는 CSS 가 아니라 head 프리페인트(`_app_mode_prepaint.html`)가 진다: 로그인
 * 세션 키가 있으면 `<html>` 에 `app-mode` 가 붙고 여기 규칙이 그 클래스로 선다.
 * 그래서 이 블록이 `panel.css` 가 아니라 이 파일에 산다 - `panel.css` 는
 * `panel.mjs` 부트가 늦게 심는 링크라 **프리페인트가 될 수 없다**. 패널 자신의
 * 상자(`.sp-overlay` 기하)는 그쪽이, 지면이 비켜 앉는 일은 여기가 한다.
 *
 * 값은 전역 토큰만 쓴다. `--sp-*` 는 `panel.css` 의 `.sayo-panel` 스코프라 이
 * 시점에 정의되지 않았다(빈 var() 는 조용히 상속색이 된다) - 그 파일이 읽는
 * **전역 원본**(`--panel`·`--line`)을 같은 값으로 읽고, 그 미러 관계는 레일
 * 기하 미러 테스트가 panel.css 에서 유도해 잠근다(파일명은 여기 적지 않는다 -
 * 앞선 판이 엉뚱한 파일을 가리켰고, 출하되는 바이트는 옮겨 다니는 좌표를 들고
 * 있어야 할 이유가 없다).
 * 리터럴 둘은 선언한다: z-index 59(= `.sp-overlay` 의 60 바로 아래, 도킹
 * 자리표시자가 70 아래 69 를 쓴 것과 같은 규율)와 <1024 탭 표면 44px
 * (손가락 최소 표면은 팔레트가 아니라 접근성 상수다, WCAG 2.5.5).
 */

@media (min-width: 1024px) {
  /* 레일 폭은 `panel.css .sayo-panel.sp-page` 의 그리드 트랙과 **같은 문자열**
   * 이어야 한다(미러 테스트 대상). 패널이 `--sp-side-w` 를 재정의하면 본문
   * 패딩이 같이 따라간다. */
  html.app-mode body.ia-v2 {
    padding-left: var(--sp-side-w, 280px);
  }
  /* 레일 표면 자리표시자. `panel.css` 가 도착하기 전 한 프레임을 메운다 -
   * 도킹의 `style.css body.sayo-shell.sp-prepaint::after` 와 같은 처분이고,
   * 색도 같은 방식으로 실제 사이드바(`.sp-page .sp-side` = 배경 `--sp-inset` ·
   * 우측 경계 `--sp-border`)가 읽는 전역 토큰을 그대로 읽는다. */
  html.app-mode body.ia-v2::before {
    content: "";
    position: fixed; top: 0; left: 0; bottom: 0;
    width: var(--sp-side-w, 280px);
    z-index: 59;
    background: var(--panel); border-right: 1px solid var(--line);
  }
  /* [U2-7c] 고양이가 걸어 들어가지 않을 좌측 구간. 레일은 z 60 이고 고양이는
   * z 49 라, 레일이 덮은 좌측 280px 로 들어간 고양이는 그냥 안 보인다(고양이를
   * 레일 위로 올리는 안은 기각이다 - 사이드바 바닥 계정 행이 클릭 표면이라 그
   * 위에 앉으면 클릭을 먹는다, 계획서 §3.7). `cat.mjs` 가 이 변수 하나를 읽어
   * 보행 구간·착지·홈·리사이즈 클램프의 좌측 경계를 한꺼번에 옮긴다.
   *
   * 변수가 없는 면(플래그 OFF · 비앱모드 · <1024 드로어 폭)에서는 고양이가
   * 0 을 읽어 **현행 그대로** 움직인다 - 부재로 닫는다.
   *
   * 폭 표현은 위 본문 패딩·자리표시자와 **같은 것**이다. 셋이 한 값이어야
   * 고양이가 서는 경계와 레일의 경계가 픽셀로 맞는다. 값을 여기서 따로 쓰지
   * 말고 그 둘이 옮겨가면 같이 따라가게 둔다. */
  html.app-mode body.ia-v2 {
    --sayo-cat-inset-left: var(--sp-side-w, 280px);
  }
  /* [U2-7 K-3] 데스크톱 앱 모드의 공개 헤더는 사라진다 - 사이드바가 유일한
   * 내비다(푸터는 법적 고지라 유지, DESIGN D4). Kevin 실견 뒤 뒤집을 수 있게
   * **독립 1규칙**으로 격리한다: 되돌리기는 이 블록 한 덩이 삭제다. */
  html.app-mode body.ia-v2 .site-header {
    display: none;
  }
}

@media (max-width: 1023px) {
  /* 드로어 폭에서는 본문을 밀지 않고(위 규칙이 1024 스코프라 부재로 닫힌다)
   * 공개 경량 헤더가 그대로 선다. 대신 `.sp-overlay > .sp-sidetoggle` 이
   * 좌상단 44px 고정 탭이라 헤더 로고와 겹친다 - 그 폭만큼 헤더 안쪽을 민다.
   * 헤더 상자가 아니라 `-inner` 를 미는 이유: 헤더의 배경·경계는 전폭으로
   * 남아야 하고 움직여야 하는 것은 로고부터의 내용뿐이다. */
  html.app-mode body.ia-v2 .site-header-inner {
    padding-left: 44px;
  }
}
