/*
 * 이 사이트는 엔진 기본 스킨(board 스킨)을 그대로 쓴다 — 강조색만 `gbun.config.ts` 의
 * `ui.accent` 가 정한다. 플러그인 화면 전용 토큰(`--nr-*`)은 `05-own-tokens.css` 에 있다.
 * 여기 남은 것은 노리터 기능 규칙이 읽는 사이트 고유 변수(`--site-*`)뿐이다.
 */

/* Pretendard Variable 은 `gbun.config.ts` 의 `site.externalStylesheets` 가 건다(cdnjs). */

:root {
  /* 눌린 단추·탭의 테두리 — 밝을 땐 강조색 그대로. */
  --site-pressed-line: #146c5a;
  /* 떠 있는 판의 그림자 — 레거시 `--shadow-md`(`_tokens.scss`). */
  --site-shadow-md: 0 10px 30px rgb(15 37 32 / 10%);
  /* 본문 글자색 — 레거시 PostContent 의 먹색. */
  --site-prose-text: #101716;
  /* 코드 칸 가장자리 — 밝을 땐 없음. */
  --site-code-line: transparent;
}

/*
 * 어두운 값. 엔진의 밝기 선택 계약대로 두 선택자에 같은 값을 둔다. 하나는 OS 가 어둡고 방문자가 밝게를
 * 고르지 않았을 때, 다른 하나는 방문자가 어둡게를 골랐을 때다. `:root:root` 겹침은 스킨의 어두운
 * 블록과 특이성을 맞추려는 것이고, 이 파일이 나중에 실려 순서로 이긴다.
 */
@media (prefers-color-scheme: dark) {
  :root:root:not([data-theme='light']) {
    --site-pressed-line: color-mix(in srgb, var(--board-accent-text) 45%, var(--board-surface));
    /* 레거시 다크 `--shadow-md`(`_themes.scss`). */
    --site-shadow-md: 0 12px 36px rgb(0 0 0 / 35%);
    --site-prose-text: #e8efed;
    /* 코드 칸(#17211f)이 글 면(#18201f)과 한 끗 차라 가장자리를 긋는다. */
    --site-code-line: var(--board-line);
  }
}

:root:root[data-theme='dark'] {
  --site-pressed-line: color-mix(in srgb, var(--board-accent-text) 45%, var(--board-surface));
  /* 레거시 다크 `--shadow-md`(`_themes.scss`). */
  --site-shadow-md: 0 12px 36px rgb(0 0 0 / 35%);
  --site-prose-text: #e8efed;
  /* 코드 칸(#17211f)이 글 면(#18201f)과 한 끗 차라 가장자리를 긋는다. */
  --site-code-line: var(--board-line);
}

/*
 * 사이트 공통 부품 — 펼침 선택(레거시 `AppSelect.vue`). 알뜰폰·성지시세·디아블로 정렬이 같은 마크업을 쓴다:
 * details.select > summary.select-trigger + form.select-content > button.select-item.
 *
 * 트리거는 12rem 을 못 박고 좁은 화면에서 `min-width: 0` 으로 푼다 — 글자 길이가 바뀌어도 옆 단추가
 * 밀리지 않게 하는 자리다. 글자가 400 에 줄 높이 1.6 인 것은 이 자리가 「단추」가 아니라 「고른 값」이라서다.
 * 펼친 판은 단추 아래로 열고 너비는 단추를 따라가며(원본 `min-width: var(--reka-select-trigger-width)`)
 * 오른쪽 끝을 맞춘다. 간격 0·안쪽 .3rem·z 100·그림자는 원본 `.select-content`(`AppSelect.vue:18`
 * — `--z-popover`·`--shadow-md`, `_tokens.scss:24,41`), 위 5px 는 원본의 `side-offset` 이다.
 * 항목은 원본 `.select-item`(`AppSelect.vue:19-20`): 패딩 .5/.6, r.3rem, 1rem/1.6 이라 줄 높이 41.6.
 * 고른 항목은 배경이 아니라 오른쪽 체크(`SelectItemIndicator` 의 svg)로 보여주고, 가리킨 항목은
 * `[data-highlighted]` 의 brand-50/700 이다. 스킨이 `button[type='submit']` 에 채우는 강조색은
 * 같은 특이도로 맞세워 벗긴다.
 */
.select {
  position: relative;
}

.select-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-width: 12rem;
  min-height: var(--nr-control-h);
  padding: var(--nr-control-pad-y) var(--nr-input-pad-x);
  border: 1px solid var(--nr-line);
  border-radius: var(--nr-control-radius);
  background: var(--nr-surface);
  color: var(--nr-text);
  font-size: var(--nr-size-ui);
  font-weight: 400;
  line-height: 1.6;
  list-style: none;
  cursor: pointer;
}

.select-trigger::-webkit-details-marker {
  display: none;
}

.select[open] > .select-content {
  position: absolute;
  top: calc(100% + 5px);
  right: 0;
  z-index: 100;
  display: grid;
  min-width: 100%;
  padding: 0.3rem;
  border: 1px solid var(--nr-line);
  border-radius: 0.4rem;
  background: var(--nr-surface);
  box-shadow: var(--site-shadow-md);
}

/* 스킨의 submit 채움 규칙(0,4,1)·hover(0,5,1)와 같은 무게로 맞선다 — 이 파일이 뒤에 실려 차례로 이긴다. */
.select .select-content button.select-item[type='submit'] {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 0.5rem 0.6rem;
  border: 0;
  border-radius: 0.3rem;
  background: transparent;
  color: var(--nr-text);
  font-family: inherit;
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.6;
  text-align: left;
  cursor: pointer;
}

.select .select-content button.select-item[type='submit']:hover,
.select .select-content button.select-item[type='submit']:focus-visible {
  background: var(--nr-brand-50);
  color: var(--nr-brand-700);
  opacity: 1;
}

/*
 * 사이트 공통 부품 — 필터 칩(레거시 `_filters.scss:29-76`). 알뜰폰·성지시세 목록은
 * submit 단추 + `aria-pressed`, 성지시세 상세는 라디오 + label 이 같은 칩을 쓴다.
 * 디아블로 칩은 자기 판이라 여기 안 건드린다.
 *
 * 스킨의 submit 채움 규칙(0,4,1)·hover(0,5,1)와 같은 무게로 맞선다 — 이 파일이 뒤에
 * 실려 차례로 이긴다. hover 는 글자 brand-700·선 brand-500 만 바뀌고(`_filters.scss:45`)
 * 눌린 칩은 accent 채움이다. 통신사 칩은 꺼졌을 때 `--chip-tone` 이 글자·hover 선을
 * 같이 잡는다(`_filters.scss:57` 의 `--carrier-color`). 50rem 이하는 같은 폭 격자
 * (`_filters.scss:70` 의 auto-fit)에 칸 2.1rem.
 */
.filter-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  margin: 0;
}

/* 추천은 칩 하나가 폼 하나다. 폼 상자가 흐름을 끊지 않도록 상자를 지운다. */
.filter-chips > form {
  display: contents;
}

.filter-chips button.filter-chip[type='submit'][aria-pressed],
.filter-chips label.filter-chip {
  min-height: 2.35rem;
  padding: 0 0.9rem;
  border: 1px solid var(--nr-line);
  border-radius: 6.4px;
  background: var(--nr-surface);
  color: var(--chip-tone, var(--nr-dim));
  font-family: inherit;
  font-size: var(--nr-size-caption);
  font-weight: 600;
  line-height: 1.6;
  cursor: pointer;
}

.filter-chips button.filter-chip[type='submit'][aria-pressed='true'],
.filter-chips input:checked + label.filter-chip {
  border-color: var(--nr-accent);
  background: var(--nr-accent);
  color: var(--nr-on-accent);
}

.filter-chips button.filter-chip[type='submit'][aria-pressed]:not([aria-pressed='true']):hover,
.filter-chips input:not(:checked) + label.filter-chip:hover {
  border-color: var(--chip-tone, var(--nr-brand-500));
  background: var(--nr-surface);
  color: var(--chip-tone, var(--nr-brand-700));
  opacity: 1;
}

/* 눌린 칩은 운영에도 별도 hover 가 없다 — `.active` 가 `:hover` 뒤에 서서 눌린 모양을 지킨다. */
.filter-chips button.filter-chip[type='submit'][aria-pressed='true']:hover {
  border-color: var(--nr-accent);
  background: var(--nr-accent);
  color: var(--nr-on-accent);
  opacity: 1;
}

.filter-chips input:focus-visible + label.filter-chip {
  outline: 2px solid var(--nr-accent);
  outline-offset: 2px;
}


/*
 * 통신사 색은 글자색이 아니라 변수로 든다. 글자색을 정하는 것은 위 칩 규칙이고(선택됐으면 강조색),
 * 여기서는 그 규칙이 읽는 값만 바꾼다 — 특이도 싸움을 한 번으로 줄이는 자리다.
 */
.carrier-tone--skt {
  --chip-tone: var(--nr-carrier-skt);
}

.carrier-tone--kt {
  --chip-tone: var(--nr-carrier-kt);
}

.carrier-tone--lgu {
  --chip-tone: var(--nr-carrier-lgu);
}

@media (max-width: 50rem) {
  /* 칸 수를 폭이 정한다 — 레거시 `_filters.scss:70` 의 auto-fit. 560 에서 6개, 800 에서 9개가
     한 줄에 서고, 칸이 좁으면 칩 글자가 두 줄로 접힌다(`white-space: normal`). */
  .filter-chips {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(4.25rem, 1fr));
    gap: 0.3rem;
  }

  .filter-chips button.filter-chip[type='submit'][aria-pressed] {
    min-width: 0;
    min-height: 2.1rem;
    padding: 0.25rem 0.4rem;
    line-height: 1.3;
    white-space: normal;
  }
}
/*
 * 헤더·네비·회원 메뉴와 본문 시작 여백은 엔진 기본 스킨 값을 그대로 쓴다. 여기 남은 것은
 * 노리터 기능 소속 규칙뿐이다.
 */

/*
 * 시세 띠(`plugins/market-strip`). 운영 noriter.com 과 같이 **상자 없는 한 줄**이다 — 레거시
 * `PromoMarketStrip.vue` 가 상자를 벗긴 판단이 맞았고, 한동안 카드였던 것을 되돌린다. 띠라는 것은
 * 아랫선 하나가 말한다(레거시 `.strip` 도 `border-bottom` 만 두고 배경은 두지 않았다).
 *
 * 띠는 헤더 **밖**, `.board-shell` 의 `.board-body` 바로 앞에 선다(스킨 `index.tsx`). 헤더는 셸 밖의
 * 전폭 띠라서 그 아랫선과의 사이는 띠가 스스로 벌인다 — 헤더 아랫선 아래로 윗여백 하나.
 *
 * 닫으면 `public/market-strip.js` 가 `<html data-market-strip="off">` 를 단다. 숨기는 것은 코어가
 * 씌운 `.gb-plugin-market-strip` 이다 — 안쪽만 숨기면 슬롯 div 가 빈 채로 남는다.
 */
html[data-market-strip='off'] .gb-plugin-market-strip {
  display: none;
}
/*
 * 노리터 화면(알뜰폰·폰덕·디아·시세 띠·관련글·해외반응 카드)의 자기 토큰(2026-10-15).
 * 이 화면들은 엔진 스킨이 아니다 — 엔진 스킨이 모양을 다시 그려도 따라 바뀌지 않게, 스킨의
 * `--board-*` 를 빌려 쓰지 않고 여기 값을 쓴다. 값은 스킨 개편(GBB-6) 전 board 스킨(엔진 0a01bb1b)
 * 에 이 사이트가 덮었던 값을 얹은 것 — 그 화면들이 맞춰 그려진 값이다.
 */
:root {
  --nr-font: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo", "Malgun Gothic", system-ui, sans-serif;
  --nr-mono: ui-monospace, "SF Mono", Menlo, Consolas, "D2Coding", monospace;
  --nr-size-caption: 0.875rem; /* 2026-10-15 엔진 ui.textSize large 에 맞춰 한 단계 올림(13→14, 14→15) */
  --nr-size-meta: 0.9375rem;
  --nr-size-ui: 1rem;
  --nr-size-read: 1.0625rem;
  --nr-size-head: 1.125rem;
  --nr-size-display: 1.375rem;
  --nr-size-page: 1.625rem;
  --nr-size-title: clamp(1.75rem, 3vw, 2.25rem);
  --nr-weight-normal: 400;
  --nr-weight-bold: 700;
  --nr-leading-tight: 1.3;
  --nr-leading-ui: 1.5;
  --nr-leading-read: 1.75;
  --nr-space-1: 0.25rem;
  --nr-space-2: 0.5rem;
  --nr-space-3: 0.75rem;
  --nr-space-4: 1rem;
  --nr-space-5: 1.25rem;
  --nr-space-6: 1.5rem;
  --nr-space-7: 2rem;
  --nr-space-8: 3rem;
  --nr-size-xs: var(--nr-size-caption);
  --nr-size-foot: var(--nr-size-caption);
  --nr-size-s: var(--nr-size-meta);
  --nr-size: var(--nr-size-ui);
  --nr-size-l: var(--nr-size-ui);
  --nr-size-xl: var(--nr-size-head);
  --nr-size-2xl: var(--nr-size-page);
  --nr-size-body: var(--nr-size-read);
  --nr-weight-title: 700;
  --nr-bg: #eef3f2;
  --nr-surface: #ffffff;
  --nr-tint: #f5f8f7;
  --nr-tint-2: #e7eeec;
  --nr-notice: #edf8f5;
  --nr-line: #dce4e2;
  --nr-rule: #c9d4d1;
  --nr-text: #17201f;
  --nr-mid: #46524f;
  --nr-dim: #65726f;
  --nr-ink: #17201f;
  --nr-on-ink: #ffffff;
  --nr-accent: #146c5a;
  --nr-on-accent: #ffffff;
  --nr-accent-hover: #105649;
  --nr-accent-text: #146c5a;
  --nr-count: #146c5a;
  --nr-new: #d13438;
  --nr-danger: #c63838;
  --nr-danger-fill: var(--nr-danger);
  --nr-radius: calc(8px * var(--ui-radius, 1));
  --nr-radius-s: calc(3px * var(--ui-radius, 1));
  --nr-radius-l: 0;
  --nr-shadow: 0 1px 2px rgb(15 37 32 / 7%);
  --nr-card-pad: 1.1rem;
  --nr-empty-pad: 2.5rem 1rem;
  --nr-control-h: calc(2.75rem * var(--ui-density, 1));
  --nr-control-pad-y: 0.55rem;
  --nr-control-pad-x: 0.9rem;
  --nr-control-radius: calc(0.55rem * var(--ui-radius, 1));
  --nr-control-leading: 1.2;
  --nr-input-pad-x: 0.7rem;
  --nr-rail-w: 11rem;
  --nr-side-w: 15rem;
  --nr-compose-w: var(--nr-side-w);
  --nr-max: 75.75rem;
  --nr-gap: 1rem;
  --nr-header-offset: calc(var(--gb-header-offset, 4.0625rem) + 0.75rem);
  --nr-carrier-skt: #d8412f;
  --nr-carrier-kt: var(--nr-ink);
  --nr-carrier-lgu: #c8247c;
  --nr-brand-500: #18806a;
  --nr-brand-50: #edf8f5;
  --nr-brand-100: #d5eee7;
  --nr-brand-700: #105649;
  --nr-ring: #d5eee7;
  --nr-focus-line: var(--nr-brand-500);
  --nr-focus-ring: var(--nr-ring);
}
@media (prefers-color-scheme: dark) {
  :root:root:not([data-theme='light']) {
    --nr-bg: #101716;
    --nr-surface: #18201f;
    --nr-tint: #202a28;
    --nr-tint-2: #2a3532;
    --nr-notice: #16302a;
    --nr-line: #34413e;
    --nr-rule: #45524f;
    --nr-text: #e8efed;
    --nr-mid: #c2ccc9;
    --nr-dim: #9eaaa7;
    --nr-ink: #e8efed;
    --nr-accent: var(--ui-accent-dark, #8ed6c5);
    --nr-on-accent: var(--ui-on-accent-dark, #102c26);
    --nr-accent-text: #56b89f;
    --nr-on-ink: #101716;
    --nr-accent-hover: color-mix(in srgb, var(--nr-accent) 72%, #000);
    --nr-count: #56b89f;
    --nr-new: #ff6b70;
    --nr-danger: #ff8a80;
    --nr-danger-fill: color-mix(in srgb, var(--nr-danger) 55%, #000);
    --nr-shadow: 0 1px 2px rgb(0 0 0 / 30%);
    --nr-carrier-skt: #ff8272;
    --nr-carrier-kt: var(--nr-ink);
    --nr-carrier-lgu: #f07cb2;
    --nr-brand-50: color-mix(in srgb, var(--nr-accent) 30%, var(--nr-surface));
    --nr-brand-100: color-mix(in srgb, var(--nr-accent-text) 35%, var(--nr-surface));
    --nr-brand-700: #56b89f;
    --nr-ring: color-mix(in srgb, var(--nr-accent-text) 30%, transparent);
  }
}
:root:root[data-theme='dark'] {
  --nr-bg: #101716;
  --nr-surface: #18201f;
  --nr-tint: #202a28;
  --nr-tint-2: #2a3532;
  --nr-notice: #16302a;
  --nr-line: #34413e;
  --nr-rule: #45524f;
  --nr-text: #e8efed;
  --nr-mid: #c2ccc9;
  --nr-dim: #9eaaa7;
  --nr-ink: #e8efed;
  --nr-accent: var(--ui-accent-dark, #8ed6c5);
  --nr-on-accent: var(--ui-on-accent-dark, #102c26);
  --nr-accent-text: #56b89f;
  --nr-on-ink: #101716;
  --nr-accent-hover: color-mix(in srgb, var(--nr-accent) 72%, #000);
  --nr-count: #56b89f;
  --nr-new: #ff6b70;
  --nr-danger: #ff8a80;
  --nr-danger-fill: color-mix(in srgb, var(--nr-danger) 55%, #000);
  --nr-shadow: 0 1px 2px rgb(0 0 0 / 30%);
  --nr-carrier-skt: #ff8272;
  --nr-carrier-kt: var(--nr-ink);
  --nr-carrier-lgu: #f07cb2;
  --nr-brand-50: color-mix(in srgb, var(--nr-accent) 30%, var(--nr-surface));
  --nr-brand-100: color-mix(in srgb, var(--nr-accent-text) 35%, var(--nr-surface));
  --nr-brand-700: #56b89f;
  --nr-ring: color-mix(in srgb, var(--nr-accent-text) 30%, transparent);
}

.market-strip {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  /* 운영과 같은 값. 글자 사이를 띄우는 값이라 토큰 눈금에 없다. */
  gap: 0.15rem 1.1rem;
  min-width: 0;
  /*
   * 아래는 `.board-body` 의 윗여백이 이미 벌린다. 위는 헤더 선에서 17.6px — 레거시
   * `.promo-slot { margin-block: 1.1rem 0 }`(`global.scss:60`). 토큰 눈금에 없는 리터럴이다.
   */
  margin: 1.1rem 0 0;
  /* 오른쪽은 닫기 단추가 설 자리, 아래는 아랫선과 글자 사이. 운영 `.strip--closable` 과 같다. */
  padding: 0 1.75rem 0.65rem 0;
  border-bottom: 1px solid var(--nr-line);
  font-size: var(--nr-size-meta);
}

.market-strip__ask {
  flex: none;
}

/* 단추가 아니라 글 속의 링크로 보이게 한다. 밑줄 하나면 눌리는 것인 줄 안다. */
.market-strip__links {
  flex: none;
}

/* 링크 색은 운영의 `--color-brand-700` — `--board-brand-700` 이 그 값이다. */
.market-strip__links a {
  color: var(--nr-brand-700);
  font-weight: var(--nr-weight-bold);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--nr-rule);
}

.market-strip__links a:hover {
  text-decoration-color: currentcolor;
}


.market-strip__how {
  flex: none;
  color: var(--nr-dim);
  font-size: var(--nr-size-caption);
}

/*
 * 수집 사실 줄(「09-05 확인 · 판매처 N곳 · 요금제 N개」). 오른쪽 끝으로 밀어 닫기 단추 앞에 붙인다.
 * 레거시 `PromoMarketStrip.vue` `.strip__fact` 그대로이고, 거기서도 `below(desktop)` — 960px
 * **이하**에서는 접는다(`_breakpoints.scss` 의 below 는 경계를 포함한다) — 좁으면 문장과 표
 * 이름이 먼저 자리를 가져야 한다.
 */
.market-strip__fact {
  flex: none;
  margin-left: auto;
  color: var(--nr-dim);
  font-size: var(--nr-size-caption);
}

@media (max-width: 960px) {
  .market-strip__fact {
    display: none;
  }
}

/*
 * 닫기 단추. 자리를 차지하지 않는다 — 절대 자리에 두고 글자는 오른쪽 여백으로 비켜 준다.
 *
 * 이 규칙의 값어치는 세로 자리다. 단추는 **첫 줄** 가운데에 온다. 넓은 화면에서는 띠가 한 줄이라
 * 블록 가운데와 첫 줄 가운데가 같지만 좁은 화면에서는 둘로 갈리므로(아래 `@media`) 첫 줄에 붙인다.
 *
 * 넓은 화면의 `top: 50%` 는 여백 상자의 가운데다. 아래 여백(0.65rem)의 절반만큼 도로 끌어올리면
 * 첫 줄 가운데와 겹친다 — 그래서 `- 0.325rem` 이다. 운영도 같은 식을 쓴다.
 */
.market-strip__close {
  position: absolute;
  top: 50%;
  right: 0;
  transform: translateY(calc(-50% - 0.325rem));
  display: grid;
  place-items: center;
  /* 스킨의 `button` 이 `min-height: 2.25rem` 을 깐다. 누를 자리는 44px, 동그라미는 안쪽 28px 만 그린다. */
  width: 2.75rem;
  height: 2.75rem;
  margin-right: -0.5rem;
  background-clip: content-box;
  min-height: 0;
  padding: 0.5rem;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--nr-dim);
  cursor: pointer;
}

.market-strip__close:hover {
  background: var(--nr-tint);
  color: var(--nr-ink);
}

/*
 * 좁은 화면에서는 문장이 한 줄을 통째로 쓰고 표 이름이 그 아래 선다. 운영과 같다.
 * 띠의 오른쪽 여백이 사라지므로(단추 자리를 글자 쪽에서 비운다) 문장에만 그만큼 준다.
 */
@media (max-width: 47.5rem) {
  .market-strip {
    gap: 0.15rem 0.9rem;
    padding: 0 0 0.55rem;
  }

  .market-strip__ask {
    width: 100%;
    padding-right: 2.25rem;
  }

  /* 두 줄이 되면 여백 상자의 가운데는 아랫줄 언저리다. 첫 줄에 붙인다. */
  .market-strip__close {
    top: calc(-3px - 0.5rem);
    transform: none;
  }
}

/* 레거시 `sm`(560px). */
@media (max-width: 35rem) {
  .market-strip {
    gap: 0.15rem 0.7rem;
  }
}

/*
 * 알뜰폰 요금제 비교(`plugins/mvno`). 플러그인 페이지의 HTML 은 코어가 준 대로 나가고
 * 스킨은 그 안을 모르므로, 이 화면들의 규칙은 여기 있어야 한다.
 *
 * **레거시 스타일을 옮겨 오지 않았다.** 레거시 `.vue` 의 scoped 스타일은 자기 디자인
 * 토큰(`--color-brand-600` 등)을 깔고 앉아 있는데 그건 이 사이트에 없다. 재현해야 하는
 * 것은 픽셀이 아니라 주소·마크업·메타이므로(gbun-board `AGENTS.md` 규칙 18) 여기서는
 * 스킨 토큰만으로 읽을 수 있게만 짠다.
 */
/*
 * 좌우 여백은 목록 카드와 같은 값을 쓴다(운영 `--compare-inset`). 머리만 이 값을 안고 있고
 * 카드·기준·툴바는 제 안쪽 패딩으로 같은 자리를 만든다 — 그래서 값이 두 군데 적혀 있다.
 */
.mvno-head {
  padding: 0 17.6px;
}

.mvno-head h1 {
  /* 아래 문단과의 사이는 레거시 `.compare-head` 의 격자 간격 .2rem 이다(`_compare.scss:21`). */
  margin: 0 0 0.2rem;
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1.3;
}

.mvno-head p {
  margin: 0;
  color: var(--nr-dim);
  font-size: var(--nr-size-meta);
  line-height: 1.6;
}

/*
 * 수집 기준. 접히는 한 줄이라 카드가 아니라 `details` 이고, 본문 셋은 그 뒤에 온다.
 * 여닫는 것은 브라우저가 하고, 열림 여부는 `[open]` 으로만 본다 — 스크립트는 없다.
 * `summary` 의 기본 삼각형은 `list-style: none` 과 `::-webkit-details-marker` 로 지운다.
 */
.mvno-note {
  margin: 0 0 1rem;
  padding: 12px 17.6px;
  border: 1px solid var(--nr-line);
  border-radius: 12px;
  background: var(--nr-surface);
}

.mvno-note > summary {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  line-height: 1.5;
  list-style: none;
  cursor: pointer;
}

.mvno-note > summary::-webkit-details-marker {
  display: none;
}

.mvno-note > summary > svg {
  flex: 0 0 auto;
  color: var(--nr-accent);
}

.mvno-note-title {
  flex: 0 0 auto;
  margin: 0;
  color: var(--nr-text);
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: inherit;
}

.mvno-note-meta {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  color: var(--nr-dim);
  font-size: var(--nr-size-caption);
  font-weight: 400;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* 색은 옅지 않다 — 접힌 줄에서 「자세히」가 먼저 눈에 들어와야 한다. 운영 값 그대로. */
.mvno-note-toggle {
  flex: 0 0 auto;
  margin-left: auto;
  color: var(--nr-brand-700);
  font-size: var(--nr-size-caption);
  font-weight: 600;
}

.mvno-note-toggle span:last-child {
  display: none;
}

.mvno-note[open] .mvno-note-toggle span:first-child {
  display: none;
}

.mvno-note[open] .mvno-note-toggle span:last-child {
  display: inline;
}

.mvno-note-body {
  margin: 0.7rem 0 0;
  padding-top: 0.7rem;
  border-top: 1px solid var(--nr-line);
  color: var(--nr-dim);
  font-size: var(--nr-size-meta);
  line-height: 1.7;
}

.mvno-note-facts,
.mvno-extra dl {
  margin: 0.6rem 0 0;
}

.mvno-note-facts {
  display: grid;
  gap: 0.35rem;
}

.mvno-note-facts > div,
.mvno-extra dl > div {
  display: grid;
  grid-template-columns: 6rem minmax(0, 1fr);
  gap: 0.7rem;
  padding: 0.35rem 0;
  font-size: var(--nr-size-caption);
}

.mvno-note-facts > div {
  border-bottom: 1px solid var(--nr-line);
}

.mvno-note-facts > div:last-child {
  border-bottom: 0;
}

.mvno-note-facts dt {
  color: var(--nr-brand-700);
  /* 레거시 `dt` 는 caption(13px)이다 — 위 `> div` 의 글자 크기만 물려 받으면 엔진의 dt 기본값에 져서 14px 로 남는다. */
  font-size: var(--nr-size-caption);
  font-weight: 600;
}

.mvno-extra dt {
  color: var(--nr-dim);
}

.mvno-note-facts dd {
  margin: 0;
  line-height: 1.6;
}

.mvno-extra dd {
  margin: 0;
}


/*
 * 조건 카드. 폼인 이유는 `plugins/mvno/src/screen.tsx` 머리에 적혀 있다 — 크롤 함정을 안 여는 것.
 * 칩 하나가 곧 조건 하나를 바꾸는 제출 단추이고, 나머지 값은 숨은 칸이 들고 간다.
 */
.mvno-picker {
  margin: 0 0 1.5rem;
  padding: 21.6px 17.6px;
  border: 1px solid var(--nr-line);
  border-radius: 16px;
  background: var(--nr-surface);
}

.mvno-rows {
  display: grid;
  gap: 0.8rem;
  margin-bottom: 1rem;
}

.mvno-row {
  display: grid;
  grid-template-columns: 7rem minmax(0, 1fr);
  gap: 1rem;
  align-items: center;
}

.mvno-row > strong {
  color: var(--nr-text);
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.6;
}

/* 추천 줄만 아래를 가른다 — 나머지 셋은 「전체 필터」로 이어지는 같은 무리다. */
.mvno-row-preset {
  padding-bottom: 1.1rem;
  border-bottom: 1px solid var(--nr-line);
}

/*
 * 「전체 필터」 줄. 여기는 `summary` 가 줄 전체다 — 「필터 초기화」가 왼쪽, 여닫는 단추가
 * 오른쪽에 같은 줄로 서야 하는데 `summary` 는 하나뿐이라 안에 둘 다 넣었다. 링크를 눌러도
 * 접기가 함께 일어나지만 그건 상관없다 — 어차피 `/mvno` 로 간다.
 */
.mvno-adv-bar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 1rem;
  padding-top: 13.6px;
  border-top: 1px solid var(--nr-line);
  list-style: none;
  cursor: pointer;
}

.mvno-adv-bar::-webkit-details-marker {
  display: none;
}

.mvno-reset {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  min-height: 2.35rem;
  margin-right: auto;
  color: var(--nr-dim);
  font-size: var(--nr-size-caption);
  font-weight: 600;
  text-decoration: none;
}

/* 안쪽 여백 1px 6px 는 운영에서 이 자리가 `button` 이라 붙던 기본값이다 — 상자 크기를 맞춘다. */
.mvno-adv-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  min-height: 2.35rem;
  padding: 1px 6px;
  color: var(--nr-dim);
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.6;
}

.mvno-adv-toggle svg:last-child {
  transition: transform 0.15s;
}

.mvno-advanced[open] .mvno-adv-toggle svg:last-child {
  transform: rotate(180deg);
}

/*
 * 상세 조건 일곱 줄 — 운영 `.advanced-filter-section`(`MvnoCompareView.vue:125`). 줄마다
 * `<form>` 하나라 이 상자는 폼이 아니라 테두리만이다.
 */
.mvno-options {
  margin-top: 0.5rem;
  border: 1px solid var(--nr-line);
  border-radius: 0.4rem;
  overflow: hidden;
}

.mvno-opt-row {
  display: grid;
  grid-template-columns: 7.5rem minmax(0, 1fr);
  min-height: 3rem;
  border-top: 1px solid var(--nr-line);
}

.mvno-opt-row:first-of-type {
  border-top: 0;
}

.mvno-opt-row > * {
  min-width: 0;
}

.mvno-opt-row > strong {
  display: flex;
  align-items: center;
  padding: 0.65rem 0.85rem;
  background: var(--nr-tint);
  color: var(--nr-text);
  font-size: var(--nr-size-caption);
  font-weight: 600;
}

/* 운영 `.filter-button-list` — 단추가 곧 그 값으로 가는 제출 단추다(위 tsx 의 `ButtonRow`). */
.mvno-btn-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem;
  padding: 0.45rem 0.65rem;
}

/*
 * 칩과 같은 이유로 스킨 제출 단추 규칙(0,4,1)과 무게를 맞춘다. 운영은 켜진 단추가
 * brand-50 면 + brand-700 글자 + 앞에 「✓」다 — 이 팔레트에서는 tint-2·`--board-brand-700`·ring
 * 이 그 자리다. 어두운 면 대응은 아래 두 선택자가 한다.
 */
.mvno-btn-list button.mvno-opt[type='submit'][aria-pressed] {
  min-height: 1.95rem;
  padding: 0 0.65rem;
  border: 1px solid transparent;
  border-radius: 0.3rem;
  background: transparent;
  color: var(--nr-dim);
  font-family: inherit;
  font-size: var(--nr-size-caption);
  font-weight: 600;
  cursor: pointer;
}

.mvno-btn-list button.mvno-opt[type='submit'][aria-pressed='true'] {
  border-color: var(--nr-ring);
  background: var(--nr-tint-2);
  color: var(--nr-brand-700);
}

.mvno-btn-list button.mvno-opt[type='submit'][aria-pressed='true']::before {
  content: '✓';
  margin-right: 0.25rem;
}


/*
 * 운영 옵션 단추엔 hover 가 없다 — 엔진의 submit:hover(0,5,1)가 채움을 입히지 못하게
 * 같은 무게 + 뒤 차례로 rest 모양을 그대로 다시 선다. 눌린 것도 눌린 모양을 지킨다.
 */
.mvno-btn-list button.mvno-opt[type='submit'][aria-pressed]:not([aria-pressed='true']):hover {
  border-color: transparent;
  background: transparent;
  color: var(--nr-dim);
  opacity: 1;
}

.mvno-btn-list button.mvno-opt[type='submit'][aria-pressed='true']:hover {
  border-color: var(--nr-ring);
  background: var(--nr-tint-2);
  color: var(--nr-brand-700);
  opacity: 1;
}


/*
 * 통신사 줄만 격자다 — 운영 `.provider-button-list`. 운영은 스크립트로 가장 넓은 단추를 재서
 * `--provider-button-width` 를 박는데, 여기는 재지 않고 그 초기값 7.5rem 을 그대로 둔다.
 */
.mvno-providers {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 7.5rem), 1fr));
  align-items: stretch;
  padding: 0.6rem 0.15rem;
}

.mvno-providers button.mvno-opt {
  width: 100%;
  overflow-wrap: break-word;
}

/* 구간 줄은 라벨 면이 끝까지 내려와야 한다(운영 `.range-filter-row`). */
.mvno-range-row {
  align-items: stretch;
}

/*
 * 두 손잡이 슬라이더 — 운영 `MvnoRangeSlider.vue` 의 `.range-slider` 를 토큰으로 옮겼다.
 * 손잡이가 싣는 값은 눈금 번호고 GB·원은 숨은 칸이 든다(화면 tsx 의 `RangeRow`).
 */
.mvno-range {
  box-sizing: border-box;
  min-width: 0;
  width: auto;
  max-width: 36rem;
  margin: 0.25rem 0.75rem;
  padding: 0.55rem 0.4rem 0.4rem;
}

/* 운영 `.range-slider__value`. 「적용」은 `<noscript>` 안이라 스크립트가 켜진 화면에서는 이 줄이 24px 다. */
.mvno-range-value {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  min-height: 1.5rem;
  margin-bottom: 0.45rem;
  color: var(--nr-accent-text);
  font-size: var(--nr-size-caption);
  font-weight: 600;
}

.mvno-range-apply {
  min-height: 1.95rem;
  padding: 0 0.65rem;
  border: 1px solid var(--nr-line);
  border-radius: 0.3rem;
  background: var(--nr-surface);
  color: var(--nr-dim);
  font-family: inherit;
  font-size: var(--nr-size-caption);
  font-weight: 600;
  cursor: pointer;
}

/* 누를 자리 44px. 보이는 줄은 그 가운데 4px 다. */
.mvno-range-rail {
  position: relative;
  height: 2.75rem;
}

.mvno-range-track {
  position: absolute;
  top: 1.25rem;
  right: 0.45rem;
  left: 0.45rem;
  height: 0.25rem;
  border-radius: 999px;
  background: var(--nr-line);
}

.mvno-range-track span {
  position: absolute;
  inset-block: 0;
  border-radius: inherit;
  background: var(--nr-accent);
}

.mvno-range-rail input[type='range'] {
  position: absolute;
  z-index: 2;
  top: 0;
  left: 0;
  width: 100%;
  height: 2.75rem;
  margin: 0;
  background: transparent;
  pointer-events: none;
  appearance: none;
}

.mvno-range-rail input[type='range']::-webkit-slider-runnable-track {
  height: 0.25rem;
  background: transparent;
}

.mvno-range-rail input[type='range']::-webkit-slider-thumb {
  width: 1.1rem;
  height: 1.1rem;
  margin-top: -0.425rem;
  border: 2px solid var(--nr-accent);
  border-radius: 50%;
  background: var(--nr-surface);
  box-shadow: 0 1px 4px rgb(0 0 0 / 16%);
  cursor: grab;
  pointer-events: auto;
  appearance: none;
}

.mvno-range-rail input[type='range']::-moz-range-track {
  height: 0.25rem;
  background: transparent;
}

.mvno-range-rail input[type='range']::-moz-range-thumb {
  width: 1rem;
  height: 1rem;
  border: 2px solid var(--nr-accent);
  border-radius: 50%;
  background: var(--nr-surface);
  box-shadow: 0 1px 4px rgb(0 0 0 / 16%);
  cursor: grab;
  pointer-events: auto;
}

.mvno-range-rail input[type='range']:focus-visible::-webkit-slider-thumb {
  outline: 3px solid color-mix(in srgb, var(--nr-accent) 25%, transparent);
  outline-offset: 2px;
}

.mvno-range-ticks {
  position: relative;
  height: 1.8rem;
  margin: 0 0.45rem;
}

.mvno-range-ticks span {
  position: absolute;
  top: 0;
  display: flex;
  align-items: center;
  flex-direction: column;
  transform: translateX(-50%);
  white-space: nowrap;
}

.mvno-range-ticks i {
  width: 1px;
  height: 0.35rem;
  background: var(--nr-line);
}

.mvno-range-ticks small {
  margin-top: 0.15rem;
  color: var(--nr-dim);
  font-size: var(--nr-size-caption);
  font-style: normal;
}

.mvno-range-ticks span:first-child {
  align-items: flex-start;
  transform: none;
}

.mvno-range-ticks span:last-child {
  align-items: flex-end;
  transform: translateX(-100%);
}

/*
 * 개수와 정렬. 왼쪽은 칸을 다 쓰고 오른쪽 정렬만 제 폭을 갖는다.
 * 아래 테두리는 이 줄과 목록을 가르는 선이다(운영 `.compare-toolbar`).
 */
.mvno-toolbar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 1rem;
  margin: 0 0 1rem;
  padding: 0.8rem 1.1rem 0.6rem;
  border-bottom: 1px solid var(--nr-line);
}

