/* AIDRA Apple 베이스·셸·공통 컨트롤 (DESIGN.md).
 * 단일책임: reset·body·셸(헤더/메인)·버튼·입력·중립(미인증) 화면.
 * 위저드/스텝 세부 컴포넌트는 components.css. 토큰은 tokens.css(@import).
 * 키·모델명·원문 없음 — 순수 표현 CSS. CDN 폰트 로드 없음(system stack — egress 0). */
@import url('/ui/tokens.css');
@import url('/ui/components.css');
@import url('/ui/skeleton.css');
@import url('/ui/cosmos.css');

* { box-sizing: border-box; }
[hidden] { display: none !important; }
*::selection { background: rgba(0, 102, 204, 0.14); color: var(--accent); }

/* ── 스크롤바 — 앱 전체 단일 디자인(트랙 투명 · 얇고 반투명한 손잡이만) ──
 * 전엔 규칙이 없어 UA 기본값(흰 트랙 + 회색 손잡이)이 다크 캔버스 위에 그대로 나왔다(오너 지적 2026-08-05).
 *
 * ⚠️ 표준(scrollbar-width/color)과 ::-webkit-scrollbar 는 **공존하지 않는다**. Chrome 121+ · Firefox 는
 *   표준값이 auto 가 아니면 webkit 의사요소를 **통째로 무시**한다(사양). 아래 webkit 블록은
 *   그것을 모르는 구형 Safari/Chrome 전용 폴백이다 — 둘은 반드시 같은 그림을 그려야 한다.
 *   그래서 스크롤바를 **숨기는 곳도 반드시 둘 다** 써야 한다(scrollbar-width:none + ::-webkit-scrollbar{display:none}).
 *   하나만 쓰면 한쪽 브라우저에서 조용히 다시 나타난다 — 현재 숨기는 3곳(.wiz-rail · .ph-tb-chips · .feed-carousel)은 둘 다 있다.
 *
 * scrollbar-color 는 상속되므로 :root 한 번이면 닿고(뷰포트 스크롤바 포함), scrollbar-width 는 비상속이라 * 가 필요하다. */
:root { scrollbar-color: var(--scroll-thumb) transparent; }
* { scrollbar-width: thin; }

