/* 프로모션 성과 리포트 (/promo-report/) — 외부 대행사 열람용.
 *
 * ⚠️ 이 파일만 **디자인 시스템 v3 값**을 쓴다(design_handoff_promotion_report/ 정본 시안).
 *    사이트 나머지는 아직 Warm Canvas v1.0 이라 전역 :root 에 v3 토큰이 없다.
 *    그래서 v3 값을 --opr-* 로 **이 페이지 안에만** 정의한다. 전역 :root 는 건드리지 않는다.
 *
 *    ⛔ 여기서 var(--radius-lg) · var(--space-xl) 같은 **전역 토큰을 쓰면 안 된다.**
 *       이름은 같은데 값이 다르다(전역 --radius-lg 16px / v3 8px, --space-xl 32px / v3 40px).
 *       오류 없이 조용히 틀리므로 이 파일에서는 --opr-* 만 쓴다.
 *
 *  - 카드 radius 8px · 배지/버튼/nav 6px · 바 2px. pill(9999px) 금지.
 *  - 카드는 그림자만, 내부 구획은 1px hairline — 테두리와 그림자를 겹치지 않는다.
 *  - 좌측 컬러바·그라디언트·blur·!important 없음. 애니메이션 없음(색 전환 150ms 만).
 *  - 채널 브랜드색은 **로고·비중 바·차트 바에만**. 텍스트 색으로 쓰지 않는다(대비 미달).
 *  - 작은 텍스트는 --opr-gray-700 이상. --opr-gray-500 은 본문·캡션 금지.
 */

/* 숫자·라틴은 Inter. 이게 리포트 인상의 절반이다.
   테마에 이미 셀프호스팅돼 있는 파일을 그대로 쓴다(외부 요청 0건 — page-main-v3.css 와 동일 선언). */
@font-face {
	font-family: 'Inter';
	src: url('../fonts/InterVariable-latin.woff2') format('woff2-variations');
	font-weight: 100 900;
	font-style: normal;
	font-display: swap;
}