.mvno-count {
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
  min-width: 0;
  margin: 0;
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 1.35;
}

.mvno-count span {
  flex: 0 0 auto;
  color: var(--nr-dim);
  font-size: var(--nr-size-meta);
  font-weight: 400;
}

.mvno-list {
  display: grid;
  /* 운영 실측 1rem. 카드가 그림자를 들면서 --board-space-3(12px)로는 그림자끼리 맞붙는다. */
  gap: 1rem;
}

/*
 * 상세(`.mvno-hero`)와 값이 갈리는 자리(폭·그림자)가 있어 더는 선택자를 공유하지 않는다.
 * 값이 같은 테두리·모서리·면만 아래 `.mvno-hero` 에 그대로 다시 적었다. hover·덮는 링크처럼
 * 목록 카드만의 것은 여전히 이 아래 두 번째 `.mvno-card` 블록에만 둔다.
 */
.mvno-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 17.5rem;
  border: 1px solid var(--nr-line);
  border-radius: 1rem;
  background: var(--nr-surface);
}

/*
 * 상세 히어로는 목록 카드와 폭이 다르다(운영 실측 300px, 목록은 280px) — 같은 선택자를 쓰면 안 된다.
 * 테두리·모서리·면은 목록과 값이 같아 그대로 옮기고, 그림자는 목록에 없던 걸 새로 준다
 * (운영 `.plan-hero` 는 그림자를 든다).
 */
.mvno-hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 18.75rem;
  overflow: hidden;
  border: 1px solid var(--nr-line);
  border-radius: 1rem;
  background: var(--nr-surface);
  box-shadow: 0 2px 10px rgb(0 0 0 / 2%);
}

.mvno-card {
  position: relative;
  overflow: hidden;
  box-shadow: 0 2px 8px rgb(0 0 0 / 2%);
  transition: box-shadow 0.24s, transform 0.24s, border-color 0.24s;
}

/* hover 테두리는 운영 `--color-brand-100`(`MvnoCompareView.vue:125`) — `--board-brand-100` 이 그 값이다. */
.mvno-card:hover {
  border-color: var(--nr-brand-100);
  box-shadow: 0 12px 28px rgb(0 0 0 / 6%);
  transform: translateY(-4px);
}


@media (prefers-reduced-motion: reduce) {
  .mvno-card {
    transition: none;
  }

  .mvno-card:hover {
    transform: none;
  }
}

/*
 * 카드 전체를 눌리게 하는 덮는 링크(운영과 같은 값). 제목에 이미 같은 곳으로 가는 링크가 있어
 * 여기 것은 `tabindex="-1"`/`aria-hidden="true"` 로 접근성 트리에서 뺀다(마크업은 `screen.tsx`) —
 * 안 그러면 같은 주소가 스크린리더에 두 번 잡힌다.
 */
.mvno-card .card-link {
  position: absolute;
  inset: 0;
  z-index: 3;
  border-radius: inherit;
}

.mvno-card-main {
  min-width: 0;
  padding: 1.4rem 1.1rem;
}

/* 운영 실측 1.5rem/1.1rem — 목록 카드의 1.4rem 과 갈려 이름도 따로 쓴다. */
.mvno-hero-main {
  min-width: 0;
  padding: 1.5rem 1.1rem;
}

.mvno-card h2 {
  /* .mvno-count(602행 근처)와 같은 크기 — 운영 제목이 딱 그 눈금이다. */
  margin: 0.7rem 0;
  font-size: 1.25rem;
  font-weight: 600;
}

.mvno-card-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--nr-space-2);
  margin: 0;
  color: var(--nr-dim);
  font-size: var(--nr-size-caption);
}

/*
 * 세 칩 모두 줄높이를 따로 두지 않는다 — 레거시도 `.rank`/`.network-chip`/`.pricing-badge`
 * (`MvnoCompareView.vue:96-98`)에 line-height 가 없어 body 의 1.6 을 물려받는다. 스킨
 * `--board-leading-ui`(1.5)를 주면 칩 높이가 운영보다 1.3px 낮아진다.
 */
.mvno-rank,
.mvno-chip,
.mvno-badge {
  padding: 0.2rem 0.5rem;
  font-weight: 600;
}

/* 레거시 `MvnoCompareView.vue:96` 의 `.rank` — brand-700 글자·brand-50 면·brand-100 선 그대로. */
.mvno-rank {
  border: 1px solid var(--nr-brand-100);
  border-radius: 0.4rem;
  color: var(--nr-brand-700);
  background: var(--nr-brand-50);
}

/* 레거시 `MvnoCompareView.vue:96` 의 `.provider-name` — muted 600. */
.mvno-provider {
  color: var(--nr-dim);
  font-size: var(--nr-size-meta);
  font-weight: 600;
}

/* 레거시 `MvnoCompareView.vue:97` 의 `.network-chip` — muted 글자·surface-subtle 면. */
.mvno-chip {
  border-radius: 0.4rem;
  color: var(--nr-dim);
  background: var(--nr-tint);
}

/*
 * 목록 카드의 통신망 칩 테두리 — 레거시 같은 규칙(`MvnoCompareView.vue:97`)의
 * `color-mix(--carrier-color 25%, --color-line)`. `--carrier-color` 는 아래 `mvno-chip-*` 가 단다.
 */
.mvno-card .mvno-chip {
  border: 1px solid color-mix(in srgb, var(--carrier-color, var(--nr-line)) 25%, var(--nr-line));
}

/*
 * 상세 머리의 통신망 칩 — 레거시 `[id].vue:90` 은 톤 클래스 없이 `--detail-line`(= `--color-line`)
 * 선에 `.23rem .5rem`·`.35rem` 이다. 목록 카드와 값이 달라 따로 둔다.
 */
.mvno-hero .mvno-chip {
  padding: 0.23rem 0.5rem;
  border: 1px solid var(--nr-line);
  border-radius: 0.35rem;
}

/*
 * 카드 칩이 테두리에 섞는 통신사 색 — 레거시 `_compare.scss:120-122` 의 `.carrier-tone--*`
 * (`--color-carrier-*` 는 `_tokens.scss:8-10`). 필터 칩은 공통 `.carrier-tone--*` 가
 * `--chip-tone` 으로 따로 주니 카드 칩엔 같은 색을 `--carrier-color` 로 단다.
 */
.mvno-chip-skt {
  --carrier-color: var(--nr-carrier-skt);
}

.mvno-chip-kt {
  --carrier-color: var(--nr-carrier-kt);
}

.mvno-chip-lgu {
  --carrier-color: var(--nr-carrier-lgu);
}

/*
 * 요금 배지 — 레거시 `MvnoCompareView.vue:98` 의 `.pricing-badge`. 테두리는 레거시에 없다
 * (두르면 운영보다 높이가 0.7px 커진다). 톤마다 `--tone`(글자)·`--tone-soft`(면)만 두고
 * 한 규칙이 칠한다. `standard` 는 톤이 없어 토큰 폴백(dim/tint)으로 다크를 따라간다.
 */
.mvno-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  min-height: 1.5rem;
  border-radius: 0.35rem;
  background: var(--nr-tint);
}

.mvno-badge[data-tone='promo'] { --tone: #b94616; --tone-soft: #fff0e8; }
.mvno-badge[data-tone='stable'] { --tone: #167454; --tone-soft: #e9f7f1; }
.mvno-badge[data-tone='unknown'] { --tone: #91610c; --tone-soft: #fff6dc; }
.mvno-badge[data-tone='conditional'] { --tone: #6750a4; --tone-soft: #f1edff; }

.mvno-badge[data-tone],
.mvno-schedule[data-warning] {
  color: var(--tone, var(--nr-dim));
  background: var(--tone-soft, var(--nr-tint));
}

/*
 * 다크의 배지 면은 톤 글자색을 어두운 면에 18% 섞고, 글자는 톤을 흰색에 40% 섞어 밝힌다 —
 * 면 휘도는 0.03 아래, 글자 대비는 7.7 이상으로 톤 구분도 남는다.
 */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .mvno-badge[data-tone]:not([data-tone='standard']),
  :root:not([data-theme='light']) .mvno-schedule[data-warning] {
    color: color-mix(in srgb, var(--tone) 40%, #ffffff);
    background: color-mix(in srgb, var(--tone) 18%, var(--nr-surface));
  }
}
:root[data-theme='dark'] .mvno-badge[data-tone]:not([data-tone='standard']),
:root[data-theme='dark'] .mvno-schedule[data-warning] {
  color: color-mix(in srgb, var(--tone) 40%, #ffffff);
  background: color-mix(in srgb, var(--tone) 18%, var(--nr-surface));
}

.mvno-bonus {
  display: flex;
  flex-wrap: wrap;
  gap: var(--nr-space-1);
  margin: 0 0 var(--nr-space-2);
  font-size: var(--nr-size-caption);
}

.mvno-bonus span {
  padding: 0 var(--nr-space-2);
  border-radius: var(--nr-radius-s);
  background: var(--nr-tint-2);
}

/*
 * 칸마다 원형 아이콘이 서는 구조(운영과 같다). `dl > div` 안에는 `dt`/`dd` 만 올 수 있어
 * 아이콘을 끼울 자리가 없었다 — 그래서 `dl` 을 버렸다. 이름(`small`)이 값 앞에 그대로 남아
 * 읽는 순서는 바뀌지 않는다(마크업은 `screen.tsx`).
 */
.mvno-specs {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: 1rem;
  margin: 0;
  padding-top: 0.85rem;
  border-top: 1px solid var(--nr-line);
}

.mvno-spec {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  min-width: 0;
}

.mvno-spec-icon {
  display: grid;
  flex: 0 0 2.25rem;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  background: var(--nr-tint);
  color: var(--nr-accent-text);
}

.mvno-spec > span:last-child {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.mvno-spec small {
  color: var(--nr-dim);
  font-size: var(--nr-size-caption);
}

.mvno-spec strong {
  /* 스킨 눈금엔 15px 단계가 없다 — 1173행 근처와 같은 값을 그대로 적는다. */
  font-size: 0.9375rem;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/*
 * 상세 머리의 스펙 값은 카드와 다르다 — 레거시 `[id].vue:90` 의 `.key-spec strong` 은
 * 14px(`--text-meta`)에 말줄임 대신 `overflow-wrap: break-word` 로 줄바꿈한다. 목록 카드는
 * 목록 레거시 `MvnoCompareView.vue:129` 의 `.allowance strong`(15px `--text-label`, 말줄임)이라
 * 위 공통 규칙 그대로 둔다.
 */
.mvno-hero .mvno-spec strong {
  font-size: var(--nr-size-meta);
  overflow: visible;
  white-space: normal;
  overflow-wrap: break-word;
}

.mvno-spec em {
  color: var(--nr-accent-text);
  font-size: var(--nr-size-caption);
  font-style: normal;
  font-weight: var(--nr-weight-normal);
}

.mvno-card-price {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-end;
  padding: 1.4rem 1.1rem;
  border-left: 1px solid var(--nr-line);
  background: color-mix(in srgb, var(--nr-tint) 60%, transparent);
  text-align: right;
  /* 덮는 링크가 이 칸 위에서도 눌리게 흘려보낸다 — 얹힌 순서만 z-index, 클릭은 아래로. */
  z-index: 2;
  pointer-events: none;
}

.mvno-card-price strong {
  margin: 0.25rem 0 0.4rem;
  font-size: 1.5rem;
  font-weight: var(--nr-weight-bold);
  line-height: 1.2;
}

.mvno-card-price strong span {
  margin-left: 0.15rem;
  font-size: var(--nr-size-ui);
  font-weight: 600;
  /* 운영은 "원" 도 body 줄높이 1.6(25.6px)을 쓴다 — 낮추면 strong 줄 상자가 28.8 아래로 내려간다. */
  line-height: 1.6;
}

.mvno-period {
  color: var(--nr-accent-text);
  font-size: var(--nr-size-caption);
  font-weight: 600;
}

.mvno-schedule {
  padding: 0.25rem 0.5rem;
  border-radius: 0.3rem;
  background: var(--nr-tint);
  color: var(--nr-dim);
  font-size: var(--nr-size-caption);
  font-weight: 600;
}

/*
 * 「요금 오름」 경고 — 레거시 `.after.warning`(`MvnoCompareView.vue:101`, 조건은 `:49` 의
 * `priceIncrease >= 10000`, 속성은 `screen.tsx` 가 단다). 배지와 같은 톤 규칙이 칠한다.
 */
.mvno-schedule[data-warning] { --tone: #c94736; --tone-soft: #fdf2f2; }

/*
 * 운영 `.load-more-wrap` + `.load-more-button`(`MvnoCompareView.vue:50,131`)을 옮겼다.
 * 운영은 단추 하나로 이어 붙이고 우리는 쪽 링크라(CSR 을 안 쓴다) 「이전」·「요금제 더보기」
 * 둘이 같이 나올 수 있어 둘 다 같은 단추 꼴로 낸다. 개수는 운영처럼 「더보기」 단추 안 `small`
 * 에 두고, 마지막 쪽이라 「더보기」 가 없으면 단추 없이 홀로 회색으로 선다.
 * 최소 15rem·3rem 과 0.4rem 모서리는 운영 값이고 스킨 단계에 없어 그대로 적었다.
 */
.mvno-more {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--nr-space-3);
  margin: 1.9rem auto 0.6rem;
  font-size: var(--nr-size-meta);
}

.mvno-more a {
  display: flex;
  min-width: 15rem;
  min-height: 3rem;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  padding: 0 var(--nr-space-4);
  border: 1px solid var(--nr-line);
  border-radius: 0.4rem;
  background: var(--nr-surface);
  color: var(--nr-ink);
  font-weight: 600;
}

.mvno-more a:hover {
  border-color: var(--nr-accent);
  color: var(--nr-accent-text);
}

/* 단추 안 개수는 운영 `small` 처럼 글자색만 흐리게 — 크기·굵기는 단추 글자와 같다. */
.mvno-more a small {
  color: var(--nr-dim);
  font-size: inherit;
  font-weight: 600;
}

/* 마지막 쪽에서 「더보기」 없이 홀로 서는 개수. */
.mvno-more > span {
  color: var(--nr-dim);
  font-weight: 600;
}

.mvno-empty {
  padding: var(--nr-space-7) 0;
  color: var(--nr-dim);
  text-align: center;
}

/*
 * 아래 두 덩이는 운영 `.category-links` 와 `.seo-guide` 다. 둘 다 면이 없고 위에 줄 하나만
 * 있는데, 좌우 여백은 위 카드들과 같은 1.1rem 을 물려 글자가 카드 글자와 한 줄로 선다.
 * 15px(0.9375rem)·20px(1.25rem)은 운영 `--text-label`·`--text-section` 이고 스킨 단계에
 * 없는 크기여서 그대로 적었다.
 */
.mvno-cats {
  display: grid;
  gap: 0.9rem;
  margin-top: var(--nr-space-7);
  padding: var(--nr-space-6) 1.1rem;
  border-top: 1px solid var(--nr-line);
}

.mvno-cats h2,
.mvno-guide h2 {
  margin: 0;
  font-size: 1.25rem;
}

.mvno-cat-group {
  display: grid;
  grid-template-columns: 5.25rem minmax(0, 1fr);
  align-items: start;
  gap: 0.6rem;
}

.mvno-cat-group > strong {
  padding-top: 0.35rem;
  color: var(--nr-dim);
  font-size: 0.9375rem;
}

.mvno-cat-group ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.mvno-cat-group a {
  display: inline-block;
  padding: 0.35rem 0.7rem;
  border: 1px solid var(--nr-line);
  border-radius: 999px;
  font-size: 0.9375rem;
}

.mvno-cat-group a:hover {
  border-color: var(--nr-accent);
}

.mvno-cat-group a[aria-current='page'] {
  border-color: var(--nr-ink);
}

.mvno-cat-all {
  font-size: 0.9375rem;
}

.mvno-guide {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--nr-space-6);
  margin-top: var(--nr-space-7);
  padding: 1.75rem 1.1rem;
  border-top: 1px solid var(--nr-line);
}

.mvno-guide h2 {
  grid-column: 1 / -1;
}

.mvno-guide h3 {
  margin: 0 0 0.4rem;
  font-size: 0.9375rem;
}

.mvno-guide p {
  margin: 0;
  color: var(--nr-dim);
  font-size: var(--nr-size-meta);
  line-height: var(--nr-leading-read);
}

/* 상세. 목록의 카드 규칙을 거의 그대로 물려받고 다른 것만 여기 있다. */
.mvno-detail {
  padding: 0 0 2rem;
}

.mvno-back {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin: 0.25rem 0 0.9rem 1.1rem;
  color: var(--nr-dim);
  font-size: var(--nr-size-meta);
  font-weight: 600;
}

.mvno-back:hover {
  color: var(--nr-accent-text);
}

/*
 * 운영 실측 0.75rem/1.4rem — 위아래 합이 토큰 조합(space-2+space-4)보다 커서 히어로 높이가 맞다.
 * 크기·줄높이는 레거시 `.compare-title`(`_compare.scss:27` — `--text-title` 1.5rem, 줄높이 1.3)이다.
 * 굵기 600 은 위 전역 h1 규칙이 준다.
 */
.mvno-hero h1 {
  margin: 0.75rem 0 1.4rem;
  font-size: 1.5rem;
  line-height: 1.3;
}

/* 상세 스펙 칸은 목록보다 아이콘이 작다(운영 실측 32×32, 목록은 36×36) — 격자 비율·위 여백도 다르다. */
.mvno-hero .mvno-specs {
  grid-template-columns: 1.45fr 1fr 1fr;
  padding-top: 1rem;
}

.mvno-hero .mvno-spec-icon {
  flex: 0 0 2rem;
  width: 2rem;
  height: 2rem;
}

.mvno-hero-price {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 1.5rem 1.1rem;
  border-left: 1px solid var(--nr-line);
  /*
   * 팔레트에 이 옅은 초록 단계가 없다 — 레거시 `[id].vue:90` 의
   * `.hero-price { background: color-mix(in srgb, var(--color-brand-50) 55%, var(--color-surface)) }`
   * 를 `--board-brand-50`(= `--color-brand-50`)으로 옮겼다. 토큰이 어두운 값을 들고 있어 다크에서도 같이 간다.
   */
  background: color-mix(in srgb, var(--nr-brand-50) 55%, var(--nr-surface));
}

.mvno-price-label {
  color: var(--nr-accent-text);
  font-size: var(--nr-size-caption);
  font-weight: 600;
}

.mvno-main-price {
  margin: 0.3rem 0 1.15rem;
}

.mvno-main-price strong {
  /* 24px — 목록 `.mvno-card-price strong`(910행 근처)과 같은 리터럴. */
  font-size: 1.5rem;
  font-weight: var(--nr-weight-bold);
  line-height: 1.2;
}

.mvno-main-price span {
  margin-left: 0.2rem;
  font-weight: 600;
}

.mvno-official {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  min-height: 2.75rem;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--nr-accent);
  border-radius: 0.4rem;
  background: var(--nr-surface);
  /* 운영 `--color-brand-700` — `--board-brand-700` 이 그 값이다. */
  color: var(--nr-brand-700);
  font-size: var(--nr-size-caption);
  font-weight: 600;
  text-align: center;
}


.mvno-official:hover {
  background: var(--nr-accent);
  color: var(--nr-surface);
}

.mvno-flow,
.mvno-extra,
.mvno-source {
  margin-top: var(--nr-space-4);
  padding: 1.4rem 1.1rem;
  border: 1px solid var(--nr-line);
  /* `--board-radius` 는 없는 토큰이라 모서리가 0 이 되던 자리 — 목록 카드와 같은 1rem 으로 적는다. */
  border-radius: 1rem;
  background: var(--nr-surface);
  box-shadow: 0 2px 10px rgb(0 0 0 / 2%);
}

.mvno-source {
  padding: 1rem 1.1rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1.5rem;
}

.mvno-sec-head {
  margin-bottom: 1.1rem;
}

.mvno-sec-kicker {
  color: var(--nr-accent-text);
  font-size: var(--nr-size-caption);
  font-weight: 600;
}

.mvno-sec-head h2 {
  margin: 0.3rem 0 0;
  /* 20px — 스킨 눈금에 없어 .mvno-cats h2(1006행 근처)처럼 리터럴로 적는다. */
  font-size: 1.25rem;
  /* 운영은 h2 가 600·줄높이 27px(레거시 `.section-heading h2`). 스킨 기본 700·26px 과 다르다. */
  font-weight: 600;
  line-height: 1.35;
}

.mvno-extra h2 {
  /* 「추가 제공」은 눈썹이 없어 절 제목이 스스로 위아래 여백을 진다(마크업은 screen.tsx). */
  margin: 0 0 var(--nr-space-3);
  font-size: 1.25rem;
}

.mvno-flow-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 2.1rem minmax(0, 1fr);
  align-items: center;
  gap: 0.65rem;
}

.mvno-phase {
  min-width: 0;
  padding: 1.1rem 1.25rem;
  border: 1px solid var(--nr-line);
  border-radius: 0.75rem;
  background: var(--nr-tint);
}

/*
 * 팔레트에 이 옅은 초록 단계가 없다 — 레거시 `[id].vue:90` 의
 * `.phase-promo { background: color-mix(in srgb, var(--color-brand-50) 62%, var(--color-surface));
 * border-color: color-mix(in srgb, var(--color-brand-600) 25%, var(--detail-line)) }` 를
 * `--board-brand-50`(`--color-brand-50`)과 `--board-accent`(= `--color-brand-600` #146c5a)로 옮겼다.
 * 두 토큰은 어두운 값도 들고 있어 다크에서도 같이 간다.
 */
.mvno-phase-promo {
  background: color-mix(in srgb, var(--nr-brand-50) 62%, var(--nr-surface));
  border-color: color-mix(in srgb, var(--nr-accent) 25%, var(--nr-line));
}

/*
 * 두 줄 다 `p` 라 시트 앞쪽의 문단 여백을 그대로 든다. 아래 여백을 지우지 않으면 두 줄 사이가
 * 12px 벌어지고 단계 판이 운영보다 14px 높아진다 — 옛 `.mvno-phase p { margin: 0 }` 자리다.
 */
.mvno-phase-top {
  display: flex;
  justify-content: space-between;
  gap: var(--nr-space-2);
  margin: 0;
  color: var(--nr-dim);
  font-size: var(--nr-size-caption);
}

.mvno-phase-top strong {
  color: var(--nr-accent-text);
}

.mvno-phase-price {
  margin: 0.45rem 0 0;
  color: var(--nr-dim);
  font-size: var(--nr-size-meta);
}

.mvno-phase-price strong {
  color: var(--nr-ink);
  /* 20px 리터럴 — 위 h2 와 같은 이유. */
  font-size: 1.25rem;
}

.mvno-flow-arrow {
  color: var(--nr-dim);
  justify-self: center;
}

/*
 * 안의 svg 가 인라인이라 몸줄높이(1.6)의 줄상자를 만들어 화살표 행이 25.6px 로 높아진다 —
 * 운영은 svg 자체가 격자 항목이라(레거시 `[id].vue:33`) 행이 그림 높이(19)다. 블록화해 같은 값을 낸다.
 */
.mvno-flow-arrow svg {
  display: block;
}

.mvno-source p {
  margin: 0;
  color: var(--nr-dim);
  font-size: var(--nr-size-caption);
}

.mvno-source p:last-child {
  text-align: right;
}

.mvno-source-left {
  display: flex;
  align-items: center;
  gap: var(--nr-space-2);
  white-space: nowrap;
}

.mvno-source-left svg {
  color: var(--nr-accent-text);
}

/* 운영은 strong 이 본문 잉크를 물려받는다(`[id].vue:43`) — dim 이 물려 내려오지 않게 잉크로 고정. */
.mvno-source-left strong {
  color: var(--nr-ink);
  font-size: var(--nr-size-meta);
}

/*
 * 800px 이하 — 레거시 `below(tablet-wide)`(`_breakpoints.scss`). 목록 카드·상세 히어로가 한 열로
 * 접히고 가격 칸이 아랫줄로 내려간다(`MvnoCompareView.vue:134`, `pages/mvno/plans/[id].vue:91`).
 * 좌우 여백은 이 폭의 `--compare-inset` 값 .9rem(`_compare.scss:182`)을 따른다 — 560px 이하에서
 * .8rem 으로 한 번 더 주는 것은 아래 35rem 블록이다.
 * 운영은 이 폭에서도 `.promo strong` 이 1.5rem/1.2(실측 28.8px)로 넓은 폭과 같다 — 레거시 소스의
 * 축소 규칙은 운영 실측과 어긋나 옮기지 않았다.
 */
@media (max-width: 50rem) {
  .mvno-card,
  .mvno-hero,
  .mvno-flow-grid,
  .mvno-guide {
    grid-template-columns: 1fr;
  }

  .mvno-detail {
    padding-inline: 0.1rem;
  }

  .mvno-flow-arrow {
    transform: rotate(90deg);
  }

  .mvno-hero-price {
    border-top: 1px solid var(--nr-line);
    border-left: 0;
  }

  .mvno-main-price {
    margin-bottom: 0.9rem;
  }

  .mvno-source {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
  }

  .mvno-source p:last-child {
    text-align: left;
  }

  .mvno-source-left {
    white-space: normal;
    flex-wrap: wrap;
  }

  /* 좁아진 폭에서 카드·가격 칸 여백을 함께 줄인다 — 운영은 `--compare-inset` 하나로 들어간다. */
  .mvno-card-main {
    padding: 1.2rem 0.9rem;
  }

  /*
   * 상세의 판들도 같이 줄인다. 우리는 규칙마다 값을 적으니 여기서 같이 적어 줘야 한다 —
   * 이게 빠지면 이 폭에서 상세만 좌우 17.6px 로 남아 같은 화면의 목록 카드와 안쪽선이 어긋난다.
   */
  .mvno-back {
    margin-left: 0.9rem;
  }

  .mvno-hero-main,
  .mvno-hero-price {
    padding-inline: 0.9rem;
  }

  .mvno-flow,
  .mvno-extra,
  .mvno-source {
    padding-inline: 0.9rem;
  }

  .mvno-card-price {
    align-items: flex-start;
    padding: 1.1rem 0.9rem;
    border-top: 1px solid var(--nr-line);
    border-left: 0;
    text-align: left;
  }

  /* 800 이하에서 운영은 가격 숫자를 24 → 20 으로 줄인다(레거시 `below(tablet-wide)` 소스 값). */
  .mvno-card-price strong {
    font-size: 1.25rem;
    line-height: 1.2;
  }

  /*
   * 상세 스펙 칸은 여기서 두 열이 된다(레거시 `.key-specs`, `[id].vue:91`). 목록 `.mvno-specs` 는
   * 560px 까지 세 열을 유지하므로 여기선 `.mvno-hero` 것만 건드린다.
   */
  .mvno-hero .mvno-specs {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.9rem;
  }

  .mvno-hero .mvno-specs > div:first-child {
    grid-column: 1 / -1;
  }

  /*
   * 위쪽 블록(머리·수집 기준·필터 판·정렬 줄)도 같은 `below(tablet-wide)` 에서 접힌다
   * (`_compare.scss:181-191`, `_filters.scss:60-73`, `MvnoCompareView.vue:134`).
   * 좌우 여백은 이 폭의 `--compare-inset` .9rem — 560 이하에서 .8rem 으로 주는 것은
   * 아래 35rem 블록이다.
   */
  .mvno-head {
    padding: 0 0.9rem;
  }

  /* 접힌 줄에서 기준일은 제 줄로 내려간다 — 제목 옆에 두면 잘려서 못 읽는다. */
  .mvno-note {
    padding: 12px 0.9rem;
  }

  .mvno-note > summary {
    flex-wrap: wrap;
    gap: 0.35rem;
  }

  .mvno-note > summary > svg {
    order: 1;
  }

  .mvno-note-title {
    order: 2;
  }

  .mvno-note-toggle {
    order: 3;
  }

  .mvno-note-meta {
    order: 4;
    flex: 1 1 100%;
    margin-top: 0.15rem;
    white-space: normal;
  }

  .mvno-note-facts > div {
    grid-template-columns: 5.5rem minmax(0, 1fr);
  }

  .mvno-picker {
    padding: 17.6px 0.9rem;
  }

  /* 줄 사이를 좁힌다 — 칩이 격자로 접혀 카드가 길어진다. */
  .mvno-rows {
    gap: 0.6rem;
  }

  .mvno-row {
    grid-template-columns: 4.6rem minmax(0, 1fr);
    gap: 0.45rem;
    align-items: start;
  }

  .mvno-row > strong {
    margin-top: 0.38rem;
    font-size: 0.875rem;
  }

  .mvno-row-preset {
    padding-bottom: 0.9rem;
  }

  .mvno-opt-row {
    grid-template-columns: 5.25rem minmax(0, 1fr);
  }

  /* 운영 `below(tablet-wide)` 의 `.provider-button-list`·`.range-slider` 분기. */
  .mvno-providers {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    padding-inline: 0.25rem;
  }

  .mvno-providers button.mvno-opt {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .mvno-range {
    margin-inline: 0.4rem;
  }

  /* 정렬은 개수 아래 제 줄로 내려가되 폭은 절반만 쓴다(운영의 두 칸 격자). */
  .mvno-toolbar {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 0.5rem 0.45rem;
    padding: 0.8rem 0.9rem 0.6rem;
  }

  .mvno-count {
    grid-column: 1 / -1;
  }

  .mvno-sort {
    grid-column: 1;
  }
}

/*
 * 44rem 이하는 위쪽 블록 분기가 아니다 — 목록 아래의 분류·안내·더 보기만 폰 폭에 맞춘다.
 * 위쪽 블록의 분기는 위 50rem·35rem 블록이 레거시 `below(tablet-wide)`·`below(sm)` 그대로 든다.
 */
@media (max-width: 44rem) {
  /*
   * `.mvno-cat-group` 은 폰에서도 `5.25rem minmax(0,1fr)` 그대로 둔다 — 운영도 여기엔 폰
   * 분기가 없다. 한 줄로 세우면 덩이마다 줄이 하나 늘어 62px 이 길어진다(실측).
   */

  /* 운영 폰 실측 12.8px. 위 카드들과 같이 좁힌다. */
  .mvno-cats {
    padding: var(--nr-space-6) 0.8rem;
  }

  .mvno-guide {
    padding: 1.75rem 0.8rem;
  }

  /* 운영은 여기에 폰 분기가 없어 단추 하나는 15rem·가운데 그대로다. 「이전」·「더보기」 가
   * 같이 나올 때만 15rem 둘이 폰 폭에 안 들어가니 줄을 나눠 한 줄씩 쓰게 한다. */
  .mvno-more:has(a + a) a {
    min-width: 0;
    flex: 1 1 100%;
  }
}

/*
 * 600px 이하 — 레거시 `below(mobile)`(`MvnoRangeSlider.vue:111`). 슬라이더 안쪽 여백을 줄이고
 * 눈금은 짝수번째(끝 하나는 살림)와 다섯 번째를 지운다 — 좁은 폭에서 글자끼리 겹치지 않게.
 */
@media (max-width: 37.5rem) {
  .mvno-range {
    padding-inline: 0.15rem;
  }

  .mvno-range-ticks small {
    font-size: 0.65rem;
  }

  .mvno-range-ticks span:nth-child(even):not(:last-child),
  .mvno-range-ticks span:nth-child(5) {
    display: none;
  }
}

/*
 * 560px 이하 — 레거시 `below(sm)`(`MvnoCompareView.vue:135`). 목록 스펙 칸이 두 열로 접히고
 * 첫 칸(데이터)이 줄 전체를 쓴다. `--compare-inset` 도 .8rem 으로 줄어(`_compare.scss:196`)
 * 위 50rem 블록에서 .9rem 으로 적은 안쪽 여백을 여기서 한 단계 더 좁힌다.
 * 상세 히어로의 스펙 칸은 이미 800px 에서 두 열이 됐고 이 폭의 추가 분기가 없다 — 여기서
 * 아이콘·글자를 줄이는 것은 목록 카드(`.mvno-card`)뿐이다.
 */
@media (max-width: 35rem) {
  .mvno-specs {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .mvno-specs > div:first-child {
    grid-column: 1 / -1;
  }

  .mvno-card .mvno-spec strong {
    font-size: var(--nr-size-meta);
  }

  .mvno-card .mvno-spec-icon {
    flex: 0 0 1.9rem;
    width: 1.9rem;
    height: 1.9rem;
  }

  .mvno-card-main {
    padding: 1.2rem 0.8rem;
  }

  .mvno-back {
    margin-left: 0.8rem;
  }

  .mvno-hero-main,
  .mvno-hero-price {
    padding-inline: 0.8rem;
  }

  .mvno-flow,
  .mvno-extra,
  .mvno-source {
    padding-inline: 0.8rem;
  }

  .mvno-card-price {
    padding: 1.1rem 0.8rem;
  }

  /* 위쪽 블록의 좌우 여백도 `--compare-inset` 이 .8rem 으로 주는 만큼 같이 좁힌다(`_compare.scss:195`). */
  .mvno-head {
    padding: 0 0.8rem;
  }

  .mvno-note {
    padding: 12px 0.8rem;
  }

  .mvno-note-facts > div {
    grid-template-columns: 1fr;
    gap: 0.2rem;
  }

  .mvno-picker {
    padding: 17.6px 0.8rem;
  }

  .mvno-opt-row {
    grid-template-columns: 4.7rem minmax(0, 1fr);
  }

  .mvno-toolbar {
    padding: 0.8rem 0.8rem 0.6rem;
  }
}

/* 운영은 400px 에서 한 번 더 좁힌다 — 상세 스펙 칸만 걸린다(목록은 이 분기가 없다). */
@media (max-width: 25rem) {
  .mvno-hero .mvno-spec {
    gap: 0.45rem;
  }

  .mvno-hero .mvno-spec-icon {
    flex: 0 0 1.8rem;
    width: 1.8rem;
    height: 1.8rem;
  }
}

/*
 * 휴대폰 성지 가격 비교(`plugins/phonedeal`). 알뜰폰과 같은 원칙이다 — 레거시 `.vue` 의
 * scoped 스타일을 옮겨 오지 않고 스킨 토큰만으로 읽을 수 있게 짠다.
 *
 * 다른 점 하나: 여기 규칙은 **플러그인 페이지와 섹션 둘 다**에 걸린다. 가격표는 공간
 * (`/posts/phone`)에 섹션으로 얹히고 조건을 건 목록은 제 페이지라, 같은 마크업이 두 자리에
 * 나온다. 그래서 선택자를 `.deal-page` 아래로 묶지 않는다.
 *
 * **통신사 색을 안 가져왔다.** 레거시는 3사에 브랜드 색을 줬는데(`_tokens.scss:8`) 칸마다
 * 이름이 글자로 이미 적혀 있어 색이 정보를 더하지 않고, 스킨에 그 토큰이 없다.
 */
.gb-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.deal-page h1,
.deal-detail h1 {
  margin: 0 0 var(--nr-space-3);
}

/* 머리 — 시세표 제목 한 줄. `head` 섹션이 들고, 표 섹션과 따로 선다. */
.compare-head {
  display: grid;
  gap: 0.2rem;
  margin: 0;
  padding: 0 1.1rem;
}

.compare-title {
  margin: 0;
  color: var(--nr-text);
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1.3;
}

/* 조건 패널. 폼인 이유는 `plugins/phonedeal/src/screen.tsx` 머리에 적혀 있다 — 크롤 함정을 안 여는 것. */
.deal-filters {
  margin: 0 0 10px;
  padding: 0.75rem 1.1rem 1.1rem;
  border: 1px solid var(--nr-line);
  border-radius: 16px;
  background: var(--nr-surface);
}

.deal-filters > summary {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  margin: 0 0 0.8rem;
  padding: 0 0 0.7rem;
  border-bottom: 1px solid var(--nr-line);
  cursor: pointer;
  /* 레거시 `PhoneDealPage.vue` 의 `summary { line-height: 1.4 }` — 물린 1.6 이면 머리 줄이 3px 높다. */
  line-height: 1.4;
  list-style: none;
}

.deal-filters > summary strong {
  font-size: 0.9375rem;
  font-weight: 600;
}

.filter-summary {
  overflow: hidden;
  color: var(--nr-dim);
  font-size: 0.8125rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/*
 * 조건 초기화. 머리(`summary`)가 아니라 조건 줄들 **아래**에 선다 — 접힌 화면에서도 조건을 한눈에
 * 보이게 하는 `filter-summary` 와 자리를 다투지 않으려고 운영이 그렇게 두었다(좁은 화면에서는
 * 그 요약이 아예 안 보인다, 아래 `@media`). 조건이 하나라도 걸렸을 때만 그려진다.
 *
 * 윗줄은 조건 줄들과의 경계다. 그래서 위 여백(`0.7rem`)은 `border-top` 바깥이 아니라 안쪽 패딩으로
 * 준다 — 운영 실측 49.8px = 테두리 1 + 패딩 11.2 + 단추 37.6.
 */
.filter-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 1rem;
  padding-top: 0.7rem;
  border-top: 1px solid var(--nr-line);
}

/*
 * 「조건 초기화」. 레거시는 글자만 있는 링크였고 지금은 회전 화살표가 앞에 선다(운영과 같은
 * lucide `rotate-ccw`, `screen.tsx`). 색은 운영의 `--color-brand-700` — `--board-brand-700` 이
 * 그 값이다(시세 띠 링크와 같은 자리).
 */
.deal-reset {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  min-height: 2.35rem;
  padding: 1px 6px;
  color: var(--nr-brand-700);
  font-size: 1rem;
  font-weight: 600;
  text-decoration: none;
}

/* 열기/닫기 안내 — 스크립트 없이 `details[open]` 으로만 바꾼다. 색은 위 「조건 초기화」와 같은 운영 `--color-brand-700`(`PhoneDealPage.vue:373`). */
.filter-toggle {
  margin-left: auto;
  color: var(--nr-brand-700);
  font-size: 0.8125rem;
  font-weight: 600;
}

.filter-toggle span:last-child {
  display: none;
}

.deal-filters[open] .filter-toggle span:first-child {
  display: none;
}

.deal-filters[open] .filter-toggle span:last-child {
  display: inline;
}


.filter-rows {
  display: grid;
  gap: 0.8rem;
}

.filter-row {
  display: grid;
  grid-template-columns: 7rem minmax(0, 1fr);
  gap: 1rem;
  align-items: center;
}

/*
 * 고른 지역 아래가 있을 때만 서는 줄(`screen.tsx` 의 `Filters`). 뿌리만 그리는 지역 줄에서는
 * 자식(서울 북부)을 눌릴 수 없어, 부모 아래에 그 자식들이 한 줄 더 선다. 운영도 이 줄만 바탕을
 * 깔아 「지역 줄에 딸린 줄」임을 보인다 — 색은 `--board-tint`(운영 rgb(245,248,247)).
 */
.sub-region-row {
  padding: 0.5rem 0;
  border-radius: 6.4px;
  background: var(--nr-tint);
  /* 운영처럼 바탕을 칩 밖으로 한 뼘 넓힌다 — 여백을 늘리면 줄의 칸이 옆 줄과 어긋난다. */
  box-shadow: 0 0 0 0.5rem var(--nr-tint);
}

.filter-row-pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem 1.4rem;
}

.filter-row strong {
  color: var(--nr-text);
  font-size: 0.9375rem;
  font-weight: 600;
}

/*
 * 공지 띠(`pinned` 섹션의 `notice` 변형 — 이 화면에서만 쓴다). 스킨은 줄마다
 * `min-height: 2.625rem` 을 깔아 항목이 42px 이다. 레거시 `PhoneDealNotices.vue` 는
 * 최소 높이 없이 여백(.5rem)과 글줄(16px/1.6 = 25.6)로 41.6px 를 만든다 — 그대로 둔다.
 */
.notice-strip a {
  min-height: 0;
}

/* 결과 블록 — 표가 자기 테두리를 들고 오므로 여기선 자리만 잡는다. */
.deal-results {
  margin: 0;
}

.compare-toolbar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 1rem;
  padding: 0.8rem 1.1rem 0.6rem;
}

.compare-toolbar__count {
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
  margin: 0;
  font-size: 1.25rem;
  font-weight: 600;
}

.compare-toolbar__count span {
  color: var(--nr-dim);
  font-size: 0.875rem;
  font-weight: 400;
}

.compare-toolbar__controls {
  display: flex;
  align-items: center;
  gap: 0.45rem;
}

/* 「기기 검색」 — 글자를 가운데로 모으고 700 으로 눕힌다(운영). 줄 높이 1.2 라 높이는 여백이 아니라 `min-height` 가 정한다. */
.device-search-button {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  min-height: var(--nr-control-h);
  padding: var(--nr-control-pad-y) var(--nr-control-pad-x);
  border: 1px solid var(--nr-line);
  border-radius: var(--nr-control-radius);
  background: var(--nr-surface);
  color: var(--nr-text);
  font-size: var(--nr-size-ui);
  font-weight: 700;
  line-height: 1.2;
  list-style: none;
  cursor: pointer;
}

/*
 * 「기기 검색」 대화상자 — 레거시 `AppModal`(`apps/frontend/app/components/ui/AppModal.vue:3-5,17-21`)
 * 을 스크립트 없는 `popover` 로 옮긴다. 열린 popover 는 최상위 레이어에 서므로 z-index 를 둘
 * 자리가 없고, `::backdrop` 이 운영의 반투명 검정(`.modal-overlay`)을, `html:has()` 규칙이
 * 본문 스크롤 잠금을 맡는다. 너비 `min(calc(100% - 2rem), 28rem)` 는 레거시 호출의
 * `width="28rem"`(`PhoneDealPage.vue:77`) 그대로다. UA 가 주는 `inset:0; margin:auto` 위에
 * 폭·높이만 얹어 가운데로 모은다.
 */
.device-search-modal {
  position: fixed;
  inset: 0;
  margin: auto;
  width: min(calc(100% - 2rem), 28rem);
  height: fit-content;
  max-height: calc(100vh - 2rem);
  overflow: auto;
  padding: 1.2rem;
  border: 0;
  border-radius: 0.75rem;
  background: var(--nr-surface);
  color: var(--nr-text);
  box-shadow: var(--site-shadow-md);
}

.device-search-modal::backdrop {
  background: rgb(0 0 0 / 50%);
}

html:has(#device-search-dialog:popover-open) {
  overflow: hidden;
}

/* 머리 — 운영 `.modal-head`(1.25rem/800)와 `.modal-close`(투명, .35rem, muted). */
.device-search-modal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 1.25rem;
  font-weight: 800;
}

.device-search-modal__close {
  min-height: 0;
  padding: 0.35rem;
  border: 0;
  border-radius: 0.4rem;
  background: transparent;
  color: var(--nr-dim);
}

.device-search-modal__description {
  margin: 0.4rem 0 1rem;
  color: var(--nr-dim);
}

/* 폼 — 운영 `.device-search`(grid, .8rem)와 `.device-search-actions`(오른쪽, .45rem). */
.device-search-form {
  display: grid;
  gap: 0.8rem;
}

/* 입력은 스킨 기본(입력칸 토큰)이 운영 `AppInput` 값이다 — 넓이만 채운다. */
.device-search-form input[type='search'] {
  width: 100%;
}

.device-search-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.45rem;
}

/*
 * 행동 단추 둘의 치수는 스킨 단추가 준다 — 「검색」의 강조색 채움은 `button[type='submit']`
 * 그대로, 「검색 초기화」는 마크업의 `.gb-btn` 이 조용한 단추를 그린다.
 */
.device-search-reset {
  display: inline-flex;
  align-items: center;
}

/*
 * 좁은 화면에서 표를 가로로 흘린다. 레거시는 같은 가격을 `<table>` 과 `<ol>` 로 두 번 그리고
 * CSS 로 하나를 감췄는데, 200줄이면 본문이 두 배가 된다. 그래서 표 하나만 두고 좁은 화면에서는
 * `.deal-price-table` 규칙이 줄 하나를 카드 하나로 접는다(gbun 은 `@media (max-width: 50rem)` 아래).
 */
.deal-table-wrap {
  overflow-x: auto;
  border: 1px solid var(--nr-line);
  border-radius: var(--nr-radius);
  background: var(--nr-surface);
}

.deal-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--nr-size-meta);
}

