/* 테마 토글의 모양·아이콘은 29mu-theme-toggle.css 한 곳에 있다.
   @import 는 규격상 다른 규칙보다 앞이어야 해서 파일 맨 위에 둔다. */
@import url("29mu-theme-toggle.css");

@font-face {
  font-family: "Pretendard Variable";
  src: url("PretendardVariable.woff2") format("woff2-variations");
  font-style: normal;
  font-weight: 45 920;
  font-display: swap;
}

/*
 * Named themes.
 *   뉴럴 다크    = dark  | night   ← 기본
 *   애플 화이트  = light | day
 * --theme-name is the human label. Do not rename the machine ids.
 *
 * 사용자 지침 (2026-08-21): 「모든 웹페이지는 — 보고서든 사이트 페이지든 —
 * 몬스타 홈 테마다. 뉴럴 다크 기본, 애플 화이트 토글로 2가지 구현.」
 *
 * **기본 테마의 단일 소스는 아래 `:root` 다.** `:root` 가 곧 기본이고,
 * 그 안의 `--theme-id` 가 기본 테마의 이름을 말한다. 29mu-theme.js 는 저장값도
 * URL 도 없을 때 그 값을 읽어 쓴다 — JS 안에 기본값을 다시 적지 않는다.
 * 기본을 바꾸려면 여기 `:root` 하나만 바꾼다.
 *
 * 여기에 apple-white / neuron-dark 별칭 선택자를 다시 만들지 마라. 29mu-theme.js 의
 * normalize() 가 모든 값을 dark/light 로 접어서 root 에 붙이므로, 그 선택자는 절대
 * 맞지 않는 죽은 코드가 된다(2026-08-21 실측: ?theme=neuron-dark → 밝은 화면).
 * 사람이 부르는 이름은 아래 --theme-name 이 이미 말한다.
 *
 * Status colors --st-ok/--st-warn/--st-bad live here only.
 */

/* 기본 = 소비자 면(베이지). 사용자 지침 2026-08-22:
   「소비자들이 보는 것들은 베이지 기본. 내가 보는 운영자 관련 페이지는 다크가
    기본값이다. 이유는 내가 눈이 부셔서 작업 페이지들은 다크로 한다.」
   운영 면은 <html data-29mu-surface="…"> 로 자기를 밝힌다 — 아래 블록이 그것을 받는다. */