*::-webkit-scrollbar { width: 10px; height: 10px; background: transparent; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-corner { background: transparent; }
/* border+background-clip = 손잡이 양옆 2px 여백(트랙 없이 떠 있는 모양). */
*::-webkit-scrollbar-thumb {
  background: var(--scroll-thumb);
  border: 2px solid transparent;
  background-clip: padding-box;
  border-radius: var(--r-pill);
}
*::-webkit-scrollbar-thumb:hover { background: var(--scroll-thumb-hover); background-clip: padding-box; }

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

body {
  margin: 0;
  min-height: 100%;
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  letter-spacing: var(--ls-body);
  color: var(--ink);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* 헤더 글꼴(SUIT) — 헤딩 요소와 헤딩 역할 클래스. 입력·버튼 안의 제목(final-doc-title-btn 등)은 inherit 로 따라온다. */
h1, h2, h3, h4, h5, h6,
.hub-title, .hub-section-title, .home-section-title, .home-hero-title, .home-greeting-title, .home-onboard-title,
.iv-hero-title, .wiz-step-title, .lib-ins-title, .trend-section-title, .settings-section-title,
.vlab-projects-title, .ep-drawer-title, .epr-title, .audio-intro-title, .frame-block-title, .sm-title {
  font-family: var(--font-heading);
}

/* ── 좌측 GNB 독(글라스 카드 — fixed, flow 밖. 인증 시 body.shell-chrome 으로만 노출) ── */
/* fixed 라서 body.iv-mode 세로 플렉스 캐스케이드를 건드리지 않는다 — main 우측 오프셋은 body padding-left 가 전담.
 *
 * 형태: 화면에 붙은 전폭 패널이 아니라 **네 변이 닫힌 떠 있는 카드**다(오너 지정 2026-07-30,
 *   Framer Sidebar Dock Menu). 원본 값: 라운드 20px · 1px rgba(255,255,255,0.08) 보더 · 패딩 16 ·
 *   blur(10px) 유리 · 세로 space-between(위=브랜드+메뉴, 아래=액션+계정).
 *   의도적 차이: 라운드·간격·유리는 제품 토큰(--r-lg 18 · --sp-md · saturate(180%) blur(20px))을 쓴다 —
 *   원본 수치를 그대로 박으면 하단 툴바 독·rail-mini 와 미세하게 다른 유리가 하나 더 생긴다.
 * ⚠️ 폭 계약: body 는 여전히 --sidebar-w(240) 만큼 padding-left 로 자리를 비운다. 카드는 그 **레인 안쪽**에
 *   좌우 여백을 두고 앉는다 — 카드 폭을 240 으로 두면 여백만큼 콘텐츠를 침범한다. */
.shell-sidebar {
  position: fixed;
  left: var(--sp-sm); top: var(--sp-sm); bottom: var(--sp-sm);
  z-index: 70;                   /* 드로어 백드롭(60)·드로어(61) 위 — 생성(백그라운드 잡) 중에도 좌측 nav 클릭 허용 */
  width: calc(var(--sidebar-w) - var(--sp-sm) * 2);
  display: none;                 /* 미인증 = 숨김(C-7). body.shell-chrome 일 때만 표시. */
  flex-direction: column;
  gap: var(--sp-md);
  padding: var(--sp-md);
  background: rgba(15, 15, 23, 0.66);   /* 카드가 콘텐츠 위에 떠 있으므로 붙어 있을 때(0.55)보다 한 단계 진하게 */
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 12px 40px rgba(0, 0, 0, 0.45);
  animation: dock-in var(--t-mid) var(--ease) both;
}
/* 펴기(display:none → flex)마다 재생된다 — 접기는 즉시(펴진 뒤 사라지는 카드를 기다릴 이유가 없다).
 * 원본은 spring(bounce 0) = 오버슈트 없는 감쇠라, 제품 토큰 --ease 가 같은 느낌이다. */
@keyframes dock-in {
  from { opacity: 0; transform: translateX(-12px); }
  to { opacity: 1; transform: none; }
}
body.shell-chrome .shell-sidebar { display: flex; }
/* 인증(크롬 on)에서만 메인 컬럼을 레일 폭만큼 우측으로. 미인증 게이트는 풀블리드 유지. */
body.shell-chrome { padding-left: var(--sidebar-w); }

/* 레일 헤더(브랜드 + 접기 토글) */
.sidebar-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-sm); }
/* 접기/펴기 토글(아이콘 버튼 — 미니멀·투명 배경) */
.rail-toggle {
  display: flex; align-items: center; justify-content: center;
  position: relative; width: 30px; height: 30px; padding: 0; flex-shrink: 0;
  font-size: 17px; line-height: 1;
  color: var(--ink-48); background: transparent; border: 1px solid transparent;
  border-radius: var(--r-sm);
  transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.rail-toggle:hover { color: var(--ink); background: rgba(255,255,255,0.06); }
/* 히트영역 40×40 확보 — 시각 30 유지, 가상요소로 클릭/터치 영역만 확장(#16) */
.rail-toggle::after { content: ''; position: absolute; inset: -5px; }
/* 사이드바 헤더 우측 액션 그룹(전체검색 트리거 + 접기 토글) — 사이드바 헤더가 3개 자식이되어도 space-between 이 중간을 띄우지 않게 묶음. */
.sidebar-head-actions { display: flex; align-items: center; gap: 2px; flex-shrink: 0; }
/* (검색 트리거 .gs-trigger 는 우측 상단 클러스터로 이관 — topActions.js/feed.css .top-actions) */
/* 접힘 상태에서만 노출되는 좌상단 플로팅 미니 헤더 — 로고 유지 + 펴기 버튼(레일 숨겨도 브랜드는 안 사라짐) */
.rail-mini {
  position: fixed; left: var(--sp-sm); top: var(--sp-sm); z-index: 71;
  display: none; align-items: center; gap: var(--sp-xs);
  padding: 5px 6px 5px 12px;
  background: rgba(15, 15, 23, 0.55);
  backdrop-filter: saturate(180%) blur(20px); -webkit-backdrop-filter: saturate(180%) blur(20px);
  border: 1px solid var(--hairline); border-radius: var(--r-md);
}
.rail-mini-brand { display: flex; align-items: center; gap: 0.28em; font-weight: 600; font-size: var(--fs-body); letter-spacing: var(--ls-tagline); color: var(--ink); }
/* 접힘(rail-collapsed): 레일 숨김 + 메인 풀폭 + 고정요소 좌측 0 + 펴기 버튼 노출. 인증(shell-chrome)일 때만 적용. */
body.shell-chrome.rail-collapsed { padding-left: 0; }
body.shell-chrome.rail-collapsed .shell-sidebar { display: none; }
body.shell-chrome.rail-collapsed .rail-mini { display: flex; }
body.shell-chrome.rail-collapsed .wiz-composer { left: 0; }
body.shell-chrome.rail-collapsed .app-toast { left: 50%; }
.brand {
  display: flex;
  align-items: center;
  gap: 0.28em;
  font-weight: 600;
  font-size: var(--fs-tagline);
  letter-spacing: var(--ls-tagline);
  color: var(--ink);
  cursor: pointer;
  padding: 0 var(--sp-sm);        /* nav 항목 텍스트 인셋과 좌측 정렬 — 이제 맞춰지는 건 심볼의 좌측 변이다 */
}
/* 브랜드 심볼 — 정본 SVG 를 알파 마스크로 깔고 색은 currentColor 로 준다(워드마크와 같은 잉크를 자동으로 따라간다).
 *
 * 🔴 크기는 px 이 아니라 **1em** 이다. 고정 22px 을 쓰던 첫 판은 워드마크와 안 붙어 보였다 — 실측으로 원인이
 *   나왔다: 이 SVG 는 viewBox 안에 상하좌우 약 6% 여백을 품고 있어 잉크가 상자의 88.5% 이고, 22px 상자면
 *   잉크가 19.0px 인데 Pretendard 18px 의 캡 높이는 13.0px 이다(잉크 = 캡의 **1.46배** → 글자 위아래로 3px 씩
 *   넘쳐 딴 물체로 읽힌다). 세로 중심은 그때도 정확히 맞아 있었다 — 어긋난 건 정렬이 아니라 비율이었다.
 *   1em 이면 잉크 = 0.885em ≈ 캡의 1.22배로, 원형 마크에 필요한 만큼만 넘친다. 글꼴 크기가 다른 세 표면
 *   (새 셸 18px · 구 셸 21px · 미니 레일 15/17px)이 각자 알아서 맞는다 — 표면마다 px 을 손으로 적지 않는다.
 * ⚠️ 하한 16px 은 광학 때문이다: 5날개가 가늘어 날개 하나가 1px 아래로 내려가면 회색 죽으로 뭉갠다
 *   (DESIGN.md 'AIDRA 심볼' — 파비콘이 512 축소본이 아니라 별도 광학 판인 이유가 이것이다).
 *   1× 에서 15~26px 을 실제로 래스터해 봤고 전부 날개가 분리되지만, 15px 이 가장 빠듯해 한 단 위를 바닥으로 둔다.
 * ⚠️ gap 도 em 이다. 위 여백 6% 때문에 **상자 사이 간격보다 눈에 보이는 간격이 더 넓다** — 0.28em 이 잉크
 *   기준 약 0.5 캡(로고 락업 관례)으로 떨어진다. px 로 적으면 표면마다 다시 어긋난다.
 * ⚠️ 마지막 -0.03em 은 폰트 메트릭 보정이다. `align-items: center` 는 심볼을 **라인박스** 중앙에 두는데
 *   눈이 맞추는 기준은 캡 높이 중앙이고, 그 둘은 디센더 몫만큼 어긋난다(실측 0.5px @18px = 0.028em).
 *   글꼴 크기에 비례하는 값이라 em 으로 적는다. 지우면 심볼이 글자보다 살짝 내려앉는다. */
.brand-mark {
  flex: none;
  width: max(1em, 16px); height: max(1em, 16px);
  margin-top: -0.03em;
  background: currentColor;
  -webkit-mask: url("/assets/aidra-mark.svg") center / contain no-repeat;
  mask: url("/assets/aidra-mark.svg") center / contain no-repeat;
}
.shell-nav {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--sp-xxs);
  /* 짧은 뷰포트에서 메뉴가 독 카드 밖으로 넘치지 않게 — 브랜드·하단(액션·계정)은 제자리, 메뉴만 스크롤한다. */
  min-height: 0;
  overflow-y: auto;
}
.nav-btn {
  position: relative;
  width: 100%;
  text-align: left;
  white-space: nowrap;            /* 한글 라벨 자모 단위 줄바꿈 방지(모바일 가로 바 포함) */
  font-size: var(--fs-caption);
  letter-spacing: var(--ls-caption);
  color: var(--ink-48);
  background: transparent;
  border: none;
  border-radius: var(--r-sm);
  padding: 10px var(--sp-sm);
  transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
/* ⚠️ 메뉴 항목은 텍스트만 — 아이콘 넣지 말 것(오너 요청 2026-07-28). navRail.js 주석 참고. */
.nav-btn:hover { color: var(--ink); background: rgba(255,255,255,0.06); }
.nav-btn--active { color: var(--ink); font-weight: 600; background: rgba(255,255,255,0.08); }
.nav-btn--active:hover { background: rgba(255,255,255,0.11); }
/* 검색+알림 — 사이드바 최하단(레일 하단 고정은 여기가 담당, auth-area 는 바로 뒤따름). topActions.js 가 채움.
   44×44 아이콘 버튼(feed-notif-bell과 동일 규칙) — 우측 상단 고정 배치가 우측 드로어와 겹치던 문제(오너 지적) 해소. */
.sidebar-foot { display: contents; } /* 하단 묶음 래퍼 — 새 셸 데스크톱 독만 레이아웃에 쓴다(v2/sidebar-dock.css) */
.sidebar-actions { margin-top: auto; display: flex; align-items: center; gap: 4px; }
.sidebar-action-btn {
  position: relative; display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border: 0; border-radius: var(--r-pill);
  background: transparent; color: var(--ink-48); cursor: pointer;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.sidebar-action-btn:hover { background: rgba(255,255,255,0.08); color: var(--ink); }
.sidebar-action-btn svg { width: 22px; height: 22px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
/* 선택 표시 = 영역 하이라이트(배경) + 볼드. 액센트 선/틱 미사용. */
.auth-area {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--sp-sm);
  color: var(--ink-48);
  font-size: var(--fs-caption);
}
#who { font-variant-numeric: tabular-nums; padding: 0 var(--sp-sm); }

/* ── 버튼 기본(유틸 — 헤어라인 사각, scale active) ── */
button {
  font: inherit;
  letter-spacing: var(--ls-caption);
  cursor: pointer;
  color: var(--ink);
  background: var(--canvas);
  border: 1px solid var(--hairline);
  border-radius: var(--r-sm);
  padding: 8px 15px;
  transition: background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease),
    transform var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
button:active { transform: scale(0.96); }
button:disabled { opacity: 0.4; cursor: default; transform: none; }
button:focus-visible { outline: 2px solid var(--accent-focus); outline-offset: 2px; }

/* 프라이머리 — Action Blue 필 CTA */
.primary-btn {
  color: var(--on-accent);
  font-weight: 600; /* 주 CTA 가 본문(400)보다 얇았다 — 위계를 바로잡음 */
  background: var(--accent);
  border: 1px solid var(--accent);
  border-radius: var(--r-pill);
  padding: 11px 22px;
  font-size: var(--fs-body);
  letter-spacing: var(--ls-body);
}
/* ⚠️ hover 가 지금까지 없었다 — 제품 전역의 주 CTA 가 마우스를 올려도 무반응이었다.
 *   element 수준에 button:hover 를 달지 않는 이유: 그건 특이도가 (0,1,1) 이라
 *   .ep-card·.pl-row 같은 클래스 배경(0,1,0)을 덮어버린다(카드를 <button> 으로 만든 9곳이 전부 깨진다).
 *   보통 버튼의 hover 는 .btn 프리미티브(button.css)가 담당하고, 여긴 기존 2종만 보완한다. */
@media (hover: hover) {
  .primary-btn:hover:not(:disabled) { background: var(--accent-focus); border-color: var(--accent-focus); }
  .secondary-btn:hover:not(:disabled) { background: var(--accent-soft); }
}
.primary-btn:active { transform: scale(0.96); }

/* 세컨더리 — 고스트 필(투명 + 액센트 텍스트/보더) */
.secondary-btn {
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--accent);
  border-radius: var(--r-pill);
  padding: 11px 22px;
  font-size: var(--fs-body);
  letter-spacing: var(--ls-body);
}

/* ── 입력(필 검색/텍스트 + 포커스 블루 링) ── */
input, textarea, select {
  font: inherit;
  letter-spacing: var(--ls-body);
  color: var(--ink);
  background: var(--canvas);
  border: 1px solid var(--hairline);
  border-radius: var(--r-pill);
  padding: 11px 20px;
  font-size: var(--fs-body);
  transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
textarea { border-radius: var(--r-lg); resize: vertical; }
input::placeholder, textarea::placeholder { color: var(--ink-48); }
input:focus, textarea:focus, select:focus {
  outline: none;
  border-color: var(--accent-focus);
  box-shadow: 0 0 0 3px rgba(0, 113, 227, 0.18);
}
input[type='checkbox'] { accent-color: var(--accent); width: 18px; height: 18px; padding: 0; border-radius: var(--r-xs); }
input[type='number'] { border-radius: var(--r-md); }

/* ── 메인 컬럼(여백 넉넉 — 갤러리) ── */
.shell-main { padding: 0; }
/* 뷰 래퍼는 페이드만(transform 미사용) — rise 의 transform 잔존(matrix identity)이 fixed 자손(.wiz-composer)의
   포함블록을 가로채 컴포저가 viewport 가 아닌 '페이지' 하단에 붙는 버그 방지. 안쪽 .wiz-content 가 translateY 모션 담당. */
.shell-view { animation: fade var(--t-mid) var(--ease) both; }
@keyframes rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

/* ── 중립(미인증) 사인인 게이트 — C-7: 기능구조·모델·툴명 0 노출 ── */
.signin-gate {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--sp-lg); text-align: center;
  min-height: 100vh; padding: var(--sp-section) var(--sp-lg);
  animation: rise var(--t-mid) var(--ease) both;
}
.signin-card {
  max-width: 420px; width: 100%;
  display: flex; flex-direction: column; gap: var(--sp-md);
  padding: var(--sp-xxl) var(--sp-xl);
  background: var(--parchment);
  border-radius: var(--r-lg);
}
.signin-mark {
  font-size: var(--fs-display-md); font-weight: 600; letter-spacing: var(--ls-display-md);
  color: var(--ink);
}
.signin-tagline { color: var(--ink-80); font-size: var(--fs-body); line-height: var(--lh-body); margin: 0; }
.signin-hint { color: var(--ink-48); font-size: var(--fs-caption); margin: var(--sp-xs) 0 0; }
.signin-actions { display: flex; flex-direction: column; gap: var(--sp-sm); margin-top: var(--sp-sm); }

/* ── 반응형(좁은 화면) ── */
@media (max-width: 720px) {
  /* 좁은 화면: 좌측 레일 → 상단 가로 바(sticky, in-flow). main 우측 오프셋 해제. */
  /* 독 카드(라운드·섀도·네 변 보더)를 전부 되돌린다 — 화면 폭을 꽉 채우는 상단 바에 라운드가 남으면
     좌우 위 모서리만 깎인 채 화면 끝에 물려 어긋난 조각처럼 보인다. */
  .shell-sidebar {
    position: sticky; inset: auto; top: 0; bottom: auto;
    width: auto; flex-direction: row; align-items: center;
    gap: var(--sp-sm); padding: var(--sp-sm) var(--sp-md);
    border: none; border-bottom: 1px solid var(--hairline);
    border-radius: 0; box-shadow: none; animation: none;
  }
  /* 가로 바에서는 메뉴가 가로로 흐른다 — 세로 스크롤 컨테이너를 남기면 항목이 잘린다. */
  .shell-nav { overflow-y: visible; }
  .shell-nav { flex-direction: row; align-items: center; gap: 2px; }
  .nav-btn { width: auto; padding: 6px 14px; }
  .auth-area { flex-direction: row; align-items: center; margin-top: 0; margin-left: auto; }
  #who { display: none; }         /* 모바일 상단 바: 장황한 상태 텍스트 숨김(로그아웃 버튼이 인증 상태 표시) */
  body.shell-chrome { padding-left: 0; }
  body.shell-chrome .wiz-composer { left: 0; }
  body.shell-chrome .app-toast { left: 50%; }
  .shell-main { padding: var(--sp-lg) var(--sp-md); }
  /* 옛 셸 전용(새 셸은 v2/chrome-shell.css 가 바·시트를 소유): 브랜드·메뉴 8칸·액션·로그아웃이 한 줄에 서서 390 문서 폭이 890 이 됐다(가로 스크롤).
     메뉴는 둘째 줄 전폭으로 내리고 그 줄 안에서만 가로로 넘긴다. 바가 레일이 아니라 접기 버튼은 뜻이 없다. */
  body:not(.shell-v2) .shell-sidebar { flex-wrap: wrap; row-gap: var(--sp-xs); }
  body:not(.shell-v2) .shell-sidebar #sidebarToggle { display: none; }
  body:not(.shell-v2) .shell-nav { order: 3; flex: 1 1 100%; min-width: 0; overflow-x: auto; scrollbar-width: none; }
  body:not(.shell-v2) .shell-nav::-webkit-scrollbar { display: none; }
  body:not(.shell-v2) .shell-nav .nav-btn { flex: 0 0 auto; white-space: nowrap; }
  /* 같은 바 안의 알림 패널: 레일 시절 규칙(위로 열림 · 벨 왼쪽 기준 300px)이 남아 화면 위로 잘리고 문서 폭을 늘렸다 —
     벨 래퍼를 기준에서 빼고(상단 바가 기준) 바 바로 아래 양쪽 여백 전폭으로 연다. */
  body:not(.shell-v2) .shell-sidebar .feed-notif { position: static; }
  body:not(.shell-v2) .shell-sidebar .feed-notif-panel { top: calc(100% + 6px); bottom: auto; left: var(--sp-md); right: var(--sp-md); width: auto; max-width: none; }
  /* 옛 셸 토스트: left:50% 로 놓이면 남은 절반 폭에 맞춰 줄어 390 에서 195px·4줄로 접혔다 — 내용 폭을 주고 기존 max-width(components.css)가 자른다. */
  body:not(.shell-v2) .app-toast { width: max-content; }
}