.deal-table th,
.deal-table td {
  padding: var(--nr-space-2) var(--nr-space-3);
  text-align: left;
  vertical-align: top;
  white-space: nowrap;
}

.deal-table thead th {
  border-bottom: 1px solid var(--nr-line);
  color: var(--nr-dim);
  font-size: var(--nr-size-caption);
  font-weight: var(--nr-weight-normal);
}

.deal-table tbody tr + tr th,
.deal-table tbody tr + tr td {
  border-top: 1px solid var(--nr-line);
}

.deal-table tbody th[scope='row'] {
  font-weight: var(--nr-weight-bold);
}

.deal-checked {
  color: var(--nr-dim);
  font-size: var(--nr-size-caption);
}

/*
 * 시세표 카드. 레거시 `.price-table` 자리다 — 상세의 `.deal-offer-table` 과 클래스가 갈려
 * 목록의 좁은 칸·가운데 정렬·카드 모서리가 상세 표로 새지 않는다.
 */
.deal-results .deal-table-wrap {
  overflow: hidden;
  border-radius: 1rem;
}

.deal-price-table {
  table-layout: fixed;
  font-size: 1rem;
}

/*
 * 선택자를 `.deal-table.deal-price-table` 로 겹쳐 무게를 올린다 — 스킨의 낙차 규칙
 * `table:not(.board-table) th` (0,1,2) 가 `.deal-price-table th` (0,1,1) 를 이겨 칸 여백이
 * 12.8px 이 아니라 8px 로 나왔다. 이 표는 두 클래스를 같이 달고 나온다(`screen.tsx` 의 Results).
 */
.deal-table.deal-price-table th,
.deal-table.deal-price-table td {
  padding: 0.8rem 0.75rem;
  border-bottom: 1px solid var(--nr-line);
  text-align: left;
  vertical-align: middle;
  white-space: normal;
}

.deal-price-table th:first-child,
.deal-price-table td:first-child {
  padding-left: 1.1rem;
}

/* 마지막 열은 좌우 여백을 같게 둬 가운데 정렬한 값이 열 가운데에 놓인다. */
.deal-price-table th:last-child,
.deal-price-table td:last-child {
  padding-inline: 1.1rem;
}

.deal-price-table thead th {
  border-bottom: 1px solid var(--nr-line);
  color: var(--nr-dim);
  background: var(--nr-tint);
  font-size: 0.8125rem;
  font-weight: 600;
  text-align: center;
}

/* 머리글과 값 모두 열 가운데에 둔다. 금액 블록은 내용 너비만 차지하고 그 안에서 오른쪽 기준선을 지킨다. */
.deal-price-table tbody td {
  text-align: center;
}

.deal-price-table th:first-child {
  width: 32%;
}

.deal-price-table th:not(:first-child):not(:last-child) {
  width: 19%;
}

.deal-price-table th:last-child {
  width: 11%;
}

.deal-price-table tbody tr:last-child > * {
  border-bottom: 0;
}

.deal-price-table tbody th[scope='row'] {
  font-size: 0.9375rem;
  font-weight: 600;
}

.deal-price-table .deal-checked {
  font-size: 0.8125rem;
  color: var(--nr-dim);
}

/* 날짜 앞 이름(매장·확인)은 좁은 화면에서만 선다. */
.deal-checked__label {
  display: none;
}

/* 목록 표는 칸마다 아래 선만 쓴다 — `.deal-table` 의 `tr + tr` 윗선을 끈다. */
.deal-price-table tbody tr + tr th,
.deal-price-table tbody tr + tr td {
  border-top: 0;
}

.deal-price-table .device-link {
  display: block;
  color: inherit;
  text-decoration: none;
}

.deal-price-table .price-row:hover > * {
  background: var(--nr-tint);
}

/* 행 hover 글자는 운영 `--color-brand-700`(`PhoneDealPage.vue:442`) — `--board-brand-700` 이 그 값이다. */
.deal-price-table .price-row:hover .device-link {
  color: var(--nr-brand-700);
}


/* 표 칸의 값: 금액과 통신사 줄을 칸의 오른쪽 기준선에 맞춘다. */
.price-cell {
  display: grid;
  width: 100%;
  gap: 0.18rem;
  justify-items: end;
  text-align: right;
}

/* 값이 없는 칸은 대시만 남기고 칸 가운데에 둔다. */
.price-cell--empty {
  place-items: center;
  text-align: center;
}

/* 구매 조건 이름. 표에서는 머리 줄이 있어 감추고, 좁은 화면 카드에서만 선다. */
.price-cell__label {
  display: none;
  color: var(--nr-dim);
  font-size: var(--nr-size-caption);
}

.price-cell__amount {
  font-size: 0.9375rem;
  font-weight: var(--nr-weight-bold);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* 지원금이 기깃값을 넘으면 음수로 나온다 — 운영은 이 값을 브랜드 색으로 강조한다. */
.price-cell__amount[data-subsidy] {
  color: var(--nr-accent-text);
}

.price-cell__carriers {
  display: flex;
  align-items: baseline;
  gap: 0.3rem;
  min-width: 0;
  font-size: var(--nr-size-caption);
  font-weight: var(--nr-weight-normal);
  white-space: nowrap;
}

/*
 * 통신사 색은 여기서만 참조한다. `.deal-filters` 의 칩 색과 같은 값이다 — 레거시
 * `_compare.scss:120-123` 의 `.carrier-tone--*` + `.carrier-text`(값은 `_tokens.scss:8-10`).
 * 상세 가격 줄의 라벨(`.carrier-price-line small`, 레거시 `PhoneDealDetailPage.vue:70,93` 의
 * `small.carrier-text`)도 같은 색을 쓴다.
 */
.price-cell__carrier {
  opacity: 0.62;
}

.price-cell__carrier[data-carrier='SKT'],
.carrier-price-line small[data-carrier='SKT'] {
  color: var(--nr-carrier-skt);
}

.price-cell__carrier[data-carrier='KT'],
.carrier-price-line small[data-carrier='KT'] {
  color: var(--nr-carrier-kt);
}

.price-cell__carrier[data-carrier='LGU'],
.carrier-price-line small[data-carrier='LGU'] {
  color: var(--nr-carrier-lgu);
}

.price-cell__carrier[data-lowest] {
  opacity: 1;
  font-weight: 600;
}

/* 「최저」 딱지는 통신사와 무관한 같은 색을 쓴다. 통신사 구분은 라벨 색이 맡는다. */
.price-cell__carrier em {
  margin-left: 0.18rem;
  padding: 0.04rem 0.22rem;
  color: var(--nr-accent-text);
  background: var(--nr-notice);
  border-radius: 0.22rem;
  font-size: 0.66rem;
  font-style: normal;
  font-weight: var(--nr-weight-bold);
}

.price-cell__empty,
.deal-empty-price,
.carrier-empty {
  color: var(--nr-dim);
  font-weight: var(--nr-weight-normal);
}

/*
 * 가격 수집 기준. 레거시 `CompareNote` 그대로 접히는 `<details>` 다. 표 카드 안에 넣으면
 * 윗줄 구분선만 남기고 자기 카드는 버린다 — 둥근 모서리 두 개가 맞물려 이음매가 생기지 않게.
 */
.compare-note {
  padding: 0.75rem 1.1rem;
  background: var(--nr-surface);
  border: 1px solid var(--nr-line);
  border-radius: 0.75rem;
}

.deal-results .deal-table-wrap > .compare-note {
  border: 0;
  border-top: 1px solid var(--nr-line);
  border-radius: 0;
}

.compare-note > summary {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  line-height: 1.5;
  cursor: pointer;
  list-style: none;
}

.compare-note > summary::-webkit-details-marker {
  display: none;
}

.compare-note > summary > svg {
  flex: 0 0 auto;
  color: var(--nr-accent);
}

.compare-note__title {
  flex: 0 0 auto;
  margin: 0;
  color: var(--nr-ink);
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: inherit;
}

.compare-note__meta {
  overflow: hidden;
  flex: 1 1 auto;
  min-width: 0;
  color: var(--nr-dim);
  font-size: var(--nr-size-caption);
  font-weight: var(--nr-weight-normal);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.compare-note__toggle {
  flex: 0 0 auto;
  margin-left: auto;
  color: var(--nr-accent-text);
  font-size: var(--nr-size-caption);
  font-weight: 600;
}

.compare-note__toggle span:last-child {
  display: none;
}

.compare-note[open] .compare-note__toggle span:first-child {
  display: none;
}

.compare-note[open] .compare-note__toggle span:last-child {
  display: inline;
}

.compare-note__body {
  margin: 0.7rem 0 0;
  padding-top: 0.7rem;
  color: var(--nr-dim);
  font-size: var(--nr-size-meta);
  line-height: 1.7;
  border-top: 1px solid var(--nr-line);
}

.compare-note__facts {
  display: grid;
  gap: 0.35rem;
  margin: 0.6rem 0 0;
}

.compare-note__facts > div {
  display: grid;
  grid-template-columns: 6rem minmax(0, 1fr);
  gap: 0.7rem;
  padding: 0.35rem 0;
  border-bottom: 1px solid var(--nr-line);
}

.compare-note__facts > div:last-child {
  border-bottom: 0;
}

.compare-note__facts dt {
  color: var(--nr-accent-text);
  font-size: var(--nr-size-caption);
  font-weight: 600;
}

.compare-note__facts dd {
  margin: 0;
  font-size: var(--nr-size-caption);
  line-height: 1.6;
}

/*
 * 빈 결과 카드 — 레거시 `AppSurface`(`ui/AppSurface.vue:4`) 위의 `.empty-result`
 * (`PhoneDealPage.vue:444`). 면·선·그림자·모서리 0(`--radius-card` 도 0 — `_tokens.scss:28`)은
 * 카드 토큰 그대로고, 글자는 `--color-muted` → `--board-dim`. 글자 크기는 레거시처럼 본문
 * 크기(1rem)를 물려받는다 — 메타 크기로 내리던 로컬 규칙은 뺐다.
 */
.deal-empty {
  display: grid;
  place-items: center;
  gap: 0.35rem;
  min-height: 12rem;
  padding: var(--nr-card-pad);
  border: 1px solid var(--nr-line);
  border-radius: var(--nr-radius-l);
  background: var(--nr-surface);
  box-shadow: var(--nr-shadow);
  color: var(--nr-dim);
  text-align: center;
}

/* 회차가 아예 없을 때 — 레거시 `.deal-state`(`PhoneDealPage.vue:348-349`): 낮은 카드·잉크 제목. */
.deal-section > .deal-empty {
  min-height: 5.5rem;
  gap: 0.25rem;
}

.deal-section > .deal-empty strong {
  color: var(--nr-ink);
}

/* 접기/펼치기는 표 카드 아래 한가운데 선다. 레거시 `.expand-wrap`·`.expand-button` 그대로다. */
.expand-wrap {
  display: flex;
  justify-content: center;
  margin: 0.9rem 0 0;
}

.expand-button {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  min-width: 16rem;
  min-height: 2.8rem;
  color: var(--nr-ink);
  background: var(--nr-surface);
  border: 1px solid var(--nr-line);
  border-radius: 0.4rem;
  font-size: var(--nr-size-meta);
  font-weight: 600;
  text-decoration: none;
}

.expand-button:hover {
  color: var(--nr-accent-text);
  border-color: var(--nr-accent);
}

/* 상세. 목록의 표 규칙을 그대로 물려받고 다른 것만 여기 있다. 값은 `PhoneDealDetailPage.vue` 의 scoped 스타일. */

/*
 * 머리 카드. 운영은 흰 판·1px 선·모서리 12·`--shadow-sm`(`PhoneDealDetailPage.vue:278`).
 * 왼쪽에 꺾쇠 링크와 제목, 오른쪽 끝에 최종 수집 시각.
 */
.deal-detail-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.65rem;
  padding: 1.1rem;
  border: 1px solid var(--nr-line);
  border-radius: 0.75rem;
  background: var(--nr-surface);
  box-shadow: var(--nr-shadow);
}

.deal-detail-heading {
  display: flex;
  align-items: flex-start;
  min-width: 0;
  gap: 0.35rem;
}

/* 제목이 두 줄로 감겨도 꺾쇠는 첫 줄 옆에 붙어 있어야 해서 flex-start 로 세우고 살짝 당긴다(`PhoneDealDetailPage.vue:279`). */
.deal-detail-back {
  display: grid;
  flex: none;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  margin-left: -0.4rem;
  /* 레거시 `.detail-eyebrow` radius-sm(.4rem, `PhoneDealDetailPage.vue:280`). */
  border-radius: 0.4rem;
  color: var(--nr-dim);
}

.deal-detail-back:hover {
  color: var(--nr-accent-text);
  background: var(--nr-tint);
}

/* `.compare-title` 수치다(`PhoneDealDetailPage.vue:19`) — 머리 카드 높이 68.4 는 이 한 줄로 정해진다. */
.deal-detail-head h1 {
  min-width: 0;
  margin: 0;
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1.3;
}

.deal-detail-updated {
  flex: none;
  color: var(--nr-dim);
  font-size: var(--nr-size-meta);
  font-weight: var(--nr-weight-normal);
}

/*
 * 상세의 공지 띠 — 머리 카드와 필터 판 사이, 마크업·클래스는 목록의 것과 같다.
 * 칸 간격은 레거시 쌓기 간격 .65rem(`PhoneDealDetailPage.vue` — 머리의 margin-bottom 도 같은 값).
 * 스킨의 `.notice-strip`(0,1,0)이 margin:0 을 깔아 여기선 아래 여백만 얹는다.
 */
.deal-detail .notice-strip {
  margin: 0 0 0.65rem;
}

/*
 * 통신사·가입 방식 필터 판 — 운영 `.offer-filters`(`PhoneDealDetailPage.vue:281`).
 * 칩은 단추가 아니라 `<input type="radio">` + `<label>` 이다 — 상세의 필터는 주소를 안
 * 만드는 화면 안 상태라(머리 주석 7번) `:checked` 만으로 걸러내고 스크립트를 안 쓴다.
 */
.offer-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 1.4rem;
  margin-bottom: 0.7rem;
  padding: 0.7rem 1.1rem;
  border: 1px solid var(--nr-line);
  border-radius: 0.75rem;
  background: var(--nr-surface);
}

.offer-filters .filter-group {
  display: flex;
  align-items: center;
  gap: 0.55rem;
}

.offer-filters .filter-group > strong {
  font-size: var(--nr-size-caption);
  font-weight: 600;
  white-space: nowrap;
}

/*
 * 입력은 시각적으로만 숨긴다 — `display: none` 이면 Tab 초점과 화살표 이동이 죽는다.
 * 초점 링은 라벨이 단다(아래 `:focus-visible + label`).
 */
.offer-filters .offer-filter-input {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/*
 * 칩 값은 공통 필터 칩(위쪽)과 같고 높이만 다르다 — 운영 상세 칩은
 * 32px(`PhoneDealDetailPage.vue:281` 의 `min-height: 2rem`)이라 목록의 2.35rem 을 안 쓴다.
 */
.offer-filters label.filter-chip {
  display: inline-flex;
  align-items: center;
  min-height: 2rem;
  padding: 0 0.7rem;
}

/*
 * 표 바로 위 주의 문단 — 레거시 `.compare-footnote`(`_compare.scss:172-178`): 위아래 .85rem·좌우
 * `--compare-inset`(1.1rem), 줄높이 1.7, 글자색은 muted 보다 한 단계 진한 ink·muted 반반.
 */
.deal-footnote {
  margin: 0.85rem 1.1rem;
  color: color-mix(in srgb, var(--nr-ink) 50%, var(--nr-dim));
  font-size: var(--nr-size-caption);
  line-height: 1.7;
}

/* 표 바깥 틀 — 운영 `.offer-table-wrap` 모서리 16(`PhoneDealDetailPage.vue:282`). */
.deal-offers .deal-table-wrap {
  overflow: hidden;
  border-radius: 1rem;
}

/*
 * 칸 수치는 전부 운영 `.offer-table` 규칙이다(`PhoneDealDetailPage.vue:282`). `table.` 을 붙이는
 * 이유: 스킨의 `table:not(.board-table) td`(0,1,2)가 클래스 하나짜리 선택자를 특이도로 이겨
 * 칸 여백·정렬이 스킨 기본값으로 돌아간다 — 같은 점수(0,1,2)로 맞세우면 차례로 이긴다.
 */
table.deal-offer-table {
  table-layout: fixed;
}

table.deal-offer-table th,
table.deal-offer-table td {
  padding: 0.8rem 0.7rem;
  border-bottom: 1px solid var(--nr-line);
  text-align: center;
  vertical-align: middle;
  white-space: normal;
}

.deal-offer-table thead th {
  background: var(--nr-tint);
  font-weight: 600;
  text-align: center;
}

.deal-offer-table tbody tr:last-child td {
  border-bottom: 0;
}

table.deal-offer-table td {
  font-size: var(--nr-size-meta);
  font-weight: var(--nr-weight-normal);
}

/* 칸 폭 — 매장 16 / 조건 셋 각 21 / 날짜 10 / 원문 11(`PhoneDealDetailPage.vue:282`). */
.deal-offer-table th:first-child {
  width: 16%;
  min-width: 7.5rem;
}

.deal-offer-table th:nth-child(2),
.deal-offer-table th:nth-child(3),
.deal-offer-table th:nth-child(4) {
  width: 21%;
  min-width: 8.5rem;
}

.deal-offer-table th:nth-last-child(2) {
  width: 10%;
  min-width: 6rem;
}

.deal-offer-table th:last-child {
  width: 11%;
  min-width: 7.5rem;
}

/* 통신사별 가격 줄 — 운영 `.carrier-price-stack`·`.carrier-price-line`(`PhoneDealDetailPage.vue:282`). */
.carrier-price-stack {
  display: inline-grid;
  gap: 0.3rem;
}

.carrier-price-line {
  display: grid;
  grid-template-columns: 2.9rem 7rem;
  align-items: baseline;
  gap: 0.45rem;
  min-height: 1.55rem;
}

.carrier-price-line small {
  color: var(--nr-dim);
  font-size: var(--nr-size-caption);
  font-weight: 600;
  white-space: nowrap;
}

/* 폰 카드 전용 한 글자 라벨(레거시 `mobileCarrierLabel`). 넓은 화면에서는 숨기고, 43.75rem 아래 블록이 둘을 바꿔 그린다. */
.carrier-price-line .carrier-initial {
  display: none;
}

.carrier-price-line strong {
  font-size: var(--nr-size-ui);
  font-weight: var(--nr-weight-bold);
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum';
  text-align: right;
  white-space: nowrap;
}

.carrier-empty {
  text-align: right;
}

.carrier-empty,
.deal-empty-price {
  color: var(--nr-dim);
}

/*
 * 여기서부터 라디오가 실제로 걸러내는 규칙 — 전부 `.deal-detail:has(input:checked)` 다.
 *
 * 통신사를 고르면(레거시 `visibleCarriers`) 그 통신사의 가격 줄만 남기고 다른 통신사 줄을
 * 지운다. 그 통신사 가격이 하나도 없는 매장은 행째 뺀다(레거시 `filteredStores`) — 행의
 * `data-carriers` 는 `storeCarriers` 가 담은, 가격이 하나라도 있는 통신사 집합이다.
 * 가입 방식을 고르면 다른 조건의 열(th·td)을 접는다 — 레거시는 열을 두고 고른 열만 칠했는데,
 * 칸 폭이 고정(`table-layout: fixed`)이라 숨긴 열의 자리는 남은 열로 다시 나뉜다.
 * 둘 다 걸리면 그 조건에서 그 통신사 가격이 있는 매장만 남는다 — 행의
 * `data-carriers-{조건}` 집합으로 보는, 레거시의 AND 다.
 */
.deal-detail:has(input[name='detail-carrier'][value='SKT']:checked) .carrier-price-line:not(:has(> small[data-carrier='SKT'])),
.deal-detail:has(input[name='detail-carrier'][value='KT']:checked) .carrier-price-line:not(:has(> small[data-carrier='KT'])),
.deal-detail:has(input[name='detail-carrier'][value='LGU']:checked) .carrier-price-line:not(:has(> small[data-carrier='LGU'])) {
  display: none;
}

/* 통신사만 골랐을 때 — 어느 조건이든 그 통신사 가격이 없는 매장 행을 뺀다. */
.deal-detail:has(input[name='detail-carrier'][value='SKT']:checked):has(input[name='detail-type'][value='ALL']:checked) .deal-offer-table tbody tr:not([data-carriers~='SKT']),
.deal-detail:has(input[name='detail-carrier'][value='KT']:checked):has(input[name='detail-type'][value='ALL']:checked) .deal-offer-table tbody tr:not([data-carriers~='KT']),
.deal-detail:has(input[name='detail-carrier'][value='LGU']:checked):has(input[name='detail-type'][value='ALL']:checked) .deal-offer-table tbody tr:not([data-carriers~='LGU']) {
  display: none;
}

/* 가입 방식만 골랐을 때 — 그 조건 가격이 없는 매장 행을 뺀다. */
.deal-detail:has(input[name='detail-type'][value='NEW']:checked):has(input[name='detail-carrier'][value='ALL']:checked) .deal-offer-table tbody tr:not([data-types~='NEW']),
.deal-detail:has(input[name='detail-type'][value='PORT_IN']:checked):has(input[name='detail-carrier'][value='ALL']:checked) .deal-offer-table tbody tr:not([data-types~='PORT_IN']),
.deal-detail:has(input[name='detail-type'][value='DEVICE_CHANGE']:checked):has(input[name='detail-carrier'][value='ALL']:checked) .deal-offer-table tbody tr:not([data-types~='DEVICE_CHANGE']) {
  display: none;
}

/* 둘 다 골랐을 때 — 고른 조건에서 고른 통신사 가격이 있어야 행이 남는다. */
.deal-detail:has(input[name='detail-carrier'][value='SKT']:checked):has(input[name='detail-type'][value='NEW']:checked) .deal-offer-table tbody tr:not([data-carriers-new~='SKT']),
.deal-detail:has(input[name='detail-carrier'][value='KT']:checked):has(input[name='detail-type'][value='NEW']:checked) .deal-offer-table tbody tr:not([data-carriers-new~='KT']),
.deal-detail:has(input[name='detail-carrier'][value='LGU']:checked):has(input[name='detail-type'][value='NEW']:checked) .deal-offer-table tbody tr:not([data-carriers-new~='LGU']),
.deal-detail:has(input[name='detail-carrier'][value='SKT']:checked):has(input[name='detail-type'][value='PORT_IN']:checked) .deal-offer-table tbody tr:not([data-carriers-port_in~='SKT']),
.deal-detail:has(input[name='detail-carrier'][value='KT']:checked):has(input[name='detail-type'][value='PORT_IN']:checked) .deal-offer-table tbody tr:not([data-carriers-port_in~='KT']),
.deal-detail:has(input[name='detail-carrier'][value='LGU']:checked):has(input[name='detail-type'][value='PORT_IN']:checked) .deal-offer-table tbody tr:not([data-carriers-port_in~='LGU']),
.deal-detail:has(input[name='detail-carrier'][value='SKT']:checked):has(input[name='detail-type'][value='DEVICE_CHANGE']:checked) .deal-offer-table tbody tr:not([data-carriers-device_change~='SKT']),
.deal-detail:has(input[name='detail-carrier'][value='KT']:checked):has(input[name='detail-type'][value='DEVICE_CHANGE']:checked) .deal-offer-table tbody tr:not([data-carriers-device_change~='KT']),
.deal-detail:has(input[name='detail-carrier'][value='LGU']:checked):has(input[name='detail-type'][value='DEVICE_CHANGE']:checked) .deal-offer-table tbody tr:not([data-carriers-device_change~='LGU']) {
  display: none;
}

/* 가입 방식을 고르면 다른 조건의 열을 접는다 — 머리 칸과 값 칸 둘 다. */
.deal-detail:has(input[name='detail-type'][value='NEW']:checked) .deal-offer-table [data-type]:not([data-type='NEW']),
.deal-detail:has(input[name='detail-type'][value='PORT_IN']:checked) .deal-offer-table [data-type]:not([data-type='PORT_IN']),
.deal-detail:has(input[name='detail-type'][value='DEVICE_CHANGE']:checked) .deal-offer-table [data-type]:not([data-type='DEVICE_CHANGE']) {
  display: none;
}

/*
 * 「원문 확인」 단추 — 운영 `.outbound-link`(`PhoneDealDetailPage.vue:282`). brand-50 은
 * `--board-notice`(#edf8f5, 다크는 #16302a)가 맡고, 팔레트에 없는 brand-200 선은 강조 25% 를
 * 면에 섞는다 — 리터럴이면 다크에서 연초록 선이 그대로 남는다. brand-700 글자는
 * `--board-brand-700` 이 그 값이다.
 */
.deal-outbound {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  min-height: 2.35rem;
  padding: 0 0.65rem;
  border: 1px solid color-mix(in srgb, var(--nr-accent) 25%, var(--nr-surface));
  /* 레거시 `.outbound-link` radius-sm(.4rem, `PhoneDealDetailPage.vue:282`). */
  border-radius: 0.4rem;
  background: var(--nr-notice);
  color: var(--nr-brand-700);
  font-size: var(--nr-size-caption);
  font-weight: 600;
  white-space: nowrap;
}


/*
 * 태블릿 대(701~959px) — 아직 표이지만 마지막 칸(11%)이 「원문 확인」 단추(88.8px)보다
 * 좁아 단추가 칸 밖으로 잘린다. 이 대에서는 단추를 아이콘만으로 줄인다 — 글자는 `.gb-sr-only`
 * 와 같은 숨김으로 남겨 접근 이름을 잃지 않는다(`<a>` 의 `aria-label` 도 그대로다).
 * 아래쪽은 700.02 부터다 — 700 은 레거시 `below(tablet-narrow)` 에 포함돼 카드형이다.
 */
@media (min-width: 700.02px) and (max-width: 59.99rem) {
  .deal-outbound .deal-outbound-label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .deal-outbound {
    gap: 0;
    width: 2.35rem;
    justify-content: center;
    padding: 0;
  }

  /*
   * 같은 대에서 조건 칸(21%, ≈125px)은 `2.9rem 7rem`(≈158px) 가격 줄보다 좁아 금액이
   * 옆 칸 위로 넘쳤다. 폰 카드와 같이 한 글자 라벨로 바꾸고 줄을 `1rem minmax(0,1fr)`
   * 로 접어, 금액을 작게 죄어 칸 안에 머물게 한다.
   */
  .deal-offer-table .carrier-price-line {
    grid-template-columns: 1rem minmax(0, 1fr);
    gap: 0.2rem;
  }

  .deal-offer-table .carrier-price-line small {
    text-align: center;
  }

  .deal-offer-table .carrier-price-line .carrier-name {
    display: none;
  }

  .deal-offer-table .carrier-price-line .carrier-initial {
    display: inline;
  }

  .deal-offer-table .carrier-price-line strong {
    font-size: clamp(0.78rem, 1.6vw, var(--nr-size-ui));
  }
}

/*
 * 폰 상세 — 레거시 `below(tablet-narrow)`(700px 포함) 분기(`PhoneDealDetailPage.vue:283`).
 * 레거시는 같은 가격을 `<ol class="mobile-offers">` 로 한 번 더 그렸는데, 여기서는 표 줄
 * 하나를 카드 한 장으로 접는다 — 목록 표(`.deal-price-table`, 아래 50rem 블록)와 같은
 * 방식이다. 칸마다 붙는 조건 이름은 `td` 의 `data-label` 이 `::before` 로 그린다.
 */
@media (max-width: 43.75rem) {
  .deal-detail-head {
    flex-direction: column;
    align-items: flex-start;
    padding: 1.2rem 1rem;
  }

  /* 운영 `below(tablet-narrow)` 의 `.offer-filters` — 그룹이 세로로 서고 칩은 4칸 같은 폭 격자다.
     안쪽 여백은 운영 `--compare-inset` — 800 이하는 .9rem, 560 이하는 .8rem(`_compare.scss:181·196`). */
  .offer-filters {
    display: grid;
    gap: 0.6rem;
    padding: 0.7rem 0.9rem;
  }

  .offer-filters .filter-group {
    align-items: flex-start;
    flex-direction: column;
  }

  .offer-filters .filter-chips {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.3rem;
    width: 100%;
  }

  .offer-filters label.filter-chip {
    justify-content: center;
  }

  /* 카드들이 스스로 선을 들므로 바깥 틀은 벗긴다. */
  .deal-offers .deal-table-wrap {
    overflow: visible;
    border: 0;
    border-radius: 0;
    background: transparent;
  }

  .deal-offer-table {
    display: block;
  }

  .deal-offer-table thead {
    display: none;
  }

  .deal-offer-table tbody {
    display: grid;
    gap: 0.65rem;
  }

  /* 한 줄 = 카드 한 장: 윗줄 매장, 가운데 조건 셋의 3열 격자, 아랫줄 날짜·원문 단추
     * (레거시 `.mobile-offers > li` 의 header·`.mobile-price-grid`·footer 차례). */
  .deal-offer-table tbody tr {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-areas:
      'store store store'
      'new port change'
      'checked checked out';
    padding: 0.9rem;
    border: 1px solid var(--nr-line);
    border-radius: 0.75rem;
    background: var(--nr-surface);
  }

  /* 칸 여백·칸 선은 카드가 맡는다 — 여백은 줄이, 선은 격자가 그린다. `table.` 은
     `.deal-table tbody tr + tr td`(0,1,4)의 윗선을 (0,1,5)로 누르려고 붙인다 — 안 누르면
     두 번째 카드부터 매장 이름 위에 줄이 선다. */
  table.deal-offer-table tbody tr > td {
    padding: 0;
    border: 0;
    white-space: normal;
  }

  .deal-offer-table td:nth-child(1) {
    grid-area: store;
    align-self: center;
    font-size: var(--nr-size-meta);
    font-weight: var(--nr-weight-normal);
    text-align: left;
  }

  /* 아랫줄 왼쪽은 레거시 footer 의 `<time>` — 「최근 가격표 게시 …」 문구까지 붙는다. */
  .deal-offer-table td:nth-child(5) {
    grid-area: checked;
    align-self: center;
    justify-self: start;
    color: var(--nr-dim);
    font-size: var(--nr-size-caption);
    text-align: left;
  }

  .deal-offer-table td:nth-child(5)::before {
    content: '최근 가격표 게시 ';
  }

  .deal-offer-table td:nth-child(6) {
    grid-area: out;
    display: flex;
    justify-content: flex-end;
  }

  .deal-offer-table .deal-outbound {
    min-height: 2.25rem;
  }

  /* 가운데 3열 격자 — 운영 `.mobile-price-grid`. 위아래 선과 칸 사이 왼쪽 선을 칸이 든다. */
  .deal-offer-table td:nth-child(2) {
    grid-area: new;
  }

  .deal-offer-table td:nth-child(3) {
    grid-area: port;
  }

  .deal-offer-table td:nth-child(4) {
    grid-area: change;
  }

  /*
   * 가입 방식을 고르면 남은 조건 칸 하나가 카드 가로를 다 쓰게 한다 — 숨긴 칸의 격자 자리를
   * 비워 두지 않기 위해 `grid-template-areas` 를 한 칸짜리로 바꾼다. `+` 형제의 왼쪽 선은
   * 숨긴 칸 기준으로도 그려지므로 남은 칸에서 뗀다.
   */
  .deal-detail:has(input[name='detail-type'][value='NEW']:checked) .deal-offer-table tbody tr,
  .deal-detail:has(input[name='detail-type'][value='PORT_IN']:checked) .deal-offer-table tbody tr,
  .deal-detail:has(input[name='detail-type'][value='DEVICE_CHANGE']:checked) .deal-offer-table tbody tr {
    grid-template-areas:
      'store store store'
      'picked picked picked'
      'checked checked out';
  }

  .deal-detail:has(input[name='detail-type'][value='NEW']:checked) .deal-offer-table td[data-type='NEW'],
  .deal-detail:has(input[name='detail-type'][value='PORT_IN']:checked) .deal-offer-table td[data-type='PORT_IN'],
  .deal-detail:has(input[name='detail-type'][value='DEVICE_CHANGE']:checked) .deal-offer-table td[data-type='DEVICE_CHANGE'] {
    grid-area: picked;
    border-left: 0;
  }

  .deal-offer-table .deal-offer-price {
    display: grid;
    grid-template-rows: auto 1fr;
    align-content: stretch;
    gap: 0.4rem;
    margin: 0.7rem 0;
    padding: 0.65rem 0.2rem;
    border-block: 1px solid var(--nr-line);
    text-align: center;
  }

  .deal-offer-table .deal-offer-price + .deal-offer-price {
    border-left: 1px solid var(--nr-line);
  }

  /* 마지막 카드: 넓은 표의 `tbody tr:last-child td{border-bottom:0}`(위)가 카드 칸의
     * `border-block` 아랫선까지 지워 1px 낮아진다 — 카드 모드에서 되돌린다. */
  .deal-offer-table tbody tr:last-child td.deal-offer-price {
    border-bottom: 1px solid var(--nr-line);
  }

  .deal-offer-table .deal-offer-price::before {
    content: attr(data-label);
    color: var(--nr-dim);
    font-size: var(--nr-size-caption);
  }

  /* 폰의 가격 줄은 칸이 좁아 라벨 1rem 에 값을 눌러 담는다(운영 `mobileCarrierLabel` 자리). */
  .deal-offer-table .carrier-price-stack {
    width: 100%;
    align-self: start;
    gap: 0.35rem;
  }

  .deal-offer-table .carrier-price-line {
    grid-template-columns: 1rem minmax(0, 1fr);
    gap: 0.2rem;
    min-height: 1.3rem;
  }

  .deal-offer-table .carrier-price-line small {
    text-align: center;
  }

  /* 폰 카드는 한 글자 라벨로 바꿔 그린다(레거시 `mobileCarrierLabel` — S/K/L). */
  .deal-offer-table .carrier-price-line .carrier-name {
    display: none;
  }

  .deal-offer-table .carrier-price-line .carrier-initial {
    display: inline;
  }

  .deal-offer-table .carrier-price-line strong {
    font-size: clamp(0.78rem, 3.3vw, var(--nr-size-meta));
  }

  /* 빈 가격 칸의 「-」는 레거시가 크기를 따로 두지 않아 body 의 1rem/1.6 = 16/25.6 을
     * 물려받는다(`PhoneDealDetailPage.vue:283` `.mobile-price-grid>div>.empty-price`) —
     * 여기는 칸이 `td` 라 표의 meta(14/22.4)를 받으므로 운영 높이로 되돌린다. */
  .deal-offer-table .deal-empty-price {
    display: grid;
    width: 100%;
    height: 100%;
    place-items: center;
    font-size: 1rem;
  }

  /* 560 이하는 운영 `--compare-inset` 이 .8rem 으로 준다(`_compare.scss:196` `below(sm)`). */
  @media (max-width: 35rem) {
    .offer-filters {
      padding: 0.7rem 0.8rem;
    }

    .deal-offer-table tbody tr {
      padding: 0.9rem 0.8rem;
    }
  }
}

/*
 * 태블릿 소(701~800px)의 필터 판 — 레거시 `below(tablet-wide)`(800 포함)가 칩 묶음을
 * 자동 맞춤 격자로 접고 칸 패딩·줄높이를 좁힌다(`_filters.scss:69-78`). 이 대에서도
 * `--compare-inset` 은 .9rem(`_compare.scss:181`)이라 판 안쪽 여백도 같이 준다.
 * 칩 높이는 2rem 유지 — `_filters.scss` 의 2.1rem 은 레거시에서 `.filter-group .filter-chip`
 * 의 2rem 에 지므로 여기서는 아예 적지 않는다.
 */
@media (min-width: 700.02px) and (max-width: 50rem) {
  /* 머리 카드의 좌우도 이 대의 `--compare-inset` .9rem — 레거시 `.detail-head` 의
     `padding: 1.1rem var(--compare-inset)`(`PhoneDealDetailPage.vue:278`)에
     `_compare.scss:182` 의 값. 700 이하는 위 43.75rem 블록의 1rem(`PhoneDealDetailPage.vue:283`)이 잡는다. */
  .deal-detail-head {
    padding-inline: 0.9rem;
  }

  .offer-filters {
    padding: 0.7rem 0.9rem;
  }

  .offer-filters .filter-chips {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(4.25rem, 1fr));
    gap: 0.3rem;
  }

  .offer-filters .filter-chips > * {
    min-width: 0;
    padding: 0.25rem 0.4rem;
    line-height: 1.3;
    white-space: normal;
  }
}