:root {
  color-scheme: light;
  --theme-id: light;
  --theme-name: "몬스타 베이지";
  --theme-paper: #f3f0e8;
  --theme-ink: #111216;
  --theme-lime: #111216;
  --focus: #1f6fd0;   /* 밝은 지면 4.35:1 */
  --bg: var(--theme-paper);
  --surface: #ffffff;
  --surface-strong: #eae9e4;
  --surface-soft: #f8f7f3;
  --text: var(--theme-ink);
  --muted: #5d626d;
  --subtle: #626770;
  --line: rgba(12, 14, 20, .13);
  --line-strong: rgba(12, 14, 20, .24);
  --accent: var(--theme-lime);
  --accent-ink: #f3f0e8;
  --shadow: 0 24px 80px rgba(33, 32, 28, .10);
  --paper: var(--theme-paper);
  --ink: var(--theme-ink);
  --grey: #555b61;
  --lime: var(--theme-lime);
  --st-ok: #1d7c3e;
  --st-warn: #9a6200;
  --st-bad: #b3261e;
  /* 「확인 불가」는 네 번째 상태다. 정상으로도 실패로도 단정하지 않는다.
     2026-08-29 전까지 두 가지 임시방편이 따로 있었다 —
     today.html 의 `.day--none{opacity:.45}` 와
     ops-fullstatus.html 의 `.state.miss{color:var(--muted)}`. 하나로 모은다. */
  --st-unknown: var(--subtle);
  --font-sans: "Pretendard Variable", Pretendard, "Noto Sans KR", "Noto Sans CJK KR", "Apple SD Gothic Neo", system-ui, sans-serif;
  --font-mono: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;
  --pc: #4aa8ff;
  --studio: #8c68ff;
  --game: #6c7079;
  --max: 1440px;
  --gutter: clamp(20px, 4vw, 64px);
  --space-1: 8px;
  --space-2: 12px;
  --space-3: 16px;
  --space-4: 24px;
  --space-5: 32px;
  --space-6: 48px;
  --space-7: 72px;
  --space-8: 112px;
  --radius-s: 6px;
  --radius-m: 10px;
  --radius-l: 16px;
  /* ops-fullstatus.html 이 `border-radius:2px` 를 5곳에 박고 있었다. 토큰화한다. */
  --radius-xs: 2px;
  /* ★ 선 색 단일 소스 (2026-09-01, 소비자 6화면 색 일관성).
     --hairline 은 --line 과 **같은 뜻**인데 값이 갈려 있었다. `:root`(라이트)에
     다크 값 rgba(255,255,255,.16) 이 그대로 복사돼 있어서, 베이지 지면 위
     흰 선 = 대비 1.02:1 로 **안 보였다**. 실측(1440·light): 그 선을 쓰는
     테두리가 archive 194 · shop 170 · index 112 · business 18 · story 10 곳.
     같은 선이 다크에서는 보이니, 라이트만 선이 사라지는 화면이 다섯이었다.
     labs 만 --line 을 써서 혼자 제대로 그렸다.
     이름은 지우지 않는다 — 별칭으로 두고 값은 --line 하나에서 온다. */
  --hairline: var(--line);

  /* ★ 가로 정렬 단일 소스 (2026-09-01, 소비자 5화면 정렬 사고 재발 방지).
     같은 뜻의 캔버스 폭/여백 변수가 media.css --page · editorial-canvas.css
     --editorial-canvas-max/gutter · journal-chrome-lock.css --chrome-canvas ·
     29mu-masthead.css --masthead-page 넷으로 복제돼 있었다(1360 vs 1600,
     여백 24px 있는 갈래/없는 갈래). 값은 여기 둘만 바꾼다 — 나머지는 전부
     이 두 값을 var() 로 읽는 별칭이다. tokens.css 는 다섯 소비자 화면
     (index/cooling/business/lab/shop) 모두가 로드하는 유일한 공통 시트라
     여기가 정본이다. */
  --canon-canvas-max: 1360px;
  --canon-canvas-gutter: 24px;

  /* 캔버스 안쪽 좌우 여백(본문 텍스트 시작선)도 media.css 3.6vw ·
     story.css/business.css 3.8vw · lab.css(tokens --gutter) 4vw 로
     셋이 갈려 있었다. 소비자 정본(index, media.css .section-intro)이
     기준이다 — 사용자 판정 「정본이 기준이다」(2026-08-31). */
  --canon-inset: clamp(18px, 3.6vw, 58px);

  /* ★ 어두운 판 단일 소스 (2026-09-01, 소비자 6화면 색 일관성).
     「테마와 무관하게 어두운 판」이 media.css(편집숍·에디터노트·소셜원장·
     매니페스토) · story.css(아티클미디어·다음기사) · editorial-canvas.css
     (카테고리 칩) · media-inherited-editions.css 에 흩어져 각자 색을 박고
     있었다. 2026-09-01 실측(6화면 × 라이트/다크 × 1440/390):
       배경  #15171b · #121419 · #0e1014 · #1a1d24 · #08090b · #08090c ·
             #090a0d · #202329   → 여덟 갈래
       글자  #f8f7f2 · #f6f5f1 · #f3f0e8                → 세 갈래
       흐린글자 #b8bbb6 · #aeb1ac · #8f948c · #aeb3bb · #9da3ad · #d4d0c7 → 여섯 갈래
       선    #3d403c · #4a4f58 · #41454e · #777b83       → 네 갈래
     값은 **새로 만들지 않는다** — 전부 다크 테마 정본
     (docs/CONSUMER_CANONICAL_PALETTE.json)에서 가져온다.
     테마 블록에 두지 않는 이유: 이 판은 라이트 지면에서도 어두워야 한다.
     그래서 `:root` 한 곳에만 두고 어느 테마에서도 다시 정의하지 않는다. */
  --slab-paper: #111216;                       /* = 다크 --theme-paper */
  --slab-raised: #161a23;                      /* = 다크 --surface-strong */
  --slab-well: #0d1016;                        /* = 다크 --surface-soft */
  --slab-ink: #f6f5f1;                         /* = 다크 --theme-ink */
  --slab-muted: #9da4b3;                       /* = 다크 --muted */
  --slab-line: rgba(255, 255, 255, .22);       /* = 다크 --line-strong */
  /* 사진 위 캡션 칩 · 다이얼로그 뒷막. 팔레트 색이 아니라 사진을 덮는 막이다. */
  --slab-scrim: rgba(0, 0, 0, .72);
}

