/* base.css — 리셋 + 기본 타이포 + 전역 유틸.
 *
 * 출처: design-v5/dashboard-performance-v4a.html:44-61, 367-375, 408-411
 *
 * 로드 순서: tokens.css → **base.css** → components.css → pages/<name>.css
 * 이 파일은 tokens.css 의 변수를 쓴다. 순서를 바꾸면 색이 사라진다.
 */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }

body {
  /* ★ Pretendard Variable 만 쓴다. Inter·Roboto·시스템 기본 글꼴 금지.
       (DESIGN-SYSTEM.md 2장) */
  font-family: 'Pretendard Variable', Pretendard, sans-serif;
  background: var(--bg);
  color: var(--ink);
  font-size: 15px;
  line-height: 1.7;
  letter-spacing: -0.01em;
  overflow-x: clip;
}

a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
ul { list-style: none; }

/* 포커스 링 — 키보드 사용자에게만 보인다 (DESIGN-SYSTEM.md 11장) */
:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; border-radius: 6px; }

/* ★ 모든 수치·날짜에 붙인다. 자릿수가 흔들리지 않게 한다. */
.num { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum'; }

/* data-state="키" 로 서버가 표시/숨김을 제어한다 (data-bind 계약) */
[hidden] { display: none !important; }


/* ══ 로드 애니메이션 ══════════════════════════════════════════
   .reveal 을 붙이고 JS 가 80ms 간격으로 .on 을 단다 (stagger).
   금지: 바운스·스프링·오버슛 이징. (DESIGN-SYSTEM.md 8장) */
.reveal { opacity: 0; transform: translateY(10px); }
/* ★★ `opacity: 1` 을 **애니메이션과 따로** 적는다 (2026-08-24 · `[106]`).
   ⚠⚠ 전에는 보이게 만드는 것이 애니메이션뿐이었다. 그래서 애니메이션이
     **안 돌면 카드가 투명한 채로 남았다** — `.on` 은 붙었는데도.
     돌지 않는 경우가 실제로 있다: 붙일 때 조상이 `display:none` 이거나,
     다시 그리는 중간에 걸리거나, 브라우저가 애니메이션을 지울 때.
   ★ 이제 `.on` 이 붙으면 **애니메이션과 무관하게 보인다.**
     애니메이션은 돌 때 더 예쁘게 보이게 할 뿐이다 (도는 값이 이긴다). */
.reveal.on { animation: riseIn 0.4s ease forwards; opacity: 1; }
@keyframes riseIn { to { opacity: 1; transform: translateY(0); } }


/* ══ 동기화 중 (스켈레톤) ═════════════════════════════════════
   body 에 .syncing 을 달면 수치 요소가 회색 블록 + 펄스로 바뀐다.
   ★ 숫자가 0 인 것과 "아직 안 불러온 것"을 구분하기 위한 장치다.
     이게 없으면 사용자가 0을 실제 값으로 읽는다.
   ★ 새 페이지를 만들 때 그 페이지의 수치 클래스를 아래 목록에 추가한다. */
@keyframes pulse { 50% { opacity: 0.4; } }

body.syncing .kpi-value,
body.syncing .channel-stat .v,
body.syncing .gauge-score {
  border-radius: 10px;
  background: rgba(0,0,0,0.07);
  animation: pulse 1.2s ease-in-out infinite;
  color: transparent;
}
body.syncing .kpi-value *,
body.syncing .channel-stat .v *,
body.syncing .gauge-score * { visibility: hidden; }


/* ══ 접근성 ══════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
  .reveal { opacity: 1; transform: none; }
}

/* ⚠⚠ `.sr-only` — **정의가 아예 없었다** (2026-08-13, 팀장이 화면에서 발견)

   템플릿 일곱 장에서 열다섯 번 쓰이는데 **CSS 에 규칙이 한 줄도 없었다.**
   `content_list.css` · `content_new.css` 는 머리말에 *「공용: … .sr-only …」*
   라고 **적어만 두고** 실제로는 아무도 안 만들었다.

   ★ 이 클래스는 **CSS 가 곧 기능**이다. 규칙이 없으면 화면에 그대로 보인다 —

       셸 검색창   「콘텐츠·키워드 검색  🔍  콘텐츠·키워드 검색」
                    ↑ sr-only 라벨        ↑ placeholder
       사장님 눈에는 **같은 말이 두 번** 적힌 것으로 보인다.

   ⚠ `display: none` 으로 숨기지 않는다 — 그러면 스크린리더도 못 읽는다.
     이 표준 조합이라야 **눈에는 안 보이고 낭독은 된다.** */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}