/*
 * 좁은 화면의 주의 문단 좌우 — `--compare-inset` 이 800 이하 .9rem, 560 이하 .8rem 으로 준다.
 * 공지 띠 링크도 같은 값 — 레거시 `.deal-notice a` 의 `padding: .5rem var(--compare-inset)`
 * (`PhoneDealNotices.vue:35`). 700 이하 블록이 이 링크는 건드리지 않으므로 561~700 도 .9rem 이다.
 */
@media (max-width: 50rem) {
  .deal-footnote {
    margin: 0.85rem 0.9rem;
  }

  .deal-detail .notice-strip a {
    padding-inline: 0.9rem;
  }
}

@media (max-width: 35rem) {
  .deal-footnote {
    margin: 0.85rem 0.8rem;
  }

  .deal-detail .notice-strip a {
    padding-inline: 0.8rem;
  }
}

@media (max-width: 50rem) {
  /*
   * 좁은 화면의 시세표 카드. 표 하나를 그대로 두고 줄 하나를 카드 한 장으로 접는다 —
   * 레거시가 `<table>` 과 `<ol>` 로 두 번 그리던 것을 CSS 만으로 흉내 낸다. 머리 줄은 감추고
   * 기기명·날짜를 첫 줄에, 구매 조건을 한 줄씩 아래에 둔다(운영 `.mobile-row` 모양).
   * 분기는 레거시 `below(tablet-wide)` = 800px 포함(`PhoneDealPage.vue:467`).
   */
  .deal-results .deal-table-wrap {
    overflow: visible;
    background: transparent;
    border: 0;
    border-radius: 0;
  }

  /* wrap 이 투명해져 감싸는 카드가 없다. 수집 기준은 자기 카드를 되찾는다. */
  .deal-results .deal-table-wrap > .compare-note {
    margin-top: 0.65rem;
    padding: 0.75rem 0.9rem;
    background: var(--nr-surface);
    border: 1px solid var(--nr-line);
    border-radius: 0.75rem;
  }

  .compare-note > summary {
    flex-wrap: wrap;
    gap: 0.35rem;
  }

  /* 요약 줄은 그림·제목·「자세히」가 첫 줄, 확인 날짜는 아래 줄을 다 쓴다. */
  .compare-note > summary > svg {
    order: 1;
  }

  .compare-note__title {
    order: 2;
  }

  .compare-note__toggle {
    order: 3;
  }

  .compare-note__meta {
    order: 4;
    flex: 1 1 100%;
    margin-top: 0.15rem;
    white-space: normal;
  }

  .compare-note__facts > div {
    grid-template-columns: 5.5rem minmax(0, 1fr);
  }

  .deal-price-table {
    display: block;
  }

  .deal-price-table thead {
    display: none;
  }

  .deal-price-table tbody {
    display: block;
    background: var(--nr-surface);
    border: 1px solid var(--nr-line);
    border-radius: 0.75rem;
  }

  .deal-price-table tbody tr {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    padding: 0.6rem 0.9rem;
  }

  /* 카드 사이는 줄의 윗선 하나로 가른다 — 칸마다 붙던 아래선은 여기서 안 쓴다. */
  .deal-price-table tbody tr + tr {
    border-top: 1px solid var(--nr-line);
  }

  .deal-price-table tbody tr + tr th,
  .deal-price-table tbody tr + tr td {
    border-top: 0;
  }

  /* 카드 안에서는 칸 여백·칸 테두리를 안 쓴다 — 여백은 줄이, 선은 카드가 맡는다. */
  .deal-table.deal-price-table tbody tr > *,
  .deal-table.deal-price-table tbody tr > *:first-child,
  .deal-table.deal-price-table tbody tr > *:last-child {
    padding: 0;
    border: 0;
  }

  .deal-price-table tbody th[scope='row'] {
    order: 1;
    flex: 1 1 auto;
    min-width: 0;
    font-size: 0.9375rem;
    font-weight: 600;
  }

  /* 날짜 둘은 기기명 옆으로 붙여 오른쪽 끝에 민다. */
  .deal-price-table .deal-checked {
    order: 2;
    flex: 0 0 auto;
    display: inline-flex;
    gap: 0.2rem;
    text-align: left;
  }

  .deal-price-table .deal-checked + .deal-checked {
    margin-left: 0.35rem;
  }

  .deal-checked__label {
    display: inline;
  }

  .deal-price-table tbody td.deal-price {
    order: 3;
    flex: 1 1 100%;
    margin-top: 0.3rem;
    text-align: left;
  }

  /* 운영은 값이 없는 구매 조건 줄을 아예 안 그린다. 표에서는 접어 감춘다. */
  .deal-price-table tbody td.deal-price-empty {
    display: none;
  }

  /* 좁은 화면 한 줄: 구매 조건 · 금액 · 통신사 순으로 붙인다. */
  .deal-price-table .price-cell {
    grid-template-columns: 3.6rem auto minmax(0, 1fr);
    align-items: baseline;
    gap: 0.4rem;
    justify-items: stretch;
    text-align: left;
  }

  .deal-price-table .price-cell__label {
    display: block;
  }

  .deal-price-table .price-cell__carriers {
    overflow: hidden;
    justify-content: flex-end;
  }

  .deal-price-table .price-cell__carrier {
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .compare-head {
    padding: 0 0.9rem;
  }

  .deal-filters {
    padding: 0.7rem 0.9rem 0.9rem;
  }

  .deal-filters > summary {
    margin: 0 0 0.6rem;
    padding: 0 0 0.55rem;
  }

  /* 좁은 화면의 머리에는 요약이 안 선다(운영). 「가격 조건 … 닫기」만 남는다. */
  .filter-summary {
    display: none;
  }

  .filter-rows {
    gap: 0.6rem;
  }

  .filter-row {
    grid-template-columns: 4.6rem minmax(0, 1fr);
    gap: 0.45rem;
    align-items: start;
  }

  /* 줄 높이가 아니라 이 여백이 이름과 첫 칩의 윗줄을 맞춘다(운영 6.08px). */
  .filter-row strong {
    margin-top: 0.38rem;
    font-size: 0.875rem;
  }

  .sub-region-row {
    padding: 0.45rem 0;
    box-shadow: 0 0 0 0.4rem var(--nr-tint);
  }

  .filter-actions {
    align-items: flex-end;
    flex-direction: column;
  }

  .filter-row-pair {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.55rem;
  }

  .compare-toolbar {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.5rem;
    padding: 0.8rem 0.9rem 0.6rem;
  }

  .compare-toolbar__controls {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.45rem;
  }

  /* 칸이 절반이라 12rem 을 내려놓는다. 안 그러면 두 단추가 폭을 넘어 가로로 새어 나간다. */
  .select-trigger {
    min-width: 0;
  }
}

/*
 * 운영은 560(below(sm)) 에서 안쪽 여백 `--compare-inset` 을 .9 → .8rem 으로 한 번 더 줄인다
 * (`_compare.scss:196`). 시세 목록에서 그 값을 쓰는 자리만 같이 줄인다.
 */
@media (max-width: 35rem) {
  .compare-head {
    padding-inline: 0.8rem;
  }

  .deal-filters {
    padding-inline: 0.8rem;
  }

  .deal-results .deal-table-wrap > .compare-note {
    padding-inline: 0.8rem;
  }

  .deal-price-table tbody tr {
    padding-inline: 0.8rem;
  }

  .compare-note__facts > div {
    grid-template-columns: 1fr;
    gap: 0.2rem;
  }

  .compare-toolbar {
    padding-inline: 0.8rem;
  }
}

/* 같은 productId 로 발행된 리뷰가 있을 때만 서는 역링크. 시세와 리뷰를 왕복하게 한다. */
.deal-detail-review {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: baseline;
  gap: 0.55rem;
  margin: 0 0 0.65rem;
  padding: 0.75rem 1.1rem;
  border: 1px solid var(--nr-line);
  border-radius: 0.75rem;
  background: var(--nr-tint);
  color: var(--nr-ink);
  text-decoration: none;
}

.deal-detail-review strong {
  color: var(--nr-accent);
  white-space: nowrap;
}

.deal-detail-review span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.deal-detail-review:hover {
  border-color: var(--nr-accent);
}

/*
 * 리뷰 본문의 시세 카드(`plugins/phonedeal/src/card.ts`). 레거시 `review-markdown/review.css` 311-390
 * 을 스킨 토큰으로 다시 짠다 — 알뜰폰·시세표와 같은 원칙이고, 값(테두리·바탕·글자)은 `--board-*`
 * 만 쓴다. 레거시가 준 파랑 기운(#d9e2ef·#f7fafd)은 스킨에 그 토큰이 없어 안 가져온다.
 *
 * **단추는 `a` 를 선택자에 박는다.** 스킨이 글 본문 링크에 밑줄과 글자색을 준다
 * (`.post .gb-body a`, 특이도 0,2,1). 클래스만으로는(0,2,0) 못 이겨서 밑줄이 단추 위에 남는다.
 * `a` 를 붙여 (0,2,1) 로 맞추면 이 파일이 스킨 시트 뒤에 실려(머리 주석) 차례로 이긴다 —
 * 남의 테마를 이기는 자리를 `!important` 대신 이렇게 잡는다. 값이 아니라 차례로 푸는 것이라
 * 다음 스킨이 같은 규칙을 갖고 오면 그때 다시 본다.
 */
.embed-phonedeal-card {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--nr-space-4);
  border: 1px solid var(--nr-line);
  border-radius: var(--nr-radius);
  background: var(--nr-tint);
  padding: var(--nr-space-4) var(--nr-space-4);
}

.embed-phonedeal-title {
  font-weight: var(--nr-weight-bold);
  letter-spacing: -0.03em;
}

.embed-phonedeal-note {
  margin-top: var(--nr-space-1);
  color: var(--nr-dim);
  font-size: var(--nr-size-meta);
  word-break: keep-all;
}

.embed-phonedeal-card a.embed-phonedeal-button,
.embed-phonedeal-card span.embed-phonedeal-button {
  border-radius: 999px;
  background: var(--nr-ink);
  color: var(--nr-on-ink);
  padding: var(--nr-space-2) var(--nr-space-4);
  font-size: var(--nr-size-meta);
  font-weight: var(--nr-weight-bold);
  white-space: nowrap;
  text-decoration: none;
}

/* 값이 없는 자리에도 단추 모양은 서지만, 눌리는 자리가 아니라는 것만 손끝에 알린다. */
.embed-phonedeal-button-dead {
  cursor: default;
}

/*
 * 값이 채워진 카드. 껍데기와 같은 테두리 안이지만 값이 주인공이라 좌우로 안 가르고 값 줄을
 * 통째로 넓게 쓴다 — 단추는 값 아래로 내려간다.
 */
.embed-phonedeal-card.embed-phonedeal-live {
  flex-direction: column;
  align-items: stretch;
  gap: var(--nr-space-3);
}

.embed-phonedeal-live .embed-phonedeal-body {
  width: 100%;
}

.embed-phonedeal-live .embed-phonedeal-button {
  align-self: flex-start;
}

.embed-phonedeal-device {
  margin-top: 2px;
  color: var(--nr-dim);
  font-size: var(--nr-size-caption);
}

.embed-phonedeal-prices {
  display: flex;
  flex-wrap: wrap;
  gap: var(--nr-space-2);
  margin-top: var(--nr-space-2);
}

/* 가입유형 한 칸. 폭을 안 고정한다 — 유형이 하나뿐인 기종도 흔하다(레거시 주석). */
.embed-phonedeal-price {
  flex: 1 1 7.25rem;
  border: 1px solid var(--nr-line);
  border-radius: var(--nr-radius);
  background: var(--nr-surface);
  padding: var(--nr-space-2) var(--nr-space-3) var(--nr-space-2);
}

.embed-phonedeal-price-type {
  display: block;
  color: var(--nr-dim);
  font-size: var(--nr-size-caption);
}

.embed-phonedeal-price-amount {
  display: block;
  margin-top: 2px;
  color: var(--nr-ink);
  font-size: var(--nr-size-head);
  font-weight: var(--nr-weight-bold);
  letter-spacing: -0.04em;
  /* 값은 자릿수로 읽는다. 폭이 흔들리면 위아래 칸이 어긋나 보인다. */
  font-variant-numeric: tabular-nums;
}

.embed-phonedeal-price-carrier {
  display: block;
  margin-top: 1px;
  color: var(--nr-dim);
  font-size: var(--nr-size-caption);
}

/*
 * 리뷰 본문 블록(`plugins/review/src/blocks`). 레거시 `review-markdown/review.css` 에서 시세 카드
 * (310-387행)를 뺀 나머지를 옮긴다 — 클래스는 렌더러가 내는 이름(`embed-review-*`), 색은 스킨
 * 토큰(`--board-*`)이다. 톤과 강조색(썰 등뼈·결론 상자·도넛 조각·주황 경고)은 값으로 남긴다.
 *
 * **스킨이 글 본문에 다는 규칙과 부딪히는 자리가 있다.** `.post .gb-body` 아래 `p`·`a`·`blockquote`·
 * `table`·`th`·`td`·`img`·`pre` 규칙(모두 특이도 0,2,1)이 바탕·여백을 정하므로, 같은 속성을 만지는
 * 규칙은 선택자를 한 겹 더 얹어 (0,2,1)로 맞춰 이긴다 — 이 파일이 스킨 시트 뒤에 실려 차례로
 * 앞선다(머리 주석·시세 카드와 같은 방식). 안 부딪히는 규칙은 그대로 둔다.
 */

/* 모든 블록에 붙는 바깥 여백. */
.embed-review-block {
  margin: 1.6em 0;
}

/* 렌더러가 이름을 못 알아본 블록. 경고 톤(주황)이라 값으로 남긴다.
   `pre` 로 나오므로 스킨의 `.post .gb-body pre`(0,2,1) 바탕을 이겨야 한다. */
pre.embed-review-block.embed-review-unknown {
  background: #fff7ed;
  border: 1px solid #fdba74;
}

/* ── 도넛 대시보드 ─────────────────────────────────────────────── */
.embed-review-pie {
  border: 1px solid var(--nr-line);
  border-radius: 17px;
  padding: var(--nr-space-5);
  background: var(--nr-tint);
}

.embed-review-pie-head {
  margin-bottom: var(--nr-space-4);
}

.embed-review-pie-title {
  font-size: var(--nr-size-head);
  font-weight: var(--nr-weight-bold);
  letter-spacing: -0.03em;
}

.embed-review-pie-note {
  font-size: var(--nr-size-caption);
  color: var(--nr-dim);
  margin-top: 2px;
}

.embed-review-pie-foot {
  font-size: var(--nr-size-caption);
  color: var(--nr-dim);
  margin-top: var(--nr-space-4);
  padding-top: var(--nr-space-3);
  border-top: 1px solid var(--nr-line);
}

/*
 * 판은 세 칸이고 좁아지면 한 칸으로 접는다. 접힌 뒤에는 도넛과 범례가 좌우로 서야
 * 세로가 무한정 길어지지 않는다.
 */
.embed-review-pie-grid {
  display: grid;
  /*
   * 세 판이 **한 줄에 서야** 대조가 보인다 ─ "좋다는 항목 / 아쉬운 항목 / 그래서 뭘
   * 권하나" 는 나란히 놓일 때 한눈에 읽히는 그림이고, 셋째가 아래로 접히면 그냥
   * 도넛 세 개가 된다.
   */
  grid-template-columns: repeat(auto-fit, minmax(152px, 1fr));
  gap: var(--nr-space-2);
}

.embed-review-pie-card {
  background: var(--nr-surface);
  border: 1px solid var(--nr-line);
  border-radius: 14px;
  padding: var(--nr-space-3) var(--nr-space-3);
}

.embed-review-pie-ring-wrap {
  display: flex;
  justify-content: center;
  margin-bottom: var(--nr-space-3);
}

/* 가운데를 뚫는 것은 `inset` 원이다. 배경이 흰 카드라 흰 원이 구멍으로 읽힌다. */
.embed-review-pie-ring {
  width: 118px;
  height: 118px;
  border-radius: 50%;
  position: relative;
}

.embed-review-pie-ring::after {
  content: '';
  position: absolute;
  inset: var(--nr-space-6);
  border-radius: 50%;
  background: var(--nr-surface);
}

.embed-review-pie-center {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: var(--nr-size-caption);
  color: var(--nr-dim);
  text-align: center;
  padding: 0 var(--nr-space-6);
  word-break: keep-all;
}

.embed-review-pie-center b {
  font-size: var(--nr-size-read);
  color: var(--nr-text);
  line-height: var(--nr-leading-tight);
}

.embed-review-pie-legend {
  display: grid;
  grid-template-columns: 10px 1fr 34px;
  gap: var(--nr-space-2);
  align-items: center;
  margin: var(--nr-space-1) 0;
  font-size: var(--nr-size-caption);
}

.embed-review-pie-swatch {
  width: 9px;
  height: 9px;
  border-radius: 3px;
}

.embed-review-pie-name {
  color: var(--nr-text);
  word-break: keep-all;
}

.embed-review-pie-legend b {
  text-align: right;
}

/* ── 먼저 결론 ─────────────────────────────────────────────── */
/*
 * 결론 상자는 어두운 판이라 톤으로 남긴다 — 밝은 바탕 토큰으로 바꾸면 판이 사라진다.
 * 안쪽 `p` 는 스킨 `.post .gb-body p`(0,2,1)가 여백을 정하므로 선택자를 얹어 이긴다.
 */
.embed-review-finding {
  background: #1c1f24;
  color: #e9ebee;
  border-radius: 16px;
  padding: var(--nr-space-5) var(--nr-space-6);
}

.embed-review-finding-label {
  font-size: var(--nr-size-caption);
  font-weight: var(--nr-weight-bold);
  letter-spacing: 0.09em;
  color: #9aa3ad;
  margin-bottom: var(--nr-space-2);
}

.embed-review-block.embed-review-finding p {
  margin: 0 0 var(--nr-space-2);
  line-height: var(--nr-leading-read);
}

.embed-review-block.embed-review-finding p:last-child {
  margin-bottom: 0;
}

/* 결론 상자는 먼저 결론과 같은 어둠을 쓰되, 마지막 상자라 조금 더 눌러 앉힌다. */
.embed-review-verdict {
  background: #14171b;
}

/* ── 썰 카드 ─────────────────────────────────────────────── */
/*
 * 320px 이면 넓은 화면에서 석 줄이 서고 한 장이 370px 가 된다. 카드는 훑는 물건이고,
 * 훑으려면 한 줄이 문장이어야 한다. 연달아 선 story 블록은 렌더러가 이 격자 하나로 합친다.
 */
.embed-review-story {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: var(--nr-space-3);
}

/*
 * **카드 바탕은 넷 다 흰색이다.** 톤마다 바탕을 칠했더니 열다섯 장이 초록·분홍·파랑
 * 조각보가 됐다. 카드가 스물이 넘게 늘어서는 글에서 바탕색은 신호가 아니라 얼룩이다.
 * 톤은 왼쪽 등뼈 한 줄과 꼬리표 글자색으로만 남긴다.
 */
.embed-review-story-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--nr-line);
  border-left: 3px solid #c8ccd1;
  border-radius: 14px;
  padding: var(--nr-space-4);
  background: var(--nr-surface);
}

/* 등뼈와 꼬리표 색은 톤이라 값으로 남긴다. */
.embed-review-story-good {
  border-left-color: #4b7a63;
}
.embed-review-story-hot {
  border-left-color: #a05a52;
}
.embed-review-story-weird {
  border-left-color: #9a7b3f;
}
.embed-review-story-blue {
  border-left-color: #4a6382;
}

.embed-review-story-tag {
  font-size: var(--nr-size-caption);
  color: var(--nr-dim);
  font-weight: var(--nr-weight-bold);
}

.embed-review-story-good .embed-review-story-tag {
  color: #4b7a63;
}
.embed-review-story-hot .embed-review-story-tag {
  color: #a05a52;
}
.embed-review-story-weird .embed-review-story-tag {
  color: #9a7b3f;
}
.embed-review-story-blue .embed-review-story-tag {
  color: #4a6382;
}

.embed-review-story-headline {
  font-size: var(--nr-size-read);
  font-weight: var(--nr-weight-bold);
  line-height: var(--nr-leading-tight);
  letter-spacing: -0.03em;
  margin: var(--nr-space-1) 0 var(--nr-space-2);
  word-break: keep-all;
}

/*
 * 카드 안의 인용은 본문 인용과 다른 물건이다. 왼쪽 굵은 선을 그대로 두면 카드 안에
 * 또 하나의 상자가 생겨 색이 두 겹으로 읽힌다. 여기서는 글자만 남긴다.
 *
 * **`.embed-review-block` 을 한 겹 더 얹은 것은 무게 때문이다.** 스킨이 글 본문 인용에
 * 바탕과 왼쪽 선을 준다(`.post .gb-body blockquote`, 0,2,1). 카드+인용(0,2,0)이면 그쪽이
 * 이겨 이 규칙이 통째로 무시되고 카드 안에 색 다른 상자가 또 생긴다.
 */
.embed-review-block .embed-review-story-card .embed-review-story-quote {
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font-size: var(--nr-size-caption);
  color: var(--nr-text);
  line-height: var(--nr-leading-read);
  word-break: keep-all;
}

/* 발은 바닥에 붙인다. 격자가 카드를 같은 높이로 늘리므로, 안 붙이면 짧은 카드의
   출처 줄만 허공에 뜬다. */
.embed-review-story-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--nr-space-1);
  margin-top: auto;
  padding-top: var(--nr-space-2);
  font-size: var(--nr-size-caption);
  color: var(--nr-dim);
}

/* 출처 링크는 스킨의 `.post .gb-body a`(0,2,1)가 밑줄과 글자색을 준다.
   선택자를 한 겹 얹어 (0,2,1)로 맞춰 이기고 밑줄만 뗀다. */
.embed-review-block .embed-review-story-foot a {
  color: #496c97;
  text-decoration: none;
  white-space: nowrap;
}

/* ── 그림 ─────────────────────────────────────────────── */
.embed-review-image {
  margin: 1.6em 0;
}

/* 스킨이 글 본문 그림에 둥근 모서리를 준다(`.post .gb-body img`, 0,2,1).
   선택자를 얹어 이겨 카드와 같은 14px 로 맞춘다. */
.embed-review-block.embed-review-image img {
  width: 100%;
  border-radius: 14px;
  display: block;
}

.embed-review-image figcaption {
  font-size: var(--nr-size-caption);
  color: var(--nr-dim);
  margin-top: var(--nr-space-2);
  font-style: italic;
}

.embed-review-image-asset {
  font-style: normal;
  font-size: var(--nr-size-caption);
  color: var(--nr-dim);
  background: var(--nr-tint);
  border-radius: 5px;
  padding: 1px var(--nr-space-1);
}

.embed-review-image-missing {
  border: 1px dashed var(--nr-rule);
  border-radius: 14px;
  padding: var(--nr-space-7);
  text-align: center;
  color: var(--nr-dim);
  font-size: var(--nr-size-caption);
}

/* ── 막대 ─────────────────────────────────────────────── */
/* 막대는 길이로 순서를 읽는 그림이다. 이름·막대·수를 한 줄에 고정폭으로 세운다. */
.embed-review-bar {
  border: 1px solid var(--nr-line);
  border-radius: 17px;
  padding: var(--nr-space-5);
  background: var(--nr-tint);
}

.embed-review-bar-rows {
  display: grid;
  gap: var(--nr-space-2);
}

.embed-review-bar-row {
  display: grid;
  grid-template-columns: minmax(96px, 148px) 1fr 34px;
  align-items: center;
  gap: var(--nr-space-2);
}

.embed-review-bar-label {
  font-size: var(--nr-size-caption);
  color: var(--nr-text);
  word-break: keep-all;
}

.embed-review-bar-track {
  background: var(--nr-tint-2);
  border-radius: 999px;
  height: 15px;
}

.embed-review-bar-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
}

.embed-review-bar-value {
  font-size: var(--nr-size-caption);
  text-align: right;
  color: var(--nr-text);
}

/* ── 대조 ─────────────────────────────────────────────── */
.embed-review-compare {
  border: 1px solid var(--nr-line);
  border-radius: 14px;
  padding: var(--nr-space-4) var(--nr-space-4);
  background: var(--nr-surface);
}

.embed-review-cmp-title {
  font-weight: var(--nr-weight-bold);
  font-size: var(--nr-size-read);
  margin-bottom: var(--nr-space-2);
  letter-spacing: -0.03em;
}

.embed-review-cmp-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--nr-space-2);
}

.embed-review-cmp-col {
  border-radius: 11px;
  padding: var(--nr-space-3) var(--nr-space-3);
  background: var(--nr-tint);
}

/* 한국 쪽 강조는 톤이라 값으로 남긴다. */
.embed-review-cmp-col-kr {
  background: #eef4fb;
}

.embed-review-cmp-label {
  font-size: var(--nr-size-caption);
  font-weight: var(--nr-weight-bold);
  color: var(--nr-dim);
}

.embed-review-cmp-value {
  font-size: var(--nr-size-read);
  font-weight: var(--nr-weight-bold);
  margin: 2px 0 var(--nr-space-1);
  letter-spacing: -0.02em;
}

.embed-review-cmp-note {
  font-size: var(--nr-size-caption);
  color: var(--nr-dim);
  line-height: var(--nr-leading-ui);
  word-break: keep-all;
}

/* ── 지표 ─────────────────────────────────────────────── */
/* 왼쪽 굵은 선(남색)은 톤이라 값으로 남긴다. */
.embed-review-metric {
  display: flex;
  gap: var(--nr-space-4);
  align-items: baseline;
  border-left: 3px solid #27364c;
  background: var(--nr-tint);
  border-radius: 0 12px 12px 0;
  padding: var(--nr-space-3) var(--nr-space-4);
}

.embed-review-metric-value {
  font-size: var(--nr-size-display);
  font-weight: var(--nr-weight-bold);
  letter-spacing: -0.04em;
}

.embed-review-metric-label {
  font-weight: var(--nr-weight-bold);
  font-size: var(--nr-size-caption);
}

.embed-review-metric-note {
  font-size: var(--nr-size-caption);
  color: var(--nr-dim);
  margin-top: 2px;
}

.embed-review-metric-src {
  font-size: var(--nr-size-caption);
}

.embed-review-metric-compare {
  border: 1px solid var(--nr-line);
  border-radius: 14px;
  padding: var(--nr-space-4);
  background: var(--nr-surface);
  overflow-x: auto;
}

/* 표는 스킨이 여백·테두리를 정한다(`.post .gb-body table`, 0,2,1). 선택자를 얹어 이긴다. */
.embed-review-block.embed-review-metric-compare table {
  width: 100%;
  border-collapse: collapse;
  margin-top: var(--nr-space-2);
}

/*
 * 칸도 스킨이 여백·정렬·밑줄을 정한다(`.post .gb-body th, .post .gb-body td`, 0,2,1). 같은 이유로 얹는다.
 * 스킨의 `border-bottom` 은 지운다 ─ 레거시 줄은 `td` 윗줄뿐이라, 남기면 머리 밑과 끝 줄 밑에 선이 하나씩 는다.
 */
.embed-review-block.embed-review-metric-compare th {
  font-size: var(--nr-size-caption);
  color: var(--nr-dim);
  text-align: right;
  padding: var(--nr-space-1) var(--nr-space-2);
  border-bottom: 0;
}

.embed-review-block.embed-review-metric-compare th:first-child {
  text-align: left;
}

.embed-review-block.embed-review-metric-compare td {
  font-size: var(--nr-size-caption);
  padding: var(--nr-space-1) var(--nr-space-2);
  border-top: 1px solid var(--nr-line);
  border-bottom: 0;
  text-align: right;
}

.embed-review-block.embed-review-metric-compare td:first-child {
  text-align: left;
  color: var(--nr-text);
}

/* ── 조사 노트와 출처 ─────────────────────────────────────────────── */
.embed-review-note {
  background: var(--nr-tint);
  border-radius: 13px;
  padding: var(--nr-space-4) var(--nr-space-4);
}

.embed-review-note-label {
  font-size: var(--nr-size-caption);
  font-weight: var(--nr-weight-bold);
  letter-spacing: 0.06em;
  color: var(--nr-dim);
  margin-bottom: var(--nr-space-2);
}

/* 노트 문단도 스킨의 `.post .gb-body p`(0,2,1) 여백을 이겨야 한다. */
.embed-review-block.embed-review-note p {
  margin: 0 0 var(--nr-space-2);
  font-size: var(--nr-size-caption);
  color: var(--nr-text);
  line-height: var(--nr-leading-read);
}

.embed-review-block.embed-review-note p:last-child {
  margin-bottom: 0;
}

.embed-review-sources {
  border: 1px solid var(--nr-line);
  border-radius: 13px;
  padding: var(--nr-space-3) var(--nr-space-4);
  background: var(--nr-surface);
}