.opr-shell {
	/* ── v3 토큰 (이 페이지 스코프) ── */
	--opr-primary-600: #047E57;
	--opr-primary-700: #036546;
	--opr-gray-50:  #F7F7F5;
	--opr-gray-100: #F0F0ED;
	--opr-gray-200: #E6E6E2;
	--opr-gray-300: #D4D4CF;
	--opr-gray-700: #45453F;
	--opr-fg-strong: #1B1B18;
	--opr-surface: #FFFFFF;
	--opr-sidenav-text: #5A6663;
	--opr-sidenav-hover-bg: #F6F8F7;
	--opr-sidenav-active-text: #151B1B;
	--opr-shadow-sm: 0 1px 2px rgba(17, 17, 16, .04), 0 2px 6px rgba(17, 17, 16, .04);
	/* Inter 에는 한글이 없다. '게시 2026-07-31' 처럼 한 줄에 섞이는 경우가 많으므로
	   폴백을 Pretendard 로 둔다 — system-ui 로 떨어지면 그 줄만 글꼴이 튄다. */
	--opr-en: 'Inter', 'Pretendard', -apple-system, BlinkMacSystemFont, sans-serif;

	/* ── 채널 브랜드색 (로고·바 전용) ── */
	--opr-yt: #FF0000;
	--opr-ig: #E1306C;
	--opr-fb: #1877F2;
	--opr-nv: #03C75A;

	max-width: var(--max-w-narrow, 900px);
	margin: 0 auto;
	padding: var(--space-2xl, 48px) var(--space-md, 16px) var(--space-3xl, 64px);
	color: var(--t-body, #3A3933);
	font-size: 15px;
	line-height: 1.7;
}

/* 모든 수치는 Inter + tabular-nums. 자릿수가 세로로 정렬돼야 표가 표로 읽힌다. */
.opr-report .opr-kpi-n,
.opr-report .opr-kpi-cpv,
.opr-report .opr-kpi-cost,
.opr-report .opr-period,
.opr-report .opr-toc-head em,
.opr-report .opr-toc-link em,
.opr-report .opr-tile-n,
.opr-report .opr-tile-head span,
.opr-report .opr-collected,
.opr-report .opr-split-types b,
.opr-report .opr-post-date,
.opr-report .opr-post-n strong,
.opr-report .opr-table td,
.opr-report .opr-table thead th,
.opr-report .opr-axis,
.opr-report .opr-chart-head em,
.opr-report .opr-dist-v,
.opr-report .opr-updated {
	font-family: var(--opr-en);
	font-variant-numeric: tabular-nums;
	font-feature-settings: 'tnum' 1;
}

/* ---------------- 안내 / 게이트 ---------------- */

/* 인증 화면은 카드 하나뿐이라 위쪽에 붙어 있으면 아래가 텅 빈다.
 * body.opr-gate-screen 은 gate.php 의 body_class 필터가 **인증 화면일 때만** 붙인다
 * (리포트 본문에는 붙지 않는다 — 본문은 길어서 세로 가운데 정렬이 의미가 없다).
 *
 * 헤더 높이를 빼는 방식(calc(100svh - 120px))을 쓰지 않았다 — 상단 배너 노출 여부와
 * 관리자 바에 따라 높이가 달라져 어떤 숫자를 넣어도 어떤 상태에서는 틀린다.
 * 흐름 전체를 flex 로 세우면 잴 필요 자체가 없어진다.
 *
 * 100svh(=작은 뷰포트) 를 쓰는 이유: 모바일에서 100vh 는 주소창이 접힌 높이라
 * 첫 화면에서 카드 아래가 잘려 보인다. */
body.opr-gate-screen {
	display: flex;
	flex-direction: column;
	min-height: 100svh;
}

/* 인증 화면에서는 푸터·맨위로 버튼을 내린다.
 * 아직 아무것도 못 본 사람에게 사이트 정보·SNS·사업자 정보를 길게 늘어놓을 이유가 없고,
 * 스크롤할 것이 없으므로 [맨 위로] 버튼도 의미가 없다. 인증만 남긴 화면이 목적이다. */
body.opr-gate-screen .site-footer,
body.opr-gate-screen .back-to-top-button { display: none; }

/* #page 가 남는 세로 공간을 전부 흡수하고, 그 안에서 #content 가 카드를 가운데 세운다. */
body.opr-gate-screen #page { flex: 1 0 auto; display: flex; flex-direction: column; }
body.opr-gate-screen #content { flex: 1 0 auto; display: flex; }

/* ⚠️⚠️ min-width: 0 은 장식이 아니다 — 없으면 **모바일에서 카드가 화면 밖으로 삐져나간다.**
 *
 * flex/grid 아이템의 기본값은 `min-width: auto` 라 **콘텐츠의 min-content 아래로 줄어들기를 거부**한다.
 * 여기서 min-content 를 부풀리는 것은 인증 폼 한 줄이다 —
 *   <input> 기본 폭 약 210px + gap 8px + nowrap 버튼 약 116px = 334px, 카드 패딩 64px → 약 398px.
 * 셸 좌우 패딩까지 더하면 430px 이 되어 402px 짜리 폰 화면을 넘고,
 * 카드가 max-width(420px)로 벌어진 채 오른쪽이 잘린다(2026-08-08 실제 발생).
 *
 * ⭐ 규칙: **뷰포트 폭을 따라야 하는 flex/grid 아이템에는 반드시 `min-width: 0`**
 *    (그리드는 `1fr` 대신 `minmax(0, 1fr)`). 데스크톱에서는 증상이 없어 모바일에서만 터진다.
 */
body.opr-gate-screen .opr-shell {
	flex: 1;
	min-width: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	padding-top: var(--space-xl, 32px);
	padding-bottom: var(--space-xl, 32px);
}

/* 가운데 정렬은 flex 가 맡으므로 카드 자신의 세로 여백은 지운다. */
body.opr-gate-screen .opr-notice,
body.opr-gate-screen .opr-gate {
	width: 100%;
	min-width: 0;
	margin: 0 auto;
}

.opr-notice,
.opr-gate {
	max-width: 420px;
	margin: var(--space-3xl, 64px) auto;
	padding: var(--space-xl, 32px);
	background: var(--surface-white);
	border-radius: var(--radius-nm, 10px);
	box-shadow: var(--shadow-card, 0 4px 24px rgba(0, 0, 0, .06));
	text-align: center;
}

.opr-notice h1,
.opr-gate-title {
	margin: 0 0 var(--space-sm, 8px);
	font-size: 19px;
	font-weight: 700;
	color: var(--t-main, #1A1916);
	line-height: 1.45;
}

.opr-notice p,
.opr-gate-desc {
	margin: 0;
	font-size: 14px;
	color: var(--t-muted, #807E73);
}

.opr-gate-lock { font-size: 30px; line-height: 1; margin-bottom: var(--space-nm, 12px); }

.opr-gate-err {
	margin: var(--space-md, 16px) 0 0;
	padding: var(--space-sm, 8px) var(--space-nm, 12px);
	background: #FDECEA;
	border-radius: var(--radius-md, 5px);
	font-size: 13px;
	color: #A02622;
}

.opr-gate-form { margin-top: var(--space-lg, 24px); display: flex; gap: var(--space-sm, 8px); }

/* ⚠️ 타입을 하나씩 나열하지 않는다 — `input[type="email"]` 을 빠뜨려 이메일 인증 화면에서만
   입력칸이 flex 로 늘어나지 않고 브라우저 기본 폭(약 180px)으로 쪼그라들었다(2026-08-08 신고).
   인증 폼 안에는 hidden 말고 다른 입력이 없으므로 통째로 잡는 편이 안전하다. */
.opr-gate-form input:not([type="hidden"]) {
	flex: 1;
	min-width: 0;
	padding: 10px var(--space-nm, 12px);
	border: 1px solid var(--surface-300, #DDDAD0);
	border-radius: var(--radius-md, 5px);
	font-size: 15px;
	background: var(--surface-white);
	color: var(--t-main, #1A1916);
}

/* 인증번호 6자리는 가운데 정렬로 자릿수를 눈에 띄게 한다.
   (등폭 글꼴·자간 확대는 placeholder 「인증번호 6자리」까지 늘어져 되레 읽기 나빴다.) */
.opr-gate-form input.opr-gate-code {
	text-align: center;
	font-size: 16px;
}

/* 포커스는 한 겹으로 끝낸다 — outline + border 색변경 + ring 을 겹치지 않는다. */
.opr-gate-form input:focus {
	outline: 2px solid var(--primary, #217346);
	outline-offset: 1px;
}

.opr-gate-form button {
	padding: 10px var(--space-md, 16px);
	border: 0;
	border-radius: var(--radius-md, 5px);
	background: var(--primary, #217346);
	color: var(--text-white);
	font-size: 14px;
	font-weight: 600;
	cursor: pointer;
	white-space: nowrap;
	transition: background var(--transition-fast, .15s ease);
}
.opr-gate-form button:hover { background: var(--primary-dark, #134026); }
.opr-gate-form button[disabled] { background: var(--surface-300, #DDDAD0); cursor: not-allowed; }

.opr-gate-help {
	margin: var(--space-nm, 12px) 0 0;
	font-size: 12px;
	line-height: 1.6;
	color: var(--t-mute, #8A8A85);
}
.opr-gate-help a { color: var(--primary, #217346); text-decoration: underline; }

/* 좁은 화면에서는 입력과 버튼을 위아래로 세운다.
   min-width: 0 만으로도 넘치지는 않지만, 한 줄에 욱여넣으면 입력칸이 180px 남짓으로 쪼그라들어
   「휴대폰 번호 (숫자만)」 안내가 잘린다. 인증은 한 화면에 이것뿐이라 세로로 세워도 손해가 없다. */
@media (max-width: 480px) {
	.opr-notice,
	.opr-gate { padding: var(--space-lg, 24px) var(--space-md, 16px); }
	.opr-gate-form { flex-direction: column; }
	.opr-gate-form button { width: 100%; }
}

/* ═══════════════════════════════════════════════════════════════
   리포트 본문 — 좌측 고정 레일 + 우측 본문
   ═══════════════════════════════════════════════════════════════ */

/* 레일 + 본문이 흰 카드로 떠 보이려면 뒤가 흰색이면 안 된다. */
/* body 는 --opr-* 스코프(.opr-shell) 밖이라 토큰을 못 쓴다 — v3 --bg-page 값을 직접 적는다. */
body.opr-report-screen { background: #F7F7F5; }
body.opr-report-screen .site-content,
body.opr-report-screen #content,
body.opr-report-screen #page { background: transparent; }

/* ⚠️ GeneratePress 는 #page 에 .grid-container(최대 1200px)를 붙인다.
   리포트 셸은 1320px 이라 이걸 풀지 않으면 레일 + 본문이 조용히 좁아진다.
   폭·여백은 .opr-shell 이 스스로 정하므로 래퍼는 통로 역할만 하게 둔다. */
body.opr-report-screen #page.grid-container {
	max-width: none;
	padding-left: 0;
	padding-right: 0;
}
body.opr-report-screen #content { padding: 0; }

/* 목차 클릭 시 부드럽게 이동. 사용자가 애니메이션을 줄이도록 설정했으면 즉시 이동한다. */
@media (prefers-reduced-motion: no-preference) {
	html:has(body.opr-report-screen) { scroll-behavior: smooth; }
}

.opr-shell.opr-report {
	max-width: 1320px;
	padding: 40px 32px 96px;
	display: grid;
	grid-template-columns: 268px minmax(0, 1fr);
	gap: 40px;
	align-items: start;
	color: var(--opr-gray-700);
	font-size: 15px;
	line-height: 1.6;
}

.opr-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.opr-logo { width: 1em; height: 1em; flex: none; fill: currentColor; }

/* 채널 브랜드색은 컨테이너의 color 로 넣고 하위 그래픽이 currentColor 로 받는다.
   이렇게 하면 채널이 늘어도 규칙이 하나뿐이다. */
.opr-ch-youtube   { color: var(--opr-yt); }
.opr-ch-instagram { color: var(--opr-ig); }
.opr-ch-facebook  { color: var(--opr-fb); }
.opr-ch-naver     { color: var(--opr-nv); }

/* 포커스는 한 겹 — outline·border 색변경·ring 을 겹치지 않는다. */
.opr-report a:focus-visible {
	outline: 2px solid var(--opr-primary-600);
	outline-offset: 2px;
}

/* ---------------- (A) 좌측 레일 ---------------- */

/* ⚠️ 사이트 네비(.oppadu-nav)가 top:0 sticky · 높이 60px 다. 목차로 이동한 게시물의
   제목이 네비에 가리지 않도록 앵커 scroll-margin-top 이 이 값을 쓴다(아래 .opr-post).
   레일 sticky 는 2026-08-10 에 걷어냈지만, 앵커 오프셋은 여전히 필요하다. */
.opr-shell.opr-report { --opr-nav: 60px; }
body.admin-bar .opr-shell.opr-report { --opr-nav: 92px; } /* 관리자 바 32px */

/* ⛔ 레일에 sticky 를 걸지 않는다(2026-08-10 해제). 본문과 함께 흐른다.
   ⛔ 레일 자체에 overflow-y: auto 도 걸지 않는다. 전에는 `max-height + overflow-y: auto` 로
   잘림을 막았는데, 그 스크롤바가 레일 안쪽을 파고들어 KPI 카드 오른쪽을 덮었다(2026-08-08 신고).
   sticky 를 뺀 지금은 레일이 길어져도 페이지가 그냥 스크롤되므로 가둘 이유 자체가 없다. */
.opr-rail {
	display: flex;
	flex-direction: column;
	gap: 22px;
}

.opr-hero {
	display: block;
	width: 100%;
	height: 150px;
	object-fit: cover;
	border-radius: 8px;
	margin-bottom: -4px;
}

.opr-report .opr-eyebrow {
	margin: 0 0 10px;
	font-size: 11px;
	font-weight: 600;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--opr-primary-600);
	line-height: 1.4;
}

.opr-report .opr-title {
	margin: 0 0 12px;
	font-size: 26px;
	font-weight: 700;
	letter-spacing: -.022em;
	line-height: 1.3;
	color: var(--opr-fg-strong);
	text-wrap: pretty;
}

.opr-period {
	margin: 0;
	font-size: 12px;
	font-weight: 600;
	color: var(--opr-gray-700);
}

/* 오늘이 며칠째인지. 날짜와 붙어 있되 «오늘의 위치» 라는 게 읽혀야 하므로 칩으로 뗀다.
   배지 radius 6px 고정 — pill 금지. */
.opr-dday {
	display: inline-block;
	margin-left: 6px;
	padding: 1px 6px;
	border-radius: 6px;
	background: var(--opr-gray-100);
	font-style: normal;
	font-size: 11px;
	font-weight: 700;
	letter-spacing: -.01em;
	color: var(--opr-fg-strong);
	vertical-align: 1px;
}

/* 진행 중 표시 — 초록 점 + 반복 glow.
 *
 * ℹ️ 이 페이지의 다른 곳에는 애니메이션을 두지 않는다(읽기 전용 리포트).
 *    여기만 예외인 이유: 「지금도 돌고 있는 캠페인」이라는 상태를 알리는 유일한 신호라서다.
 *    ⚠️ 집행 종료일 필드가 없으므로 **시작만 하면 계속 켜진다** — 끝난 캠페인도 깜빡인다.
 *       종료일을 도입하면 그때 조건을 좁힐 것.
 * ⭐ 완전 원형(50%)이 허용되는 것은 dot·아바타·스위치·스피너뿐이다. 이건 dot 이라 해당된다.
 * blur·gradient 는 쓰지 않는다 — 퍼짐은 box-shadow 하나로 만든다.
 */
.opr-live {
	display: inline-block;
	width: 6px;
	height: 6px;
	margin-right: 5px;
	border-radius: 50%;
	background: #16A34A;
	vertical-align: 1px;
	animation: opr-live-pulse 2.4s ease-out infinite;
}

@keyframes opr-live-pulse {
	0%        { box-shadow: 0 0 0 0 rgba(22, 163, 74, .55); }
	70%, 100% { box-shadow: 0 0 0 5px rgba(22, 163, 74, 0); }
}

/* 움직임을 줄이도록 설정한 사용자에게는 점만 남긴다(정보는 색으로 이미 전달된다). */
@media (prefers-reduced-motion: reduce) {
	.opr-live { animation: none; }
}

/* 종이에는 '지금 진행 중' 이라는 개념이 없다 — 인쇄 시점과 읽는 시점이 다르다. */
@media print {
	.opr-live { display: none; }
}

/* KPI 카드 */
.opr-kpi {
	background: var(--opr-surface);
	border-radius: 8px;
	box-shadow: var(--opr-shadow-sm);
	padding: 20px 22px;
}
.opr-kpi-lb { display: block; font-size: 12px; font-weight: 600; color: var(--opr-gray-700); }
.opr-kpi-n {
	display: block;
	margin: 4px 0 6px;
	font-size: 34px;
	font-weight: 700;
	letter-spacing: -.035em;
	line-height: 1;
	color: var(--opr-fg-strong);
}
.opr-kpi-sub { display: block; font-size: 11px; font-weight: 600; color: var(--opr-gray-700); }

.opr-kpi-split {
	display: flex;
	justify-content: space-between;
	gap: 12px;
	margin-top: 16px;
	padding-top: 16px;
	border-top: 1px solid var(--opr-gray-200);
}
.opr-kpi-split .is-right { text-align: right; }
.opr-kpi-lb2 { display: block; font-size: 12px; font-weight: 600; color: var(--opr-gray-700); }
.opr-kpi-cpv,
.opr-kpi-cost {
	display: block;
	margin-top: 2px;
	font-size: 20px;
	font-weight: 700;
	letter-spacing: -.03em;
	white-space: nowrap;
}
.opr-kpi-cpv { color: var(--opr-primary-600); }
.opr-kpi-cost { color: var(--opr-fg-strong); }
/* 단위 '원'은 한글이라 --opr-en 폴백(Pretendard)이 받는다. 숫자보다 작게 둔다. */
.opr-kpi-cpv i { font-style: normal; font-size: 13px; }

/* 목차 — 게시물 수만큼 자라는 유일한 블록. 데스크톱에서는 통째로 편다.
   레일이 sticky 였을 때는 34vh 로 가두고 안에서 스크롤시켰지만, sticky 를 뺀 뒤로는
   그 안쪽 스크롤이 오히려 방해가 된다 — overscroll-behavior: contain 탓에 목차 위에
   커서가 있는 동안 페이지 스크롤이 멈춘다. 모바일 캡(168px)은 사정이 달라 그대로 둔다. */
.opr-toc {
	display: flex;
	flex-direction: column;
	gap: 14px;
}
.opr-toc-grp { display: flex; flex-direction: column; }

.opr-toc-head {
	display: flex;
	align-items: center;
	gap: 8px;
	margin: 0;
	padding: 0 10px 6px;
}
.opr-toc-head .opr-logo { font-size: 15px; }
.opr-toc-head span {
	font-size: 12px;
	font-weight: 600;
	color: var(--opr-fg-strong);
}
.opr-toc-head .opr-toc-name {
	display: flex;
	min-width: 0;
	flex-direction: column;
	line-height: 1.35;
}
.opr-toc-head .opr-collected {
	font-size: 10px;
	font-weight: 500;
	color: var(--opr-gray-700);
	white-space: nowrap;
}
.opr-toc-head em {
	margin-left: auto;
	font-style: normal;
	font-size: 11px;
	font-weight: 600;
	color: var(--opr-gray-700);
}

.opr-toc-link {
	display: flex;
	align-items: baseline;
	gap: 8px;
	padding: 7px 10px 7px 32px;
	border-radius: 6px;
	font-size: 12px;
	font-weight: 600;
	color: var(--opr-sidenav-text);
	text-decoration: none;
	transition: background .15s ease, color .15s ease;
}
.opr-toc-link em {
	margin-left: auto;
	font-style: normal;
	color: var(--opr-gray-700);
}
.opr-toc-link:hover,
.opr-toc-link:focus-visible {
	background: var(--opr-sidenav-hover-bg);
	color: var(--opr-sidenav-active-text);
}

/* 데이터 내려받기 — 읽기 전용 리포트에서 유일하게 '누르는' 요소라 눈에 띄되 튀지는 않게.
   테두리 1px 만 쓰고 그림자는 얹지 않는다(테두리와 그림자를 겹치지 않는다). */
.opr-dl {
	display: block;
	padding: 9px 12px;
	border: 1px solid var(--opr-gray-300);
	border-radius: 6px;
	background: var(--opr-surface);
	font-size: 12px;
	font-weight: 600;
	color: var(--opr-gray-700);
	text-align: center;
	text-decoration: none;
	transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.opr-dl-t {
	display: inline-flex;
	align-items: center;
	gap: 6px;
}
.opr-dl-i { width: 14px; height: 14px; flex: none; }
.opr-dl > span:last-child {
	display: block;
	margin-top: 2px;
	font-size: 10.5px;
	font-weight: 600;
	opacity: .75;
}
.opr-dl:hover {
	background: var(--opr-sidenav-hover-bg);
	border-color: var(--opr-primary-600);
	color: var(--opr-primary-600);
}

/* 안내 — 페이지에서 문장이 있는 곳은 여기뿐이다. */
.opr-rail-notes {
	display: flex;
	flex-direction: column;
	gap: 14px;
	padding: 16px 12px 0;
	border-top: 1px solid var(--opr-gray-200);
}
.opr-note-t { margin: 0 0 2px; font-size: 11px; font-weight: 600; color: var(--opr-fg-strong); }
.opr-note-b { margin: 0; font-size: 11px; font-weight: 600; line-height: 1.6; color: var(--opr-gray-700); }
.opr-updated { margin: 0; font-size: 11px; font-weight: 600; color: var(--opr-gray-700); }

/* ---------------- (B) 채널 요약 타일 ---------------- */

.opr-main { display: flex; flex-direction: column; gap: 24px; min-width: 0; }

.opr-tiles {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
	gap: 12px;
	align-items: stretch;
}

.opr-tile {
	display: flex;
	flex-direction: column;
	background: var(--opr-surface);
	border-radius: 8px;
	box-shadow: var(--opr-shadow-sm);
	padding: 18px 20px 16px;
	min-width: 0;
}

.opr-tile-head {
	display: flex;
	align-items: center;
	gap: 8px;
	margin: 0 0 14px;
}
.opr-tile-head .opr-logo { font-size: 18px; }
.opr-tile-head span {
	font-size: 11px;
	font-weight: 600;
	letter-spacing: .07em;
	color: var(--opr-gray-700);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.opr-tile-n {
	display: block;
	margin-bottom: 12px;
	font-size: 27px;
	font-weight: 700;
	letter-spacing: -.032em;
	line-height: 1;
	color: var(--opr-fg-strong);
}

.opr-tile-bar {
	display: block;
	height: 4px;
	border-radius: 2px;
	background: var(--opr-gray-100);
	overflow: hidden;
}
.opr-tile-bar i { display: block; height: 100%; background: currentColor; }

.opr-tile-meta {
	margin: 10px 0 0;
	font-size: 11px;
	font-weight: 600;
	color: var(--opr-gray-700);
}

.opr-tile-collected {
	margin: 2px 0 0;
	font-size: 10px;
	font-weight: 500;
	line-height: 1.4;
	color: var(--opr-gray-700);
}

/* 유형 분해 — 유형이 2종 이상일 때만 렌더된다(PHP 에서 판정). */
.opr-split-types {
	list-style: none;
	margin: 14px 0 0;
	padding: 12px 0 0;
	border-top: 1px solid var(--opr-gray-200);
	display: flex;
	flex-direction: column;
	gap: 8px;
}
.opr-split-types li {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 10px;
}
.opr-split-types span { font-size: 11px; font-weight: 600; color: var(--opr-gray-700); }
.opr-split-types b {
	font-size: 13px;
	font-weight: 700;
	letter-spacing: -.02em;
	color: var(--opr-fg-strong);
}

/* ---------------- (C) 게시물 섹션 ---------------- */

.opr-post {
	background: var(--opr-surface);
	border-radius: 8px;
	box-shadow: var(--opr-shadow-sm);
	overflow: hidden;
	/* 목차로 이동했을 때 제목이 sticky 네비에 가리지 않게 한다. */
	scroll-margin-top: calc(var(--opr-nav) + 20px);
}

.opr-post-head {
	display: flex;
	justify-content: space-between;
	gap: 32px;
	padding: 22px 28px;
	border-bottom: 1px solid var(--opr-gray-200);
}
.opr-post-id { min-width: 0; }

/* 배지 — radius 6px 고정. pill 금지. */
.opr-chip {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	padding: 4px 10px 4px 7px;
	border-radius: 6px;
	background: var(--opr-gray-100);
	margin-bottom: 10px;
}
.opr-chip .opr-logo { font-size: 15px; }
.opr-chip b {
	font-size: 11px;
	font-weight: 600;
	color: var(--opr-fg-strong);
	white-space: nowrap;
}

.opr-post-title {
	margin: 0 0 6px;
	font-size: 16px;
	font-weight: 600;
	line-height: 1.5;
	letter-spacing: -.01em;
	color: var(--opr-fg-strong);
	max-width: 66ch;
	text-wrap: pretty;
}
.opr-post-title a { color: var(--opr-primary-600); text-decoration: none; }
.opr-post-title a:hover { color: var(--opr-primary-700); text-decoration: underline; }

.opr-post-date { margin: 0; font-size: 12px; font-weight: 600; color: var(--opr-gray-700); }

.opr-post-n { text-align: right; flex: none; }
.opr-post-n strong {
	display: block;
	font-size: 30px;
	font-weight: 700;
	letter-spacing: -.035em;
	line-height: 1.1;
	color: var(--opr-fg-strong);
}
.opr-post-n span { font-size: 11px; font-weight: 600; color: var(--opr-gray-700); white-space: nowrap; }

/* 2단 — 구분선을 border 가 아니라 gap:1px + 배경으로 그린다.
   1단으로 접힐 때 세로선이 오른쪽 끝에 남지 않는다. */
.opr-post-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
	gap: 1px;
	background: var(--opr-gray-200);
}
.opr-pane { background: var(--opr-surface); padding: 22px 28px 24px; min-width: 0; }

/* ---------------- 차트 ---------------- */

.opr-chart-head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 12px;
	margin-bottom: 14px;
}
.opr-chart-t {
	font-size: 12px;
	font-weight: 600;
	letter-spacing: .04em;
	color: var(--opr-gray-700);
}
.opr-chart-head em {
	font-style: normal;
	font-size: 11px;
	font-weight: 600;
	color: var(--opr-gray-700);
}
.opr-chart-legend {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	font-size: 11px;
	font-weight: 600;
	color: var(--opr-gray-700);
}
.opr-lg-bar {
	display: inline-block;
	width: 8px;
	height: 8px;
	border-radius: 2px;
	background: currentColor;
}
.opr-lg-bar + .opr-lg-bar { margin-left: 8px; }
.opr-lg-bar.is-est { opacity: .4; }

.opr-chart-body { height: 120px; }
.opr-bars { display: flex; align-items: flex-end; gap: 4px; height: 100%; }
.opr-bar { flex: 1; min-width: 0; height: 100%; display: flex; align-items: flex-end; }
.opr-bar-fill {
	display: block;
	width: 100%;
	border-radius: 1px 1px 0 0;
	background: currentColor;
}
/* 추정 구간도 채널색을 유지하고 투명도로만 낮춘다 — 회색으로 빼면 어느 플랫폼인지 못 읽는다. */
.opr-bar-fill.is-est { opacity: .4; }
/* 값이 없는 날은 아주 옅은 바닥선만 남겨 '칸이 있다'는 사실만 보인다. */
.opr-bar.is-missing::after {
	content: '';
	display: block;
	width: 100%;
	height: 2px;
	background: var(--opr-gray-200);
	border-radius: 1px;
}
.opr-bar.is-future::after { background: var(--opr-gray-100); }

.opr-axis {
	display: flex;
	justify-content: space-between;
	margin-top: 8px;
	padding-top: 8px;
	border-top: 1px solid var(--opr-gray-200);
	font-size: 11px;
	font-weight: 600;
	color: var(--opr-gray-700);
}
.opr-axis em { font-style: normal; margin-left: 4px; opacity: .75; }

.opr-chart-empty {
	margin: 0;
	padding: 28px 0;
	font-size: 12px;
	font-weight: 600;
	color: var(--opr-gray-700);
	text-align: center;
}

/* ---------------- 누적 지표 표 ---------------- */

/* ⚠️ GeneratePress(assets/css/main.css:190)가 `table, th, td { border: 1px solid }` 에
   `th/td { border-width: 0 1px 1px 0 }` 를 얹는다 — 그 우측 1px 이 표를 격자로 가른다.
   `table` 에는 `border-collapse: separate` 와 `margin: 0 0 1.5em` 까지 들어온다.
   구획은 가로 hairline 하나면 충분하므로 전부 지우고 필요한 선만 다시 긋는다.
   ⛔ 세로 구분선을 다시 넣지 말 것 — 열이 4개뿐이라 격자가 숫자를 읽는 속도만 늦춘다. */
.opr-table {
	width: 100%;
	border-collapse: collapse;
	table-layout: fixed;
	border: 0;
	margin: 0;
}
/* ⚠️ padding 도 함께 지운다. GeneratePress 의 `th, td { padding: 8px }` 는
   내가 thead 에 padding-bottom 만 주면 **좌우·상단이 8px 로 남아** 헤더 글자가
   본문 셀보다 안쪽으로 밀린다(실제로 열이 어긋나 보였다).
   가로 여백은 아래 '열 간격' 규칙 한 곳에서만 준다. */
.opr-table tr,
.opr-table th,
.opr-table td { border: 0; background: none; padding: 0; }

/* 열 간격 — 헤더와 본문이 **같은 규칙**을 쓴다.
   라벨열은 오른쪽으로, 숫자열은 왼쪽으로만 8px. 바깥쪽 가장자리에는 여백을 두지 않아
   표의 좌우 끝이 패널 안에서 정렬된다. */
.opr-table th:first-child { padding-right: 8px; }
.opr-table th + th,
.opr-table td { padding-left: 8px; }

.opr-table thead th {
	padding-bottom: 10px;
	border-bottom: 1px solid var(--opr-gray-300);
	font-size: 11px;
	font-weight: 600;
	color: var(--opr-gray-700);
	text-align: right;
}
/* 라벨열은 반드시 auto(=남는 폭 전부) — 고정폭을 주면 좁은 화면에서 숫자가 잘린다. */
.opr-table thead th:first-child {
	width: auto;
	text-align: left;
	font-size: 12px;
	letter-spacing: .04em;
}
.opr-table thead th:nth-child(2),
.opr-table thead th:nth-child(3) { width: 74px; }
.opr-table thead th:nth-child(4) { width: 86px; }

/* 세로 여백만 여기서 준다 — 가로는 위 '열 간격' 규칙이 헤더와 공유한다.
   ⚠️ `padding: 6px 0` 처럼 단축으로 쓰면 그 가로 여백을 도로 0 으로 덮어쓴다.
   행이 7~8개라 8px 이면 표만 세로로 길어져 옆 차트(120px)와 높이가 크게 어긋난다. */
.opr-table tbody th,
.opr-table tbody td {
	padding-top: 6px;
	padding-bottom: 6px;
	border-bottom: 1px solid var(--opr-gray-100);
	vertical-align: baseline;
}
.opr-table tbody th {
	text-align: left;
	font-size: 13px;
	font-weight: 600;
	color: var(--opr-gray-700);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.opr-table tbody td {
	text-align: right;
	font-size: 12px;
	font-weight: 600;
	color: var(--opr-gray-700);
}
.opr-table tbody td.is-now {
	font-size: 15px;
	font-weight: 700;
	letter-spacing: -.02em;
	color: var(--opr-fg-strong);
}
.opr-table tbody tr:last-child th,
.opr-table tbody tr:last-child td { border-bottom: 0; }

/* '참여 조회 기준' 처럼 라벨이 분모를 들고 있어야 하는 경우.
   이 한 줄이 없으면 위의 조회수와 곱해지고, 그 곱은 틀린다. */
.opr-scope {
	display: block;
	font-style: normal;
	font-size: 10.5px;
	font-weight: 600;
	color: var(--opr-gray-700);
	opacity: .8;
	line-height: 1.4;
}

.opr-manual {
	display: inline-block;
	margin-left: 4px;
	padding: 1px 5px;
	border-radius: 6px;
	background: var(--opr-gray-100);
	font-size: 10px;
	font-weight: 600;
	color: var(--opr-gray-700);
	vertical-align: middle;
}

/* ---------------- 시청자 분석 ---------------- */

.opr-aud { background: var(--opr-gray-50); border-top: 1px solid var(--opr-gray-200); padding: 20px 28px 22px; }
.opr-aud-t {
	margin: 0 0 14px;
	font-size: 12px;
	font-weight: 600;
	letter-spacing: .04em;
	color: var(--opr-gray-700);
}
.opr-aud-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
	gap: 24px;
}
.opr-dist-t { margin: 0 0 8px; font-size: 11px; font-weight: 600; color: var(--opr-fg-strong); }
.opr-dist-list { list-style: none; margin: 0; padding: 0; }
.opr-dist-list li {
	display: grid;
	grid-template-columns: 46px minmax(0, 1fr) minmax(0, 76px);
	align-items: center;
	gap: 10px;
	padding: 5px 0;
}
.opr-dist-k { font-size: 11px; font-weight: 600; color: var(--opr-gray-700); }
.opr-dist-bar {
	display: block;
	height: 6px;
	border-radius: 2px;
	background: var(--opr-gray-200);
	overflow: hidden;
}
.opr-dist-bar i { display: block; height: 100%; background: currentColor; }
.opr-dist-v {
	text-align: right;
	font-size: 12px;
	font-weight: 700;
	color: var(--opr-fg-strong);
}
.opr-aud-note {
	margin: 12px 0 0;
	font-size: 11px;
	font-weight: 600;
	line-height: 1.6;
	color: var(--opr-gray-700);
}
.opr-aud-date { opacity: .8; }

/* ---------------- 유입 분석 ----------------
   시청자 분석과 같은 막대를 쓰되 **라벨 열이 다르다**.
   연령·성별은 '25-34' 처럼 짧지만 유입은 '기타 YouTube 페이지'·'네이버 클립 추천 카드' 라
   46px 고정폭에 넣으면 잘린다. 여기서만 라벨 열을 넓히고 줄바꿈을 허용한다. */
.opr-aud-traffic .opr-dist-list li { grid-template-columns: minmax(88px, 132px) minmax(0, 1fr) minmax(0, 76px); }
.opr-aud-traffic .opr-dist-k { line-height: 1.35; word-break: keep-all; }

/* 화면이 항목을 접어 둬 합이 100%가 아닐 때. 눈에 띄되 경고처럼 보이지는 않게. */
.opr-dist-gap {
	margin: 8px 0 0;
	font-size: 10.5px;
	font-weight: 600;
	line-height: 1.5;
	color: var(--opr-gray-700);
}

.opr-post-note {
	margin: 0;
	padding: 14px 28px 18px;
	font-size: 11px;
	font-weight: 600;
	line-height: 1.6;
	color: var(--opr-gray-700);
}

.opr-report .opr-empty {
	margin: 0;
	padding: 40px 28px;
	text-align: center;
	font-size: 13px;
	font-weight: 600;
	color: var(--opr-gray-700);
}

/* ---------------- 반응형 ---------------- */

/* 태블릿 — 레일을 조금 좁힌다. 섹션 내부 2단은 auto-fit 이 알아서 접는다. */
@media (max-width: 1120px) {
	.opr-shell.opr-report { grid-template-columns: 232px minmax(0, 1fr); gap: 28px; padding: 32px 20px 72px; }
}

/* 모바일 — 레일을 본문 위로 올려 1단으로 세운다. */
@media (max-width: 900px) {
	.opr-shell.opr-report {
		grid-template-columns: minmax(0, 1fr);
		gap: 20px;
		padding: 24px 16px 64px;
	}
	.opr-rail {
		gap: 16px;
	}
	.opr-hero { height: 120px; }
	.opr-report .opr-title { font-size: 22px; }

	/* 목차는 접이식으로 — 게시물이 6건만 돼도 첫 화면이 목차로 가득 찬다. */
	.opr-toc {
		max-height: 168px;
		overflow-y: auto;
		padding: 12px;
		border: 1px solid var(--opr-gray-200);
		border-radius: 8px;
		background: var(--opr-surface);
	}

	.opr-post-head { flex-direction: column; gap: 12px; padding: 18px 18px; }
	.opr-post-n { text-align: left; }
	.opr-post-n strong { font-size: 26px; }
	.opr-pane { padding: 18px; }
	.opr-aud { padding: 18px; }
	.opr-post-note { padding: 12px 18px 16px; }
	.opr-table thead th:nth-child(2),
	.opr-table thead th:nth-child(3) { width: 62px; }
	.opr-table thead th:nth-child(4) { width: 74px; }
}

@media (max-width: 480px) {
	.opr-tiles { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
	.opr-tile { padding: 14px 16px 14px; }
	.opr-tile-n { font-size: 23px; }
	.opr-dist-list li { grid-template-columns: 44px minmax(0, 1fr) minmax(0, 64px); gap: 8px; }
	/* 480px 에서 유입 라벨까지 넓게 두면 막대가 사라진다 — 라벨을 줄이고 막대를 남긴다. */
	.opr-aud-traffic .opr-dist-list li { grid-template-columns: minmax(72px, 96px) minmax(0, 1fr) minmax(0, 56px); }
}

/* ---------------- 인쇄 / PDF ---------------- */

/* 대행사가 이 화면을 그대로 광고주에게 넘긴다. 브라우저 기본 인쇄로는
   레일이 본문과 겹치고 차트 색이 전부 날아가 리포트가 아니라 표 뭉치가 된다. */
@media print {
	@page { size: A4 portrait; margin: 12mm; }

	body.opr-report-screen { background: var(--surface-white); }
	body.opr-report-screen .site-header,
	body.opr-report-screen .site-footer,
	body.opr-report-screen .back-to-top-button,
	body.opr-report-screen #wpadminbar,
	body.opr-report-screen .opr-toc,
	body.opr-report-screen .opr-dl { display: none; }

	.opr-shell.opr-report {
		display: block;
		max-width: none;
		padding: 0;
		font-size: 11pt;
	}

	/* 레일은 표지처럼 맨 위에 눕힌다 — 세로 컬럼으로 두면 본문 폭이 절반이 된다. */
	.opr-rail {
		display: block;
		margin-bottom: 10mm;
		padding-bottom: 6mm;
		border-bottom: 1px solid var(--opr-gray-300);
	}
	.opr-hero { height: 34mm; margin-bottom: 5mm; }
	.opr-kpi { box-shadow: none; border: 1px solid var(--opr-gray-200); margin-top: 5mm; }
	.opr-rail-notes { margin-top: 5mm; }

	.opr-main { display: block; }
	.opr-tiles { margin-bottom: 6mm; }

	/* 게시물 한 건이 페이지 경계에서 잘리면 D+7·D+14 표만 다음 장으로 넘어가
	   어느 게시물의 숫자인지 알 수 없게 된다. */
	.opr-post {
		break-inside: avoid;
		page-break-inside: avoid;
		box-shadow: none;
		border: 1px solid var(--opr-gray-200);
		margin-bottom: 6mm;
	}
	.opr-tile { box-shadow: none; border: 1px solid var(--opr-gray-200); }

	/* 차트 바·비중 바가 흰색으로 날아가면 리포트가 성립하지 않는다. */
	.opr-bar-fill,
	.opr-tile-bar i,
	.opr-dist-bar i,
	.opr-logo {
		-webkit-print-color-adjust: exact;
		print-color-adjust: exact;
	}

	/* 링크 화살표(↗)는 종이에서 의미가 없다. */
	.opr-post-title a { color: var(--opr-fg-strong); text-decoration: none; }
}