/* 운영자 면 기본 = 다크. 눈부심 때문이다.
   표식은 이미 있던 것을 쓴다(허브가 모든 운영 화면에 붙인다) — 새 표식을 만들지 않는다.
   아래 html[data-theme=…] 블록이 뒤에 오므로, 사람이 고른 테마가 이것을 이긴다. */
html[data-29mu-surface] {
  color-scheme: dark;
  --theme-id: dark;
  --theme-name: "몬스타 다크";
  --theme-paper: #111216;
  --theme-ink: #f6f5f1;
  --theme-lime: #f6f5f1;
  --focus: #4aa8ff;   /* 어두운 지면 7.43:1 */
  --bg: var(--theme-paper);
  --surface: #10131a;
  --surface-strong: #161a23;
  --surface-soft: #0d1016;
  --text: var(--theme-ink);
  --muted: #9da4b3;
  --subtle: #727a89;
  --line: rgba(255, 255, 255, .12);
  --line-strong: rgba(255, 255, 255, .22);
  --accent: var(--theme-lime);
  --paper: var(--theme-paper);
  --ink: var(--theme-ink);
  --grey: #adb1ba;
  --hairline: var(--line);
  --lime: var(--theme-lime);
  --accent-ink: #111216;
  --shadow: 0 24px 80px rgba(0, 0, 0, .24);
  --st-ok: #5cbd82;
  --st-warn: #d9a441;
  --st-bad: #e0695f;
  --st-unknown: var(--subtle);
}


html[data-theme="light"],
html[data-theme="day"] {
  color-scheme: light;
  --theme-id: light;
  --theme-name: "몬스타 베이지";
  --theme-paper: #f3f0e8;
  --theme-ink: #111216;
  --theme-lime: #111216;
  --focus: #1f6fd0;   /* 밝은 지면 4.35:1 */
  --bg: var(--theme-paper);
  --surface: #ffffff;
  --surface-strong: #eae9e4;
  --surface-soft: #f8f7f3;
  --text: var(--theme-ink);
  --muted: #5d626d;
  --subtle: #626770;
  --line: rgba(12, 14, 20, .13);
  --line-strong: rgba(12, 14, 20, .24);
  --accent: var(--theme-lime);
  --accent-ink: #f3f0e8;
  --shadow: 0 24px 80px rgba(33, 32, 28, .10);
  --paper: var(--theme-paper);
  --ink: var(--theme-ink);
  --grey: #555b61;
  --lime: var(--theme-lime);
  --st-ok: #1d7c3e;
  --st-warn: #9a6200;
  --st-bad: #b3261e;
  --st-unknown: var(--subtle);
}

html[data-theme="dark"],
html[data-theme="night"] {
  color-scheme: dark;
  --theme-id: dark;
  --theme-name: "몬스타 다크";
  --theme-paper: #111216;
  --theme-ink: #f6f5f1;
  --theme-lime: #f6f5f1;
  --focus: #4aa8ff;   /* 어두운 지면 7.43:1 */
  --bg: var(--theme-paper);
  --surface: #10131a;
  --surface-strong: #161a23;
  --surface-soft: #0d1016;
  --text: var(--theme-ink);
  --muted: #9da4b3;
  --subtle: #727a89;
  --line: rgba(255, 255, 255, .12);
  --line-strong: rgba(255, 255, 255, .22);
  --accent: var(--theme-lime);
  --paper: var(--theme-paper);
  --ink: var(--theme-ink);
  --grey: #adb1ba;
  --hairline: var(--line);
  --lime: var(--theme-lime);
  --accent-ink: #111216;
  --shadow: 0 24px 80px rgba(0, 0, 0, .24);
  --st-ok: #5cbd82;
  --st-warn: #d9a441;
  --st-bad: #e0695f;
  --st-unknown: var(--subtle);
}


/* Instant scrub while toggling day/night (prevents mid-frame residual) */
html.theme-switching,
html.theme-switching body,
html.theme-switching .site-header,
html.theme-switching .journal-global-masthead,
html.theme-switching .masthead {
  transition: none !important;
}