.embed-review-sources summary {
  font-weight: var(--nr-weight-bold);
  font-size: var(--nr-size-caption);
  cursor: pointer;
}

/* 목록 여백은 스킨의 `.post .gb-body ul`(0,2,1)이 정한다. 선택자를 얹어 이긴다. */
.embed-review-block.embed-review-sources ul {
  margin: var(--nr-space-2) 0 0;
  padding-left: 0;
  list-style: none;
}

.embed-review-sources li {
  font-size: var(--nr-size-caption);
  margin-bottom: var(--nr-space-1);
  display: flex;
  gap: var(--nr-space-2);
}

.embed-review-src-type {
  flex: none;
  font-size: var(--nr-size-caption);
  font-weight: var(--nr-weight-bold);
  color: var(--nr-dim);
  background: var(--nr-tint);
  border-radius: 5px;
  padding: 1px var(--nr-space-1);
  height: fit-content;
}

/*
 * 관련글(`plugins/related`). 레거시 `PostDetailView.vue:115` 의 `.related-posts` 를 스킨 토큰으로
 * 다시 짠다 — `--color-muted` 는 `--board-dim`, `--color-line` 은 `--board-line`, 글자 크기는
 * `--board-size-*` 다(`--text-body-lg`=1.0625rem 는 `--board-size-read`, `--text-caption`=.8125rem 는
 * `--board-size-caption` 와 값이 같다).
 *
 * 코어가 이 슬롯 기여를 `<div class="slot slot-content.after plugin-related">` 로 씌워 글의
 * `.post` 안, `.gb-body` 밖에 놓는다. 스킨의 `.post .gb-body …`(0,2,1)와는 안 부딪히지만, 일반 `h2`
 * (0,0,1)와 `a`(0,0,1)는 이기도록 선택자를 `.related-posts` 아래로 잡는다.
 *
 * 읽음 표시(`.is-read`)는 안 옮긴다. 레거시는 브라우저에 남긴 읽은 글을 보고 제목을 흐리게
 * 했지만, 여기엔 그 기록이 없다.
 */
.related-posts header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--nr-space-4);
  margin-bottom: var(--nr-space-2);
}

.related-posts h2 {
  margin: 0;
  font-size: var(--nr-size-read);
}

.related-posts header span {
  color: var(--nr-dim);
  font-size: var(--nr-size-meta);
}

.related-posts ul {
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
}

.related-posts li {
  border-top: 1px solid var(--nr-line);
}

.related-posts li:first-child {
  border-top: 0;
}

.related-posts a {
  display: grid;
  /* 운영 3.2px — 레거시 `PostDetailView.vue` 의 `.related-posts a{gap:.2rem}` 그대로. */
  gap: 0.2rem;
  padding: var(--nr-space-3) 2px;
}

/* 둘 다 grid 칸이라 `min-width: 0` 이 없으면 칸이 한 줄짜리 제목만큼 늘어나 말줄임이 안 된다. */
.related-posts strong {
  min-width: 0;
  overflow: hidden;
  font-size: var(--nr-size-ui);
  font-weight: var(--nr-weight-normal);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.related-posts a span {
  color: var(--nr-dim);
  /* 게시판·날짜 줄은 운영 13px(`--text-caption`)이다 — `--board-size-meta`(14px)를 쓰면 줄 하나가 76px 로 운영 73.6 을 넘는다. */
  font-size: var(--nr-size-caption);
}

/*
 * 디아블로2 아이템 DB(`plugins/d2r`). 화면 다섯 × 로케일 둘이 이 한 절을 쓴다.
 *
 * 앞의 둘과 달리 **여기는 레거시의 어두운 판을 그대로 들여온다.** 2026-09-16 에 뒤집은
 * 결정이다 — 그전에는 「보드는 밝은 바탕이라」 등급 색만 값으로 들고 어둠은 버렸는데,
 * 운영과 나란히 놓으면 같은 화면으로 안 보였다. 디아블로는 운영에서도 사이트의 다른 데와
 * 다른 판이고, 그 어둠이 등급 색을 읽히게 하는 바탕이다.
 *
 * 색은 레거시 값 그대로다. 등급 색은 장식이 아니라 정보이고 — 초록이면 세트, 금색이면
 * 유니크 — 어두운 바탕에서만 그 값이 원래 뜻대로 읽힌다.
 *
 * **판을 어둡게 하는 것은 스킨 토큰을 `.d2r` 에서 다시 정의하는 것 하나다.** 토큰은 가장
 * 가까운 곳의 값이 이기므로, 이 절의 나머지 규칙을 한 줄도 안 고치고 카드·선·글자가 전부
 * 돈다. 운영도 `body.page-theme-diablo` 에서 자기 `--color-*` 를 갈아 끼우는 같은 손이다.
 * 헤더와 페이지 바깥까지 도는 것은 `body:has(.d2r)` 다 — 이 화면에만 걸리고 스크립트가 없다.
 *
 * 선택자는 전부 `.d2r` 아래다. 안쪽 이름(`.grid`·`.stats`·`.content`)은 레거시 그대로라
 * 대조가 되지만 그만큼 흔한 이름이고, 뿌리를 안 씌우면 스킨·코어 마크업과 부딪힌다.
 *
 * **값은 운영 화면을 재서 쓴 게 아니라 레거시 원본을 옮긴 것이다**(2026-09-16). 원본은
 * 이 저장소 안에 있다 — `apps/frontend/app/components/diablo/*.vue` 와 `pages/diablo/*.vue`
 * 의 `<style scoped>`, 그리고 `app/assets/styles/{_tokens,_filters,_diablo}.scss`. 재서
 * 맞추면 78×104px 짜리 아이템 그림이 3.5rem 이 되는 식으로 조용히 틀린다. 고칠 일이
 * 생기면 화면을 재지 말고 그 `.vue` 를 열어라. SCSS 중첩은 펴고 `@include below(x)` 는
 * px 미디어로, `:deep(X)` 는 그냥 자손 선택자로 바꿨다.
 */
.d2r {
  /* 등급 색. 레거시 값 그대로다. */
  --d2r-base: #dddddd;
  --d2r-unique: #c7b377;
  --d2r-set: #00c400;
  --d2r-runeword: #d8b45c;
  --d2r-magic: #6969ff;
  --d2r-rare: #ffff64;
  --d2r-crafted: #ffa800;
  /* 판·선·금색. */
  --d2r-panel-strong: #101010;
  --d2r-panel: #171717;
  --d2r-panel-subtle: #1c1913;
  --d2r-line: #302d27;
  --d2r-line-strong: #49443a;
  --d2r-line-gold: #8e7339;
  --d2r-gold: #d8b45c;
  --d2r-gold-strong: #f0d898;
  --d2r-gold-soft: #b49b60;
  --d2r-text: #dddddd;
  --d2r-text-muted: #aaaaaa;
  --d2r-text-dim: #777777;
  --d2r-stat: #7da6ff;
  /*
   * 시세 신호 색 셋. 운영이 값으로 든 것이고 등급 색과 다른 계열이다 — 옵션에 따라 값이
   * 갈리는 것은 보라, 거래가 으뜸이거나 상급인 것은 주황 둘이다. 등급 색을 돌려 쓰면 범례에
   * 같은 색 점이 두 개 생긴다(「시세」 절의 `.dot` 주석).
   */
  --d2r-cond: #c98fe0;
  --d2r-market-top: #f0b35a;
  --d2r-market-high: #e0a84f;
  --d2r-set-bonus: #00c400;
  --d2r-shadow: rgb(0 0 0 / 33%);
  --d2r-shadow-strong: rgb(0 0 0 / 53%);
  --d2r-glow-gold: rgb(178 139 61 / 15%);
  /* 레거시 토큰 다리 — 옮겨 온 규칙이 쓰는 이름을 이 절 안에서만 정의한다(_tokens.scss 원본 값). */
  --text-caption: 0.875rem;
  --text-meta: 0.9375rem;
  --text-label: 0.9375rem;
  --text-body: 1rem;
  --text-body-lg: 1.0625rem;
  --text-subheading: 1.125rem;
  --text-section: 1.25rem;
  --text-title: 1.5rem;
  --text-title-lg: 1.75rem;
  --text-display: 2.25rem;
  --text-page: clamp(1.75rem, 3vw, 2.25rem);
  --weight-normal: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;
  --weight-extrabold: 800;
  --radius-sm: 0.4rem;
  --radius-md: 0.75rem;
  --radius-lg: 1rem;
  --radius-card: 0;
  --z-raised: 3;
  --content-width: 1180px;
  /*
   * 운영 헤더는 4rem 이고 우리 헤더는 그 아래에 실선 1px 이 더 있다. 붙는 자리가 1px 어긋난다.
   * 스킨의 headerAutohide 를 켜면 엔진 런타임이 `<html>` 의 --gb-header-offset 에 실측 높이를 쓰고
   * 헤더가 물러난 동안은 0 으로 둔다(레거시가 --app-header-offset 에 직접 쓰던 값,
   * AppHeader.vue `syncHeaderOffset`). 스크립트가 돌기 전·아예 안 도는 환경에선 그려진 65px 이다.
   */
  --app-header-offset: var(--gb-header-offset, 4.0625rem);
  --filter-label-width: 4.5rem;
  /*
   * 운영이 `body.page-theme-diablo` 에서 갈아끼우는 `--color-*` 다(`_themes.scss:16-28` 원본 값).
   * **이건 `--d2r-*` 의 다른 이름이 아니라 다른 값이다** — 칩·단추처럼 사이트 공통 규칙을 그대로
   * 옮긴 자리는 `--color-muted`(#aa9a73, 따뜻한 금갈색)를 쓰는데, 뜻이 비슷해 보이는
   * `--d2r-text-muted` 는 #aaa 회색이다. 옮길 때 `--d2r-*` 로 바꿔 쓰면 그 자리가 식는다.
   */
  --color-brand-50: #21190d;
  --color-brand-100: #392b13;
  --color-brand-500: #c9a227;
  --color-brand-600: #d6b85b;
  --color-brand-700: #f0cf78;
  --color-ink: #f6e7c2;
  --color-muted: #aa9a73;
  --color-line: rgb(201 162 39 / 18%);
  --color-surface: #17120d;
  --color-surface-subtle: #211a11;
  --color-canvas: #0d0a08;
  --color-on-brand: #fff;
  /* 스킨 토큰을 이 판의 값으로 다시 든다(머리의 셋째 단락). */
  --board-bg: var(--d2r-panel-strong);
  --nr-bg: var(--d2r-panel-strong);
  --board-surface: var(--d2r-panel);
  --nr-surface: var(--d2r-panel);
  --board-tint: var(--d2r-panel-subtle);
  --nr-tint: var(--d2r-panel-subtle);
  --board-tint-2: #23201a;
  --nr-tint-2: #23201a;
  --board-line: var(--d2r-line);
  --nr-line: var(--d2r-line);
  --board-rule: var(--d2r-line-strong);
  --nr-rule: var(--d2r-line-strong);
  --board-text: var(--d2r-text);
  --nr-text: var(--d2r-text);
  --board-mid: var(--d2r-text-muted);
  --nr-mid: var(--d2r-text-muted);
  --board-dim: var(--d2r-text-dim);
  --nr-dim: var(--d2r-text-dim);
  --board-ink: var(--d2r-gold);
  --nr-ink: var(--d2r-gold);
  --board-on-ink: #1a1208;
  --nr-on-ink: #1a1208;
  --board-accent: var(--d2r-gold);
  --nr-accent: var(--d2r-gold);
  --board-focus-line: initial;
  --nr-focus-line: initial;
  --board-focus-ring: initial;
  --nr-focus-ring: initial;
  --board-on-accent: #1a1208;
  --nr-on-accent: #1a1208;
  --board-accent-text: var(--d2r-gold);
  --nr-accent-text: var(--d2r-gold);
  --board-count: var(--d2r-stat);
  --nr-count: var(--d2r-stat);
  --board-shadow: none;
  --nr-shadow: none;
  /* 판은 글 너비보다 좌우 16px 넓고, 위아래로는 본문 여백만큼 비어져 나가 밝은 띠를 안 남긴다. */
  min-height: 70vh;
  margin: calc(-1 * var(--nr-space-6)) -1rem calc(-1 * var(--nr-space-8));
  padding: 1.4rem 1rem 3rem;
  background: var(--d2r-panel-strong);
  color: var(--d2r-text);
}

/*
 * 레거시 `_reset.scss` 가 `ul, ol { margin:0; padding:0; list-style:none }` 으로 전부 초기화한다 —
 * 운영 D2R 화면엔 기본 여백·불릿 목록이 없다. 우리 시트엔 그 초기화가 없어 세트 보너스 목록
 * 같은 자리에 브라우저 기본값(위아래 1em·왼쪽 40px·불릿)이 살아 있었다. 자기 값을 주는 목록
 * (`.item-card .stats`·`.price-grid` 등)은 특이도가 더 높아 이 규칙에 안 밀린다.
 */
.d2r ul,
.d2r ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

/*
 * 판 밖도 어두워야 판이 밝은 종이에 붙인 띠로 안 보인다. 헤더·푸터는 위와 같은 토큰 교체로
 * 돌고, 금색 그라디언트와 브랜드 색만 값으로 든다. `:has` 를 두 번 겹친 것은 스킨의 다크
 * 토큰(`:root:root`)보다 구체성이 낮아 그냥 쓰면 시스템 다크에서 밀리기 때문이다.
 */
body:has(.d2r):has(.d2r) {
  --board-bg: #0d0a08;
  --nr-bg: #0d0a08;
  --board-surface: #17120d;
  --nr-surface: #17120d;
  --board-tint: #211a11;
  --nr-tint: #211a11;
  --board-tint-2: #2a2115;
  --nr-tint-2: #2a2115;
  --board-line: rgb(201 162 39 / 22%);
  --nr-line: rgb(201 162 39 / 22%);
  --board-rule: rgb(201 162 39 / 34%);
  --nr-rule: rgb(201 162 39 / 34%);
  --board-text: #f6e7c2;
  --nr-text: #f6e7c2;
  --board-mid: #d8c9a2;
  --nr-mid: #d8c9a2;
  --board-dim: #aa9a73;
  --nr-dim: #aa9a73;
  --board-ink: #d6b85b;
  --nr-ink: #d6b85b;
  --board-on-ink: #1a1208;
  --nr-on-ink: #1a1208;
  --board-accent: #d6b85b;
  --nr-accent: #d6b85b;
  --board-focus-line: initial;
  --nr-focus-line: initial;
  --board-focus-ring: initial;
  --nr-focus-ring: initial;
  --board-on-accent: #1a1208;
  --nr-on-accent: #1a1208;
  --board-accent-text: #f0cf78;
  --nr-accent-text: #f0cf78;
  /* 브랜드 눈금 — 레거시 `body.page-theme-diablo`(`_themes.scss:15-19`). 판 밖 시세 띠 링크 같은 공통 부품이 읽는다. */
  --board-brand-50: #21190d;
  --nr-brand-50: #21190d;
  --board-brand-100: #392b13;
  --nr-brand-100: #392b13;
  --board-brand-500: #c9a227;
  --nr-brand-500: #c9a227;
  --board-brand-700: #f0cf78;
  --nr-brand-700: #f0cf78;
  --board-shadow: 0 2px 8px rgb(0 0 0 / 35%);
  --nr-shadow: 0 2px 8px rgb(0 0 0 / 35%);
  color-scheme: dark;
  background: radial-gradient(circle at 50% -10%, rgb(123 68 11 / 14%), rgb(0 0 0 / 0) 34rem), #0d0a08;
}

body:has(.d2r) .board-header {
  border-bottom-color: rgb(201 162 39 / 22%);
  background: linear-gradient(rgb(26 18 4 / 97%), rgb(18 13 8 / 96%));
  box-shadow: 0 0.5rem 2rem rgb(0 0 0 / 53%);
}

/* 운영은 브랜드 글자에 불꽃 그라디언트를 돌린다. 여기선 금색 한 톤으로 세운다 — 애니메이션은 안 옮긴다. */
body:has(.d2r) .gb-brand {
  color: #d6b85b;
}

body:has(.d2r) .board-menu a,
body:has(.d2r) .gb-sign-in {
  color: #e5d5b1;
}

body:has(.d2r) .board-menu a:hover,
body:has(.d2r) .board-menu a[aria-current] {
  color: #f1c75e;
}

body:has(.d2r) .sign-up {
  border-color: transparent;
  background: linear-gradient(#e7c568, #a87927);
  color: #1a1208;
}

body:has(.d2r) .gb-theme-toggle {
  border-color: rgb(201 162 39 / 24%);
  color: #d8b45c;
}

/*
 * 영문 다섯 화면의 전용 셸 — 레거시 `layouts/default.vue` 의 `.site-shell--diablo` 분기
 * (`<style scoped>` 마지막 열 줄)다. 이 셸이 그려지는 페이지는 `chrome: 'none'` 이라 스킨의
 * 헤더·슬롯·푸터가 없고, `.d2r` 판은 `.d2r-en-main` 안에 선다.
 *
 * 셸은 `.d2r` 의 겉이라 판이 정의한 `--d2r-*` 를 물려받지 못한다 — 헤더·푸터가 쓰는 다섯만
 * 같은 값으로 여기도 둔다.
 */
.d2r-en-shell {
  display: flex;
  flex: 1 0 auto;
  flex-direction: column;
  --d2r-panel-strong: #101010;
  --d2r-line-strong: #49443a;
  --d2r-gold: #d8b45c;
  --d2r-text-muted: #aaaaaa;
  --d2r-text-dim: #777777;
  --text-caption: 0.875rem;
}

/*
 * `flex: 1` 이 먹으려면 셸까지 이어지는 마디마다 flex 여야 한다 — 몸(body flex column)과
 * 셸 사이에 `article.gb-plugin-page` 와 `.gb-body` 둘이 block 으로 끼어 있어, 둘을 같은 식으로
 * 잇는다. 이 화면들만 걸리도록 `:has(.d2r-en-shell)` 로 한정한다.
 */
.gb-plugin-page:has(> .gb-body > .d2r-en-shell),
.gb-plugin-page > .gb-body:has(> .d2r-en-shell) {
  display: flex;
  flex: 1 0 auto;
  flex-direction: column;
}

/* 레거시 `.container`(`global.scss:17`). 갈림점 `tablet-narrow`(700px)는 아래 블록이 맡는다. */
.d2r-en-container {
  width: min(calc(100% - 2rem), 1180px);
  margin-inline: auto;
}

@media (max-width: 43.75rem) {
  .d2r-en-container {
    width: min(calc(100% - 1rem), 1180px);
  }
}

.d2r-en-header {
  border-bottom: 1px solid var(--d2r-line-strong);
  background: var(--d2r-panel-strong);
}

.d2r-en-header-inner,
.d2r-en-footer-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 0.8rem;
}

.d2r-en-brand {
  color: var(--d2r-gold);
  font-weight: 600;
}

.d2r-en-main {
  flex: 1 0 auto;
  padding-block: 1.4rem 3rem;
}

/*
 * 판이 화면 끝까지 칠해지는 손은 `.d2r` 절의 음수 여백 그대로다 — 좌우 -1rem(폰 -.5rem)·
 * 아래 -3rem·패딩 1rem 은 `.board-body` 대신 이 본문의 여백(1.4rem·1rem·3rem)과 어긋남 없이
 * 맞는다. 다른 것은 위쪽 하나다 — `.board-body` 윗여백 1.5rem 을 메우던 -1.5rem 을
 * 레거시 값 -1.4rem(`items/index.vue:314`, `level-items.vue` 의 같은 줄)으로 고친다.
 */
.d2r-en-main > .d2r {
  margin-top: -1.4rem;
}

.d2r-en-footer {
  margin-top: 2rem;
  border-top: 1px solid var(--d2r-line-strong);
  background: var(--d2r-panel-strong);
}

.d2r-en-footer-inner {
  flex-wrap: wrap;
}

.d2r-en-footer nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
}

.d2r-en-footer a {
  color: var(--d2r-text-muted);
  font-size: var(--text-caption);
}

.d2r-en-footer p {
  margin: 0;
  color: var(--d2r-text-dim);
  font-size: var(--text-caption);
}

.d2r .rarity-unique,
.d2r .rarity-normal.rarity-unique {
  color: var(--d2r-unique);
}
.d2r .rarity-set {
  color: var(--d2r-set);
}
.d2r .rarity-runeword {
  color: var(--d2r-runeword);
}
.d2r .rarity-magic {
  color: var(--d2r-magic);
}
.d2r .rarity-rare {
  color: var(--d2r-rare);
}
.d2r .rarity-crafted {
  color: var(--d2r-crafted);
}

/* 나침반. 세 화면이 같은 것을 인다. */
/*
 * 스킨은 form 의 제출 단추를 강조색으로 칠한다 (styles.ts 의
 * `button[type="submit"]:not(.gb-link):not(.gb-reaction):not(.gb-danger)`, 특이도 0,4,1). 이 판에서 강조색은
 * 금색이라, 그대로 두면 등급·분류·정렬 칩이 전부 금색으로 칠해진 판이 된다. 디아블로 화면에 칠해진
 * 단추는 없다 — 고른 것만 금 테두리와 금 글씨로 선다. 그래서 스킨과 같은 :not 사슬을 한 단 위에서
 * 되돌린다. `.d2r` 를 두 번 적은 것은 특이도를 한 칸 올리는 것 말고 뜻이 없다.
 * 아래 d2r 단추 규칙들은 이 규칙보다 뒤에 서야 하고, 색을 다시 정할 때는 사슬을 같이 적는다.
 */
.d2r.d2r button:not(.gb-link):not(.gb-reaction):not(.gb-danger) {
  border-color: var(--d2r-line);
  background: var(--d2r-panel);
  color: var(--d2r-text-muted);
}

.d2r.d2r button:not(.gb-link):not(.gb-reaction):not(.gb-danger):hover {
  border-color: var(--d2r-line-gold);
  background: var(--d2r-panel);
  color: var(--d2r-gold);
  opacity: 1;
}

.d2r .d2r-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 1rem;
}

.d2r .d2r-nav a {
  padding: 0.45rem 0.7rem;
  border: 1px solid var(--d2r-line-strong);
  border-radius: 0.3rem;
  color: var(--d2r-text-muted);
}

/* 레거시는 vue-router 의 `.router-link-active` 를 쓴다. 여기는 스크립트가 없어 현재 화면을 `active` 클래스로 직접 표시한다(screen.tsx `Nav`). */
.d2r .d2r-nav a:hover,
.d2r .d2r-nav a.active {
  border-color: var(--d2r-line-gold);
  color: var(--d2r-gold);
}

/* 패치 번호는 지금 어느 판 자료인지가 곧 값이라, 나침반에서 혼자 금색으로 선다. */
.d2r .d2r-nav .patch {
  display: inline-flex;
  align-items: center;
  padding: 0.45rem 0.7rem;
  border: 1px solid var(--d2r-line-gold);
  border-radius: 0.3rem;
  background: var(--d2r-panel-subtle);
  color: var(--d2r-gold);
  font-size: var(--text-caption);
  font-weight: var(--weight-extrabold);
  white-space: nowrap;
}

.d2r .d2r-nav .locale {
  margin-left: auto;
}

/* ------------------------------------------------------------------ 목록 */

/* 머리는 가운데로 선다. 아이템 DB 는 글이 아니라 도구라, 제목이 자료의 문패 노릇을 한다. */
.d2r .page-head {
  text-align: center;
}

.d2r .page-head p {
  margin: 1rem 0 0.25rem;
  color: var(--d2r-gold-soft);
  font-size: var(--text-caption);
  font-weight: var(--weight-extrabold);
  letter-spacing: 0.16em;
}

/* 부제(`<span>`)는 원본에 표시 규칙이 없어 inline 으로 h1 아래 줄에 흐른다(16px/25.6 — 본문 값). */
.d2r .page-head span {
  margin: 0;
  color: var(--d2r-text);
  font-size: 1rem;
}

/* 제목 크기는 레거시 h1 의 `--text-page`(clamp 1.75~2.25rem, `_typography.scss:3`)다 — 고정 36 을 주면
 * 900px 처럼 3vw 가 그보다 작은 폭에서 머리가 10px 불었다. 굵기·줄높이는 같은 자리의 600·1.25. */
.d2r .page-head h1 {
  margin: 0;
  color: var(--d2r-gold);
  font-size: var(--text-page);
  font-weight: var(--weight-semibold);
  line-height: 1.25;
  text-shadow: 0 0 1rem var(--d2r-glow-gold);
}

/* 검색은 페이지 폭을 다 쓰지 않는다. 한 줄 물음이라 44rem 이면 충분하고, 가운데 서면 머리와 한 덩어리로 읽힌다. */
.d2r .gb-search {
  max-width: 44rem;
  margin: 1.2rem auto;
}

.d2r .gb-search label {
  display: block;
  margin-bottom: 0.35rem;
  color: var(--d2r-gold);
  font-size: var(--text-caption);
  font-weight: var(--weight-bold);
}

/* 칸과 단추는 한 몸이다 — 오른쪽 모서리만 단추가 잇고, 테두리는 1px 겹쳐 두 줄이 안 보인다. */
.d2r .search-control {
  position: relative;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: stretch;
  border-radius: 0.4rem;
}

/* 스킨은 입력 칸 높이를 2.25rem 으로 못박는다. 여기선 여백이 높이를 정해야 해서 풀고, 운영과 같은
 * 53px 을 최소 높이로 준다 — 단추는 stretch 라 같이 53 이 된다. */
.d2r .search-control input {
  grid-area: 1 / 1;
  min-width: 0;
  height: auto;
  min-height: 3.3125rem;
  padding: 0.78rem 2.4rem 0.78rem 0.85rem;
  border: 1px solid var(--d2r-line-gold);
  border-radius: 0.4rem 0 0 0.4rem;
  background: var(--d2r-panel);
  color: var(--d2r-text);
}

.d2r.d2r .search-control button:not(.gb-link):not(.gb-reaction):not(.gb-danger) {
  position: relative;
  grid-area: 1 / 2;
  margin-left: -1px;
  padding: 0.55rem 0.9rem;
  border: 1px solid var(--d2r-line-gold);
  border-radius: 0 0.4rem 0.4rem 0;
  background: var(--d2r-panel-subtle);
  color: var(--d2r-gold);
  font-weight: var(--weight-bold);
  cursor: pointer;
}

/* 운영 `_diablo.scss:68` — hover 에 면이 한 단계 밝아지고(panel-subtle → panel) 테두리가 금색이 된다. */
.d2r.d2r .search-control button:not(.gb-link):not(.gb-reaction):not(.gb-danger):hover {
  border-color: var(--d2r-gold);
  background: var(--d2r-panel);
  color: var(--d2r-gold-strong);
}

/* 지우기는 칸의 셋째 칸이 아니라 칸 위에 얹힌다 — 그래서 입력 칸 오른쪽 여백이 2.4rem 이다.
 * 입력·단추도 자리를 박아 둔다. 안 박으면 자리를 박은 지우기가 1열을 먼저 차지해 입력이 2열로, 단추가 아랫줄로 밀린다.
 * 누를 자리는 44px, 글자는 오른쪽에 붙인다. */
.d2r .search-clear {
  z-index: 1;
  grid-area: 1 / 1;
  align-self: center;
  justify-self: end;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  color: var(--d2r-text-muted);
}

.d2r .search-help {
  margin: 0.4rem 0 0;
  color: var(--d2r-text-dim);
  font-size: var(--text-caption);
}

.d2r .search-help strong {
  color: var(--d2r-gold);
}

/* 범위는 칩이 아니라 밑줄 탭이다. 둘 중 어디를 보고 있나가 한눈에 서야 한다. */
.d2r .scope-tabs {
  display: flex;
  justify-content: center;
  margin: 0;
  border-bottom: 1px solid var(--d2r-line);
}

.d2r .scope-tabs a {
  display: grid;
  place-items: center;
  min-width: 8rem;
  padding: 0.65rem;
  border: 0;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  background: none;
  color: var(--d2r-text-dim);
}

.d2r .scope-tabs a.active {
  border-bottom-color: var(--d2r-line-gold);
  color: var(--d2r-gold);
}

/*
 * 레벨별·시세 화면이 쓰는 칩 줄이다(목록 화면은 안 쓴다 — `.socket-filter`·`.gb-categories` 다른 단추를 쓴다).
 * `_filters.scss:29-33` 공통 값을 옮겼다.
 */
.d2r .filter-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
}

/*
 * 소켓 거르기는 원본에서 자기 테두리를 가진 판이다 — 등급 단추 밑에 떠 있는 상자 하나로 선다.
 * 버튼인 이유는 `plugins/d2r/src/screen.tsx` 머리에 적혀 있다 — 링크로 만들면 조건 조합이 전부
 * 크롤 대상이 된다.
 */
.d2r .socket-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  padding: 0.6rem 0.75rem;
  background: var(--d2r-panel);
  border: 1px solid var(--d2r-line);
  border-radius: 0.45rem;
}

.d2r .socket-filter strong {
  margin-right: 0.35rem;
  color: var(--d2r-gold-soft);
  font-size: var(--text-caption);
}

/*
 * 정렬 고르기. 원본은 `AppSelect` 드롭다운이다(`items/index.vue:77` 결과 머리, `:50` 폰 도구 줄;
 * 마크업·기본값은 `components/ui/AppSelect.vue:3-5,17-20`) — 「최신등록순 ⌄」 한 칸을 누르면
 * 항목 셋이 열린다. 스크립트 없는 `<details>` 로 같은 모양을 내고, 안의 폼이 `sort` 를 제출한다
 * (성지시세 `.compare-sort` 선례). 원본이 못 박은 폭은 결과 머리 쪽만 9.5rem 이다.
 */
.d2r .desktop-sort {
  width: 9.5rem;
  flex: 0 0 9.5rem;
}

/*
 * 트리거의 색은 운영의 디아블로 덮어쓰기다 — 결과 머리 `items/index.vue:314`
 * (`.result-head :deep(.select-trigger)`), 폰 도구 줄 `:336`(`.mobile-tools :deep(.select-trigger)`).
 * 높이·여백·flex 손은 위 공통 `.select-trigger` 가 이미 준다 — `min-width:12rem` 만 풀어
 * 원본 폭(9.5rem·내용만큼)이 산다.
 */
.d2r .select-trigger {
  min-width: 0;
  padding: 0.55rem 0.7rem;
  color: var(--d2r-text);
  background: var(--d2r-panel);
  border-color: var(--d2r-line-strong);
}

/*
 * 열린 판은 왼쪽 끝을 맞추고 색은 이 판 머리의 `--color-*` 다리를 쓴다 — `.d2r` 에서
 * `--color-surface` 는 #17120d, `--color-line` 은 금색 18% 다(원본 `_themes.scss:16-28`).
 * z-index 는 붙는 헤더(20) 위인 30. 나머지 치수는 위 공통 `.select[open] > .select-content` 가 준다.
 */
.d2r .select[open] > .select-content {
  left: 0;
  z-index: 30;
  border-color: var(--color-line);
  background: var(--color-surface);
  box-shadow: 0 14px 36px rgb(0 0 0 / 48%);
}

/*
 * 메뉴 항목(원본 `.select-item`, `AppSelect.vue:19`). `.d2r.d2r button:not(.gb-link)…`(0,5,1)이
 * 스킨의 단추 손을 되돌리는 규칙이라, 같은 사슬에 `.select-item` 을 얹어 한 단 위에서 쓴다 —
 * 안 그러면 패널 배경과 테두리가 씌워져 항목이 단추 행으로 보인다.
 */
.d2r.d2r .select-item:not(.gb-link):not(.gb-reaction):not(.gb-danger) {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 0.5rem 0.6rem;
  border: 0;
  border-radius: 0.3rem;
  background: transparent;
  color: var(--color-ink);
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.6;
  text-align: left;
  cursor: pointer;
}

/* 가리킨 항목. 원본 `.select-item[data-highlighted]`(`AppSelect.vue:20`)의 디아블로 값 — 이 판에서 `--color-brand-50` 은 #21190d, `--color-brand-700` 은 #f0cf78 다. */
.d2r.d2r .select-item:not(.gb-link):not(.gb-reaction):not(.gb-danger):hover,
.d2r.d2r .select-item:not(.gb-link):not(.gb-reaction):not(.gb-danger):focus-visible {
  background: var(--color-brand-50);
  color: var(--color-brand-700);
}

/* 등급 넷은 폭을 똑같이 나눈다. 고르는 것이 아니라 고를 것이 넷이라는 사실이 먼저 읽혀야 한다. */
.d2r .rarities {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.5rem;
  margin: 1rem 0;
}

.d2r .rarities button {
  display: grid;
  place-items: center;
  min-height: 3rem;
  border: 1px solid var(--d2r-line);
  border-radius: 0.55rem;
  background: var(--d2r-panel);
  color: var(--d2r-text-muted);
  cursor: pointer;
}

/*
 * 등급 단추는 등급색으로 말한다. 위에서 되돌린 회색을 여기서 등급색으로 다시 올린다 — 운영도 같은
 * 자리에서 같은 짓을 한다(`body.page-theme-diablo.page-theme-diablo .rarity-unique`).
 */
.d2r.d2r .rarities button.rarity-base:not(.gb-link):not(.gb-reaction):not(.gb-danger) { color: var(--d2r-base); }
.d2r.d2r .rarities button.rarity-unique:not(.gb-link):not(.gb-reaction):not(.gb-danger) { color: var(--d2r-unique); }
.d2r.d2r .rarities button.rarity-set:not(.gb-link):not(.gb-reaction):not(.gb-danger) { color: var(--d2r-set); }
.d2r.d2r .rarities button.rarity-runeword:not(.gb-link):not(.gb-reaction):not(.gb-danger) { color: var(--d2r-runeword); }
.d2r.d2r .rarities button.rarity-magic:not(.gb-link):not(.gb-reaction):not(.gb-danger) { color: var(--d2r-magic); }
.d2r.d2r .rarities button.rarity-rare:not(.gb-link):not(.gb-reaction):not(.gb-danger) { color: var(--d2r-rare); }
.d2r.d2r .rarities button.rarity-crafted:not(.gb-link):not(.gb-reaction):not(.gb-danger) { color: var(--d2r-crafted); }

/* 고른 등급은 칠하지 않는다. 테두리가 금색이 되고 판이 한 칸 떠오른다 — 운영과 같다. */
.d2r.d2r .rarities button:not(.gb-link):not(.gb-reaction):not(.gb-danger):hover,
.d2r.d2r .rarities button.active:not(.gb-link):not(.gb-reaction):not(.gb-danger) {
  border-color: var(--d2r-line-gold);
  background: var(--d2r-panel);
  box-shadow: 0 0.5rem 1.5rem var(--d2r-shadow);
  translate: 0 -1px;
}

/* 원본은 `.socket-filter button,.categories button` 을 한 규칙으로 묶는다. */
.d2r .socket-filter button {
  padding: 0.45rem 0.7rem;
  border: 1px solid var(--d2r-line);
  border-radius: 0.3rem;
  background: var(--d2r-panel);
  color: var(--d2r-text-muted);
  cursor: pointer;
}

/*
 * `_filters.scss:34-48` 공통 칩 값이다. `--color-*` 를 그대로 쓴다 — 머리의 `--color-*` 다리가
 * 운영 디아블로 판의 값(#aa9a73·#17120d·금색 18%)을 주므로 원본을 한 글자도 안 고친다.
 * 예전에 이걸 `--d2r-text-muted`(#aaa) 로 바꿔 놨었는데 그러면 칩만 회색으로 식어 보였다.
 */
.d2r .filter-chip {
  min-height: 2.35rem;
  padding: 0 0.9rem;
  border-radius: var(--radius-sm);
  font-size: var(--text-caption);
  font-weight: var(--weight-semibold);
  /* 원본은 줄높이를 따로 안 잡고 본문 값(1.6)을 물려받는다. 스킨은 단추에 1.3 을 걸어 놔서 다시 든다. */
  line-height: 1.6;
  cursor: pointer;
}

/*
 * 색만 따로, 그리고 특이도를 올려서 잡는다. 이 절 위쪽의
 * `.d2r.d2r button:not(.gb-link):not(.gb-reaction):not(.gb-danger)` 가 스킨의 단추 손을 이기려고 세워 둔
 * 규칙인데(0,5,1) 칩도 `<button>` 이라 같이 걸린다. `.d2r .filter-chip`(0,2,0) 으로는 못 이겨서
 * 칩이 회색으로 식었다. 운영엔 이런 규칙이 없다 — 스킨이 없으니 생길 이유가 없었다.
 */
.d2r.d2r .filter-chip:not(.gb-link):not(.gb-reaction):not(.gb-danger) {
  color: var(--color-muted);
  background: var(--color-surface);
  border: 1px solid var(--color-line);
}