/* ══ ★★ 셸 없는 화면의 세로 가운데 정렬 (2026-08-25 · `[107]`⑪) ══════

   ⛔ 실측: **로그인 카드가 왼쪽, 푸터가 그 오른쪽에 나란히** 붙어 있었다.

   원인은 한 줄이다 —

   ```css
   .login-body { display: flex; align-items: center; justify-content: center; }
   ```

   `<body>` 를 **가로 flex** 로 만들어 놓고 그 안에 `<main>` 과 `<footer>`
   둘을 넣었다. flex 는 **형제를 나란히 놓는다.** 카드를 가운데 두려던
   한 줄이 푸터까지 끌고 들어갔다.

   ⚠⚠ **같은 모양이 셋이었다** — `.login-body`(로그인·심사 로그인) ·
     `.err-body`(오류) · `.pay-body`(결제 다리·결과). 셋 다 셸이 없어서
     각자 자기 CSS 에 같은 세 줄을 적어 두고 있었다.
     → **한 곳에 둔다.** 안 그러면 넷째 화면이 같은 자리에서 또 깨진다.

   ★ 방법: 세로 flex 로 바꾸고 **본문이 남는 높이를 다 먹는다.**
     가운데 정렬은 그 본문 안에서 한다. 푸터는 자연히 맨 아래 가로다.
   ⚠ `min-height` 는 각 화면 CSS 가 이미 갖고 있다 — 여기서 다시 안 적는다. */
.shell-less {
  display: flex;
  flex-direction: column;
  /* ⚠ 본문에 `max-width` 가 걸려 있으면 세로 flex 는 그것을 **왼쪽에**
       붙인다 (기본 `stretch` 가 max-width 에 막혀서다). 가운데로 잡아 준다. */
  align-items: center;
  /* ⚠ 좌우 여백은 **안쪽 본문**이 갖는다. 여기 주면 푸터까지 밀려서
       테두리 선이 화면 끝까지 안 간다. */
  padding: 0;
}
.shell-less > main {
  /* ★ 남는 높이를 다 먹고, 그 안에서 가운데를 잡는다. */
  flex: 1 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  box-sizing: border-box;
  padding: 40px 20px;
}
/* ⚠ `<main>` 이 **카드 자신이면 안 된다.** 위 규칙의 여백이 카드 여백을
     덮어쓴다. 오류 화면이 그랬어서 `.shell-main` 으로 한 겹 감쌌다. */
.shell-less > main > * { max-width: 100%; }
/* ⚠ `align-items:center` 때문에 푸터도 안 늘어난다. **가로로 꽉 채운다** —
     팀장 지시 「푸터는 맨 아래 가로로」. */
.shell-less > .ls-foot { flex: none; margin-top: 0; width: 100%; }

@media (max-width: 480px) {
  .shell-less > main { padding: 24px 16px; }
}

/* ══ 법적 고지 푸터 ═══════════════════════════════════════════
   `partials/legal_footer.html` 한 장이 쓴다.

   ★★ **`base.css` 에 있다.** 셸 화면(layout.css 를 얹는 아홉 장)과
     셸 없는 화면(로그인·소개·약관·요금제)이 **같은 푸터**를 쓰는데,
     둘이 공통으로 얹는 파일이 tokens 와 base 뿐이다.
     page CSS 에 두면 화면마다 한 벌씩 복사되고 한쪽만 바뀐다.

   ⚠ 색 리터럴을 쓰지 않는다 (금지 6). 전부 토큰이다.
   ⚠ `--off`(비활성 점 색)를 쓰지 않는다 — 사업자 정보는 **읽으라고 두는
     글**이다. 심사관도 본다 (`landing.css` 가 같은 판단을 적어 두었다). */
.ls-foot {
  border-top: 1px solid var(--line);
  background: var(--white);
  /* ★ 셸 화면에서 사이드바 옆 본문 아래에 붙는다. `.main` 이 이미
       좌측 여백을 갖고 있어 여기서 따로 밀지 않는다. */
  margin-top: 40px;
}

.ls-foot-in {
  max-width: var(--main-max);
  margin: 0 auto;
  padding: 24px 28px 36px;
}

.ls-foot-links { display: flex; gap: 18px; flex-wrap: wrap; }
.ls-foot-links a {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--sub-strong);
  text-decoration: none;
}
.ls-foot-links a:hover { color: var(--ink); text-decoration: underline; }

.ls-foot-biz {
  margin-top: 14px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  font-size: 12.5px;
  line-height: 1.7;
}
.ls-foot-row { display: flex; gap: 6px; }
.ls-foot-biz dt { color: var(--sub); }
.ls-foot-biz dd { color: var(--sub-strong); }

.ls-foot-note {
  margin-top: 10px;
  font-size: 12.5px;
  color: var(--sub);
  max-width: var(--read-max);   /* ⚠ 읽기 폭 (`[107]`⑤) */
}

@media (max-width: 640px) {
  .ls-foot-in { padding: 20px 16px 32px; }
}