/* ── 머리말 정본 규칙 (2026-09-02) ──────────────────────────────────────
   실측: 머리말 총높이가 화면마다 갈려 있었다.
     index 173.00px · shop·lab 162.22px · 서브페이지 119.22px
   사용자가 며칠째 지적한 「서브 페이지부터 메뉴선이 두께 차이가 있어 틀어짐」의
   실체가 이것이다 — 선 두께가 아니라 **머리말 높이 차**이고, 그래서 메뉴 줄과
   그 아래 구분선의 관계가 페이지마다 달라 보였다.

   원인은 같은 머리말 CSS 가 네 벌로 복제된 것이다.
     media.css            index 만 읽는다. **유일하게 최신 패치를 받았다**
     journal-shell.css    shop·lab. 파일 주석이 "Values copied 1:1 from media.css"
                          라고 스스로 적어 놓고도 이후 패치를 못 받았다
     editorial-canvas.css 서브페이지의 .journal-global-* 네임스페이스.
                          애초에 media.css 를 본 적이 없다
   빠진 패치는 접근성 규정이다 — min-height:44px (WCAG 2.5.5 터치 타깃).
   **없는 쪽이 결함**이지 있는 쪽이 과한 게 아니다.

   여섯 화면이 공통으로 읽는 파일은 tokens.css 하나뿐이라 여기에 둔다.
   사본을 또 만들지 않는다 — 그게 이 사고를 만든 방식이다.
   ──────────────────────────────────────────────────────────────────── */
:root {
  --canon-nav-touch: 44px;   /* WCAG 2.5.5 최소 터치 타깃 */
  --canon-mast-pad-top: 22px;
}
@media (min-width: 981px) {
  :root { --canon-mast-pad-top: 20px; }
}

/* 1차 내비·유틸 링크는 두 체계 모두 같은 높이를 갖는다 */
.editorial-nav :is(a, button),
.journal-global-nav :is(a, button),
.account-nav :is(a, button),
.journal-global-utility :is(a, button) {
  display: inline-flex;
  align-items: center;
  min-height: var(--canon-nav-touch);
}

/* 데스크톱에서 머리말 상단 여백과 구분선을 한 방식으로 통일한다.
   구분선은 래퍼의 box-shadow 하나로만 그린다 — nav 자신이 border 를 또 그으면
   활성 탭의 4px 밑줄과 같은 자리에 겹쳐 그 부분만 두꺼워 보인다(2026-09-02 수정분). */
@media (min-width: 981px) {
  .masthead,
  .journal-global-masthead {
    padding-top: 20px;
    box-shadow: 0 1px 0 var(--ink);
  }
}

/* ── 티커 정본 (2026-09-02) ────────────────────────────────────────────
   사용자 판정: 서브페이지에도 이번 호 안내(.ticker)를 넣는다. 이걸로 여섯
   화면의 머리말 구성이 완전히 같아진다(그 전엔 index·shop·lab 에만 있어
   머리말 높이가 173 vs 130px 로 갈렸다).

   규칙 자체는 media.css(165행)와 journal-shell.css(123행)에 **바이트가 같은
   두 벌**로 이미 복제돼 있었다 — 머리말 사고와 같은 병이다. 서브페이지가 읽는
   editorial-canvas.css 에는 아예 없어서, 마크업만 넣으면 스타일 없이 깨진다.
   사본을 세 번째로 만들지 않고 여섯 화면이 공통으로 읽는 여기에 둔다.
   ──────────────────────────────────────────────────────────────────── */
.ticker {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 22px;
  align-items: center;
  padding-block: 12px;
  border-block: 1px solid var(--ink);
  font: 10px/1.4 var(--font-mono);
  letter-spacing: .08em;
}
.ticker p {
  margin: 0;
  overflow: hidden;
  /* 2026-09-02: line-height 를 배수(1.4)로 두면 폰트 메트릭에 따라
     16.797px 처럼 소수가 나와 화면마다 티커 높이가 0.2px 갈렸다.
     정수 픽셀로 고정한다 — 머리말 총높이가 여섯 화면에서 같아야 한다. */
  font: 12px/17px var(--font-sans);
  letter-spacing: 0;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.brand-slogan {
  margin-right: .35em;
  font-weight: 800;
  letter-spacing: 0;
}
.ticker p .brand-slogan { white-space: nowrap; }

@media (max-width: 620px) {
  .ticker time { display: none; }
}