.d2r.d2r .filter-chip:not(.gb-link):not(.gb-reaction):not(.gb-danger):hover {
  border-color: var(--color-brand-500);
  background: var(--color-surface);
  color: var(--color-brand-700);
}

.d2r.d2r .filter-chip:not(.gb-link):not(.gb-reaction):not(.gb-danger):focus-visible {
  outline: 2px solid var(--color-brand-500);
  outline-offset: 2px;
}

.d2r .filter-chip small {
  margin-left: 0.35rem;
  font-size: inherit;
  opacity: 0.65;
}

.d2r.d2r .socket-filter button.active:not(.gb-link):not(.gb-reaction):not(.gb-danger),
.d2r.d2r .gb-categories button.active:not(.gb-link):not(.gb-reaction):not(.gb-danger),
.d2r.d2r .filter-chip.active:not(.gb-link):not(.gb-reaction):not(.gb-danger) {
  border-color: var(--d2r-line-gold);
  background: var(--d2r-panel-subtle);
  color: var(--d2r-gold);
}

/* 고른 칩만 굵다(`_diablo.scss:71-76`). 스킨이 단추에 거는 굵기를 이기려고 특이도를 올렸다. */
.d2r.d2r .filter-chip.active:not(.gb-link):not(.gb-reaction) {
  font-weight: var(--weight-bold);
}

/*
 * 시세 화면 칩은 공통 칩 색이 아니라 자기 값이다 — `prices.vue:200` 이 글자
 * `--d2r-text-muted`(#aaa)·판 `none`·테두리 `--d2r-line-strong`(#49443a) 로 덮는다. 아래쪽
 * `.d2r-prices .filter-chip` 규칙이 같은 값을 들고 있지만 특이도(0,2,0)가 위쪽 `:not()` 사슬
 * (0,6,0)에 져서 못 쓰므로, 여기서 사슬을 하나 더 얹어 이긴다. 칩 안 `small` 은 글자색을
 * 물려받고 `opacity:.65`(`prices.vue:202`)라 색 규칙만 맞추면 운영과 같아진다.
 */
.d2r.d2r.d2r-prices .filter-chip:not(.gb-link):not(.gb-reaction):not(.gb-danger):not(.active) {
  color: var(--d2r-text-muted);
  background: none;
  border-color: var(--d2r-line-strong);
}

/*
 * hover 의 금색 두 개(`_filters.scss:45` 의 brand-500 선·brand-700 글자)는 그대로 두고 판만
 * 투명으로 되돌린다 — 운영은 scoped `background: none`(`prices.vue:200`)이 hover 에도 남는다.
 */
.d2r.d2r.d2r-prices .filter-chip:not(.gb-link):not(.gb-reaction):not(.gb-danger):not(.active):hover {
  background: none;
}

/*
 * 갈래 제목은 `prices.vue:207` 이 줄높이를 안 적어 h2 공통 1.35(`_typography.scss:4`)를 탄다 —
 * 20px×1.35=27px. 아래쪽 `.d2r .price-group h2` 의 1.3(26px)을 특이도 한 칸 올려 되돌린다.
 */
.d2r.d2r .price-group h2 {
  line-height: 1.35;
}

/* `.socket-filter` 자기 여백은 위 판 규칙에 없어 여기서 준다. `.rarities` 여백은 위 규칙(1rem)이 이미
 * 정했으니 여기서 다시 안 잡는다 — 값이 둘이면 나중 것(정의 안 된 토큰)이 이겨 깨진다. */
.d2r .socket-filter {
  margin: 0.8rem 0;
}

.d2r .filter-summary strong,
.d2r .filter-row strong {
  color: var(--d2r-text-dim);
  font-size: var(--text-caption);
  font-weight: var(--weight-normal);
}

/* `.filter-summary`·`.filter-reset` 은 원본 vue 에 없다 — 고른 조건을 한눈에 보여주는 우리 기능이다. */
.d2r .filter-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0.8rem 0;
  padding: 0.5rem 0.7rem;
  border: 1px solid var(--d2r-line);
  border-radius: 0.35rem;
  background: var(--d2r-panel);
}

.d2r .filter-summary > div {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}

.d2r .filter-summary a {
  padding: 0.25rem 0.5rem;
  border: 1px solid var(--d2r-line-strong);
  border-radius: 0.3rem;
  background: var(--d2r-panel-subtle);
  color: var(--d2r-text);
  font-size: var(--text-caption);
}

.d2r .filter-reset {
  margin-left: auto;
  color: var(--d2r-text-dim);
}

/*
 * 왼쪽 분류 레일. **모바일에서도 안 숨긴다** — 레거시는 여기를 감추고 바텀시트를 열었는데
 * 그건 자바스크립트다. 좁아지면 위로 접혀 올라간다.
 */
.d2r .content {
  display: grid;
  grid-template-columns: 14rem minmax(0, 1fr);
  gap: 1.2rem;
  margin-top: 1.1rem;
}

.d2r .content--sets {
  grid-template-columns: minmax(0, 1fr);
}

/*
 * 분류는 카드 한 장이다. 머리가 붙고 묶음 사이에 줄이 그어진다. 목록이 화면보다 길어서 스크롤을
 * 내려도 따라오게 붙여 두는데, 헤더 아래 0.75rem 에서 선다. 헤더가 물러나면 --app-header-offset 이
 * 0 이 돼 레일도 위로 붙고 높이가 늘어난다 — 운영과 같은 식이다
 * (`pages/diablo/items/index.vue:315-316`, 헤더 상태는 `--app-header-offset` 이 따라간다).
 */
.d2r .gb-categories {
  position: sticky;
  top: calc(var(--app-header-offset) + 0.75rem);
  align-self: start;
  min-width: 0;
  max-height: calc(100vh - var(--app-header-offset) - 1.5rem);
  transition: top 0.22s ease, max-height 0.22s ease;
  overflow: hidden auto;
  border: 1px solid var(--d2r-line);
  border-radius: 0.45rem;
  background: var(--d2r-panel);
  scrollbar-color: var(--d2r-panel-subtle) var(--d2r-panel);
}

.d2r .category-head {
  padding: 0.8rem;
  background: var(--d2r-panel);
  color: var(--d2r-gold);
  font-size: var(--text-meta);
  font-weight: var(--weight-extrabold);
}

.d2r .gb-categories form {
  display: block;
  margin: 0;
  padding: 0.65rem;
}

.d2r .gb-categories form + form {
  border-top: 1px solid var(--d2r-line);
}

.d2r .gb-categories h2 {
  margin: 0 0 0.35rem;
  color: var(--d2r-text-dim);
  font-size: var(--text-caption);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.09em;
}

/* 분류 단추는 칩이 아니라 목록 줄이다 — 한 줄에 하나, 왼쪽 정렬, 테두리는 고를 때만 보인다. */
.d2r.d2r .gb-categories button:not(.gb-link):not(.gb-reaction):not(.gb-danger) {
  display: block;
  width: 100%;
  margin: 0.12rem 0;
  padding: 0.45rem 0.7rem;
  border-color: transparent;
  border-radius: 0.3rem;
  background: var(--d2r-panel);
  /* 원본은 크기·줄높이를 안 잡아 본문 16px/1.6 이다 — 스킨 단추 기본(13px/20.8)이 들어가 높이가 37 에 머물던 것을 42 로 돌린다. */
  font-size: 1rem;
  font-weight: var(--weight-normal);
  line-height: 1.6;
  text-align: left;
}

/*
 * 고른 분류는 왼쪽에 금색 막대가 서고 오른쪽에 체크가 붙는다. 원본에는 이 손이 없다 — 목록이
 * 길어 색만으로는 눈에 안 걸려서 우리가 더한 표식이다.
 */
.d2r.d2r .gb-categories button.active:not(.gb-link):not(.gb-reaction):not(.gb-danger) {
  box-shadow: inset 3px 0 var(--d2r-gold);
  font-weight: var(--weight-extrabold);
}

.d2r .gb-categories button.active::after {
  float: right;
  color: var(--d2r-gold);
  content: "✓";
}

/* 폰 도구 줄은 760 이하에서만 선다(원본 `.mobile-tools{display:none}`) — 넓은 화면의 분류·정렬은 곁칸과 결과 머리가 맡는다. */
.d2r .mobile-tools {
  display: none;
}

/* 필터 시트는 `<details>` 가 여는 판이다 — 닫혀 있으면 summary 만 보이고 안쪽은 그려지지 않는다. */
.d2r .filter-pop > summary {
  list-style: none;
  cursor: pointer;
}

.d2r .filter-pop > summary::-webkit-details-marker {
  display: none;
}

/*
 * 원본 `index.vue` 의 `@include below(tablet)`(760px) 분기다. 곁칸과 데스크톱 정렬이 접히고
 * 도구 줄이 선다 — 필터 단추가 시트를 열고, 정렬은 같은 GET 폼이 한 벌 더 있다.
 */
@media (max-width: 47.5rem) {
  .d2r .content {
    grid-template-columns: 1fr;
    margin-top: 0.75rem;
  }

  .d2r .gb-categories,
  .d2r .desktop-sort {
    display: none;
  }

  .d2r .mobile-tools {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 0.8rem;
  }

  /* 단추는 `<summary>` 다 — `<button>` 이 아니라 details 의 손잡이라 스킨의 단추 손이 안 닿는다. */
  .d2r .mobile-filter-button {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.55rem 0.7rem;
    color: var(--d2r-gold);
    background: var(--d2r-panel);
    border: 1px solid var(--d2r-line-gold);
    border-radius: 0.35rem;
  }

  /* 고른 조건 개수 뱃지. */
  .d2r .mobile-filter-button span {
    display: grid;
    place-items: center;
    min-width: 1.2rem;
    height: 1.2rem;
    color: var(--d2r-gold-soft);
    background: var(--d2r-panel-subtle);
    border-radius: 99px;
    font-size: var(--text-caption);
    font-weight: var(--weight-extrabold);
  }

  /* 본 규칙이 결과 머리의 기본 `min-height:3.5rem` 보다 앞에 서서 `.d2r.d2r` 로 특이도를 올린다. */
  .d2r.d2r .result-head {
    min-height: auto;
  }

  /*
   * 열린 details 의 판은 화면 아래에서 올라오는 시트다(원본 `.filter-dialog`/`.filter-sheet`).
   * z-index 는 원본의 `--z-sheet`(60)다 — 붙어 있는 헤더(20) 위로 덮어야 한다.
   */
  .d2r .filter-dialog {
    position: fixed;
    z-index: 60;
    inset: 0;
    display: flex;
    align-items: flex-end;
    background: var(--d2r-shadow-strong);
  }

  .d2r .filter-sheet {
    width: 100%;
    max-height: 78vh;
    overflow: auto;
    padding: 1rem;
    background: var(--d2r-panel);
    border-top: 1px solid var(--d2r-line-gold);
    border-radius: 1rem 1rem 0 0;
    box-shadow: 0 -1rem 3rem var(--d2r-shadow-strong);
  }

  .d2r .filter-sheet > header {
    display: flex;
    align-items: start;
    justify-content: space-between;
    margin-bottom: 0.8rem;
  }

  /* 스킨의 h2·p 바깥 여백을 지운다 — 원본엔 없어 머리 높이가 닫기 단추 높이(44.8)가 된다. */
  .d2r .filter-sheet h2 {
    margin: 0;
    font-size: var(--text-body-lg);
  }

  .d2r .filter-sheet header p {
    margin: 0;
    color: var(--d2r-gold-soft);
    font-size: var(--text-caption);
  }

  /* 닫기는 같은 주소로의 링크다 — 다시 읽으면 details 는 닫힌 채 그려진다(스크립트 없는 닫기).
   * 폭 2.5rem 은 운영 실측(40×44.8)이다 — 원본 단추의 글리프가 이 폰트의 × 보다 넓다. */
  .d2r .filter-sheet header a {
    width: 2.5rem;
    padding: 0.2rem 0;
    color: var(--d2r-text-muted);
    font-size: var(--text-title);
    text-align: center;
    text-decoration: none;
  }

  .d2r .filter-sheet form {
    margin: 0;
    padding: 0.7rem 0;
    border-top: 1px solid var(--d2r-line);
  }

  .d2r .filter-sheet h3 {
    margin-bottom: 0.45rem;
    color: var(--d2r-text-dim);
    font-size: var(--text-caption);
    font-weight: var(--weight-semibold);
    letter-spacing: 0.08em;
  }

  .d2r .filter-sheet form > div {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.35rem;
  }

  .d2r.d2r .filter-sheet button:not(.gb-link):not(.gb-reaction):not(.gb-danger) {
    padding: 0.65rem;
    border: 1px solid var(--d2r-line);
    border-radius: 0.35rem;
    background: var(--d2r-panel);
    color: var(--d2r-text-muted);
    font-size: 1rem;
    font-weight: var(--weight-normal);
    line-height: 1.6;
    /* 스킨은 단추를 가운데 정렬 flex 로 둔다 — 원본은 왼쪽 정렬 블록이다. */
    justify-content: flex-start;
    text-align: left;
  }

  .d2r.d2r .filter-sheet button.active:not(.gb-link):not(.gb-reaction):not(.gb-danger) {
    color: var(--d2r-gold);
    border-color: var(--d2r-line-gold);
    background: var(--d2r-panel-subtle);
  }
}

/* 개수와 정렬은 한 줄에서 양 끝으로 벌어진다. 3.5rem 을 비워 두는 것은 정렬 단추가 들어와도 줄이 안 흔들리게 하는 것이다. */
.d2r .result-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  min-height: 3.5rem;
  margin-bottom: 0.65rem;
  color: var(--d2r-text-muted);
}

.d2r .result-head > div:first-child {
  flex: 1 1 0;
  min-width: 0;
}

.d2r .result-head p {
  margin: 0;
  color: inherit;
}

.d2r .result-head strong {
  color: var(--d2r-gold);
}

.d2r .none {
  padding: 4rem 1rem;
  color: var(--d2r-text-dim);
  background: var(--d2r-panel);
  border: 1px solid var(--d2r-line);
  border-radius: 0.4rem;
  text-align: center;
}

.d2r .none strong {
  color: var(--d2r-text-muted);
}

.d2r .none p {
  margin: 0.35rem 0 1rem;
  font-size: var(--text-meta);
}

/* 원본은 여기가 `<button>` 이다. 우리 마크업은 목록 초기화가 그냥 링크(`<a>`)라 값만 그대로 옮긴다. */
.d2r .none a {
  display: inline-block;
  padding: 0.5rem 0.8rem;
  color: var(--d2r-gold);
  background: transparent;
  border: 1px solid var(--d2r-line-gold);
  border-radius: 0.35rem;
}

/* ------------------------------------------------------------------ 카드 */

/* 아이템은 한 줄에 한 장이다. 옵션 줄이 카드의 셋째 칸을 통째로 쓰기 때문에, 두 장을 나란히 놓으면 그 줄이 먼저 접힌다. */
.d2r .grid {
  display: grid;
  gap: 0.65rem;
}

/*
 * 레벨별 화면만 다르다 — 그 카드는 세로로 서는 좁은 카드(`.item-card.compact`)라 한 줄에
 * 셋이 들어간다. 로컬은 이 줄도 한 장씩 그려 레벨 하나가 화면 한 판이었다.
 */
.d2r .level-row .grid {
  grid-template-columns: repeat(auto-fill, minmax(min(18rem, 100%), 1fr));
}

.d2r .level-row .grid .item-card {
  height: 100%;
}

/* 세트 목록은 원본 `items/index.vue:314` 처럼 정확히 두 열이다 — auto-fill 이라 1024 에서 네 칸이 됐다. */
.d2r .set-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.65rem;
}

/* 관련 아이템은 원본 `D2RRelatedItems.vue` 처럼 정확히 두 열이다 — 폰에서 한 열로 접는 것은 아래 47.5rem 분기. */
.d2r .related-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.65rem;
}

/* 카드 한 장이 세 칸이다 — 그림, 이름, 옵션. 이름 칸은 13~17rem 사이에서만 늘어나고 남는 폭은 옵션이 받는다. */
.d2r .item-card {
  position: relative;
  display: grid;
  grid-template-columns: 8.5rem minmax(13rem, 17rem) minmax(0, 1fr);
  gap: 1.15rem;
  min-height: 10.5rem;
  padding: 1rem 1.2rem;
  border: 1px solid var(--d2r-line-strong);
  border-radius: 0.45rem;
  background: var(--d2r-panel);
  transition: border-color 0.18s, background 0.18s;
}

.d2r .item-card:hover {
  border-color: var(--d2r-line-gold);
  background: var(--d2r-panel);
}

/* 카드 전체를 덮는 링크 한 장. 안에 링크를 여럿 두면 색인이 같은 주소를 여러 번 받는다. */
.d2r .card-link {
  position: absolute;
  z-index: 1;
  inset: 0;
}

.d2r .item-card .visual {
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 0.5rem;
  min-width: 0;
  border-right: 1px solid var(--d2r-line);
}

/* 룬 무리는 카드를 덮는 링크(위 `.card-link`, z-index 1)보다 위에 서야 한다 — 원본 그대로다. */
.d2r .item-card .runes {
  position: relative;
  z-index: 2;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.35rem;
}

.d2r .item-card .runes span {
  display: grid;
  justify-items: center;
  color: var(--d2r-gold);
}

/* 룬은 운영과 같은 28px 이다. 1.1rem(17.6px)으로는 어느 룬인지 분간이 안 된다(2026-09-16 확인). */
.d2r .item-card .runes img {
  width: 28px;
  height: 28px;
  object-fit: contain;
  image-rendering: pixelated;
}

/* 룬 이름을 안 지운다. 아이콘이 없는 룬이 있고 그때 남는 건 이 글자뿐이다. 색은 위 `.runes span` 의 금색을 물려받는다. */
.d2r .item-card .runes small {
  font-size: var(--text-caption);
}

/* 아이템 그림은 원본 그대로 78×104px 다 — 도트 그림이라 늘리면 흐려진다. 픽셀을 그대로 키운다. */
.d2r .item-card .item-image {
  width: 78px;
  height: 104px;
  object-fit: contain;
  image-rendering: pixelated;
}

.d2r .gb-identity {
  display: flex;
  min-width: 0;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  text-align: left;
}

.d2r .name-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.d2r .name-row h2 {
  margin: 0;
  font-size: var(--text-body-lg);
  line-height: 1.3;
}

/* 래더 전용 표식은 이름 옆 금색 테두리 칩이다. */
.d2r .name-row span {
  padding: 0.12rem 0.32rem;
  border: 1px solid var(--d2r-line-gold);
  border-radius: 0.2rem;
  color: var(--d2r-gold);
  font-size: var(--text-caption);
}

.d2r .name-en {
  margin: 0.15rem 0 0;
  color: var(--d2r-text-muted);
  font-size: var(--text-caption);
}

/* 어느 무기에 붙는 룬워드인지가 이 줄이다. 금색으로 서는 유일한 본문 줄이라 카드에서 먼저 읽힌다. */
.d2r .bases {
  margin: 0.5rem 0 0;
  color: var(--d2r-gold);
  font-size: var(--text-caption);
  line-height: 1.4;
}

.d2r .requirements {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 0.55rem;
  margin-top: 0.65rem;
  color: var(--d2r-text-muted);
  font-size: var(--text-caption);
}

/* 요구치는 쉼표가 아니라 가운뎃점으로 갈린다. */
.d2r .requirements span + span {
  position: relative;
  padding-left: 0.55rem;
}

.d2r .requirements span + span::before {
  position: absolute;
  left: 0;
  color: var(--d2r-gold-soft);
  content: '·';
}

.d2r .stat-groups {
  align-self: center;
  min-width: 0;
  text-align: left;
}

/*
 * 카드의 `.stats` 다. 상세 화면(`.detail-grid .stats`)도 같은 클래스를 쓰지만 레거시에서
 * 각자 컴포넌트 scoped 스타일이라 안 부딪혔다 — 우리는 시트가 하나라 `.item-card` 로 가른다.
 */
.d2r .item-card .stats {
  padding-left: 1rem;
  color: var(--d2r-stat);
  font-size: var(--text-meta);
  line-height: 1.5;
}

.d2r .item-card .stats li,
.d2r .piece-bonuses li {
  overflow-wrap: break-word;
}

/* 세트 조각 보너스 판. 위에 실선이 서고 이름 칸(5.5rem)과 목록 칸이 나란한 두 칸 표다 — 원본에 있던 판인데 우리 시트엔 빠져 있었다. */
.d2r .piece-bonuses {
  display: grid;
  gap: 0.35rem;
  margin-top: 0.65rem;
  padding-top: 0.65rem;
  border-top: 1px solid var(--d2r-line);
  font-size: var(--text-meta);
  line-height: 1.5;
}

.d2r .piece-bonuses > div {
  display: grid;
  grid-template-columns: 5.5rem minmax(0, 1fr);
  gap: 0.5rem;
}

.d2r .piece-bonuses strong {
  color: var(--d2r-text-muted);
}

.d2r .piece-bonuses ul {
  color: var(--d2r-set-bonus);
}

/* 아래 여백이 없는 게 원본(`D2RCard.vue` 의 `.set-count{margin-top:.6rem}`) — 스킨의 p 기본 아래 여백(12px)이 카드를 171.3 으로 키웠다. */
.d2r .set-count {
  margin: 0.6rem 0 0;
  color: var(--d2r-set-bonus);
  font-size: var(--text-caption);
}

/* 옵션 칸은 13rem 밑으로 못 내려간다. 그래서 960 아래는 세 칸을 두 칸으로 접고 옵션을 이름 밑으로 내린다. */
@media (max-width: 60rem) {
  .d2r .item-card:not(.compact) {
    grid-template-columns: 7rem minmax(0, 1fr);
  }

  .d2r .item-card:not(.compact) .stat-groups {
    grid-column: 2;
  }

  .d2r .item-card:not(.compact) .stats {
    padding-left: 0;
  }

  .d2r .item-card:not(.compact) .visual {
    grid-row: 1 / span 2;
  }

  .d2r .gb-identity {
    justify-content: start;
  }
}

@media (max-width: 37.5rem) {
  .d2r .item-card:not(.compact) {
    grid-template-columns: 5.5rem minmax(0, 1fr);
    gap: 0.75rem;
    min-height: auto;
    padding: 0.85rem;
  }

  .d2r .item-card:not(.compact) .visual {
    justify-content: start;
    border-right: 1px solid var(--d2r-line);
  }

  .d2r .item-card:not(.compact) .item-image {
    width: 58px;
    height: 76px;
  }

  .d2r .item-card:not(.compact) .runes img {
    width: 23px;
    height: 23px;
  }

  .d2r .item-card .stats {
    font-size: var(--text-caption);
  }
}

/*
 * 좁은 카드는 세로다 — 그림, 이름, 옵션이 위에서 아래로 선다. 로컬은 두 칸 격자에 옵션을
 * 아예 숨겼는데, 레벨별 화면에서 옵션은 그 레벨에 그 아이템을 드는 이유라 숨기면 카드에
 * 이름만 남는다. 운영은 최소 18rem 을 주고 셋을 다 싣는다.
 */
.d2r .item-card.compact {
  display: flex;
  min-height: 18rem;
  flex-direction: column;
  gap: 0.55rem;
  padding: 0.9rem;
}

.d2r .item-card.compact .visual {
  min-height: 5.2rem;
  border-right: 0;
  border-bottom: 1px solid var(--d2r-line);
}

.d2r .item-card.compact .item-image {
  width: 60px;
  height: 70px;
}

.d2r .item-card.compact .gb-identity {
  align-items: center;
  text-align: center;
}

.d2r .item-card.compact .name-row {
  justify-content: center;
}

.d2r .item-card.compact .requirements {
  justify-content: center;
  margin-top: 0.4rem;
}

.d2r .item-card.compact .stat-groups {
  align-self: stretch;
  text-align: center;
}

/* 가운데로 모은 줄에 점을 달면 점만 왼쪽 끝에 남는다. 운영도 좁은 카드에서만 점을 뗀다(원본 scss 엔 없고, 운영 계산 스타일 대조로 확인한 값). */
.d2r .item-card.compact .stats {
  padding: 0;
  list-style: none;
  font-size: var(--text-caption);
}

.d2r .item-card.compact .piece-bonuses {
  font-size: var(--text-caption);
}

.d2r .item-card.compact .piece-bonuses > div {
  grid-template-columns: 1fr;
}

/* 세트 요약 카드(조각 수만 보여줄 때, 옵션 없음)는 두 칸이다. 우리 시트엔 통째로 빠져 있었다. */
.d2r .item-card.set-summary {
  grid-template-columns: 7.5rem minmax(0, 1fr);
  min-height: 10.5rem;
}

.d2r .item-card.set-summary .gb-identity {
  align-items: flex-start;
}

.d2r .item-card.set-summary .item-image {
  width: 70px;
  height: 90px;
}

/* ------------------------------------------------------------------ 상세 */

.d2r.d2r-detail .back {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin: 0.8rem 0;
  color: var(--d2r-text-muted);
}

.d2r .detail-grid {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(16rem, 1fr);
  gap: 1rem;
  align-items: start;
}

/* 상세의 판 둘은 원본 값이다 — 1.5rem 여백, 0.5rem 둥근 모서리, 진한 테두리, 판 바탕(2026-09-16 운영 대조로 확인). */
.d2r .detail-grid > article,
.d2r .detail-grid > aside {
  padding: 1.5rem;
  border: 1px solid var(--d2r-line-strong);
  border-radius: 0.5rem;
  background: var(--d2r-panel);
}

.d2r .detail-grid > article {
  display: grid;
  grid-template-columns: 12rem minmax(0, 1fr);
  gap: 1.5rem;
}

/* `display: block` 은 레거시 `_reset.scss:6` 의 img 기본값이다 — inline 으로 두면 그림 아래 줄상자 틈(실측 7.6)이 생겨 `.visual`·article 이 커진다. */
.d2r .detail-grid .visual img {
  display: block;
  width: 100%;
  max-height: 16rem;
  object-fit: contain;
  image-rendering: pixelated;
}

.d2r .detail-grid .visual .runes {
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  margin-bottom: 0.7rem;
}

.d2r .detail-grid .visual .runes span {
  display: grid;
  justify-items: center;
  color: var(--d2r-gold);
  font-size: var(--text-caption);
}

/*
 * 룬 이름은 레거시 `_typography.scss` 의 `small { font-size: var(--text-caption) }` — 스킨은
 * `small` 에 더 작은 크기를 줘 룬 무리가 3.5px 낮아졌다(2026-09-17 실측 10.8px→13px).
 */
.d2r .detail-grid .visual .runes small {
  font-size: var(--text-caption);
}

.d2r .detail-grid .visual .runes img {
  width: 2rem;
  height: 2rem;
  object-fit: contain;
  image-rendering: pixelated;
}

.d2r .labels {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.d2r .labels span {
  padding: 0.15rem 0.4rem;
  border: 1px solid var(--d2r-line-gold);
  border-radius: 0.25rem;
  color: var(--d2r-gold);
  font-size: var(--text-caption);
}

/* 제목 아래 0.5rem 은 스킨 h1 기본값이다 — 레거시 `_reset.scss` 는 h1 여백이 0 이라 뗀다. 줄높이 1.25 는 `_typography.scss:3` 의 h1 값(스킨은 1.3 이라 36.4 로 나왔다 — 운영 35). */
.d2r.d2r-detail h1 {
  margin: 0;
  font-size: var(--text-title-lg);
  line-height: 1.25;
}

/* baseName·영문명·별칭 줄은 레거시에 전용 규칙이 없다 — `_reset.scss:8`(p 여백 0)과 본문 값(16px/1.6)을 그대로 받는다. */
.d2r .detail-grid > article > div > p:not(.base-types) {
  margin: 0;
}

/* 크래프트 가능 베이스 줄만 금색이다 — 원본 값. */
.d2r .base-types {
  margin-top: 0.8rem;
  color: var(--d2r-gold);
}

/*
 * 카드의 `.stats` 와 이름이 같지만 상세 전용이다(`.detail-grid` 안쪽으로 가른다). 옵션 목록엔
 * 위 여백도 줄 사이 여백도 없어야 하는데, 스킨의 기본 목록 여백이 살아 있으면 카드 쪽 높이가
 * 어긋난다 — 그래서 `ul.stats` 는 일단 0 으로 눕히고 상세만 원본 값(1rem)을 다시 올린다.
 */
.d2r ul.stats {
  margin: 0;
}

/* 줄머리 점도 들여쓰기도 없다 — 줄마다 알약이 붙는 목록이라 점이 있으면 줄이 어긋난다. */
.d2r .detail-grid .stats {
  margin-top: 1rem;
  padding-left: 0;
  color: var(--d2r-stat);
  line-height: 1.55;
  list-style: none;
}

/* 옵션 줄 끝의 「같은 옵션 보기」 알약(`D2RDetail.vue:31`). 여백은 아래 `li` 의 gap 이 준다. */
.d2r .option-link {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 0.25rem;
  min-height: 2rem;
  padding: 0.2rem 0.5rem;
  border: 1px solid var(--d2r-line-gold);
  border-radius: 99px;
  color: var(--d2r-gold-soft);
  font-size: var(--text-caption);
  white-space: nowrap;
}

.d2r .option-link:hover {
  background: var(--d2r-panel-subtle);
  color: var(--d2r-gold);
}

/* 알약이 줄 오른쪽 끝에 서야 옵션 글자와 안 엉킨다. */
.d2r .detail-grid .stats li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.d2r .base-stats {
  margin-bottom: 1rem;
  padding-bottom: 0.8rem;
  color: var(--d2r-stat);
  border-bottom: 1px solid var(--d2r-line);
  font-size: var(--text-meta);
  line-height: 1.6;
}

/*
 * aside 의 머리(「기본 정보」)와, 상세 페이지 바로 아래 오는 section 들(세트 보너스·변형·구성원)의
 * 머리가 같은 값이다. `> h2` 로 좁히는 이유: 레거시는 scoped 라 이 규칙이 자식 컴포넌트 안의 h2
 * (관련 아이템 머리·카드 이름)까지 닿지 않았다 — 후손 선택자로 두면 카드 이름에 0.8rem 이 붙어
 * 카드가 13px 커진다(2026-09-17 실측).
 */
.d2r .detail-grid > aside h2,
.d2r.d2r-detail > section > h2 {
  margin-bottom: 0.8rem;
  color: var(--d2r-gold);
  font-size: var(--text-body-lg);
  /* `_typography.scss:4` 의 h2 줄높이다 — 스킨 1.3(22.1)이면 운영 22.95 보다 낮다. */
  line-height: 1.35;
}

.d2r .detail-grid dl {
  margin: 0;
}

/* 원본은 flex space-between 이다 — dt 폭은 글자대로, dd 는 오른쪽 끝에 붙는다. 6rem 격자로 두면 긴 dt(영문명 등)가 두 줄로 접힌다. */
.d2r .detail-grid dl > div {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.48rem 0;
  border-top: 1px solid var(--d2r-line);
}

.d2r .detail-grid dt {
  color: var(--d2r-text-dim);
  /* 엔진의 dt 기본값(14px)을 누르고 본문 크기로 둔다 — 원본엔 전용 규칙이 없어 body 16px 이다. */
  font-size: var(--text-body);
}

.d2r .detail-grid dd {
  margin: 0;
  color: var(--d2r-text);
  text-align: right;
}

.d2r .set-link {
  display: block;
  margin-top: 1rem;
  padding: 0.65rem;
  color: var(--d2r-gold);
  border: 1px solid var(--d2r-line-gold);
  border-radius: 0.35rem;
  text-align: center;
}

/* 상세의 절(관련 아이템·세트 보너스·변형·구성원)은 위의 판 둘과 같은 표면이다 — 원본 `.d2r-detail > section` 이 같은 규칙에 묶여 있다. */
.d2r.d2r-detail > section {
  margin-top: 1rem;
  padding: 1.5rem;
  border: 1px solid var(--d2r-line-strong);
  border-radius: 0.5rem;
  background: var(--d2r-panel);
}

.d2r .set-bonuses > div,
.d2r .variants > div {
  display: grid;
  padding: 0.65rem 0;
  border-top: 1px solid var(--d2r-line);
}

.d2r .set-bonuses > div {
  grid-template-columns: 8rem minmax(0, 1fr);
}

.d2r .variants > div {
  grid-template-columns: 7rem minmax(0, 1fr);
}

.d2r .variants strong {
  color: var(--d2r-gold);
}

.d2r .set-bonuses li {
  color: var(--d2r-set-bonus);
}

.d2r .variants li {
  color: var(--d2r-stat);
}

.d2r .members {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.75rem;
}

/* 거래 정보. 레거시 `D2RTradeInfo.vue` — 접기(`.toggle`)만 `<details>` 로 바뀌었다. */
/*
 * 거래 정보는 아이템 머리와 옵션 줄 사이에 끼는 칸이라 상자로 묶는다. 상자가 없으면 큰 제목 밑
 * 구분선과 「전체 보기」 단추 뒤의 옵션 줄까지 한 덩어리로 읽혀, 어디까지가 거래 정보인지 안 보였다.
 */
.d2r .trade-info {
  margin: 1rem 0;
  padding: 0.75rem 0.9rem 0.85rem;
  background: var(--d2r-panel-subtle);
  border: 1px solid var(--d2r-line);
  border-radius: 0.4rem;
}

.d2r .trade-info > h2 {
  margin: 0 0 0.35rem;
  color: var(--d2r-text-muted);
  font-size: var(--text-meta);
  font-weight: 600;
}

.d2r .trade-info > h2 + .entry,
.d2r .trade-info > .shared + .entry {
  padding-top: 0;
  border-top: 0;
}

.d2r .trade-info .shared {
  margin-bottom: 0.5rem;
  color: var(--d2r-text-muted);
  font-size: var(--text-caption);
}

.d2r .trade-info .entry {
  padding: 0.45rem 0;
  border-top: 1px solid var(--d2r-line);
}

.d2r .trade-info .entry-label {
  display: block;
  color: var(--d2r-text);
}

.d2r .trade-info .gb-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin-top: 0.3rem;
}

.d2r .trade-info .rule,
.d2r .trade-info .note {
  margin-top: 0.3rem;
  color: var(--d2r-text-muted);
  font-size: var(--text-caption);
  line-height: 1.5;
}

/* 레거시는 자바스크립트 토글 단추다. 여기는 `<details>` 라 여는 것은 기본 `summary` 가 한다 — 값은 원본 `.toggle`. */
.d2r .trade-info summary {
  margin-top: 0.6rem;
  padding: 0.45rem;
  color: var(--d2r-text-muted);
  border: 1px solid var(--d2r-line);
  border-radius: 0.3rem;
  cursor: pointer;
}

.d2r .trade-info summary:hover {
  color: var(--d2r-gold);
  border-color: var(--d2r-line-gold);
}

.d2r .trade-info .gb-more {
  display: block;
  margin-top: 0.7rem;
  padding: 0.55rem;
  color: var(--d2r-gold);
  border: 1px solid var(--d2r-line-gold);
  border-radius: 0.35rem;
  text-align: center;
}

/*
 * 꼬리표는 테두리를 글자색으로 받는다(`border: 1px solid currentcolor`). 그래서 아래가 색을
 * 하나씩만 든다. `.gb-tag.late`·`.cond`·`.cash`·`.market-*` 색은 시세 신호고 등급 색과 다른
 * 계열이다 — 값은 원본 그대로(카드 옵션 색 `--d2r-stat` 과 우연히 비슷하지만 다른 색이다).
 */
.d2r .gb-tag {
  padding: 0.05rem 0.35rem;
  border: 1px solid currentcolor;
  border-radius: 0.2rem;
  font-size: var(--text-caption);
  /*
   * 스킨의 `.gb-tag` 는 글 태그용 알약이다 — `min-height: 1.8125rem`, `border: 0`,
   * `border-radius: 999px`, 그리고 밝은 바탕(`--board-notice` #edf8f5)에 강조색 글자.
   * 여기 꼬리표는 테두리를 글자색으로 받는 얇은 상자라 그 셋을 되돌린다. 안 되돌리면
   * 어두운 판 위에 흰 알약이 서고 높이가 24px 대신 29px 이 된다.
   */
  min-height: 0;
  background: transparent;
  color: inherit;
}

.d2r .gb-tag.early {
  color: var(--d2r-gold);
}

.d2r .gb-tag.late {
  color: #7aa7ff;
}

.d2r .gb-tag.cond {
  color: var(--d2r-cond);
}

.d2r .gb-tag.cash {
  color: #6fcf97;
}

.d2r .gb-tag.market-low {
  color: #999;
}

.d2r .gb-tag.market-high {
  color: var(--d2r-market-high);
}

.d2r .gb-tag.market-top {
  color: var(--d2r-market-top);
}

/* 시세 화면의 「일반 시세」 태그 — 원본 `prices.vue` 에만 있고 다른 곳은 안 쓴다. */
.d2r .gb-tag.market {
  color: var(--d2r-text-muted);
}

.d2r .related-items header {
  display: flex;
  align-items: start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.8rem;
}

/*
 * 이 h2 는 레거시에서 별도 컴포넌트(`D2RRelatedItems.vue`) 안이라 상세의 `section h2` 규칙이
 * 안 닿고 전역 h2 값(`_typography.scss`: `--text-section`·1.35, `_reset.scss` margin 0)을
 * 받았다 — 우리 시트는 하나라 그 값을 여기서 다시 선언한다.
 */
.d2r .related-items header h2 {
  margin: 0;
  font-size: var(--text-section);
  font-weight: var(--weight-semibold);
  line-height: 1.35;
}

.d2r .related-items header p {
  margin: 0;
  color: var(--d2r-text-dim);
  font-size: var(--text-meta);
}

.d2r .related-items header > a {
  flex: none;
  padding: 0.35rem 0.55rem;
  color: var(--d2r-gold-soft);
  border: 1px solid var(--d2r-line-gold);
  border-radius: 0.35rem;
  font-size: var(--text-caption);
}

/* 룬워드 ↔ 베이스. 양쪽 다 한 화면에 수백 줄이라 `<details>` 안에서 연다. */
.d2r .runeword-bases {
  margin-top: 1rem;
  background: var(--d2r-panel);
  border: 1px solid var(--d2r-line-strong);
  border-radius: 0.5rem;
}

.d2r .runeword-bases summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 1.25rem;
  color: var(--d2r-gold);
  font-weight: var(--weight-bold);
  cursor: pointer;
}

.d2r .runeword-bases summary small {
  color: var(--d2r-gold-soft);
  font-weight: var(--weight-normal);
}

.d2r .base-content {
  display: grid;
  gap: 1.2rem;
  padding: 0 1.25rem 1.25rem;
  border-top: 1px solid var(--d2r-line);
}

.d2r .base-content section {
  padding-top: 1.1rem;
}

.d2r .base-content h3 {
  margin-bottom: 0.55rem;
  color: var(--d2r-gold);
  font-size: var(--text-meta);
}

.d2r .tier-head,
.d2r .family {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.5rem;
}

.d2r .tier-head {
  padding: 0.35rem 0.5rem;
  color: var(--d2r-text-dim);
  font-size: var(--text-caption);
  text-align: center;
}

.d2r .family + .family {
  margin-top: 0.45rem;
}

.d2r .base {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  min-height: 4.2rem;
  padding: 0.5rem;
  color: var(--d2r-text);
  background: var(--d2r-panel);
  border: 1px solid var(--d2r-line);
  border-radius: 0.35rem;
}

.d2r .base:not(.gb-empty):hover {
  border-color: var(--d2r-line-gold);
}

.d2r .base img {
  width: 2.5rem;
  height: 3rem;
  flex: 0 0 2.5rem;
  object-fit: contain;
  image-rendering: pixelated;
}

.d2r .base > span:not(.mobile-tier) {
  display: grid;
  min-width: 0;
}

.d2r .base strong {
  font-size: var(--text-meta);
  font-weight: var(--weight-normal);
  line-height: 1.3;
}

.d2r .base small {
  margin-top: 0.15rem;
  color: var(--d2r-text-dim);
  font-size: var(--text-caption);
  line-height: 1.3;
}

.d2r .base.base-empty {
  justify-content: center;
  color: var(--d2r-text-dim);
  pointer-events: none;
}

/* 계층 이름은 넓은 화면에서 표 머리가 대신한다. 좁아지면 칸마다 다시 붙는다. */
.d2r .mobile-tier {
  display: none;
}

/* `.base-runewords` 는 자기 h2 를 금색·meta 크기로 따로 잡는다 — 위 aside/section 공통 규칙(body-lg)보다 늦게 서야 이긴다. */
.d2r .base-runewords {
  margin-top: 1rem;
  padding: 1.1rem 1.25rem 1.25rem;
  background: var(--d2r-panel);
  border: 1px solid var(--d2r-line-strong);
  border-radius: 0.5rem;
}

.d2r .base-runewords > header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.9rem;
}

.d2r .base-runewords > header h2 {
  margin: 0;
  color: var(--d2r-gold);
  font-size: var(--text-meta);
}

.d2r .base-runewords > header small {
  color: var(--d2r-gold-soft);
  font-size: var(--text-caption);
}

.d2r .socket-group + .socket-group {
  margin-top: 1rem;
}

.d2r .socket-group h3 {
  margin-bottom: 0.5rem;
  color: var(--d2r-text-dim);
  font-size: var(--text-caption);
}

.d2r .runeword-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 0.55rem;
}

.d2r .runeword {
  display: grid;
  gap: 0.3rem;
  padding: 0.6rem 0.7rem;
  color: var(--d2r-text);
  background: var(--d2r-panel-strong);
  border: 1px solid var(--d2r-line);
  border-radius: 0.35rem;
}

.d2r a.runeword:hover {
  border-color: var(--d2r-line-gold);
}

.d2r .runeword strong {
  color: var(--d2r-runeword);
  font-size: var(--text-meta);
  font-weight: var(--weight-normal);
  line-height: 1.3;
}

.d2r .runeword .runes {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem;
}

.d2r .runeword .runes img {
  width: 1.15rem;
  height: 1.15rem;
  object-fit: contain;
  image-rendering: pixelated;
}

.d2r .runeword small {
  color: var(--d2r-text-dim);
  font-size: var(--text-caption);
  line-height: 1.3;
}

/* --------------------------------------------------------------- 레벨별 */

/*
 * 원본 `.levels` 의 풀블리드 래퍼(`min-height:70vh; margin:-1.4rem -1rem -3rem; ...`)는 안
 * 옮긴다 — 우리 페이지는 스킨 본문 안에 들어가 바깥 여백이 다르다(`.d2r-detail` 도 같다).
 */

/*
 * 머리는 한 줄에 제목과 부제, 그 아래 금색 선 하나다. 로컬은 선이 없고 제목이 26px/700 이라
 * 바로 아래 칩 판과 같은 층으로 읽혔다. 운영 값은 금색 28px/600 이다.
 */
.d2r-levels .level-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 0;
  padding: 1rem 0 0.8rem;
  border-bottom: 1px solid var(--d2r-line-gold);
}

.d2r-levels .level-toolbar h1 {
  margin: 0;
  color: var(--d2r-gold);
  font-size: 1.75rem;
  font-weight: 600;
  line-height: 1.25;
}

.d2r-levels .level-toolbar p {
  margin: 0.25rem 0 0;
  color: var(--d2r-text-dim);
  font-size: var(--text-meta);
  line-height: 1.6;
}

/*
 * 거르는 판은 카드다 — 줄 넷을 두 칸에 나눠 담고 판 색과 밝은 테두리를 두른다. 로컬은
 * 테두리만 있는 한 칸이라 줄 넷이 200px 을 먹었다(운영은 106px). 머리에 붙어 따라오는 것도
 * 운영과 같다 — 스킨 머리띠가 `sticky` 라 그 높이(`styles.ts:212` 의 4rem)만큼 내려 둔다.
 */
.d2r .filter-panel {
  position: sticky;
  z-index: var(--z-raised);
  top: var(--app-header-offset);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: min-content;
  align-items: start;
  gap: 0.55rem 1.25rem;
  margin-bottom: 0.5rem;
  padding: 0.8rem !important;
  color: var(--d2r-text) !important;
  background: var(--d2r-panel) !important;
  border: 1px solid var(--d2r-line-strong) !important;
  backdrop-filter: blur(8px);
  transition: top 0.22s ease;
}

/*
 * 넓은 화면에선 판이 늘 펼쳐져 있고 토글은 안 보인다(원본 `level-items.vue:175` 의
 * `.filter-toggle{display:none}`). 마크업은 닫힌 `<details>` 인데, 닫힌 details 는 내용을
 * `::details-content` 에 `content-visibility: hidden` 으로 숨기므로 여기서 다시 보이게 한다.
 * `.level-head`·`.level-filters` 의 상자도 지운다 — 남아 있으면 판의 `position: sticky` 가
 * 짧은 부모 안에 갇혀 머리에 붙어 따라오지 못한다.
 */
@media (min-width: 800.02px) {
  .d2r-levels .level-head,
  .d2r-levels .level-filters {
    display: contents;
  }

  .d2r-levels .level-filters::details-content {
    content-visibility: visible;
  }
}

/*
 * `::details-content` 를 모르는 브라우저에선 위 규칙이 무시돼 판이 닫힌 채 남는다 — 그때는
 * 토글을 데스크톱에도 남겨 똑같이 열게 한다. 지원하면 판이 늘 열려 있으니 토글을 숨긴다.
 */
@supports selector(details::details-content) {
  @media (min-width: 800.02px) {
    .d2r-levels .level-filters > summary {
      display: none;
    }
  }
}

/* 이름과 칩이 두 칸이다. 이름 칸을 고정해 두면 줄 넷의 칩이 같은 자리에서 시작한다. */
.d2r .filter-row {
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 1fr);
  align-items: center;
  gap: 1rem;
}

.d2r .filter-row > strong {
  color: var(--d2r-gold-soft);
  font-size: var(--text-caption);
  white-space: nowrap;
}

/* 판 안의 레벨별 칩은 한 치수 작다 — 줄이 넷이라 그만큼이 판 높이로 곱해진다. */
.d2r-levels .filter-chip {
  min-width: 2.2rem;
  min-height: 2.1rem;
  padding: 0.38rem 0.58rem;
  flex: 0 0 auto;
}

/* 레벨 점프 줄은 옆으로 민다 — 서른 칸이 넘어 접으면 판이 화면을 다 먹는다. */
.d2r-levels .jumps {
  overflow-x: auto;
}

/* 한 줄 안의 칩은 안 접고 옆으로 민다 — 레벨 점프는 서른 칸이 넘어 접으면 판이 화면을 다 먹는다. */
.d2r .filter-row .filter-chips {
  flex-wrap: nowrap;
  gap: 0.3rem;
  overflow-x: auto;
}

/* 점프 칸이 `#level-NN` 로 떨어진다. 머리에 여백을 두지 않으면 줄이 가장자리에 붙는다. */
.d2r .level-row {
  scroll-margin-top: calc(var(--app-header-offset) + 6rem);
  display: grid;
  grid-template-columns: 4.8rem minmax(0, 1fr);
  gap: 1rem;
  padding-top: 1.4rem;
}

/*
 * 레벨은 금색 명패다 — 줄 위에 얹혀 따라오고, 카드가 몇 장이든 위에서 4.5rem 만 쓴다. 로컬은
 * 흐린 회색 띠가 줄 전체 높이로 늘어나 어느 줄이 어느 레벨인지 훑기 어려웠다.
 */
.d2r .level {
  position: sticky;
  top: calc(var(--app-header-offset) + 6rem);
  align-self: start;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 4.5rem;
  border: 1px solid var(--d2r-line-gold);
  background: var(--d2r-panel);
  box-shadow: inset 0 0 1rem var(--d2r-glow-gold);
  color: var(--d2r-gold);
  transition: top 0.22s ease;
}

.d2r .level small {
  color: var(--d2r-text-dim);
  font-size: var(--text-caption);
  line-height: 1.6;
}

.d2r .level strong {
  color: var(--d2r-gold);
  font-size: 1.75rem;
  line-height: 1;
}

.d2r .rail-wrap {
  min-width: 0;
  padding: 2px;
}

.d2r .empty-state {
  padding: var(--nr-space-7) var(--nr-space-4);
  border: 1px dashed var(--nr-line);
  border-radius: 0.45rem;
  color: var(--nr-dim);
  text-align: center;
}

/* ----------------------------------------------------------------- 시세 */

/*
 * 머리 셋은 운영 값이다 — 제목이 금색 36px(`--text-page`), 부제는 안 흐린 본문 16px, 패치 줄만
 * 작고 흐리다. 로컬은 셋 다 한 단계씩 작고 부제까지 흐려서, 제목이 아래 표의 첫 줄처럼 읽혔다.
 */
.d2r-prices .prices-head {
  margin-bottom: 1rem;
}

.d2r-prices .prices-head h1 {
  margin: 0;
  color: var(--d2r-gold);
  font-size: clamp(1.75rem, 3vw, 2.25rem);
  font-weight: 600;
  line-height: 1.25;
}

.d2r-prices .prices-head p {
  margin: 0.35rem 0 0;
  color: var(--d2r-text);
  font-size: var(--text-body);
  line-height: 1.6;
}

.d2r-prices .prices-head small {
  display: block;
  margin-top: 0.35rem;
  color: var(--d2r-text-muted);
  font-size: var(--text-caption);
  line-height: 1.6;
}

/*
 * 범례는 판에 담는다. 원본 마크업이 `<AppSurface class="legend">`(`prices.vue:10`) 라
 * 판 값은 그 컴포넌트가 주고 `.legend` 규칙엔 색이 없다 — 우리는 맨 `div` 라 여기서 준다.
 * 값은 운영 실측(#17120d · 금색 18%)이고 곧 `--color-surface`·`--color-line` 이다.
 */
.d2r .legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 1.4rem;
  margin: 0 0 1rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--color-line);
  background: var(--color-surface);
  color: var(--d2r-text-muted);
  font-size: var(--text-caption);
  line-height: 1.6;
}

.d2r .legend span {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

/*
 * 점 다섯의 색은 운영 값이고, 아래 꼬리표(`.gb-tag`)와 짝이다. 로컬은 초반을 초록, 후반과
 * 상급을 둘 다 금색으로 써서 범례에 같은 색 점이 두 개 있었다 — 색이 뜻을 나르는 자리에서
 * 그건 범례가 아니다.
 */
.d2r .dot {
  display: inline-block;
  flex: 0 0 auto;
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 50%;
  background: var(--d2r-text-muted);
}

.d2r .dot.early {
  background: var(--d2r-gold);
}

.d2r .dot.late {
  background: var(--d2r-stat);
}

.d2r .dot.cond {
  background: var(--d2r-cond);
}

.d2r .dot.low {
  background: #999999;
}

.d2r .dot.top {
  background: var(--d2r-market-top);
}

/* 시세 화면은 칩 줄을 공통 값이 아니라 자기 값으로 완전히 덮는다 — 원본이 그렇다. */
.d2r-prices .filter-chips {
  gap: 0.4rem;
  margin-bottom: 0.55rem;
}

/*
 * 여기 칩은 패딩·색·테두리만 다시 잡는다. 최소 높이(2.35rem)는 **공통 칩 값 그대로 남는다** —
 * `prices.vue:200` 은 높이를 안 적는데 그건 안 준다는 뜻이 아니라 `_filters.scss` 값을
 * 물려받는다는 뜻이다. 예전에 이걸 「안 준다」로 읽고 `min-height: 0` 을 넣어 칩이 운영보다
 * 2px 낮았다(35.6 vs 37.6).
 */
.d2r-prices .filter-chip {
  padding: 0.4rem 0.7rem;
  color: var(--d2r-text-muted);
  background: none;
  border: 1px solid var(--d2r-line-strong);
  border-radius: 0.3rem;
}
/* 고른 칩 값(테두리·판 금색)은 위쪽 공통 `.filter-chip.active` 규칙이 이미 준다 — 여기서 또 안 잡는다. */

/* 아이템 한 줄의 태그 묶음. */
.d2r-prices .gb-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin-top: 0.25rem;
}

/*
 * 「저가 포함」은 칩 줄의 오른쪽 끝이다(운영 `.low-toggle { margin-left: auto }`). 운영은 칩과
 * 스위치가 한 폼인데 이쪽은 보내는 값이 달라 폼이 둘이라, 줄을 하나 만들어 둘을 담는다.
 * 좁은 화면에서는 줄을 바꿔 왼쪽에 붙는다.
 */
.d2r .price-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 0.55rem;
}

/*
 * 보내는 값이 달라 폼은 둘이지만 상자를 지우면(`display: contents`) 단추들이 위 줄의 칩으로
 * 직접 선다 — 운영의 한 `.filter-chips` 와 같은 나열이 된다. 폼 자기 margin 이 남아 줄 높이를
 * 밀던 것도 이걸로 사라진다.
 */
.d2r .price-filters > form {
  display: contents;
}

/* 「저가 포함」은 칩 줄의 오른쪽 끝이다(운영 `.low-toggle { margin-left: auto }`). */
.d2r .price-filters .low-toggle {
  margin-left: auto;
}

.d2r .low-hidden-note {
  margin: 0 0 1.5rem;
  color: var(--d2r-text-muted);
  font-size: var(--text-caption);
  line-height: 1.6;
}

/* 갈래 제목은 금색에 밑줄 한 줄이다. 로컬은 줄이 없어 아래 작은 제목과 같은 층으로 보였다. */
.d2r .price-group {
  margin-bottom: 2rem;
}

.d2r .price-group h2 {
  margin: 0;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--d2r-line-strong);
  color: var(--d2r-gold);
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 1.3;
}

.d2r .group-note {
  margin: 0.6rem 0;
  color: var(--d2r-text-muted);
  font-size: var(--text-caption);
  line-height: 1.6;
}

.d2r .section-title {
  margin: 1rem 0 0.55rem;
  color: var(--d2r-text-muted);
  font-size: var(--text-meta);
  /* `h3` 다. 원본은 굵기를 안 잡고 공통 제목 값(600)을 받는데 스킨은 700 을 건다. */
  font-weight: var(--weight-semibold);
  /* 원본은 줄높이도 안 잡는다 — 공통 `h3` 값 1.4 다(`_typography.scss`). 스킨은 1.3 을 건다. */
  line-height: 1.4;
}

.d2r .price-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 0.5rem;
  margin: 0.6rem 0 0;
  padding: 0;
  list-style: none;
}

.d2r .price-grid.wide {
  grid-template-columns: repeat(auto-fill, minmax(21rem, 1fr));
}

.d2r .price-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--d2r-line);
  border-radius: 0.35rem;
  background: var(--d2r-panel);
  transition: border-color 0.18s;
}

.d2r .price-item:hover {
  border-color: var(--d2r-line-gold);
}

.d2r .price-item .hit {
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
}

/*
 * 스프라이트는 원래 크기가 작아 늘리면 뭉갠다. 운영은 34x40 에 `pixelated` 로 못을 박아 둔다 —
 * 도트 그림은 흐리게 늘리는 것보다 계단이 보이는 게 낫다.
 */
.d2r .price-item .gb-icon {
  width: 34px;
  height: 40px;
  flex: 0 0 auto;
  object-fit: contain;
  image-rendering: pixelated;
}

.d2r .price-item .gb-body {
  min-width: 0;
}

.d2r .price-item .name {
  display: block;
  line-height: 1.35;
  overflow-wrap: break-word;
}

/* 시세 규칙은 금색, 메모는 흐린 색. 둘 다 이름 아래 한 칸이다. */
.d2r .price-item .market-note,
.d2r .price-item .note {
  display: block;
  margin-top: 0.25rem;
  font-size: var(--text-caption);
  line-height: 1.4;
}

.d2r .price-item .market-note {
  color: var(--d2r-gold);
}

.d2r .price-item .note {
  color: var(--d2r-text-muted);
}

/* ------------------------------------------------------------- 좁은 화면 */

/* 목록 `.content` 는 60rem 에서 접지 않는다 — 원본 `index.vue` 는 760(`below(tablet)`) 이하에서만 한
 * 칸이 되고, 그 위에서는 14rem 곁칸이 남는다. 접히는 자리는 위쪽 47.5rem 판이다. */

/*
 * 원본 `level-items.vue` 의 `@include below(tablet-wide)`(800px) 분기다. 전에는 눈으로 잰
 * 40rem(640px) 이었다 — 원본 폭으로 바꿨다.
 */
@media (max-width: 800px) {
  /*
   * `_filters.scss:75` 의 `below(tablet-wide)`(800px) 분기다 — 이 폭에서 칩이 한 치수
   * 작아진다(높이 2.35→2.1rem, 줄높이 본문 1.6→1.3). 원본의 `padding:.25rem .4rem` 은
   * prices.vue 가 자기 칩 값(.4rem .7rem)으로 이기므로 여기서도 위쪽 `.d2r-prices .filter-chip`
   * 값이 그대로 선다.
   */
  .d2r-prices .filter-chip {
    min-width: 0;
    min-height: 2.1rem;
    line-height: 1.3;
    white-space: normal;
  }

  /*
   * 좁으면 판이 접힌다 — 원본 `level-items.vue:6,42,180` 의 `filter-toggle` 과
   * `filter-panel.open` 을 `details`/`summary` 로 옮겼다(스크립트 없음). details 의 상자를
   * 지우면(`display: contents`) 토글과 판이 `.level-head` 의 flex 줄에 직접 선다: 첫 줄은
   * 제목+토글이고, 열린 판은 다음 줄 전체 폭을 쓴다. 원본도 이 폭에서 판을 접고 단추로 연다 —
   * 조건이 걸린 주소도 처음엔 닫혀 있다(`filtersOpen = ref(false)`).
   */
  .d2r-levels .level-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    border-bottom: 1px solid var(--d2r-line-gold);
  }

  .d2r-levels .level-head .level-toolbar {
    flex: 1;
    min-width: 0;
    border-bottom: none;
  }

  .d2r-levels .level-filters {
    display: contents;
  }

  /* 토글 모양은 원본 `.filter-toggle`(`level-items.vue:175,180`) 그대로다. */
  .d2r-levels .filter-toggle {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    flex: none;
    min-height: 2.75rem;
    padding: 0.5rem 0.7rem;
    color: var(--d2r-gold);
    font-size: inherit;
    font-weight: inherit;
    background: var(--d2r-panel);
    border: 1px solid var(--d2r-line-gold);
    border-radius: 0.35rem;
    list-style: none;
    cursor: pointer;
  }

  .d2r-levels .filter-toggle::-webkit-details-marker {
    display: none;
  }

  /* 닫힘·열림 낱말 — 원본은 `filtersOpen` 에 따라 글자를 바꿨다. */
  .d2r-levels .level-filters .when-open {
    display: none;
  }

  .d2r-levels .level-filters[open] .when-closed {
    display: none;
  }

  .d2r-levels .level-filters[open] .when-open {
    display: inline;
  }

  /*
   * 열린 판은 다음 줄 전체 폭을 쓴다. flex 줄에 서는 것은 판 자체가 아니라 details 가 만드는
   * `::details-content` 상자다 — 판에 `flex-basis` 를 줘도 안 먹는다(실측).
   */
  .d2r-levels .level-filters::details-content {
    order: 3;
    flex-basis: 100%;
  }

  /* 열린 동안에도 금색 선은 제목 줄 아래에 그대로다 — 머리 선이 판 밑으로 내려가지 않게. */
  .d2r-levels .level-head:has(.level-filters[open]) {
    border-bottom: none;
  }

  .d2r-levels .level-head:has(.level-filters[open])::after {
    content: '';
    order: 2;
    flex-basis: 100%;
    border-top: 1px solid var(--d2r-line-gold);
  }

  .d2r .filter-panel {
    position: static;
    grid-template-columns: 1fr;
    margin-top: 0.5rem;
    padding: 0.7rem !important;
  }

  /* 판 안 줄은 원본 `_filters.scss:62-67` 그대로다 — 이름 칸을 남기고 칸 사이만 좁힌다. */
  .d2r .filter-row {
    align-items: start;
    gap: 0.45rem;
  }

  .d2r .filter-row > strong {
    margin-top: 0.38rem;
    font-size: var(--text-meta);
  }

  /* 칩은 옆으로 미는 대신 칸을 나눠 접는다 — 원본 `_filters.scss:70-75` 와 같은 손이다. */
  .d2r .filter-row .filter-chips {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(4.25rem, 1fr));
    overflow-x: visible;
  }

  .d2r-levels .filter-chip {
    min-height: 2.1rem;
    padding: 0.25rem 0.4rem;
    line-height: 1.3;
    white-space: normal;
  }

  /*
   * 레벨 줄 카드는 폰에서도 세로로 쌓인다 — 원본은 `level-items.vue:180` 의 모바일 분기가 옆
   * 스크롤(`scroll-snap`)을 넣지만, 바로 뒤 같은 파일 `:182` 의 범위 없는 규칙이
   * `overflow:visible`·wrap 격자로 덮어 실제 운영은 카드가 한 열로 늘어선다(운영 390 카드
   * x82.8·w289.2 실측과 일치). 전에는 이 분기로 옆 띠를 만들었다 — 지운다.
   */

  .d2r .level-row {
    grid-template-columns: 3.4rem minmax(0, 1fr);
    gap: 0.65rem;
    scroll-margin-top: calc(var(--app-header-offset) + 1rem);
  }

  .d2r .level {
    top: calc(var(--app-header-offset) + 1rem);
    min-height: 3.5rem;
  }

  .d2r .level strong {
    font-size: var(--text-title);
  }

  .d2r-levels .level-toolbar h1 {
    font-size: 1.25rem;
  }

  .d2r-levels .level-toolbar p {
    font-size: var(--text-caption);
  }
}

/* 원본 `prices.vue` 의 `@include below(mobile)`(600px) 분기 — 카드가 한 칸이 된다. */
@media (max-width: 600px) {
  .d2r .price-grid,
  .d2r .price-grid.wide {
    grid-template-columns: 1fr;
  }

  /* 원본 `below(mobile)`(600px) 의 `.low-toggle { margin-left: 0 }` — 좁으면 왼쪽에 붙는다. */
  .d2r .price-filters .low-toggle {
    margin-left: 0;
  }
}

/* 원본 `tablet-narrow`(700px) 분기 — 룬워드 베이스 계층표가 여기서 접힌다. 40rem(640px) 분기와 값이 달라 따로 둔다. */
@media (max-width: 700px) {
  .d2r .base-runewords {
    padding-inline: 0.8rem;
  }

  .d2r .runeword-grid {
    grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  }

  .d2r .base-content {
    padding-inline: 0.8rem;
  }

  .d2r .tier-head {
    display: none;
  }

  .d2r .family {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.3rem;
    padding: 0.35rem;
    background: var(--d2r-panel-strong);
    border: 1px solid var(--d2r-line);
    border-radius: 0.4rem;
  }

  .d2r .family + .family {
    margin-top: 0.7rem;
  }

  .d2r .base {
    min-height: 3.7rem;
  }

  .d2r .base.base-empty {
    display: none;
  }

  .d2r .mobile-tier {
    display: block;
    width: 4.2rem;
    flex: 0 0 4.2rem;
    color: var(--d2r-gold-soft);
    font-size: var(--text-caption);
  }
}

/* 폰에서는 판이 화면 끝까지 간다. 좌우 8px 를 남기면 어두운 판이 종이에 붙인 쪽지로 보인다. */
@media (max-width: 47.5rem) {
  .d2r {
    margin-inline: -0.5rem;
    padding-inline: 1rem;
  }

  /*
   * 시세만 예외다 — 원본 prices.vue 의 뿌리는 `.d2r` 가 아니라 `.prices` 라 판의 음수 마진·
   * 패딩을 안 받고 `.container`(좁으면 좌우 8px) 안에 그대로 선다. 그래서 운영 시세 폰 화면은
   * 다른 D2R 화면(x16)과 달리 x8 다.
   */
  .d2r.d2r-prices {
    margin-inline: 0;
    padding-inline: 0;
  }

  .d2r .page-head h1 {
    font-size: var(--text-title);
  }

  .d2r .gb-search {
    margin-top: 1rem;
  }

  .d2r .search-help {
    line-height: 1.45;
  }

  .d2r .rarities {
    gap: 0.3rem;
  }

  .d2r .rarities button {
    min-height: 2.7rem;
    font-size: var(--text-caption);
  }

  /* 원본 `D2RRelatedItems.vue` 의 `below(tablet)` 분기 — 관련 아이템이 한 열이 된다. */
  .d2r .related-grid {
    grid-template-columns: 1fr;
  }

  /* 같은 분기에서 세트 목록도 한 열이다(원본 `items/index.vue:316` 의 `below(tablet)` 안 `.set-grid{grid-template-columns:1fr}`). */
  .d2r .set-grid {
    grid-template-columns: 1fr;
  }

  /*
   * 상세 격자의 폰 분기는 원본 `D2RDetail.vue` 의 `@include below(tablet)`(760px)다 — 처음엔
   * `.content` 와 같이 60rem 에 묶여 있어 760~960 사이에서 한 칸으로 접혔다(900 실측).
   * 같은 분기의 나머지 손(article 한 칸·그림 12rem·세트/변형 한 칸)도 같이 온다.
   */
  .d2r .detail-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .d2r .detail-grid > article {
    grid-template-columns: minmax(0, 1fr);
  }

  .d2r .detail-grid .visual img {
    max-height: 12rem;
  }

  .d2r .set-bonuses > div,
  .d2r .variants > div {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* -------------------------------------------------------------- 해외반응 */

/*
 * 해외반응 목록 한 줄의 출처(레거시 `PostRows.vue:20-23,73-76`).
 *
 * 코어가 슬롯을 제목 링크 바깥, 행의 제목 아래에 놓으므로(`skins/board/src/index.tsx` 의
 * `listing.row`) 여기서 블록으로 세우면 제 줄을 갖는다. 색은 행의 meta 글과 같게 두고
 * 크기는 운영 실측대로 한 단계 작은 caption(13px)이다 — 제목 아래 보조 줄이라 meta 보다
 * 작아야 제목이 먼저 읽힌다.
 */
.row-source {
  display: block;
  /* 위 틈 0.2rem(3.2)과 줄높이 1.4(13px→18.2)는 레거시 `.row-source` 값 그대로다. */
  margin: 0.2rem 0 0;
  color: var(--board-dim);
  font-size: var(--board-size-caption);
  line-height: 1.4;
}

.row-source:hover {
  color: var(--board-text);
}

/*
 * 홈 사이드바의 최근 댓글(home-widgets 플러그인). 한 줄에 하나, 넘치면 말줄임 — 레거시 홈과 같은
 * 밀도다. 두 줄로 접으면 일곱 개가 사이드바 절반을 먹는다.
 */
/* `contain` 가 없으면 한 줄로 묶인 글자 폭이 그리드 칸의 최소 폭이 되어 폰에서 페이지가 옆으로 늘어난다. */
.gb-widget-recent-comments .recent-comments {
  contain: inline-size;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* 운영 사이드바는 줄 사이 선이 없고 한 줄이 36.8px 이다 — 16px 글자의 25.6px 줄높이 위아래로 0.35rem(레거시 `.mini a`). */
.gb-widget-recent-comments .recent-comments a {
  display: block;
  padding: 0.35rem 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--board-text);
}

/*
 * 홈 아래 띠의 디아블로 DB 칸. 운영의 `tool-card` 다 — 검은 바탕에 금색 글자, 작은 「도구」, 큰
 * 제목, 회색 한 줄, 칸 전체가 링크. 조립 섹션은 마크다운 한 덩이라 클래스를 못 붙이므로 아래 띠의
 * 마크다운 칸으로 잡고, 링크는 `::after` 로 칸 전체를 덮는다. 색은 운영 값 그대로 두 테마에 같다.
 */
.gb-area-page-bottom .gb-widget-slot-markdown > .gb-widget {
  position: relative;
  display: grid;
  align-content: center;
  padding: 1.3rem;
  border-color: #171614;
  background: #171614;
  color: #aaaaaa;
  font-size: var(--board-size-ui);
}

.gb-area-page-bottom .gb-widget-slot-markdown p {
  margin: 0;
}

.gb-area-page-bottom .gb-widget-slot-markdown p:first-child {
  font-size: var(--board-size-caption);
  color: #f0d27b;
}

.gb-area-page-bottom .gb-widget-slot-markdown a {
  font-size: 1.25rem;
  font-weight: var(--board-weight-bold);
  color: #f0d27b;
  text-decoration: none;
}

.gb-area-page-bottom .gb-widget-slot-markdown a::after {
  content: '';
  position: absolute;
  inset: 0;
}

/*
 * 홈 시세 줄의 두 칸(폰덕·알뜰폰). 두 플러그인이 같은 뼈대를 내고 색·면은 토큰이 정한다 —
 * 폰덕은 phonedeal, 알뜰폰은 mvno 가 `home-market` 계열 클래스로 그린다. 카드 하나가 링크
 * 하나라 안쪽에 블록을 두지 않는다(레거시 `HomeMarket.vue` 의 `market__panel` 자리).
 *
 * 머리와 「더 보기」가 첫 행의 두 칸을 나눠 갖고, 시세 줄 셋이 그 아래를 가로지른다 — 운영
 * 카드의 격자와 같은 자리다. 시세 줄의 칸은 줄 묶음에 한 번만 두고 각 줄은 `display: contents`
 * 로 비켜선다 — 줄마다 제 격자를 가지면 칸 폭이 그 줄 내용에 맞춰져 곁줄·값의 x 가 줄마다
 * 흔들린다(레거시 `.market__items` / `.market__item`).
 *
 * 좁은 화면에서 넘치지 않게 하는 것이 이 블록의 절반이다. 이름·곁줄·값에 `nowrap` 이 걸려
 * 있으므로 `contain: inline-size` 로 카드가 그리드 칸을 밀어 넓히지 못하게 막는다 — 없으면
 * 한 줄로 묶인 글자 폭이 칸의 최소 폭이 되어 폰에서 페이지가 옆으로 늘어난다.
 */
.home-market {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  /* 틈 .5/.8 과 안쪽 여백 .9/1 은 레거시 `.market__panel` 값이다. */
  gap: 0.5rem 0.8rem;
  min-width: 0;
  /* 나란히 선 두 칸이 한 높이로 끝나게 한다 — 슬롯이 격자 stretch 로 늘어나도 카드가 따라간다. */
  height: 100%;
  /* 늘어난 높이는 아래에 남긴다 — 줄이 모자란 카드에서 기본 stretch 가 행을 벌려 값이 카드 한가운데 뜬다. */
  align-content: start;
  padding: 0.9rem 1rem;
  color: var(--board-text);
  background: var(--board-surface);
  border: 1px solid var(--board-line);
  border-radius: var(--board-radius-l);
  box-shadow: var(--board-shadow);
  /* `contain: inline-size` + 질의 컨테이너 — 아래 `@container` 가 이 카드를 잰다(레거시 `HomeMarket.vue:77` 의 `container-type`). */
  container-type: inline-size;
  font-size: var(--board-size-meta);
  text-decoration: none;
  /* hover 전환 폭·시간은 레거시 `HomeMarket.vue:88` 그대로다. */
  transition: border-color 0.15s, box-shadow 0.15s;
}

/*
 * 카드 hover — 운영 `.market__panel:hover`(`HomeMarket.vue:90`): 테두리 `--color-brand-600`
 * (--board-accent, #146c5a)에 `--shadow-md`(`_tokens.scss:24`) — `--site-shadow-md` 가 밝기를 따라간다.
 */
.home-market:hover {
  border-color: var(--board-accent);
  box-shadow: var(--site-shadow-md);
}

/* 머리 — 작은 아이콘, 굵은 이름, 흐린 확인 범위. 좁아지면 확인 범위가 먼저 접힌다. */
.home-market__head {
  grid-column: 1;
  grid-row: 1;
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  min-width: 0;
}

/* 아이콘만 브랜드색을 쓴다 — 글자와 같은 색이면 그냥 기호로 읽힌다. `-text` 쪽을 쓰는 것은 어두운 면에서 밝아져야(`--board-accent` 는 3:1 이 안 된다) 그 선이 보이기 때문이다. */
.home-market__icon {
  flex: none;
  align-self: center;
  color: var(--board-accent-text);
}

.home-market__name {
  flex: none;
  margin-right: 0.1rem;
  color: var(--board-text);
  font-size: var(--board-size-head);
  font-weight: var(--board-weight-bold);
}

.home-market__facts {
  min-width: 0;
  overflow: hidden;
  color: var(--board-dim);
  font-size: var(--board-size-caption);
  text-overflow: ellipsis;
  white-space: nowrap;
}

/*
 * 카드 안쪽 폭이 좁아지면 확인 범위를 접는다 — 뷰포트가 아니라 카드 자신의 폭에 반응해야,
 * 두 칸이 나란히 서는 1024 처럼 화면은 넓어도 칸이 좁은 자리에서 「N곳 중 M곳 · 날짜」가
 * 중간에서 잘리지 않는다(레거시 `HomeMarket.vue:177-179` 의 `@container (max-width: 19.5rem)`).
 * `.home-market` 의 `contain: inline-size` 가 곧 질의 컨테이너다.
 */
@container (max-width: 19.5rem) {
  .home-market__facts {
    display: none;
  }
}

/*
 * 「더 보기」 — 머리와 같은 행의 오른쪽 끝에 선다. 글자는 흐리고, 끝의 화살표가 「눌러서
 * 넘어간다」를 혼자 말한다. 손을 올리면 브랜드색으로 진해진다.
 */
.home-market__go {
  grid-column: 2;
  grid-row: 1;
  display: flex;
  align-items: center;
  gap: 0.15rem;
  justify-self: end;
  color: var(--board-dim);
  font-size: var(--board-size-caption);
  /* 600 — 레거시 `--weight-semibold`. 토큰에 없는 굵기라 고정값이다. */
  font-weight: 600;
  white-space: nowrap;
}

.home-market:hover .home-market__go {
  color: var(--board-accent-text);
}

/*
 * 이름·곁줄·값이 줄마다 같은 칸(같은 x)에 서게 하는 것이 이 격자다. 줄은 `display: contents`
 * 로 비켜서고 자식들이 여기 둔 칸을 직접 차지한다(레거시 `.market__items`). 칸 사이는 gap 이
 * 아니라 곁줄·값의 `padding-left` 가 벌린다 — 값과 그 단위는 붙어 한 덩어리로 읽혀야 하는데
 * gap 은 칸마다 똑같이 벌어져 그 둘까지 떼어 놓는다.
 */
.home-market__rows {
  grid-column: 1 / -1;
  grid-row: 2;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: baseline;
  column-gap: 0;
  row-gap: 0.35rem;
  min-width: 0;
}

/* 한 줄이 곧 한 기종이다 — 이름, 곁줄(통신사·판매처), 값이 한 줄에 나란히 선다. */
.home-market__row {
  display: contents;
}

.home-market__label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.home-market__sub {
  min-width: 0;
  overflow: hidden;
  padding-left: 0.9rem;
  color: var(--board-dim);
  font-size: var(--board-size-caption);
  text-overflow: ellipsis;
  white-space: nowrap;
}

/*
 * 이 줄에서 눈에 띄어야 하는 것은 값 하나다. 숫자는 크고 굵게, 통화 단위는 작고 흐리게 뒤에
 * 붙는다. `tabular-nums` 는 자리마다 숫자 폭이 달라도 값이 흔들리지 않게 한다.
 */
.home-market__value {
  justify-self: end;
  padding-left: 0.9rem;
  /* 운영 `--color-brand-700` — 가격표가 지원금에 쓰는 색과 같다. `--board-brand-700` 이 그 값이다. */
  color: var(--board-brand-700);
  /* 15px — 레거시 `--text-label`. 스킨 눈금(14px/16px) 사이의 값이라 고정값이다. */
  font-size: 0.9375rem;
  font-weight: var(--board-weight-bold);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.home-market__unit {
  color: var(--board-dim);
  font-size: var(--board-size-caption);
  font-weight: 600;
}


/* 밑줄은 이름 하나에만. 카드 전체가 링크라 나머지 글자까지 밑줄이 그이면 값이 안 읽힌다. */
.home-market:hover .home-market__name {
  text-decoration: underline;
}

/*
 * 폰에서는 두 카드가 위아래로 쌓여 본문이 한 화면 아래로 밀린다. 운영도 좁은 화면에서 곁줄을
 * 접고 이름·값만 한 줄로 남긴다 — 그래도 시세 줄 셋은 다 그린다(레거시가 모바일에서 둘만
 * 그리던 것과 다르다).
 */
@media (max-width: 47.5rem) {
  .home-market__sub {
    display: none;
  }

  .home-market__label {
    font-size: var(--board-size-caption);
  }

  .home-market__value {
    font-size: var(--board-size-meta);
  }
}

/* ------------------------------------------------------------------------- *
 * 「예전 게시판」. 마크업은 `site/pages/legacy-boards.tsx`, 값은 운영 실측(1280, 2026-09-16).
 *
 * 이 화면은 게시판 머리를 안 쓴다 — 운영이 `.page-head` 로 따로 그리고, 표가 아니라 2단
 * 링크 목록이다. 목록 클래스만 운영과 이름이 다르다: 운영은 `board-list` 인데 그건 스킨이
 * 글 목록 카드에 쓰는 이름이라(`skins/board/src/styles.ts:572`) `legacy-list` 로 바꿨다.
 *
 * 줄높이는 운영이 전부 1.6 이다. 스킨의 `--board-leading-ui` 는 1.5 라 줄마다 직접 적는다.
 * ------------------------------------------------------------------------- */
.legacy-page {
  padding-block: 1rem 3rem;
}
/* 운영 `.stack` — 머리와 흰 판 사이 10.4px 하나. */
.legacy-page.stack {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.65rem;
}
.legacy-page .app-surface,
.site-info .app-surface,
.legal-page .app-surface {
  padding: var(--board-card-pad);
  border: 1px solid var(--board-line);
  border-radius: var(--board-radius-l);
  background: var(--board-surface);
  box-shadow: var(--board-shadow);
}
.legacy-page .page-head p {
  margin: 0;
  /* 글자로 쓰는 녹색은 `--board-accent-text` 다 — 어두운 면에서 `#146c5a` 는 대비가 3:1 이 안 된다(위 다크 블록). */
  color: var(--board-accent-text);
  font-size: var(--board-size-caption);
  font-weight: 800;
  line-height: 1.6;
  letter-spacing: 0.12em;
}
.legacy-page .page-head h1 {
  margin: 0.2rem 0;
  font-size: clamp(1.75rem, 3vw, 2.25rem);
  line-height: 1.25;
  letter-spacing: normal;
}
.legacy-page .page-head span {
  display: block;
  color: var(--board-dim);
  font-size: var(--board-size-ui);
  line-height: 1.6;
}

/*
 * 한 줄에 이름 + 주소 조각 + 「N개」 가 서고 날짜는 두 칸을 다 써서 아래로 내려간다.
 * 줄 높이를 84px 로 못 박아 스무 줄이 두 단으로 가지런히 선다.
 */
.legacy-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 1.25rem;
}
.legacy-list a {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-content: center;
  gap: 0.2rem 1rem;
  min-height: 5.25rem;
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--board-line);
  color: var(--board-text);
  text-decoration: none;
}
.legacy-list a:hover strong,
.legacy-list a:focus-visible strong {
  color: var(--board-accent-text);
}
.legacy-list div {
  display: flex;
  align-items: baseline;
  gap: 0.55rem;
  min-width: 0;
}
.legacy-list strong {
  overflow: hidden;
  font-size: var(--board-size-ui);
  font-weight: 600;
  line-height: 1.6;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.legacy-list small,
.legacy-list time {
  color: var(--board-dim);
  font-size: var(--board-size-caption);
  line-height: 1.6;
}
.legacy-list > a > span {
  /* 운영은 여기만 `--color-brand-700` 이다 — `--board-brand-700` 이 그 값. */
  color: var(--board-brand-700);
  font-size: var(--board-size-meta);
  font-weight: 700;
  line-height: 1.6;
}

.legacy-list time {
  grid-column: 1 / -1;
}
.legacy-empty {
  margin: 0;
  color: var(--board-dim);
  font-size: var(--board-size-ui);
  line-height: 1.6;
}

/* 운영은 정확히 700px 에서 한 단으로 접고, 이름과 주소 조각도 위아래로 쌓는다. */
@media (width <= 43.75rem) {
  .legacy-page {
    padding-top: 0.25rem;
  }
  .legacy-list {
    grid-template-columns: 1fr;
  }
  .legacy-list a {
    min-height: 5rem;
  }
  .legacy-list div {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.1rem;
  }
}

/* ------------------------------------------------------------------------- *
 * 안내 화면 넷. 마크업은 `site/pages/static.tsx`, 값은 전부 운영 실측(1280, 2026-09-16)이다.
 *
 * 운영 토큰은 이 시트 앞쪽의 다리로 옮겼다 — `--color-brand-600` = `--board-accent`,
 * `--color-line` = `--board-line`, `--color-muted` = `--board-dim`,
 * `--radius-card` = `--board-radius-l`(0), `--shadow-sm` = `--board-shadow`.
 * 없는 단계는 섞어 만든다: `--color-brand-50 #edf8f5` ≈ 강조 8% 를 흰 면에.
 * 리터럴로 적으면 다크모드에서 연초록 판이 그대로 남으므로 섞는 쪽이어야 한다.
 * (`--color-brand-700` 은 `--board-brand-700` 이 그 값이다.) 1.2rem·0.75rem·2.6rem 과 굵기 600·800 은 스킨에 토큰이
 * 없어 그대로 적는다(이 시트의 기존 관례).
 *
 * `.hero`·`.card`·`.grid`·`.contact` 는 운영 이름 그대로인데 흔한 이름이다. 운영은 Vue 의
 * `data-v-` 로 범위를 잡지만 우리 시트는 전역이라 **두 겉껍질(`.site-info`·`.legal-page`)
 * 아래로만** 건다. 스킨에는 이 이름들이 없다(`.card` 는 `.card-grid .card` 뿐).
 * ------------------------------------------------------------------------- */

/* 소개·편집 원칙 (운영 `div.site-info`, 폭 896) */
.site-info {
  max-width: 56rem;
  margin-inline: auto;
  padding: 0.4rem 0 2rem;
}
/* 오른쪽 위에 강조색 원 하나를 옅게 얹은 뒤 대각선으로 흰 면에서 연초록으로 간다. */
.site-info .hero {
  padding: 2.8rem 3rem 2.35rem;
  border: 1px solid var(--board-line);
  border-radius: 1.2rem;
  background:
    radial-gradient(circle at 88% 14%, color-mix(in srgb, var(--board-accent) 15%, transparent) 0 4.6rem, transparent 4.7rem),
    linear-gradient(135deg, var(--board-surface), color-mix(in srgb, var(--board-accent) 8%, var(--board-surface)));
}
.site-info .eyebrow {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--board-accent-text);
  font-size: var(--board-size-caption);
  font-weight: 800;
  line-height: 1.6;
  letter-spacing: 0.12em;
}
.site-info .hero h1 {
  margin: 1rem 0 0;
  font-size: clamp(2rem, 4vw, 2.7rem);
  line-height: 1.25;
  letter-spacing: -0.045em;
}
.site-info .hero > p {
  margin: 1rem 0 0;
  color: var(--board-dim);
  font-size: var(--board-size-read);
  line-height: 1.6;
}
.site-info .hero nav {
  display: flex;
  gap: 0.5rem;
  margin-top: 1.8rem;
}
/*
 * `line-height` 를 적는 이유: 스킨의 `--board-leading-ui` 가 1.5(24px)인데 운영 링크는 1.6
 * (25.6px)이다. 안 적으면 알약 단추가 45px 대신 44px 로 서고 히어로 전체가 1px 짧아진다.
 * 아래 `.legal-hero nav a`·`.card a` 도 같은 이유다.
 */
.site-info .hero nav a {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.55rem 0.85rem;
  border: 1px solid var(--board-line);
  border-radius: 999px;
  background: var(--board-surface);
  font-weight: var(--board-weight-bold);
  line-height: 1.6;
}
/*
 * 지금 보는 탭. 운영은 글자를 `--color-brand-700` 으로 쓴다 — `--board-brand-700` 이 그 값이다.
 * 테두리는 `--color-brand-600` — `--board-accent-text` 가 그 값이다. `--board-accent` 로 두면
 * 어두운 면에서 알약 테두리가 안 보여 지금 쪽을 알 수 없다.
 */
.site-info .hero nav a.active {
  border-color: var(--board-accent-text);
  background: color-mix(in srgb, var(--board-accent) 8%, var(--board-surface));
  color: var(--board-brand-700);
}

.site-info .grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.85rem;
  margin-top: 1rem;
}
/* 아이콘 칸과 글 칸. 최소 높이는 운영 값이라 글이 짧아도 넉 장이 같은 키로 선다. */
.site-info .card {
  display: grid;
  grid-template-columns: 2.6rem minmax(0, 1fr);
  gap: 0.9rem;
  min-height: 11.5rem;
}
.site-info .card-icon {
  display: grid;
  place-items: center;
  width: 2.6rem;
  height: 2.6rem;
  border-radius: 0.75rem;
  background: color-mix(in srgb, var(--board-accent) 8%, var(--board-surface));
  color: var(--board-accent-text);
}
.site-info .card h2,
.site-info .contact h2 {
  margin: 0 0 0.45rem;
  font-size: var(--board-size-read);
  line-height: 1.35;
}
.site-info .card p,
.site-info .contact p {
  margin: 0;
  color: var(--board-dim);
  line-height: 1.7;
}
.site-info .card a,
.site-info .contact > a {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  margin-top: 0.75rem;
  color: var(--board-accent-text);
  font-weight: var(--board-weight-bold);
  line-height: 1.6;
}
.site-info .contact {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-top: 1rem;
}
.site-info .contact > div {
  flex: 1;
}
/*
 * 운영이 정확히 700px 에서 갈린다. 이 시트 다른 폰 블록의 44rem 을 따르지 않고 그 값을 쓴다 —
 * 카드가 두 단으로 남는 폭이 그거고, 여기만 다르게 끊으면 한 단으로 떨어지는 지점이 어긋난다.
 */
@media (width <= 43.75rem) {
  .site-info .hero {
    padding: 2rem 1.4rem;
  }
  .site-info .grid {
    grid-template-columns: 1fr;
  }
  .site-info .contact {
    flex-wrap: wrap;
    align-items: flex-start;
  }
  .site-info .contact > a {
    width: 100%;
    margin-left: 3.6rem;
  }
}

/* 이용약관·개인정보처리방침 (운영 `div.legal-page`, 폭 896) */
.legal-page {
  display: grid;
  gap: 1rem;
  max-width: 56rem;
  margin-inline: auto;
}
/* 약관 쪽 히어로는 원이 없고 대각선 하나뿐이다. 모서리도 1.2rem 이 아니라 1rem. */
.legal-hero {
  padding: 2.2rem 2.4rem;
  border: 1px solid var(--board-line);
  border-radius: 1rem;
  background: linear-gradient(135deg, var(--board-surface), color-mix(in srgb, var(--board-accent) 8%, var(--board-surface)));
}
.legal-hero > p {
  margin: 0;
  color: var(--board-accent-text);
  font-size: var(--board-size-caption);
  font-weight: 800;
  line-height: 1.6;
  letter-spacing: 0.14em;
}
.legal-hero h1 {
  margin: 0.45rem 0 0;
  font-size: clamp(1.75rem, 3vw, 2.25rem);
  line-height: 1.25;
  letter-spacing: normal;
}
.legal-hero > span {
  display: block;
  margin-top: 0.55rem;
  color: var(--board-dim);
  font-size: var(--board-size-meta);
  line-height: 1.6;
}
.legal-hero nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 1.4rem;
}
.legal-hero nav a {
  display: flex;
  align-items: center;
  min-height: 2.65rem;
  padding: 0.5rem 0.8rem;
  border: 1px solid var(--board-line);
  border-radius: 999px;
  background: var(--board-surface);
  font-weight: 600;
  line-height: 1.6;
}
.legal-hero nav a.active,
.legal-hero nav a:hover {
  border-color: var(--board-accent);
  background: var(--board-accent);
  color: var(--board-on-accent);
}
.legal-section > h2 {
  margin: 0 0 0.85rem;
  font-size: 1.5rem;
  line-height: 1.35;
}
.legal {
  display: grid;
  gap: 0.8rem;
}
.legal section {
  padding: 1rem;
  border: 1px solid var(--board-line);
  border-radius: 0.4rem;
}
.legal h3 {
  margin: 0 0 0.45rem;
  /* 운영은 `--color-brand-700` — `--board-brand-700` 이 그 값. */
  color: var(--board-brand-700);
  font-size: 1.125rem;
  line-height: 1.4;
}

.legal p,
.legal ul {
  margin: 0;
  line-height: 1.7;
}
.legal ul {
  /* 레거시 `_reset.scss:9` 가 `ul, ol` 의 점을 전부 지웠다 — 운영도 list-style: none 이다. */
  list-style: none;
  padding-left: 1.2rem;
}
.legal li {
  margin: 0;
}
/* 이쪽은 운영이 600px 에서 갈린다. 조항 상자가 두 겹으로 겹쳐 있어 안쪽 여백을 같이 줄인다. */
@media (width <= 37.5rem) {
  .legal-hero {
    padding: 1.5rem 1.2rem;
  }
  .legal-hero h1 {
    font-size: 1.75rem;
  }
  .legal-page .legal-section {
    padding: 0.85rem;
  }
  .legal section {
    padding: 0.85rem;
  }
}
/*
 * 엔진 board 스킨·코어 테마를 레거시에 맞추던 덮기는 걷었다 — 엔진 기본 모양을 쓴다.
 * 남은 것은 노리터 기능 소속 규칙뿐이다: 본문 출처 줄(`.source`), 해외반응 플러그인 섹션
 * (`data-section='overseas'`), D2R 판의 쪽번호 hover, 폰 시세 띠(`home-market`), 프로필 눈썹 글.
 */

/*
 * D2R 판의 같은 hover — 운영은 테마 변수를 따라 `--color-brand-600`(#d6b85b) 글자에
 * `--color-surface-subtle`(#211a11) 바탕이다(`_themes.scss:19,25`). 이 값들은 `.d2r` 안
 * `--color-*` 다리에 있다 — `--board-accent-text`·`--board-tint` 는 판 값(#d8b45c·#1c1913)으로
 * 갈려 있어 그대로 쓰면 한 단계 어긋난다.
 */
.d2r .gb-pagination-strip a:hover,
.d2r .gb-pagination-line a:hover {
  color: var(--color-brand-600);
  background: var(--color-surface-subtle);
}

/*
 * 본문 끝 출처 줄. 플러그인이 아니라 글 마크다운이 `<p class="source">출처: <a>…</a></p>` 로
 * 찍어 `.post-body > .gb-body` 의 마지막에 온다. 스킨의 `.post .gb-body p`(0,2,1)와 `.post .gb-body a`
 * (0,2,1)를 이겨야 해서 `.post-body` 까지 붙여 (0,3,0)/(0,3,1) 로 잡는다.
 *
 * 위로 글을 가르는 실선 하나, 라벨은 `--board-dim` 14px, 링크는 `--board-accent-text` 에
 * 밑줄 없이 두고 hover 에서만 긋는다.
 *
 * 위 간격·선 안쪽 여백은 레거시 `.post-content :deep(.source)` 의 `margin-top:1.5rem`·
 * `padding-top:.75rem`(`PostContent.vue:255-262`)이다 — `--board-space-6`·`--board-space-3`
 * 이 그 값이다. `PostDetailView.vue:114` 의 `footer.source` 는 본문에 `class="source"` 가
 * 이미 박힌 글에서는 그려지지 않는다(`hasLegacySource`) — 이 선택자가 겨냥하는 판이다.
 *
 * 마크다운이 찍는 건 `<p class="source">` 라 위의 `p + p`(0,3,2)가 margin-top 을 덮어 쓴다 —
 * 선택자에 `p` 를 붙여 (0,3,2)로 맞추고 이 파일에서 더 뒤에 선언해 이긴다. 선·색·크기는
 * 태그를 가리지 않게 원래 선택자에 둔다.
 */
.post-body .gb-body .source,
.post .post-body .gb-body p.source {
  margin-top: var(--board-space-6);
  padding-top: var(--board-space-3);
  border-top: 1px solid var(--board-line);
  color: var(--board-dim);
  font-size: var(--board-size-meta);
  /* 레거시 `PostContent.vue:258-262` 의 `.source{line-height:1.6}` — 두지 않으면 본문 1.75 를 상속한다. */
  line-height: 1.6;
}

/*
 * 그림·동영상 출처는 같은 펜스가 `<p class="image-source">`/`<p class="video-source">` 로 찍는다
 * (코어 `renderer.ts` sourceHtml) — 링크 규칙은 세 종류가 같이 쓴다. 레거시는 셋 다
 * `--color-brand-600`·`--weight-medium`(500)·밑줄 없음에 hover 밑줄이다
 * (`PostContent.vue:245-252,263-264`). `.video-source a`·`.image-source a` 는 이 선택자에만
 * 기대므로, 본문 링크 규칙(0,3,0)보다 한 단계 위인 (0,3,1)을 유지한다.
 */
.post-body .gb-body .source a,
.post-body .gb-body .gb-image-source a,
.post-body .gb-body .gb-video-source a {
  color: var(--board-accent-text);
  font-weight: 500;
  text-decoration: none;
}

.post-body .gb-body .source a:hover,
.post-body .gb-body .gb-image-source a:hover,
.post-body .gb-body .gb-video-source a:hover {
  text-decoration: underline;
}

/*
 * 해외반응(`plugins/overseas`). 코어가 이 묶음을 `.gb-comments` 안의
 * `<section class="comment-section" data-section="overseas">` 로 그린다 — 스킨의 댓글 부품을
 * 그대로 쓰되 토큰만 다시 입힌다.
 *
 * 하나하나가 스킨의 기본값을 이겨야 한다. 제목의 무거운 잉크 선은 `.gb-comments h2`(0,1,1)가
 * `.gb-comment-section-title`(0,1,0)을 제치고 남긴 것이라 `.gb-comments h2.…`(0,2,1) 로 지운다.
 * 점수 배지도 스킨의 `.gb-badge.tone-info`(0,2,0)를 이겨야 해서 섹션·항목까지 붙여 (0,4,0) 로
 * 잡는다. 점수 마크업(`<span class="badge tone-info">▲ 22</span>`) 자체는 플러그인 테스트가
 * 단언하므로 그대로 두고, 테두리·여백·바탕만 걷어 인라인 글자로 만든다.
 */
/*
 * 운영은 옅은 상자가 제목과 처음 몇 줄만 감싸고, 「더 보기」 단추는 상자 밖 아래에 둔다. 코어는
 * 접힌 줄을 `<details class="comment-section-more">` 로 같은 섹션 안에 그리므로, 섹션 자체에
 * 바탕을 칠하면 단추까지 상자 안에 든다. 그래서 섹션을 한 줄 격자로 세우고 바탕은 `::before` 가
 * 제목·첫 목록 두 행에만 깐다. 격자 칸이 겹쳐도 `::before` 가 문서 순서상 먼저라 글자가 위에 온다.
 */
.gb-comment-section[data-section='overseas'] {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}

/* 상자 모서리는 운영의 --radius-sm(.4rem) 이다 — 스킨 기본 --board-radius(8px)는 더 둥글다. */
.gb-comment-section[data-section='overseas']::before {
  content: '';
  grid-area: 1 / 1 / 3 / 2;
  border-radius: 0.4rem;
  background: var(--board-tint);
}

/*
 * 제목줄 — 레거시 `.comment-section>header` 는 `align-items:end; justify-content:space-between`
 * 이다. 코어 마크업은 아이콘·제목·수·캡션이 한 줄의 나란한 자식이라, 스킨이 둔 캡션의
 * `margin-left:auto` 가 오른쪽 끝을 만들고 아이콘-제목 사이는 아이콘의 오른쪽 여백이 .45rem 을
 * 낸다. 「해외반응 6」의 제목-숫자 사이는 마크업의 보통 띄어쓰기 한 칸이다 — 격자 틈을 두지 않는다.
 * 상자 안쪽 여백 1rem 은 제목이 위·좌·우를, 목록이 좌·우·아래를 나눠 든다.
 */
.gb-comment-section[data-section='overseas'] > .gb-comment-section-title {
  grid-row: 1;
  grid-column: 1;
  align-items: flex-end;
  gap: 0;
  margin: 0 0 0.7rem;
  padding: 1rem 1rem 0;
  line-height: 1.35;
}

/* 아이콘만 줄 가운데 — flex-end 는 캡션을 제목줄 아래끝에 붙이려는 것이라 아이콘은 따로 뺀다. */
.gb-comment-section[data-section='overseas'] .gb-comment-section-icon {
  align-self: center;
  margin-right: 0.45rem;
}

/* 띄어쓰기는 줄 끝에서 접혀 숫자가 제목에 붙는다 — 한 칸 폭(.25em)을 여백으로 돌려준다. */
.gb-comment-section[data-section='overseas'] .gb-comment-section-count {
  margin-left: 0.25em;
}

.gb-comment-section[data-section='overseas'] > :not(.gb-comment-section-title, .gb-comment-section-more) {
  grid-row: 2;
  grid-column: 1;
  padding: 0 1rem 1rem;
}

.gb-comment-section[data-section='overseas'] > .gb-comment-section-more {
  grid-row: 3;
  grid-column: 1;
}

.gb-comments h2.gb-comment-section-title {
  border-bottom: 0;
}

/* 운영은 개수도 제목 글과 같은 색·굵기다(`PostDetailView.vue:28`) — 스킨의 accent·bold 를 되돌린다. */
.gb-comment-section[data-section='overseas'] .gb-comment-section-count {
  color: inherit;
  font-weight: inherit;
}

/* 캡션 — 운영 13px/1.6. 오른쪽 끝은 스킨의 margin-left:auto, 아래끝은 flex-end 가 맞춘다. */
.gb-comment-section[data-section='overseas'] .gb-comment-section-caption {
  line-height: 1.6;
}

/*
 * 스킨은 이름 위 줄에 점수를 따로 그리고 항목마다 아래 실선을 긋는다. 운영은 이름 옆에
 * 붙은 작은 강조 글자고 구분은 여백이다. flex 로 순서를 바꿔 이름(`p.gb-meta`)을 먼저,
 * 점수(`.gb-slot`)를 그 옆에, 본문(`.gb-body`)을 다음 줄로 내린다.
 */
.gb-comment-section[data-section='overseas'] .gb-comment-section-item {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  /* 이름-본문 .35rem, 이름-점수 .5rem — 운영 CommentItem 의 틈이다. */
  gap: 0.35rem var(--board-space-2);
  border-bottom: 0;
}

/* 이름은 운영대로 16px/700·줄높이 1.6 — 스킨의 .gb-comment .gb-meta(14px)를 덮는다. */
.gb-comment-section[data-section='overseas'] .gb-comment-section-item > .gb-meta {
  order: 0;
  margin: 0;
  font-size: 1rem;
  line-height: 1.6;
}

.gb-comment-section[data-section='overseas'] .gb-comment-section-item > .gb-slot {
  order: 1;
}

/* 본문 16px/1.6. 아래 .45rem 은 레거시의 빈 액션줄(좋아요·답글 줄)이 서던 자리다. */
.gb-comment-section[data-section='overseas'] .gb-comment-section-item > .gb-body {
  order: 2;
  flex-basis: 100%;
  margin-bottom: 0.45rem;
  font-size: 1rem;
  line-height: 1.6;
}

.gb-comment-section[data-section='overseas'] .overseas-score {
  margin: 0;
}

.gb-comment-section[data-section='overseas'] .overseas-score .gb-badge {
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--board-accent-text);
  font-size: var(--board-size-caption);
  vertical-align: baseline;
}

/* 구분선은 이미 걷었으니 남는 건 항목 위아래 .8rem 여백뿐이다 — 운영 CommentItem 의 안쪽이다. */
.gb-comment-section[data-section='overseas'] .gb-comment-section-list > li {
  padding: 0.8rem 0;
}

/*
 * 운영의 더 보기 단추는 상자 밖 가운데 놓인 흰 단추 하나다 — 레거시 `AppButton` 의 quiet 판
 * (320 한정 폭, min-height 2.55rem = 40.8, 여백 .55/.9, 모서리 .4rem). 위 14.4 는 운영의
 * 카드 격자 틈 24 에서 9.6 을 뺀 값(`.overseas-more` 의 `margin-top:-.6rem`)이다. 펼친 줄은
 * 단추 아래에 같은 옅은 상자로 한 번 더 깐다 — 자바스크립트 없이 `<details>` 가 여는 자리다.
 */
.gb-comment-section[data-section='overseas'] .gb-comment-section-more > summary {
  display: flex;
  align-items: center;
  justify-content: center;
  width: min(20rem, 100%);
  min-height: 2.55rem;
  margin: 0.9rem auto 0;
  padding: 0.55rem 0.9rem;
  border: 1px solid var(--board-line);
  border-radius: 0.4rem;
  background: var(--board-surface);
  list-style: none;
  cursor: pointer;
  font-size: var(--board-size-ui);
  line-height: 1.2;
  font-weight: var(--board-weight-bold);
  color: var(--board-ink);
}

.gb-comment-section[data-section='overseas'] .gb-comment-section-more > summary::-webkit-details-marker {
  display: none;
}

/* 펼친 상자는 제목이 없어 위아래가 항목 여백(.8rem)만이다 — .2rem 을 얹어 상자와 같은 16 을 맞춘다. */
.gb-comment-section[data-section='overseas'] .gb-comment-section-more[open] > .gb-comment-section-list {
  margin-top: var(--board-space-3);
  padding: 0.2rem 1rem;
  border-radius: 0.4rem;
  background: var(--board-tint);
}

/*
 * 좁은 화면(레거시 `below(mobile)` = 600px 미만): 상자 안쪽 여백이 .7rem 로 줄고 캡션은
 * 제목 밑으로 내린다. 레거시는 헤더를 세로로 돌리지만(`flex-direction:column`) 코어 마크업은
 * 펼친 한 줄이라, 캡션만 다음 줄로 넘겨 같은 모양을 만든다 — 위 1rem 은 헤더의 격자 틈이다.
 */
@media (max-width: 599.98px) {
  .gb-comment-section[data-section='overseas'] > .gb-comment-section-title {
    flex-wrap: wrap;
    row-gap: 1rem;
    padding: 0.7rem 0.7rem 0;
  }

  .gb-comment-section[data-section='overseas'] > :not(.gb-comment-section-title, .gb-comment-section-more) {
    padding: 0 0.7rem 0.7rem;
  }

  .gb-comment-section[data-section='overseas'] .gb-comment-section-caption {
    flex-basis: 100%;
    margin-left: 0;
  }
}

/*
 * 폰 시세 띠(`home-market`, 홈 위젯). 운영 값:
 * - 시세 카드는 한 줄짜리 띠다. 왼쪽 3px 브랜드색 선, 이름 옆에 시세를 이어 쓰고 그 아래 흐린
 *   안내 한 줄. 확인 범위(개수·날짜)는 접고, 한 줄에 안 들어가는 시세는 다음 줄로 넘겨 가린다.
 */
@media (max-width: 47.5rem) {
  .home-market {
    /*
     * 이름 칸은 4.6rem 으로 못박는다 — 내용에 맡기면 「폰덕」(두 자)과 「알뜰폰」(세 자)의 폭이
     * 달라 두 카드의 값이 서로 다른 자리에서 시작한다(레거시 `below(tablet)` 블록).
     */
    grid-template-columns: 4.6rem minmax(0, 1fr);
    align-items: center;
    gap: 0.1rem 0.55rem;
    min-height: 3.25rem;
    padding: 0.5rem 0.7rem 0.5rem 0.55rem;
    border-left: 3px solid var(--board-accent-text);
  }

  .home-market__head {
    grid-column: 1;
    /* 첫 행에만 둔다 — 두 행을 걸치면 머리가 카드 가운데로 내려와 운영(첫 줄에 가운데 맞춤)과 어긋난다. */
    grid-row: 1;
    align-items: center;
    gap: 0.25rem;
  }

  .home-market__name {
    font-size: var(--board-size-meta);
  }

  .home-market__facts {
    display: none;
  }

  .home-market__rows {
    grid-column: 2;
    grid-row: 1;
    display: flex;
    flex-wrap: wrap;
    column-gap: 0.55rem;
    /*
     * 값은 한 줄에 들어가는 만큼만 선다 — 넘치는 값은 다음 줄로 흘러 1.4rem 에서 잘린다.
     * 줄 간격을 넉넉히 두는 것은 둘째 줄이 실오라기만큼도 비치지 않게 하려는 것이다(레거시).
     */
    row-gap: 1rem;
    max-height: 1.4rem;
    overflow: hidden;
  }

  .home-market__row {
    display: flex;
    flex: none;
    align-items: baseline;
    gap: 0.25rem;
  }

  .home-market__label {
    overflow: visible;
    color: var(--board-text);
  }

  /* 좁은 화면에서도 값 색은 그대로 둔다(레거시가 브랜드색을 유지하던 자리). 여백만 되돌린다. */
  .home-market__value {
    padding-left: 0;
  }

  .home-market__go {
    grid-column: 2;
    grid-row: 2;
    /* 상자는 칸 끝까지 늘린다(넓은 화면의 `end` 를 되돌림) — 글자는 왼쪽, 줄은 오른쪽 끝까지 닿는다. */
    justify-self: stretch;
    gap: 0;
    font-weight: var(--board-weight-normal);
  }

  .home-market__go svg {
    width: 0.9rem;
    height: 0.9rem;
  }

  /*
   * 시세 두 칸 사이는 .45rem(레거시 모바일 `.market{gap:.45rem}`) — `.gb-area-page-main` 격자의
   * .65rem 보다 좁으므로 둘째 칸을 3.2px 당긴다. 최근 카드와의 간격(.65rem)은 그대로다.
   */
  .gb-area-page-main > .gb-widget-slot:has(.home-market) + .gb-widget-slot:has(.home-market) {
    margin-top: -0.2rem;
  }
}

/* 소제목 — 레거시 `.eyebrow`. 밝을 때 accent-text 는 brand-600(#146c5a), 어두울 때는 읽히는 초록이다. */
.gb-profile::before {
  content: "노리터 회원";
  display: block;
  color: var(--board-accent-text);
  font-size: var(--board-size-caption);
  font-weight: var(--board-weight-bold);
  line-height: 1.6;
}
/* 엔진 쪽지 플러그인(@gbun/plugin-messaging)을 레거시에 맞추던 규칙이 있던 자리 — 엔진 기본 모양을 쓴다. */
   `apps/frontend/public/images/{naver,kakao}.svg` 를 `site/public/images/` 에 옮긴 것.
   색 규칙은 스킨의 `button[type="submit"]:not(.gb-link):not(.gb-reaction):not(.gb-danger)`(0,4,1)을
   이겨야 해서 같은 :not 사슬에 `.gb-providers` 를 얹어 0,5,1 로 올린다(d2r 단추 되돌림과 같은 수법). */
/* 소제목과 윗 구분선은 운영 `SocialLoginButtons.vue` 그대로다. 아랫선은 두지 않는다 — 뒤에 오는
   `.gb-auth > p:last-child`(링크 줄)이 스킨에서 이미 윗선을 그으니 겹쳐 두 줄이 된다. */
.gb-providers {
  margin-top: 20px;
  padding: 20px 0 0;
  border-top: 1px solid var(--gb-border);
  gap: 10px;
}
.gb-providers::before {
  content: "소셜 로그인";
  text-align: center;
  color: var(--gb-text-soft);
  font-size: var(--gb-size-s);
}
.gb-providers .gb-provider {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  width: 100%;
  /* 스킨은 --board-radius(8px)를 주지만 같은 카드의 단추들은 --board-control-radius(6.4px)다. */
  border-radius: var(--board-control-radius);
}
.gb-providers .gb-provider::before {
  content: "";
  width: 24px;
  height: 24px;
  background: center / contain no-repeat;
}
.gb-providers button.gb-provider-naver:not(.gb-link):not(.gb-reaction):not(.gb-danger) {
  border-color: transparent;
  background: #03c75a;
  color: #fff;
}
.gb-providers .gb-provider-naver::before { background-image: url("/images/naver.svg"); }
.gb-providers button.gb-provider-naver:not(.gb-link):not(.gb-reaction):not(.gb-danger):hover { background: #02b351; }
.gb-providers button.gb-provider-kakao:not(.gb-link):not(.gb-reaction):not(.gb-danger) {
  border-color: transparent;
  background: #fee500;
  color: #3c1e1e;
}
.gb-providers .gb-provider-kakao::before { background-image: url("/images/kakao.svg"); }
.gb-providers button.gb-provider-kakao:not(.gb-link):not(.gb-reaction):not(.gb-danger):hover { background: #fdd835; }

/* 애드센스 칸(`plugins/adsense`). 레거시 `AdSense.vue` 처럼 90px 를 먼저 잡아 광고가 늦게 떠도 덜 밀린다. */
.ad-unit {
  display: grid;
  place-items: center;
  width: 100%;
  min-height: 90px;
  overflow: hidden;
  margin-block: 1rem;
}
/* 격자 안에 끼는 칸은 한 줄을 다 쓰고, 격자·목록 간격이 위아래를 맡는다. */
.ad-unit.ad-in-grid {
  grid-column: 1 / -1;
}
.ad-unit.ad-in-grid,
.ad-unit.ad-in-list,
.gb-widget-slot > .ad-unit {
  margin-block: 0;
}
/* 글 카드와 댓글 카드 사이. 두 카드 사이 원래 간격(댓글 카드 위 24px)을 위아래로 똑같이 쓴다. */
.gb-slot-content-after > .ad-unit {
  margin-block: 24px 0;
}
/* 디아 시세 묶음은 아래 2rem 으로 띄운다. 칸도 그 리듬을 따른다. */
.d2r .price-group + .ad-unit {
  margin-block: 0 2rem;
}
.ad-unit .adsbygoogle {
  display: block;
  width: 100%;
}
.ad-unit[data-ad-test] {
  border: 1px dashed var(--board-line);
  background: var(--board-tint);
}
.ad-unit[data-ad-test]::before {
  content: '광고 영역';
  color: var(--board-dim);
  font-size: var(--board-size-caption);
}
.ad-unit[data-ad-test] .adsbygoogle {
  display: none;
}
