/* ═══════════════════════════════════════════════════════════════
   juso-4 — 라이트 테마 + 포인트 컬러 1개(--accent, 관리자에서 교체)

   성능 원칙 ([6])
   · 첫 페인트에 콘텐츠가 그대로 보입니다. 등장 애니메이션 때문에
     초기 상태를 opacity:0 으로 두는 곳이 한 군데도 없습니다.
   · 움직임은 폴드 밖 요소의 translate 로만, prefers-reduced-motion 존중.
   ═══════════════════════════════════════════════════════════════ */

:root {
  --bg: #f7f8fa;
  --bg-raised: #ffffff;
  --bg-sunken: #eef1f5;
  --border: #e3e8ef;
  --border-strong: #cdd5df;
  --text: #111827;
  --text-muted: #4b5563;
  --text-dim: #6b7280;

  /* 사이드바 토큰 (피그마 Frame 1707488302) */
  --nav-text: #1f2353;           /* 메뉴 항목 기본 글자색 */
  --nav-label: #808791;          /* 그룹 라벨 */
  --accent: #9054e8;             /* 포인트 컬러 — 관리자에서 교체 가능 */
  /*
   * 공백 구분입니다 — 쉼표로 두면 안 됩니다.
   * 이 값은 스타일시트 전체에서 `rgb(var(--accent-rgb) / 0.3)` 형태로만
   * 쓰이는데, 쉼표 문법과 슬래시 알파는 섞을 수 없어
   * `rgb(144, 84, 232 / 0.3)` 은 무효가 됩니다. 게다가 var() 는 계산 시점에
   * 판정되므로 선언 하나가 통째로 초기값으로 떨어질 뿐, 앞 규칙으로
   * 되돌아가지도 않습니다(= 그림자·틴트가 소리 없이 사라짐).
   */
  --accent-rgb: 144 84 232;
  --accent-soft: #f7eeff;        /* 포인트 컬러 배경 틴트 (사이드바·목록 호버, 카드 하단 바) */
  --accent-on: #ffffff;          /* 포인트 컬러 위에 얹는 글자색 */
  --sidebar-w: 340px;

  --danger: #b42318;
  --danger-soft: #fef3f2;
  --danger-border: #fecdca;
  /*
   * 모서리 반경 — 5단계만 씁니다.
   * 값이 흩어지면 같은 성격의 요소가 미묘하게 달라 보입니다.
   *   xs 배지·작은 칩 / sm 썸네일·바로가기 / md 입력·드롭다운
   *   lg 카드류      / pill 알약 버튼
   */
  --r-xs: 4px;
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-pill: 999px;

  /* 이전 이름 — 관리자 CSS 가 계속 참조합니다. */
  --radius: var(--r-lg);
  --radius-sm: var(--r-sm);
  /*
   * 본문 최대폭 — 카드 2열이 시안 치수와 정확히 맞도록 역산한 값입니다.
   *   카드 630 + 간격 40 + 카드 630 = 1300  (콘텐츠 영역)
   *   1300 + 좌우 패딩 16×2          = 1332  (--wrap)
   */
  --wrap: 1332px;
  --shadow: 0 1px 2px rgb(16 24 40 / 0.04), 0 4px 16px rgb(16 24 40 / 0.06);
  --shadow-hover: 0 1px 2px rgb(16 24 40 / 0.06), 0 10px 28px rgb(16 24 40 / 0.10);
  --shadow-side: 4px 4px 10px rgb(34 34 34 / 0.12);
  --shadow-card: 8px 10px 10px rgb(0 0 0 / 0.16);
  --shadow-card-hover: 10px 18px 28px rgb(0 0 0 / 0.20);
  /*
   * 히어로 그라디언트 (피그마 933:9150).
   * 포인트 컬러(--accent)와 달리 관리자에서 바꾸지 않는 고정 값이라
   * 여기 한 곳에만 정의해 둡니다. 배지 점·배지 글자·검색 버튼이 공유합니다.
   */
  --hero-gradient: linear-gradient(45deg, #4338ca 9.31%, #6366f1 51.32%, #a78bfa 93.33%);
  /* 버튼용은 색을 한 번 더 되돌려 두어, 배경 위치를 밀었을 때
     끝에서 색이 뚝 끊기지 않고 이어집니다. */
  --hero-gradient-btn: linear-gradient(75deg, #4338ca 0%, #6366f1 30%, #a78bfa 55%, #6366f1 78%, #4338ca 100%);
  /* 같은 계열을 작은 면(순위 배지·화살표 버튼·로고 자리)에 채울 때 */
  --brand-fill: linear-gradient(135deg, #4338ca 0%, #8b5cf6 52%, #c084fc 100%);
  /* ── 상호작용 토큰 ────────────────────────────────────────
     호버·포커스 반응을 사이트 전체가 같은 문법으로 쓰도록 모아 둡니다.
     값을 여기서 한 번 바꾸면 사이드바·카드·타일·배너가 함께 움직입니다. */
  --ease-out: cubic-bezier(0.22, 0.61, 0.36, 1);
  --dur-fast: .18s;                /* 색 변화 */
  --dur: .28s;                     /* 위치·그림자 */
  --lift: -6px;                    /* 표면이 떠오르는 높이 */
  --lift-sm: -3px;                 /* 작은 표면(타일·배너) */
  --focus-width: 2px;

  /* 디스플레이 폰트 — 시안이 Tenada 를 쓰는 자리(카드 카테고리명·사이트명) */
  --font-display: "Tenada", "Pretendard", "Pretendard Variable", -apple-system, BlinkMacSystemFont,
                  "Segoe UI", "Malgun Gothic", "Apple SD Gothic Neo", "Noto Sans KR", sans-serif;
}

/*
 * Tenada — 자체 호스팅(외부 CDN 의존 없음).
 *
 * font-weight 를 범위로 선언해 두면 800 을 지정해도 브라우저가 가짜 볼드를
 * 합성하지 않고 이 한 벌을 그대로 씁니다(Tenada 는 단일 웨이트입니다).
 * font-display: swap — 폰트를 기다리느라 첫 화면 글자가 비지 않게. ([6])
 */
@font-face {
  font-family: "Tenada";
  src: url("/assets/fonts/Tenada.woff2") format("woff2");
  font-weight: 400 900;
  font-style: normal;
  font-display: swap;
}

*, *::before, *::after { box-sizing: border-box; }

html {
  background: var(--bg);
  color-scheme: light;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: "Pretendard", "Pretendard Variable", -apple-system, BlinkMacSystemFont,
               "Segoe UI", "Malgun Gothic", "Apple SD Gothic Neo", "Noto Sans KR", sans-serif;
  font-size: 16px;
  line-height: 1.6;
  word-break: keep-all;
  overflow-wrap: anywhere;
  -webkit-font-smoothing: antialiased;
}

img, svg { max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
ul, ol { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, p { margin: 0; }

/* ── 접근성 ─────────────────────────────────────────────────── */

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: 12px;
  top: -60px;
  z-index: 200;
  padding: 10px 16px;
  background: var(--accent);
  color: var(--accent-on);
  font-weight: 700;
  border-radius: 0 0 var(--r-sm) var(--r-sm);
  transition: top .15s ease;
}
.skip-link:focus { top: 0; }

/*
 * 포커스 표시는 사이트 전체가 한 가지 모양을 씁니다.
 * 개별 컴포넌트에서 outline 을 끄는 경우(히어로 검색 등)에는
 * 반드시 그만큼 잘 보이는 다른 표시를 대신 줍니다.
 */
:focus-visible {
  outline: var(--focus-width) solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

/* ── 셸: 사이드바 + 본문 ────────────────────────────────────── */

.shell {
  display: grid;
  grid-template-columns: 1fr;              /* 모바일: 세로로 쌓임 */
  min-height: 100vh;
}
.shell__body { min-width: 0; display: flex; flex-direction: column; }

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: 16px;
}
.wrap--narrow { max-width: 820px; }

.main { padding-block: 28px 64px; flex: 1 1 auto; }

/* ── 사이드바 (피그마: 340px, 패딩 24/36, 아이템 56px) ──────── */

.sidebar {
  background: var(--bg-raised);
  box-shadow: var(--shadow-side);
  z-index: 40;
}

/* 모바일 열고 닫기 — JS 없이 동작하는 체크박스 토글 */
.sidebar__switch { position: absolute; }

.sidebar__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 24px;
}

.sidebar__brand { display: flex; align-items: center; gap: 10px; min-width: 0; }
.sidebar__logo { width: 36px; height: 36px; object-fit: contain; border-radius: var(--r-sm); flex: 0 0 auto; }
/*
 * 가로형 워드마크 로고를 쓸 때 — 정사각 36px 안에 넣으면 2:1 그림이
 * 36×17 로 눌려 글자를 알아볼 수 없습니다. 폭을 풀고 높이로만 맞춥니다.
 * (비율은 object-fit: contain 이 지킵니다.)
 */
.sidebar__brand--mark .sidebar__logo {
  width: auto;
  height: 56px;
  max-width: 100%;
  border-radius: 0;
}
.sidebar__name {
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.1;
  color: #000;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sidebar__toggle {
  display: inline-grid;
  place-items: center;
  width: 42px; height: 42px;
  flex: 0 0 auto;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  color: var(--nav-text);
  cursor: pointer;
}
.sidebar__toggle:hover { background: var(--accent-soft); color: var(--accent); border-color: var(--accent-soft); }
.sidebar__switch:focus-visible + .sidebar__bar .sidebar__toggle {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.sidebar__panel { display: none; padding: 0 24px 28px; }
.sidebar__switch:checked ~ .sidebar__panel { display: block; }

/* 모바일: 상단 헤더(사이드바 바)를 화면 위에 고정 — 스크롤해도 따라옵니다.
   메뉴가 닫혀 있으면 바만 붙어 있고, 열면 그 아래로 메뉴가 펼쳐집니다.
   데스크톱(≥1024px)은 아래 별도 규칙에서 전체 높이 고정으로 처리합니다. */
@media (max-width: 1023px) {
  .sidebar {
    position: sticky;
    top: 0;
    z-index: 50;
    border-bottom: 1px solid var(--border);
  }
}

.snav__list { display: flex; flex-direction: column; }

/* 항목: 아이콘 24 + gap 8 + 텍스트, padding 12/16 → 높이 56px */
.snav__item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 16px 12px;
  border-radius: var(--r-xs);
  color: var(--nav-text);
  font-size: 1rem;
  font-weight: 500;
  line-height: 24px;
  letter-spacing: -0.4px;
  transition: background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}

/* 왼쪽 포인트 바 — 카드 목록의 행과 같은 표현을 씁니다. */
.snav__item::before {
  content: "";
  position: absolute;
  left: 0; top: 8px; bottom: 8px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--accent);
  transform: scaleY(0);
  transition: transform .22s var(--ease-out);
}
.snav__item:hover::before,
.snav__item:focus-visible::before,
.snav__item[aria-current="page"]::before { transform: scaleY(1); }

.snav__icon {
  width: 24px; height: 24px;
  flex: 0 0 auto;
  transition: translate var(--dur-fast) var(--ease-out);
}
.snav__item:hover .snav__icon,
.snav__item:focus-visible .snav__icon { translate: 2px 0; }
.snav__text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ⚠️ 피그마 시안의 보라색 항목은 호버 상태입니다.
   특정 항목에 고정하지 않고 :hover 로 두고, 현재 페이지에만 같은 표시를 씁니다. */
.snav__item:hover,
.snav__item:focus-visible,
.snav__item[aria-current="page"] {
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 600;
}

/* ── 히어로 (피그마 933:9150) ─────────────────────────────────
   배지 → 제목 → 서브텍스트 ↕48px 검색 바 */

.hero {
  display: flex;
  flex-direction: column;
  gap: 48px;
  padding-block: 16px 0;
  margin-bottom: 64px;
}

.hero__head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 36px;
}

/* ── 배지 ── */

.hero-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 16px 40px;
  background: #fff;
  border: 1px solid #fff;
  border-radius: var(--r-pill);
  box-shadow: 0 6px 8px rgb(0 0 0 / 0.04);
  backdrop-filter: blur(8px);
  font-size: 1.25rem;
  font-weight: 500;
  line-height: 30px;
  letter-spacing: -0.5px;
}

/*
 * "살아 있다"는 신호로 아주 느리게 번지는 링.
 * opacity 대신 box-shadow 색의 알파를 줄여 사라지게 하므로
 * 첫 페인트에 무언가를 숨기는 규칙과 무관합니다. ([6])
 */
.hero-badge__dot {
  width: 10px; height: 10px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--hero-gradient);
}
@media (prefers-reduced-motion: no-preference) {
  .hero-badge__dot { animation: dot-pulse 2.6s var(--ease-out) infinite; }
  @keyframes dot-pulse {
    0%   { box-shadow: 0 0 0 0 rgb(99 102 241 / 0.45); }
    70%  { box-shadow: 0 0 0 9px rgb(99 102 241 / 0); }
    100% { box-shadow: 0 0 0 0 rgb(99 102 241 / 0); }
  }
}

/*
 * 그라디언트 글자.
 * background-clip 을 지원하지 않는 브라우저에서 글자가 사라지지 않도록
 * 단색을 먼저 깔고, 지원할 때만 transparent 로 바꿉니다.
 */
.hero-badge__text { color: #4338ca; }
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .hero-badge__text {
    background-image: var(--hero-gradient);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
}

/* ── 제목 ── */

.hero__title-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  text-align: center;
}
.hero__title {
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 1.5rem + 3vw, 3.5rem);
  line-height: 1.108;
  font-weight: 800;
  color: #222;
}
.hero__sub {
  max-width: 842px;
  font-size: 1.125rem;
  line-height: 26px;
  letter-spacing: -0.45px;
  color: #767676;
}

/* 검색 바와 바로가기 줄은 한 덩어리로 묶어 40px 간격을 씁니다. */
.hero__tools {
  display: flex;
  flex-direction: column;
  gap: 40px;
}

/* ── 검색 바 ── */

/*
 * 바 자체를 알약 모양으로 잡습니다. 안에 든 검색 버튼이 알약인데
 * 바깥 상자만 각지면 두 모서리가 서로 따로 놉니다.
 * 높이는 84(내용) + 14×2(여백) + 테두리 2×2 = 116px.
 */
.hero-search {
  position: relative;
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
  padding: 14px 14px 14px 26px;
  border: 2px solid transparent;
  border-radius: var(--r-pill);
  /*
   * 두 겹으로 칠합니다.
   *   padding-box → 안쪽 면. 위는 순백, 아래로 갈수록 옅은 라벤더.
   *   border-box  → 테두리 자리. 안쪽 면이 덮으므로 2px 테두리만 남습니다.
   * 덕분에 그라디언트 테두리를 이미지 하나 없이 그릴 수 있습니다.
   */
  background:
    linear-gradient(180deg, #ffffff 55%, #f6f3ff) padding-box,
    linear-gradient(115deg, #c9c3f9, #dfc4fd 55%, #cccefb) border-box;
  /*
   * 시안의 그림자(8px 10px 10px / 검정 16%)는 오른쪽 아래로 쏠려 있어
   * 바가 기울어 보입니다. 가운데로 모으고, 아래로 아주 넓게 퍼지는
   * 세 번째 겹을 더해 바 밑에 빛무리를 깔았습니다.
   */
  box-shadow: 0 1px 2px rgb(16 24 40 / 0.04),
              0 16px 34px -12px rgb(67 56 202 / 0.22),
              0 40px 80px -36px rgb(99 102 241 / 0.34);
  transition: box-shadow .28s var(--ease-out);
}
/* 커서만 올려도 테두리가 한 톤 진해집니다 — 누를 수 있는 자리라는 신호. */
.hero-search:hover {
  background:
    linear-gradient(180deg, #ffffff 55%, #f6f3ff) padding-box,
    linear-gradient(115deg, #a99ff5, #cf9dfc 55%, #adb1f8) border-box;
  box-shadow: 0 1px 2px rgb(16 24 40 / 0.04),
              0 18px 38px -12px rgb(67 56 202 / 0.26),
              0 44px 86px -36px rgb(99 102 241 / 0.38);
}
/* 안쪽 어디든 포커스가 들어오면 테두리에 히어로 그라디언트가 켜집니다. */
.hero-search:focus-within {
  background:
    linear-gradient(180deg, #ffffff 55%, #f6f3ff) padding-box,
    var(--hero-gradient) border-box;
  box-shadow: 0 2px 4px rgb(16 24 40 / 0.05),
              0 22px 46px -14px rgb(67 56 202 / 0.34),
              0 48px 92px -36px rgb(99 102 241 / 0.42);
}

/*
 * 바 뒤에 깔리는 빛무리.
 *
 * 흰 바를 거의 흰 배경(#F7F8FA) 위에 얹으면 아무리 그림자를 키워도
 * 묻힙니다. 바닥에 색을 깔아 두면 흰색이 스스로 도드라집니다.
 *
 * z-index:-1 이라 바의 흰 배경 뒤로 들어갑니다. .hero-search 는
 * position:relative 이지만 z-index 가 auto 라 쌓임 맥락을 만들지 않고,
 * 그래서 음수 z-index 자식이 부모 배경보다 아래에 그려집니다.
 */
.hero-search::before {
  content: "";
  position: absolute;
  inset: -34px -44px -52px;
  z-index: -1;
  pointer-events: none;
  border-radius: var(--r-pill);
  background:
    radial-gradient(58% 105% at 50% 56%, rgb( 99 102 241 / 0.26), transparent 70%),
    radial-gradient(46%  92% at 14% 60%, rgb( 67  56 202 / 0.20), transparent 72%),
    radial-gradient(48%  95% at 86% 54%, rgb(192 132 252 / 0.26), transparent 72%);
  transition: scale .4s var(--ease-out);
}
.hero-search:focus-within::before { scale: 1.04; }

/* ── 검색 엔진 커스텀 드롭다운 ── */

.engine { position: relative; flex: 0 0 auto; width: 144px; }
.engine__box { width: 100%; }

/*
 * 트리거·검색 입력 모두 평소에는 테두리도 배경도 없습니다.
 * 흰 카드 위에 글자만 얹힌 상태(시안 그대로)이고,
 * 반응은 색과 은은한 틴트로만 표현합니다.
 */
.engine__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  height: 84px;
  padding: 0 16px;
  background: transparent;
  border: 0;
  border-radius: var(--r-pill);            /* 바가 알약이라 안쪽 반응도 알약으로 */
  color: #374151;
  font-size: 1.125rem;
  font-weight: 600;                        /* 고른 값이므로 자리표시자처럼 보이지 않게 */
  line-height: 26px;
  letter-spacing: -0.45px;
  cursor: pointer;
  list-style: none;                        /* 기본 삼각형 제거 */
  user-select: none;
  transition: background-color .2s var(--ease-out), color .2s var(--ease-out),
              box-shadow .2s var(--ease-out);
}
.engine__trigger::-webkit-details-marker { display: none; }
.engine__trigger:hover { background: rgb(99 102 241 / 0.06); color: #4338ca; }

/* 열려 있을 때·포커스가 왔을 때 */
.engine__box[open] .engine__trigger,
.engine__trigger:focus-visible {
  background: rgb(99 102 241 / 0.08);
  color: #4338ca;
  box-shadow: 0 0 0 3px rgb(99 102 241 / 0.18);
  outline: none;
}

.engine__chevron {
  width: 18px; height: 18px;
  flex: 0 0 auto;
  color: #a8aeba;
  transition: transform .2s var(--ease-out), color .2s var(--ease-out);
}
.engine__trigger:hover .engine__chevron { color: #4338ca; }
.engine__box[open] .engine__chevron { transform: rotate(180deg); }

/* 라디오는 화면에서 감추되 키보드 포커스는 살려 둡니다(값의 실체). */
.engine__radio:focus-visible ~ .engine__box .engine__trigger {
  background: rgb(99 102 241 / 0.08);
  color: #4338ca;
  box-shadow: 0 0 0 3px rgb(99 102 241 / 0.18);
}

/* 선택된 항목의 이름만 트리거에 표시.
   :has() 를 못 쓰는 아주 오래된 브라우저에서는 기본값(네이버)이 보입니다. */
.engine__value > span { display: none; }
.engine__value > [data-for="naver"] { display: inline; }
@supports selector(:has(*)) {
  .engine__value > [data-for="naver"] { display: none; }
  .engine:has(#eng-naver:checked)  .engine__value > [data-for="naver"]  { display: inline; }
  .engine:has(#eng-google:checked) .engine__value > [data-for="google"] { display: inline; }
  .engine:has(#eng-daum:checked)   .engine__value > [data-for="daum"]   { display: inline; }
}

.engine__list {
  position: absolute;
  z-index: 20;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  padding: 6px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: 0 14px 32px -8px rgb(67 56 202 / 0.24);
}

.engine__option {
  display: block;
  padding: 11px 12px;
  border-radius: var(--r-sm);
  color: #4b5563;
  font-size: 1rem;
  line-height: 24px;
  letter-spacing: -0.4px;
  cursor: pointer;
  transition: background-color .15s var(--ease-out), color .15s var(--ease-out);
}
.engine__option:hover { background: #eef2ff; color: #4338ca; }

/* 현재 선택된 항목 강조 */
@supports selector(:has(*)) {
  .engine:has(#eng-naver:checked)  .engine__option[for="eng-naver"],
  .engine:has(#eng-google:checked) .engine__option[for="eng-google"],
  .engine:has(#eng-daum:checked)   .engine__option[for="eng-daum"] {
    background: #eef2ff;
    color: #4338ca;
    font-weight: 600;
  }
}

/* 엔진 셀렉트와 같은 높이(84) · 테두리와 배경 없음 */
.hero-search__field {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1 1 320px;
  min-width: 0;
  height: 84px;
  padding: 0 14px;
  background: transparent;
  border: 0;
  border-radius: var(--r-pill);
  transition: background-color .2s var(--ease-out), box-shadow .2s var(--ease-out);
}
.hero-search__field:hover { background: rgb(99 102 241 / 0.05); }

/* 입력 안의 어디에 포커스가 들어와도 영역 전체가 반응합니다. */
.hero-search__field:focus-within {
  background: rgb(99 102 241 / 0.08);
  box-shadow: 0 0 0 3px rgb(99 102 241 / 0.18);
}

/*
 * 돋보기를 동그란 자리에 앉힙니다. 허공에 뜬 회색 아이콘보다
 * "여기가 입력 칸"이라는 게 분명해지고, 바가 커진 만큼 왼쪽이 비지 않습니다.
 */
.hero-search__badge {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 52px; height: 52px;
  border-radius: 50%;
  background: #f1f0fd;
  color: #8b8fa3;
  transition: background-color .2s var(--ease-out), color .2s var(--ease-out);
}
.hero-search__field:hover .hero-search__badge { background: #e7e4fc; color: #6366f1; }
.hero-search__field:focus-within .hero-search__badge {
  background: var(--hero-gradient);
  color: #fff;
  box-shadow: 0 6px 14px -4px rgb(99 102 241 / 0.55);
}

.hero-search__icon { width: 22px; height: 22px; }

.hero-search__input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0;
  background: transparent;
  border: 0;
  color: var(--text);
  font: inherit;
  font-size: 1.125rem;
  line-height: 26px;
  letter-spacing: -0.45px;
}
.hero-search__input::placeholder { color: #a8aeba; }
/* 커서와 드래그 선택도 포인트 컬러로 — 작지만 손에 닿는 부분입니다. */
.hero-search__input { caret-color: #6366f1; }
.hero-search__input::selection { background: rgb(99 102 241 / 0.22); }
/* 포커스 표시는 위의 상자(:focus-within 링)가 대신하므로 기본 아웃라인은 끕니다. */
.hero-search__input:focus { outline: none; }

/*
 * 검색 버튼 — 그라디언트를 넓게 깔고(220%) 호버 때 위치를 밀어
 * 색이 흐르듯 바뀌게 합니다. filter 로 밝기만 바꾸는 것보다 훨씬 부드럽습니다.
 */
.hero-search__submit {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  height: 84px;
  padding: 0 44px;
  border: 0;
  border-radius: var(--r-pill);
  background-image: var(--hero-gradient-btn);
  background-size: 220% 100%;
  background-position: 0% 50%;
  /* 위쪽 안쪽에 흰 선 한 줄 — 버튼 윗면에 광택이 생깁니다. */
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.28),
              0 6px 16px rgb(99 102 241 / 0.30);
  color: #fff;
  font: inherit;
  font-size: 1.125rem;
  font-weight: 600;
  line-height: 26px;
  letter-spacing: -0.45px;
  cursor: pointer;
  transition: background-position .5s var(--ease-out), box-shadow .25s var(--ease-out),
              translate .2s var(--ease-out);
}
.hero-search__submit:hover {
  background-position: 100% 50%;
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.28),
              0 12px 26px rgb(99 102 241 / 0.42);
  translate: 0 -2px;
}
.hero-search__submit:focus-visible {
  outline: none;
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.28),
              0 6px 16px rgb(99 102 241 / 0.30),
              0 0 0 4px rgb(99 102 241 / 0.32);
}
.hero-search__submit:active {
  translate: 0 1px;
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.28),
              0 4px 12px rgb(99 102 241 / 0.30);
}

/* 글자 뒤 화살표 — 눌렀을 때 어디로 가는지(바깥 검색 결과)를 알려 줍니다. */
.hero-search__submit-arrow {
  width: 15px; height: 15px;
  flex: 0 0 auto;
  transition: translate .2s var(--ease-out);
}
.hero-search__submit:hover .hero-search__submit-arrow { translate: 3px -3px; }

/* ── 바로가기 줄 (피그마 926:8622 외) ─────────────────────────
   카드 206.67×104 · radius 8 · 흰 배경 · 간격 12px
   개수가 달라져도 한 줄을 고르게 채우도록 flex 로 나눕니다. */

.shortcuts__list {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.shortcuts__item { flex: 1 1 168px; }

.shortcuts__link {
  display: grid;
  place-items: center;
  height: 104px;
  padding: 16px 20px;
  background: #fff;
  border-radius: var(--r-sm);
  overflow: hidden;
  transition: translate var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}
a.shortcuts__link:hover,
a.shortcuts__link:focus-visible {
  translate: 0 var(--lift-sm);
  box-shadow: var(--shadow-hover);
}
.shortcuts__link--plain { cursor: default; }

/* 로고는 잘리지 않게 contain — 비율이 제각각이라 cover 면 글자가 날아갑니다. */
.shortcuts__img {
  max-width: 100%;
  max-height: 56px;
  width: auto;
  height: auto;
  object-fit: contain;
  transition: scale var(--dur) var(--ease-out);
}
a.shortcuts__link:hover .shortcuts__img { scale: 1.06; }
.shortcuts__link .img-fallback { width: auto; min-width: 96px; aspect-ratio: 3 / 1; }

@media (max-width: 720px) {
  .hero { gap: 32px; }
  .hero__head { gap: 24px; }
  .hero-badge { padding: 12px 24px; font-size: 1rem; line-height: 24px; }
  /* 세로로 쌓이면 알약 모양이 성립하지 않으므로 모서리를 되돌립니다. */
  .hero-search { padding: 14px; gap: 8px; border-radius: var(--r-lg); }
  .hero-search::before { inset: -20px -16px -28px; border-radius: var(--r-lg); }
  .engine { width: 100%; }
  .engine__trigger { height: 64px; border-radius: var(--r-md); }
  .hero-search__field { flex-basis: 100%; height: 64px; border-radius: var(--r-md); }
  .hero-search__badge { width: 40px; height: 40px; }
  .hero-search__submit { width: 100%; height: 60px; padding: 0 24px; justify-content: center; }

  /* 본문(.prose) 의 좁은 화면 규칙은 기본 정의보다 뒤에 있어야 해서
     파일 뒤쪽 "좁은 화면의 본문" 블록으로 옮겼습니다. */

  .shortcuts__item { flex: 1 1 calc(50% - 6px); }
  .shortcuts__link { height: 78px; padding: 12px; }
  .shortcuts__img { max-height: 40px; }
}

/* ── 배너 섹션 (피그마 925:3830) ──────────────────────────────
   제목 블록 ↕32px 그리드 · 2열 · 가로 20px / 세로 16px · 높이 118px */

.promo {
  display: flex;
  flex-direction: column;
  gap: 32px;
  margin-bottom: 64px;
}

.promo__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);   /* 모바일도 2열 */
  gap: 12px;
}

/*
 * 모바일에서는 높이를 고정하지 않고 비율로 둡니다. 폭이 절반으로 줄어든
 * 자리에 118px 을 그대로 두면 거의 정사각형이 되어, 가로로 긴 배너 원본이
 * 가운데만 남고 양옆이 잘려 나갑니다.
 *
 * 비율은 PC 와 같은 시안 치수 630×118 그대로입니다 — 폭만 달라지고
 * 잘리는 정도는 PC 와 똑같습니다.
 */
.promo__item {
  display: block;
  aspect-ratio: 630 / 118;
  overflow: hidden;
  background: #d9d9d9;                     /* 이미지가 뜨기 전 자리 색 (시안과 동일) */
  transition: opacity var(--dur) var(--ease-out);
}
/* 하나를 가리키면 나머지는 살짝 물러납니다(가리키는 대상에 시선이 모이게). */
.promo__grid:hover .promo__item { opacity: .55; }
.promo__grid:hover .promo__item:hover,
.promo__grid .promo__item:focus-within { opacity: 1; }
.promo__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.promo__item .img-fallback {
  width: 100%; height: 100%;
  aspect-ratio: auto;
  border: 0;
  border-radius: 0;
}

/* 링크가 걸린 배너에만 반응 — 장식 배너는 그대로 둡니다. */
a.promo__item {
  transition: translate var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}
a.promo__item .promo__img { transition: scale .5s var(--ease-out); }
a.promo__item:hover,
a.promo__item:focus-visible {
  translate: 0 var(--lift-sm);
  box-shadow: var(--shadow-hover);
}
a.promo__item:hover .promo__img,
a.promo__item:focus-visible .promo__img { scale: 1.05; }

@media (min-width: 640px) {
  /* 시안 치수 — 폭이 충분해지면 높이를 118px 로 고정합니다(원본 비율에 가깝습니다). */
  .promo__grid { column-gap: 20px; row-gap: 16px; }
  .promo__item { height: 118px; aspect-ratio: auto; }
}

/* ── 페이지 헤딩 ────────────────────────────────────────────── */

.page-title {
  font-size: clamp(1.5rem, 1.15rem + 1.4vw, 2.1rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.25;
}

/*
 * 홈 상단 제목 블록 (피그마 925:3804)
 *   아이브로우 20px/30px · -0.5px · #767676
 *   제목      Tenada ExtraBold 48px/56px · #222
 *   간격 16px · 텍스트 폭 585px
 * 좁은 화면에서는 제목만 줄어들도록 clamp 로 감쌌고, 데스크톱에서 정확히 48px 입니다.
 */
/*
 * 제목 블록 자체에는 아래 여백을 두지 않습니다.
 * 제목과 뒤따르는 내용의 간격은 항상 바깥 섹션의 gap 이 정합니다(둘 다 32px).
 * 여기에 margin 을 두면 flex 섹션에서는 gap 에 더해지고(배너 40px),
 * 블록 섹션에서는 형제 마진과 병합돼(카드 24px) 값이 서로 어긋납니다.
 */
.page-intro {
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 585px;
}
.page-intro__eyebrow {
  font-size: 1.25rem;
  line-height: 30px;
  letter-spacing: -0.5px;
  color: #767676;
}
.page-intro__title {
  font-family: var(--font-display);
  font-size: clamp(2rem, 1.4rem + 2.4vw, 3rem);
  line-height: 1.17;
  font-weight: 800;
  color: #222;
}
/* 서브페이지에서 제목 아래에 붙는 설명 (히어로 서브텍스트와 같은 타입) */
.page-intro__desc {
  max-width: 842px;
  font-size: 1.125rem;
  line-height: 26px;
  letter-spacing: -0.45px;
  color: #767676;
}

/*
 * 제목 블록 ↕32px 내용 — 홈의 배너·카드 섹션과 같은 간격 규칙을 씁니다.
 * 간격은 언제나 바깥 섹션의 gap 한 곳에서만 결정됩니다.
 */
.page-section {
  display: flex;
  flex-direction: column;
  gap: 32px;
}
/* 섹션이 연달아 올 때의 간격 — 홈의 카드 섹션 ↕ 설명 본문 섹션 */
.page-section + .page-section { margin-top: 120px; }
.page-lead { margin-top: 10px; color: var(--text-muted); max-width: 68ch; }
.page-meta { margin-top: 8px; font-size: .85rem; color: var(--text-dim); }
.page-head { margin-bottom: 24px; }
.section-title { font-size: 1.15rem; font-weight: 700; margin-bottom: 12px; }

.breadcrumb { margin-bottom: 16px; font-size: .84rem; color: var(--text-dim); }
.breadcrumb ol { display: flex; flex-wrap: wrap; gap: 6px; }
.breadcrumb li + li::before { content: "›"; margin-right: 6px; color: var(--border-strong); }
.breadcrumb a:hover { color: var(--accent); }

/* ── 홈: 카테고리 카드 (피그마 927:8836) ──────────────────────
   히어로 이미지 → 라벨/카테고리명 → 상위 N개 랭킹 → 전체 랭킹보러가기.
   열 간격 40px, 행 간격 60px 은 시안 값입니다. */

.cards {
  display: grid;
  grid-template-columns: 1fr;              /* 모바일 1열 */
  column-gap: 40px;
  row-gap: 60px;
}

.card {
  display: flex;
  flex-direction: column;
  background: var(--bg-raised);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--shadow-card);
  transition: translate var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}
.card:hover,
.card:focus-within {
  translate: 0 var(--lift);
  box-shadow: var(--shadow-card-hover);
}

/* ── 히어로 ── */

.card__hero {
  display: block;
  height: 260px;
  overflow: hidden;
  background: var(--bg-sunken);
}
.card__hero-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: scale .5s var(--ease-out);
}
.card:hover .card__hero-img { scale: 1.04; }
.card__hero .img-fallback { width: 100%; height: 100%; aspect-ratio: auto; border-radius: 0; }

.card__hero-body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 24px 24px 16px;
}

.card__eyebrow {
  font-size: .875rem;
  line-height: 20px;
  font-weight: 600;
  letter-spacing: -0.3px;
  color: #767676;                          /* 서브페이지 라벨과 같은 회색 */
}

/* 제목이 포인트 컬러를 가져갔으므로 링크 표시는 두지 않습니다. */
.card__title {
  font-family: var(--font-display);
  font-size: 2rem;
  line-height: 40px;
  font-weight: 800;
  letter-spacing: -0.8px;
  color: var(--accent);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.card__empty {
  padding: 0 24px 20px;
  color: var(--text-dim);
  font-size: .9rem;
}

/* ── 랭킹 행 ──
   호버 배경이 아래 "전체 랭킹보러가기" 와 겹치지 않도록 목록 자체에
   아래 여백을 두고, 행은 그 안에서만 칠해집니다. */

.card__list {
  display: flex;
  flex-direction: column;
  padding: 0 16px 16px;
}

.row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 12px 12px 10px;
  border-radius: var(--r-sm);
  transition: background-color var(--dur-fast) var(--ease-out);
}
.row:hover,
.row:focus-visible { background: var(--accent-soft); }

.row__badge {
  flex: 0 0 auto;
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 30px; height: 30px;
  overflow: hidden;
  border-radius: 9px;
  background: #222;
  color: #fff;
  font-size: .9375rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
  transition: background-color var(--dur-fast) var(--ease-out);
}
.row:hover .row__badge { background: var(--accent); }
/* 호버할 때 배지 위로 빛이 한 번 스칩니다. */
.row__badge::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 20%, rgb(255 255 255 / 0.55), transparent 80%);
  translate: -130% 0;
  transition: translate .5s var(--ease-out);
}
.row:hover .row__badge::after { translate: 130% 0; }

.row__body {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1 1 auto;
}
.row__name {
  height: 26px;                            /* 한 줄 — .roll 이 이 높이만큼 굴립니다 */
  font-family: var(--font-display);
  font-size: 1.1875rem;
  line-height: 26px;
  font-weight: 800;
  letter-spacing: -0.4px;
  color: #000;
  transition: color var(--dur-fast) var(--ease-out);
}
.row:hover .row__name { color: var(--accent); }

.row__domain {
  font-size: .9375rem;
  line-height: 20px;
  letter-spacing: -0.35px;
  color: #9ca3af;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 구르는 건 사이트명뿐 — 도메인은 제자리에 둡니다. */
.row:hover .row__name .roll__inner { translate: 0 -50%; }

.row__arrow {
  width: 15px; height: 15px;
  flex: 0 0 auto;
  color: #6b7280;
  transition: color var(--dur-fast) var(--ease-out), translate var(--dur-fast) var(--ease-out);
}
.row:hover .row__arrow { color: var(--accent); translate: 3px -3px; }

/* ── 전체 랭킹보러가기 ── */

.card__more {
  display: block;
  margin-top: auto;
  padding: 18px 24px;
  border-top: 1px solid var(--border);
  color: var(--accent);
  font-size: 1rem;
  font-weight: 700;
  text-align: center;
  transition: background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.card__more:hover,
.card__more:focus-visible { background: var(--accent); color: var(--accent-on); }

/* ── 카테고리 페이지: 순위 목록 ───────────────────────────────
   항목마다 독립된 둥근 면. 공용 판(panel) 을 쓰면 항목 수가 열 수로
   나눠떨어지지 않을 때 구분선이 허공에서 끊겨 보여서 그렇게 하지 않습니다.

     ┌──────────────────────────────────┐
     │ 01  [로고]  디시인사이드      (↗) │
     │             dcinside.com         │
     └──────────────────────────────────┘ */

/*
 * 열 수를 뷰포트가 아니라 실제 남은 폭으로 정합니다.
 *
 * 미디어 쿼리로 잡으면 1024px 에서 사이드바(340px)가 나타나는 순간 카드가
 * 갑자기 좁아져 이름·도메인이 잘립니다. auto-fit + minmax 는 그리드가 쓸 수
 * 있는 폭만 보고 판단하므로 사이드바 유무가 저절로 반영됩니다.
 *
 * min(440px, 100%) — 440px 이 그대로 최소값이면 모바일에서 그리드가
 * 뷰포트보다 넓어집니다. 100% 로 한 번 묶어 둡니다.
 */
.rank-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(440px, 100%), 1fr));
  gap: 16px;
}

.rank {
  position: relative;
  display: flex;
  align-items: stretch;
  min-width: 0;
  background: var(--bg-raised);
  border-radius: var(--r-lg);
  overflow: hidden;
  /* 테두리는 inset 그림자로 그립니다 — 바깥 그림자와 한 속성 안에 모여
     있어 상태가 바뀔 때 값만 갈아 끼우면 됩니다.
     흰 카드가 #f7f8fa 배경 위에 있어 1px 선만으로는 형태가 흐립니다.
     넓게 퍼지는 그림자를 한 겹 더 깔아 판이 떠 있게 만듭니다. */
  box-shadow: inset 0 0 0 1px var(--border),
              0 1px 2px rgb(16 24 40 / 0.04),
              0 10px 24px -16px rgb(16 24 40 / 0.28);
  transition: translate var(--dur) var(--ease-out),
              box-shadow var(--dur) var(--ease-out);
}
/*
 * box-shadow 전환은 매 프레임 다시 그립니다. 그림자 개수를 평소와 똑같이
 * 세 겹으로 맞춰 두면 브라우저가 층을 새로 만들지 않고 값만 보간합니다.
 */
.rank:hover,
.rank:focus-within {
  translate: 0 var(--lift);
  /* 바뀌는 건 맨 앞 층(테두리)뿐입니다 — 바깥 두 층은 평소 값 그대로라
     색이 번지지 않고 카드만 떠오릅니다. */
  box-shadow: inset 0 0 0 1px rgb(var(--accent-rgb) / 0.55),
              0 1px 2px rgb(16 24 40 / 0.04),
              0 10px 24px -16px rgb(16 24 40 / 0.28);
}

/* 1위도 카드 자체는 다른 항목과 똑같습니다 — 순위는 .rank__no--top 의
   그라디언트 숫자가 표시합니다. (.rank--first 는 마크업 훅으로만 남습니다.) */

.rank__main {
  position: relative;
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: 16px;
  min-width: 0;
  padding: 22px 20px;                      /* 68(로고) + 22×2 = 112px */
}

/*
 * 순위 —— 카드의 첫 번째 조형 요소로 크게 세웁니다.
 *
 * 숫자에는 디스플레이 폰트(Tenada)를 쓰지 않습니다. 세로 메트릭이 본문
 * 폰트와 달라 상자 안에서 위로 치우치고, 자간도 0 으로 둡니다 — 음수
 * 자간은 마지막 글자 뒤에도 붙어 한 자리 숫자를 왼쪽으로 밀어 버립니다.
 */
.rank__no {
  flex: 0 0 auto;
  width: 34px;
  text-align: center;
  font-size: 2rem;
  line-height: 1;
  font-weight: 800;
  letter-spacing: 0;
  color: #d3d8e0;
  font-variant-numeric: tabular-nums;
}
.rank__no--top { color: var(--accent); }

/*
 * 1~3위 숫자는 브랜드 그라디언트로 칠합니다. 글자를 배경으로 칠하는
 * 방식이라 획 안에서 색이 흐르고, 배지처럼 면을 만들지 않아 로고 타일과
 * 부딪히지 않습니다.
 *
 * @supports 로 감싼 이유: background-clip 이 없는 브라우저에서
 * color:transparent 만 적용되면 숫자가 통째로 사라집니다.
 */
@supports (background-clip: text) or (-webkit-background-clip: text) {
  .rank__no--top {
    background: var(--brand-fill);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
}

/*
 * 사이트 로고 — 관리자가 올린 이미지가 있으면 그것을, 없으면 이름 첫 글자를
 * 보여줍니다. 순위 숫자와 이름 사이의 빈 공간을 메워 카드가 허전하지 않게
 * 하는 자리입니다(.rank__main 의 패딩도 이 폭을 전제로 잡혀 있습니다).
 */
.rank__logo {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 68px; height: 68px;
  border-radius: 18px;
  overflow: hidden;
  /* 바탕은 흰색 — 업로드한 로고가 색 위에 얹히지 않게 둡니다. */
  background: var(--bg-raised);
  box-shadow: inset 0 0 0 1px var(--border);
}
.rank__logoimg { width: 68px; height: 68px; object-fit: contain; }
/*
 * 폴백(머리글자)일 때만 타일 안쪽을 포인트 컬러로 칠합니다. 이미지가 없는
 * 항목이 빈 흰 네모로 남지 않고, 로고가 올라오면 흰 바탕으로 되돌아갑니다.
 */
.rank__logo .img-fallback {
  width: 68px; height: 68px;
  aspect-ratio: auto;
  min-width: 0;
  border: 0;
  border-radius: 0;
  background: linear-gradient(140deg, rgb(var(--accent-rgb) / 0.20), rgb(var(--accent-rgb) / 0.07)),
              var(--accent-soft);
  /* 라벤더 면에는 회색 테두리가 탁해 보여 같은 계열로 한 겹 얹습니다. */
  box-shadow: inset 0 0 0 1px rgb(var(--accent-rgb) / 0.18);
  font-size: 1.625rem;
}

.rank__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;                 /* 도메인 칩이 폭 전체로 늘어나지 않게 */
  gap: 8px;
  min-width: 0;
  flex: 1 1 auto;
}

.rank__name {
  height: 28px;
  max-width: 100%;
  font-family: var(--font-display);
  font-size: 1.3125rem;
  line-height: 28px;
  font-weight: 800;
  letter-spacing: -0.4px;
  color: #111;
}

/*
 * 도메인은 칩으로 — 맨 글자로 두면 이름 아래 회색 줄 하나로 흘러가서
 * 카드가 "제목 + 부제" 로만 읽힙니다. 면을 주면 주소라는 성격이 드러납니다.
 */
.rank__domain {
  max-width: 100%;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  background: var(--bg-sunken);
  font-size: .8125rem;
  line-height: 18px;
  letter-spacing: -0.2px;
  /* #a0a6b2 는 흰 배경에서 2.3:1 이라 본문 크기 글자로는 읽기 어렵습니다.
     --text-dim 은 4.8:1 로 WCAG AA 를 넘깁니다. */
  color: var(--text-dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/*
 * 오른쪽 끝의 행동 버튼. 화살표만 두면 2열 카드에서 오른쪽 절반이 비고,
 * "눌러서 어디로 가는지" 도 글자로 남지 않습니다. 알약 + 라벨로 둡니다.
 */
.rank__cta {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 40px;
  padding: 0 16px;
  border-radius: var(--r-pill);
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--border);
  color: var(--text-dim);
  font-size: .8125rem;
  font-weight: 700;
  white-space: nowrap;
}
.rank__arrow {
  width: 15px; height: 15px;
}

/* 상세 스위치가 켜졌을 때만 붙는 외부 이동 버튼 (행 오른쪽 끝) */
.rank__go {
  position: relative;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  padding: 0 16px;
  border-left: 1px solid var(--border);
  color: var(--accent);
  font-size: .8125rem;
  font-weight: 600;
  white-space: nowrap;
  transition: background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.rank__go:hover,
.rank__go:focus-visible { background: var(--accent); color: var(--accent-on); }
/* ── 굴러가는 글자 ───────────────────────────────────────────
   같은 글자를 두 벌 세로로 쌓아 두고, 호버하면 한 줄만큼 밀어 올립니다.
   위 글자가 빠져나가는 자리에 아래 글자가 정확히 들어오므로 제자리에서
   한 바퀴 구르는 것처럼 보입니다.

     평소            굴러가는 중        끝
     ┌────────┐      ┌────────┐       ┌────────┐
     │ ESPN   │      │ ESP…   │↑      │ ESPN   │
     └────────┘      └────────┘       └────────┘
       ESPN            ESPN

   미는 양은 -50% — 안쪽 상자가 두 줄이므로 그 절반이 정확히 한 줄입니다.
   줄 높이가 바뀌어도 값을 따라 고칠 필요가 없습니다.
   두 번째 벌은 Html::roll() 에서 aria-hidden 으로 막아 둡니다. */

.roll {
  display: block;
  overflow: hidden;                        /* 높이는 쓰는 쪽에서 한 줄로 고정 */
}
.roll__inner {
  display: flex;
  flex-direction: column;
  transition: translate .42s var(--ease-out);
}
.roll__line {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── 이미지 폴백 ([10] 깨진 이미지 금지) ────────────────────── */

.img-fallback {
  display: inline-grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 1;
  min-width: 36px;
  border-radius: var(--r-sm);
  background: linear-gradient(135deg, rgb(var(--accent-rgb) / 0.16), rgb(var(--accent-rgb) / 0.04)),
              var(--bg-sunken);
  border: 1px solid var(--border);
  color: var(--accent);
  font-size: .8rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  overflow: hidden;
}
.banners__item .img-fallback { aspect-ratio: 1200 / 200; font-size: 1rem; }

/* ── 상세 페이지 ────────────────────────────────────────────── */

.detail-head {
  display: flex;
  gap: 20px;
  align-items: flex-start;
  flex-wrap: wrap;
  padding: 22px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
}
.detail-head__thumb { flex: 0 0 auto; width: 88px; }
.detail-head__img { width: 88px; height: 88px; object-fit: contain; border-radius: var(--r-lg); background: var(--bg-sunken); }
.detail-head__body { flex: 1 1 260px; display: flex; flex-direction: column; gap: 10px; align-items: flex-start; }
.detail-cta { margin-top: 28px; text-align: center; }

/* ── 설명 본문 (관리자가 넣은 HTML) ──────────────────────────
   관리자는 태그만 쓰고 클래스는 붙이지 않습니다. 그래서 모든 모양을
   태그 선택자로만 잡습니다 — h2/h3/p/ul/table 만 써도 형태가 잡히도록. */

.prose {
  margin-top: 28px;
  color: #374151;
  font-size: 1.0625rem;
  line-height: 1.85;
  letter-spacing: -0.2px;
}
.prose > :first-child { margin-top: 0; }
.prose > :last-child  { margin-bottom: 0; }

/* 큰 제목 — 아래 실선으로 단락을 끊습니다 */
.prose h2 {
  margin-block: 2.2em .9em;
  padding-bottom: 14px;
  border-bottom: 2px solid var(--border);
  font-family: var(--font-display);
  font-size: 1.5rem;
  line-height: 1.4;
  font-weight: 800;
  letter-spacing: -0.6px;
  color: #111;
}

/* 소제목 — 앞에 포인트 컬러 막대. 관리자가 아이콘을 넣지 않아도
   시안처럼 항목이 구분됩니다. */
/* 소제목 — 표시 없이 글자만. 굵기와 위 여백으로 구분합니다. */
.prose h3 {
  margin-block: 2.1em .7em;
  font-size: 1.1875rem;
  line-height: 1.5;
  font-weight: 700;
  letter-spacing: -0.4px;
  color: #111;
}

.prose h4 {
  margin-block: 1.5em .5em;
  font-size: 1.0625rem;
  font-weight: 700;
  color: var(--accent);
}

.prose p { margin-block: 0 1.15em; }
.prose ul, .prose ol { margin-block: 0 1.15em; padding-left: 1.35em; }
.prose ul { list-style: disc; }
.prose ol { list-style: decimal; }
.prose li { margin-bottom: .4em; }
.prose li::marker { color: var(--accent); }

.prose a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}
.prose a:hover { text-decoration-thickness: 2px; }

.prose strong { font-weight: 700; color: #111; }
/* 강조 표시 — 시안에서 문장 중간을 색으로 짚는 자리 */
.prose em { font-style: normal; color: var(--accent); font-weight: 600; }
.prose mark { background: var(--accent-soft); color: var(--accent); padding: 0 4px; border-radius: 4px; }

.prose blockquote {
  margin-block: 1.4em;
  padding: 14px 20px;
  border-left: 3px solid var(--accent);
  background: var(--accent-soft);
  color: #4b5563;
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
}

.prose img { max-width: 100%; height: auto; border-radius: var(--r-md); }
.prose figure { margin-block: 1.6em; }
.prose hr { margin-block: 2em; border: 0; border-top: 1px solid var(--border); }

/* 표 — 머리행 회색 · 가운데 정렬 · 모서리 둥글게 */
.prose table {
  width: 100%;
  margin-block: 1.4em;
  border-collapse: separate;
  border-spacing: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  overflow: hidden;
  font-size: .9375rem;
  line-height: 1.6;
}
.prose th, .prose td {
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
  border-right: 1px solid var(--border);
  text-align: center;
}
/* 마지막 칸·마지막 줄의 선은 바깥 테두리와 겹치므로 지웁니다 */
.prose tr > :last-child { border-right: 0; }
.prose tr:last-child > * { border-bottom: 0; }
.prose th { background: var(--bg-sunken); font-weight: 700; color: #111; }

/* ── 본문 안에서 쓸 수 있는 조각들 ────────────────────────────
   앞의 규칙들이 태그만으로 모양을 잡는다면, 여기서부터는 관리자가
   HTML 소스에 클래스를 직접 적어 고르는 형태입니다.
   이름을 짧게 둔 이유는 손으로 타이핑하기 때문입니다. */

/*
 * ① 알림 상자 — <div class="note">
 *
 * 모양은 한 가지뿐입니다. 예전에 쓰던 .note--warn / .note--tip 도 같은
 * 모양으로 나옵니다(이미 저장된 글이 깨지지 않도록 클래스만 남겨 둠).
 * 무슨 상자인지는 색이 아니라 맨 앞의 <strong> 이 알려 줍니다 —
 * "주의", "도움말", "정리하면" 처럼요.
 */
.prose .note {
  display: flow-root;                      /* 안쪽 문단 여백이 밖으로 새지 않게 */
  margin-block: 1.5em;
  padding: 18px 22px;
  border-left: 4px solid var(--border-strong);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  background: var(--bg);
  color: var(--text-muted);
  font-size: 1rem;
}
.prose .note > :last-child { margin-bottom: 0; }
/* 색은 앞머리 한 낱말에만 — 회색 상자 위에서 그 낱말만 도드라집니다. */
.prose .note strong { color: var(--accent); }

/* ② 번호 단계 — <ol class="steps"> */
.prose ol.steps {
  counter-reset: step;
  margin-block: 1.5em;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.prose ol.steps > li {
  position: relative;
  margin: 0;
  padding: 16px 20px 16px 58px;
  background: var(--bg);
  border-radius: var(--r-md);
}
.prose ol.steps > li::before {
  counter-increment: step;
  content: counter(step);
  position: absolute;
  left: 18px; top: 17px;
  display: grid;
  place-items: center;
  width: 26px; height: 26px;
  border-radius: 7px;
  background: var(--brand-fill);
  color: #fff;
  font-size: .875rem;
  font-weight: 800;
  line-height: 1;
}
/* 항목 첫머리의 <strong> 은 제목 줄로 떼어 냅니다 — 굵은 지침 + 설명 형태 */
.prose ol.steps > li > strong:first-child {
  display: block;
  margin-bottom: .35em;
  color: #111;
  line-height: 1.6;
}
/* 회색 상자 안에 들어가면 항목의 바탕은 뺍니다(상자와 겹쳐 탁해집니다) */
.prose .box ol.steps { gap: 18px; }
.prose .box ol.steps > li {
  padding: 0 0 0 40px;
  background: none;
  border-radius: 0;
}
.prose .box ol.steps > li::before { left: 0; top: 1px; }

/* ③ 용어 목록 — <dl> / <dt> / <dd> (클래스 없이) */
.prose dl {
  margin-block: 1.5em;
  display: grid;
  gap: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  overflow: hidden;
}
.prose dt {
  padding: 14px 20px 6px;
  font-weight: 700;
  color: #111;
}
.prose dd {
  margin: 0;
  padding: 0 20px 16px;
  color: #4b5563;
  font-size: 1rem;
}
.prose dd + dt { border-top: 1px solid var(--border); }

/* ④ 접히는 문답 — <details><summary>질문</summary>…</details>
      JS 없이 브라우저 기본 동작으로 열고 닫힙니다.

      상자를 하나씩 띄우면 질문 여섯 개가 여섯 덩어리로 흩어져 목록으로
      읽히지 않습니다. 테두리를 지우고 가로선만 남겨 한 판으로 묶습니다.
      연달아 놓인 것끼리 자동으로 이어 붙습니다. */
.prose details {
  margin-block: 0;
  border: 0;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  background: none;
}
.prose details:first-of-type { border-top: 1px solid var(--border); }

.prose summary {
  position: relative;
  display: block;
  padding: 20px 48px 20px 2px;
  font-size: 1.0625rem;
  line-height: 1.6;
  font-weight: 700;
  color: #111;
  cursor: pointer;
  list-style: none;
  transition: color var(--dur-fast) var(--ease-out);
}
.prose summary::-webkit-details-marker { display: none; }
.prose summary:hover,
.prose summary:focus-visible { color: var(--accent); }

/* 오른쪽 끝의 동그란 자리 안에 화살표. 열리면 채워지고 180° 돕니다. */
.prose summary::before {
  content: "";
  position: absolute;
  right: 0; top: 50%;
  width: 30px; height: 30px;
  translate: 0 -50%;
  border-radius: 50%;
  background: var(--bg);
  transition: background-color var(--dur-fast) var(--ease-out);
}
.prose summary::after {
  content: "";
  position: absolute;
  right: 11px; top: 50%;
  width: 8px; height: 8px;
  border-right: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  rotate: 45deg;
  translate: 0 -70%;
  transition: rotate var(--dur) var(--ease-out),
              translate var(--dur) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.prose summary:hover::before { background: var(--accent-soft); }

.prose details[open] summary { color: var(--accent); }
.prose details[open] summary::before { background: var(--accent); }
.prose details[open] summary::after {
  rotate: 225deg;
  translate: 0 -20%;
  border-color: var(--accent-on);
}

/* 답 — 질문과 같은 왼쪽 선에서 시작하고 아래에 여백을 둡니다 */
.prose details > :not(summary) { margin-inline: 2px; color: #4b5563; }
.prose details > :last-child { margin-bottom: 22px; }

/* ⑤ 두 칸 배치 — <div class="cols">…</div> */
.prose .cols {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
  margin-block: 1.5em;
}
.prose .cols > * { margin: 0; }
@media (min-width: 720px) {
  .prose .cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .prose .cols--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ⑥ 작은 상자 — .cols 안에 넣거나 단독으로 */
.prose .box {
  display: flow-root;
  padding: 28px 30px;
  background: var(--bg);
  border-radius: var(--r-lg);
}
/* 상자 안의 소제목은 포인트 컬러 대신 검정 — 회색 바탕에서 색이 뜹니다 */
.prose .box h4 {
  margin-block: 1.6em .7em;
  font-size: 1rem;
  color: #111;
}
.prose .box h4:first-child { margin-top: 0; }
.prose .box > :last-child { margin-bottom: 0; }
.prose .box h4 { margin-top: 0; }

/* ⑦ 체크 목록 — <ul class="check"> */
.prose ul.check { list-style: none; padding-left: 0; }
.prose ul.check > li {
  position: relative;
  padding-left: 28px;
}
.prose ul.check > li::before {
  content: "";
  position: absolute;
  left: 4px; top: .55em;
  width: 11px; height: 6px;
  border-left: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  rotate: -45deg;
}

/* ⑧ 코드·주소 표기 */
.prose code {
  padding: 2px 6px;
  border-radius: 5px;
  background: var(--bg-sunken);
  color: var(--accent);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .9em;
}
.prose pre {
  margin-block: 1.4em;
  padding: 18px 20px;
  border-radius: var(--r-md);
  background: #1f2333;
  color: #e6e8f2;
  overflow-x: auto;
  font-size: .875rem;
  line-height: 1.7;
}
.prose pre code { padding: 0; background: none; color: inherit; }

/* ⑨ 각주·부연 */
.prose small { font-size: .875rem; color: var(--text-dim); }

/* ⑩ 지침 목록 — <dl class="rules">
      굵은 한 문장(지침) 아래 설명 문단이 붙고, 쌍 사이가 넓게 벌어집니다.
      기본 <dl>(테두리 있는 용어 상자)과 달리 선 없이 글만 놓입니다. */
.prose dl.rules {
  display: block;
  margin-block: 1.8em;
  border: 0;
  border-radius: 0;
  overflow: visible;
}
.prose dl.rules dt {
  margin-top: 2.2em;
  padding: 0;
  font-size: 1.0625rem;
  line-height: 1.65;
  font-weight: 700;
  color: #111;
}
.prose dl.rules dt:first-child { margin-top: 0; }
.prose dl.rules dd {
  margin-top: .55em;
  margin-inline: 0;                        /* 브라우저 기본 들여쓰기 40px 제거 */
  padding: 0;
  color: #4b5563;
  font-size: 1rem;
}
.prose dl.rules dd + dt { border-top: 0; }
/* 지침 아래 붙는 참고 링크 목록 */
.prose dl.rules dd ul { margin-block: .7em 0; }

/* ⑪ 중첩 목록 — 1단계 ● / 2단계 –
      2단계에 다시 disc 를 쓰면 두 단계가 구분되지 않습니다. */
.prose li > ul,
.prose li > ol { margin-block: .55em 0; }
.prose ul ul { list-style: none; padding-left: 1.1em; }
.prose ul ul > li { position: relative; padding-left: 16px; }
.prose ul ul > li::before {
  content: "–";
  position: absolute;
  left: 0;
  color: var(--text-dim);
}
.prose ol ol { list-style: lower-alpha; }
.prose ol ol ol { list-style: lower-roman; }

/* ⑫ 용어 풀이 목록 — <ol class="terms">
      번호 · 용어 · 설명을 세 칸으로 나눕니다.

      용어에 min-width 를 주는 방식은 용어가 그 폭을 넘는 순간 그 줄만
      설명이 밀려 정렬이 깨집니다. 칸을 격자로 고정하면 용어 길이와
      상관없이 설명 시작선이 언제나 한 줄로 맞습니다. */
.prose ol.terms {
  margin-block: 1.6em;
  padding-left: 0;
  list-style: none;
  counter-reset: term;
  border-top: 1px solid var(--border);
}
.prose ol.terms > li {
  display: grid;
  grid-template-columns: 26px minmax(96px, 168px) minmax(0, 1fr);
  gap: 0 18px;
  margin: 0;
  padding: 15px 2px;
  border-bottom: 1px solid var(--border);
}
.prose ol.terms > li::before {
  counter-increment: term;
  content: counter(term) ".";
  color: var(--text-dim);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.prose ol.terms > li > :is(strong, b) {
  min-width: 0;
  color: #111;
  font-weight: 700;
}
/* 중첩 목록·문단은 설명 칸에 이어 붙입니다 */
.prose ol.terms > li > :is(ol, ul, p) {
  grid-column: 3;
  margin-block: .55em 0;
}

/* ⑬ 더 보기 링크 — <a class="more" href="…"> */
.prose a.more {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: .3em;
  font-weight: 600;
  text-underline-offset: 5px;
}
.prose a.more::after {
  content: "›";
  font-size: 1.2em;
  line-height: 1;
  translate: 0 -1px;
  transition: translate var(--dur-fast) var(--ease-out);
}
.prose a.more:hover::after { translate: 4px -1px; }

/* ── 카드에 담긴 설명 본문 (홈) ─────────────────────────────
   모든 요소가 카드 왼쪽 한 선에서 시작하고, 글줄은 카드 폭을 그대로
   씁니다. 폭을 좁히지 않으므로 같은 높이에 글이 더 많이 들어갑니다.

   위아래 여백은 margin-block 으로만 잡습니다 — 좌우에 값을 주면
   왼쪽 정렬선이 요소마다 어긋납니다. */

.prose--card {
  margin-top: 0;
  padding: 56px 40px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  min-width: 0;
}
.prose--card > * { max-width: none; margin-inline: 0; }

/* 카드 안에서는 바깥 면과 구분되도록 상자류의 바탕을 한 톤 낮춥니다. */
.prose--card ol.steps > li,
.prose--card .box { background: var(--bg); }

/* 본문 이미지 캡션은 시각적으로만 숨깁니다 (스크린리더는 읽음). ([4]) */
.prose figcaption {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── 좁은 화면의 본문 ─────────────────────────────────────────
 *
 * ⚠️ 이 블록은 반드시 위의 .prose 기본 정의보다 "뒤에" 있어야 합니다.
 *    선택자 우선순위가 같으면 미디어쿼리라도 나중에 선언된 쪽이 이깁니다.
 *    앞쪽(hero 옆) 720px 블록에 두었더니 한 줄도 적용되지 않았습니다.
 */
@media (max-width: 720px) {
  .prose--card { padding: 24px 20px; }

  /*
   * 표가 페이지를 옆으로 밀지 않도록 표 자체를 스크롤 상자로 만듭니다.
   * 관리자 HTML 에 감싸는 태그를 끼워 넣을 수 없어서(원문 변형 금지, [4])
   * 표에 직접 겁니다.
   */
  .prose table { display: block; width: max-content; max-width: 100%; overflow-x: auto; }

  /*
   * 용어 목록 — 세 칸이 들어갈 폭이 없어 설명 칸이 27px 로 찌그러집니다.
   * 격자를 아예 풀고 번호만 왼쪽에 띄워, 용어와 설명이 세로로 쌓이게 합니다.
   *
   * 격자를 2열로 줄이는 방법은 쓸 수 없습니다 — 설명은 태그 없는 맨 텍스트라
   * 익명 아이템이 되어 선택자가 닿지 않고, 자동 배치에 맡기면 설명이 번호 칸
   * 아래로 떨어집니다.
   */
  .prose ol.terms > li {
    display: block;
    position: relative;
    padding: 15px 2px 15px 30px;
  }
  .prose ol.terms > li::before {
    position: absolute;
    left: 2px;
    top: 15px;
  }
  .prose ol.terms > li > :is(strong, b) {
    display: block;
    margin-bottom: .25em;
  }
}

.related { margin-top: 44px; }
.related__list { display: flex; flex-wrap: wrap; gap: 8px; }
.related__list a {
  display: inline-block;
  padding: 7px 14px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  font-size: .86rem;
}
.related__list a:hover { border-color: var(--accent); color: var(--accent); }

/* ── 기타 ───────────────────────────────────────────────────── */

/* 비어 있는 목록 — 허전한 글자 한 줄 대신 카드로 자리를 채웁니다. */
.empty {
  display: grid;
  place-items: center;
  padding: 56px 24px;
  background: var(--bg-raised);
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-lg);
  text-align: center;
  color: var(--text-dim);
}
.link-list { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 32px; }
.link-list a {
  display: inline-block;
  padding: 8px 16px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
}

/* ── 푸터 ───────────────────────────────────────────────────── */

/*
 * 가운데 정렬 한 덩어리입니다. 카테고리 목록은 싣지 않습니다 — 사이드바가
 * 모든 페이지에서 같은 링크를 전부 보여주므로 푸터에 한 벌 더 늘어놓으면
 * 같은 링크가 두 번 쌓일 뿐입니다.
 */
.site-footer {
  position: relative;
  margin-top: 72px;
  padding-block: 56px 28px;
  /* 흰 판 하나로 두면 본문과 경계가 흐립니다. 아래로 갈수록 옅은 라벤더가
     깔리고, 바닥 가운데에서 빛이 한 번 올라옵니다. */
  background:
    radial-gradient(64% 118% at 50% 114%, rgb(var(--accent-rgb) / 0.18), transparent 66%),
    linear-gradient(180deg, #ffffff 0%, #f9f7ff 100%);
  font-size: .9rem;
  color: var(--text-muted);
  text-align: center;
  overflow: hidden;
}
/* 푸터가 시작되는 자리를 색으로 끊습니다 — 회색 실선보다 마무리가 분명합니다.
   2px 로 얇게, 양 끝은 배경으로 풀어 선이 뚝 잘리지 않게 둡니다. */
.site-footer::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 2px;
  background: linear-gradient(90deg,
    rgb(67 56 202 / 0), #4338ca 6%, #6366f1 30%, #8b5cf6 58%, #c084fc 82%,
    rgb(233 213 255 / 0) 100%);
}

.site-footer__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* ── 브랜드 — 마크 위, 이름 아래로 세워 가운데에 둡니다 ── */

.fbrand {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}
.fbrand__mark {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 56px; height: 56px;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--bg-sunken);
  /* 평소에도 옅게 떠 있게 — 로고가 배경에 붙어 보이지 않습니다 */
  box-shadow: 0 8px 20px -8px rgb(var(--accent-rgb) / 0.45);
  transition: scale var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}
.fbrand__logo { width: 56px; height: 56px; object-fit: contain; }
.fbrand__mark .img-fallback {
  width: 56px; height: 56px;
  aspect-ratio: auto;
  min-width: 0;
  border: 0;
  border-radius: 0;
}
.fbrand:hover .fbrand__mark {
  scale: 1.06;
  box-shadow: 0 14px 28px -8px rgb(var(--accent-rgb) / 0.55);
}
/*
 * 가로형 워드마크 로고 — 정사각 타일 안에 가두면 56px 안에서 letterbox 가
 * 되어 글자가 작아집니다. 타일(바탕·그림자·둥근 모서리)을 걷어내고
 * 로고 자체를 그대로 보여줍니다.
 */
.fbrand--mark .fbrand__mark {
  width: auto;
  height: auto;
  max-width: min(220px, 100%);
  border-radius: 0;
  background: none;
  box-shadow: none;
}
.fbrand--mark .fbrand__logo { width: 100%; height: auto; }
.fbrand--mark:hover .fbrand__mark { box-shadow: none; }
.fbrand__name {
  font-family: var(--font-display);
  font-size: 1.5rem;
  line-height: 1.25;
  font-weight: 800;
  letter-spacing: -0.6px;
  color: #111;
  transition: color var(--dur-fast) var(--ease-out);
}
.fbrand:hover .fbrand__name { color: var(--accent); }

.site-footer__slogan {
  margin-top: 10px;
  font-size: .8125rem;
  line-height: 1.5;
  color: var(--text-dim);
}

.site-footer__desc {
  margin-top: 14px;
  /* 한글 폰트는 1ch 가 넓어 44ch 가 모바일 뷰포트를 넘깁니다 — 100% 로 묶습니다. */
  max-width: min(44ch, 100%);
  font-size: .875rem;
  line-height: 1.75;
  color: var(--text-dim);
  text-wrap: pretty;               /* 마지막 줄에 한 단어만 남지 않게 */
}

/* ── 링크 — 알약 한 줄 ── */

.site-footer__meta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-top: 28px;
}
.site-footer__meta a {
  padding: 7px 16px;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: rgb(255 255 255 / 0.7);
  font-weight: 600;
  transition: background-color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              translate var(--dur-fast) var(--ease-out);
}
.site-footer__meta a:hover,
.site-footer__meta a:focus-visible {
  background: var(--accent-soft);
  border-color: rgb(var(--accent-rgb) / 0.35);
  color: var(--accent);
  translate: 0 -2px;
}

/* ── 저작권 ── */

.site-footer__copy {
  width: 100%;
  margin-top: 36px;
  padding-top: 22px;
  border-top: 1px solid var(--border);
  font-size: .8rem;
  color: var(--text-dim);
}

.site-footer a:hover,
.site-footer a:focus-visible { color: var(--accent); }

/* ── 반응형: 태블릿 2열 / 데스크톱 3~4열 ([3]) ──────────────── */

/* .rank-list 는 여기서 분기하지 않습니다 — auto-fit 으로 폭에 따라 스스로
   1열/2열이 됩니다(정의부 주석 참고). */

/* 데스크톱: 사이드바 고정 2열. 토글 없이 항상 펼쳐져 있습니다. */
@media (min-width: 1024px) {
  .shell { grid-template-columns: var(--sidebar-w) minmax(0, 1fr); }

  .sidebar {
    position: sticky;
    top: 0;
    /* 한 화면 높이에 고정 — 페이지를 스크롤해도 사이드바는 그 자리에 붙어
       있습니다. 메뉴가 화면보다 길면 사이드바 안에서만 스크롤되고(얇은
       스크롤바), 페이지 본문과 함께 밀려 사라지지 않습니다. */
    height: 100vh;
    overflow-y: auto;
    overscroll-behavior: contain;
    display: flex;
    flex-direction: column;
    /* 사이드바 내부 스크롤바를 얇고 은은하게 */
    scrollbar-width: thin;
    scrollbar-color: var(--border-strong) transparent;
  }
  .sidebar::-webkit-scrollbar { width: 8px; }
  .sidebar::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 999px; }
  .sidebar::-webkit-scrollbar-track { background: transparent; }
  .sidebar__bar { padding: 36px 24px 0; }
  .sidebar__toggle { display: none; }
  .sidebar__panel { display: block; padding: 32px 24px 36px; }
  .sidebar__name { font-size: 2rem; letter-spacing: -0.8px; line-height: 32px; }
  .sidebar__brand--mark .sidebar__logo { height: 76px; }

  .main  { padding-block: 36px 72px; }
}

/*
 * 카드 2열. 간격은 시안대로 40px 고정, 카드 폭은 남는 공간을 반씩 나눠 갖습니다.
 *
 * 카드가 시안 치수(630px)와 정확히 같아지는 지점:
 *   사이드바 340 + 패딩 32 + (630 + 40 + 630) = 1672px 뷰포트
 * 1400~1671px 구간에서는 두 열을 유지하되 카드가 그만큼 좁아집니다.
 */
@media (min-width: 1400px) {
  .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /*
   * 순위 카드는 3열로 늘리지 않습니다. 로고 68 + 순위 34 + 화살표 38 을
   * 빼고 나면 이름·도메인이 쓸 폭이 110px 남짓이라 도메인이 잘립니다.
   * 2열을 유지하면 카드마다 500px 이상이 확보됩니다.
   */
}

/*
 * 모바일 2열 — 카테고리 카드가 뷰포트 절반 폭으로 들어갑니다.
 * 시안의 40/60px 간격은 카드가 630px 일 때 기준이라 여기서는 과합니다.
 */
@media (max-width: 767px) {
  .cards {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 12px;
    row-gap: 28px;
  }
}

/*
 * 좁은 화면에서는 카드 한 장이 375px 뷰포트 기준 166px, 안쪽 패딩을 빼면
 * 140px 남짓입니다. 히어로 260px·제목 2rem 을 그대로 두면 제목이 말줄임으로
 * 잘리고 카드는 세로로만 길어지므로, 이 구간에서만 카드 폭에 맞춰 줄입니다.
 */
@media (max-width: 599px) {
  .cards { column-gap: 10px; row-gap: 24px; }

  .card__hero { height: 120px; }
  .card__hero-body { gap: 2px; padding: 12px 12px 8px; }
  .card__eyebrow { font-size: .75rem; line-height: 16px; }
  .card__title { font-size: 1.125rem; line-height: 24px; letter-spacing: -0.4px; }

  .card__list { padding: 0 8px 8px; }
  .row { gap: 8px; padding: 8px 6px; }
  .row__badge { width: 22px; height: 22px; border-radius: 7px; font-size: .75rem; }
  /* .roll 은 상자 높이만큼 굴립니다 — height 와 line-height 를 같은 값으로. */
  .row__name { height: 20px; font-size: .875rem; line-height: 20px; letter-spacing: -0.3px; }
  .row__domain { font-size: .75rem; line-height: 16px; }
  .row__arrow { display: none; }           /* 장식(aria-hidden) — 폭을 이름에 넘깁니다 */

  .card__more { padding: 12px 10px; font-size: .8125rem; }
}

/*
 * 좁은 화면의 순위 카드 — 320px 뷰포트에서 카드 안쪽 폭은 288px 인데
 * 순위 34 + 로고 68 + 바로가기 알약 102 + 간격 48 + 패딩 40 = 292px 라
 * 이름이 들어설 자리가 남지 않아 사이트명·도메인이 통째로 잘렸습니다.
 * 고정 폭 요소를 모두 줄이고, 알약은 화살표만 남긴 원형으로 접습니다.
 */
@media (max-width: 560px) {
  .rank__main { gap: 10px; padding: 14px 12px; }

  .rank__no { width: 22px; font-size: 1.375rem; }

  .rank__logo { width: 46px; height: 46px; border-radius: 14px; }
  .rank__logoimg,
  .rank__logo .img-fallback { width: 46px; height: 46px; }
  .rank__logo .img-fallback { font-size: 1.125rem; }

  .rank__body { gap: 6px; }
  /* .roll 은 상자 높이만큼 굴립니다 — height 와 line-height 를 같은 값으로. */
  .rank__name { height: 24px; font-size: 1.125rem; line-height: 24px; }
  .rank__domain { padding: 3px 8px; font-size: .75rem; line-height: 16px; }

  .rank__go { padding: 0 12px; font-size: .75rem; }
}

/*
 * 380px 아래에서는 알약(약 102px)까지 빼야 이름이 온전히 들어갑니다.
 * 라벨은 지우지 않고 감춥니다 — 지우면 스크린리더에서도 사라지지만,
 * 감추면 링크 이름의 일부("… 바로가기")로 그대로 읽힙니다.
 */
@media (max-width: 380px) {
  .rank__cta {
    width: 34px; height: 34px;
    padding: 0; gap: 0;
    justify-content: center;
    border-radius: 50%;
  }
  .rank__cta-text {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

/* ── 텍스트 링크 밑줄 ────────────────────────────────────────
   글자 아래에서 밑줄이 좌→우로 그어집니다.
   text-decoration 을 켜고 끄면 줄 높이가 흔들리지만, 배경 그라디언트로
   그리면 레이아웃이 전혀 움직이지 않습니다. */

.breadcrumb a,
.related__list a,
.link-list a {
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 1px;
  transition: background-size .28s var(--ease-out), color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.breadcrumb a:hover,
.breadcrumb a:focus-visible,
.related__list a:hover,
.related__list a:focus-visible,
.link-list a:hover,
.link-list a:focus-visible { background-size: 100% 1px; }

/* 테두리가 있는 알약형 링크는 밑줄 대신 떠오릅니다. */
.related__list a,
.link-list a {
  background-image: none;
  transition: translate var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}
.related__list a:hover,
.link-list a:hover { translate: 0 -2px; box-shadow: var(--shadow); }

/* ── 페이지 내 앵커 이동 ──────────────────────────────────── */
html { scroll-behavior: smooth; }

/* ── 텍스트 선택 색 ──────────────────────────────────────── */
::selection { background: rgb(var(--accent-rgb) / 0.22); color: var(--text); }

/* ── 사이드바 스크롤바 ───────────────────────────────────── */
.sidebar { scrollbar-width: thin; scrollbar-color: rgb(var(--accent-rgb) / 0.35) transparent; }
.sidebar::-webkit-scrollbar { width: 8px; }
.sidebar::-webkit-scrollbar-track { background: transparent; }
.sidebar::-webkit-scrollbar-thumb {
  background: rgb(var(--accent-rgb) / 0.28);
  border-radius: var(--r-pill);
  border: 2px solid transparent;
  background-clip: content-box;
}
.sidebar::-webkit-scrollbar-thumb:hover { background: rgb(var(--accent-rgb) / 0.5); background-clip: content-box; }

/* 사이드바 로고 */
.sidebar__logo { transition: scale var(--dur) var(--ease-out); }
.sidebar__brand:hover .sidebar__logo { scale: 1.08; }
.sidebar__name { transition: color var(--dur-fast) var(--ease-out); }
.sidebar__brand:hover .sidebar__name { color: var(--accent); }

/* ── 스크롤 진행 바 ──────────────────────────────────────────
   지원하지 않는 브라우저에서는 scaleX(0) 그대로라 보이지 않습니다.
   장식 요소라 없어도 아무것도 잃지 않습니다. */

.scroll-progress {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  height: 3px;
  background: var(--hero-gradient-btn);
  transform: scaleX(0);
  transform-origin: 0 50%;
  pointer-events: none;
}
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .scroll-progress {
      animation: scroll-progress linear both;
      animation-timeline: scroll(root block);
    }
    @keyframes scroll-progress {
      from { transform: scaleX(0); }
      to   { transform: scaleX(1); }
    }
  }
}

/* ── 하단 고정 문의 버튼 (피그마 935:9206) ─────────────────── */

/*
 * 가로 가운데 정렬은 transform 으로, 호버 시 떠오르는 건 translate 로 나눠 씁니다.
 * 두 속성은 별개라 서로 덮어쓰지 않고 합성됩니다.
 * (하나로 몰면 호버할 때 가운데 정렬이 풀립니다)
 */
.float-cta {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: 24px;
  z-index: 60;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 20px 44px;
  border-radius: var(--r-sm);
  overflow: hidden;                        /* 아래 빛줄기를 버튼 안쪽으로 가둡니다 */
  background-image: var(--hero-gradient-btn);
  background-size: 220% 100%;
  background-position: 0% 50%;
  color: #fff;
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 30px;
  letter-spacing: -0.5px;
  white-space: nowrap;
  box-shadow: 0 10px 24px rgb(67 56 202 / 0.34);
  transition: background-position .5s var(--ease-out), box-shadow var(--dur) var(--ease-out),
              translate var(--dur-fast) var(--ease-out);
}

.float-cta__icon { width: 22px; height: 22px; flex: 0 0 auto; }

/*
 * 눈에 띄게 만드는 두 가지 — 둘 다 무한 반복이라 과하지 않게 잡았습니다.
 *   1) 후광이 천천히 번졌다 사라지는 링 (box-shadow 의 알파만 변함)
 *   2) 4.8초에 한 번 버튼 위를 지나가는 빛줄기
 * opacity 를 쓰지 않으므로 "첫 페인트에 무언가를 숨기지 않는다" 규칙과 무관합니다. ([6])
 */
@media (prefers-reduced-motion: no-preference) {
  .float-cta { animation: cta-glow 3.2s var(--ease-out) infinite; }
  @keyframes cta-glow {
    0%   { box-shadow: 0 10px 24px rgb(67 56 202 / 0.34), 0 0 0 0 rgb(99 102 241 / 0.5); }
    70%  { box-shadow: 0 10px 24px rgb(67 56 202 / 0.34), 0 0 0 18px rgb(99 102 241 / 0); }
    100% { box-shadow: 0 10px 24px rgb(67 56 202 / 0.34), 0 0 0 0 rgb(99 102 241 / 0); }
  }

  .float-cta::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(105deg, transparent 36%, rgb(255 255 255 / 0.45) 50%, transparent 64%);
    translate: -140% 0;
    animation: cta-sheen 4.8s var(--ease-out) infinite;
  }
  @keyframes cta-sheen {
    0%        { translate: -140% 0; }
    26%, 100% { translate: 140% 0; }
  }
}

/* 호버하면 반복 애니메이션을 멈추고(그림자 충돌 방지) 더 크게 반응합니다. */
.float-cta:hover {
  animation: none;
  background-position: 100% 50%;
  box-shadow: 0 18px 36px rgb(67 56 202 / 0.5);
  translate: 0 -3px;
}
.float-cta:focus-visible {
  animation: none;
  box-shadow: 0 10px 24px rgb(67 56 202 / 0.34), 0 0 0 4px rgb(99 102 241 / 0.4);
}
.float-cta:active { translate: 0 1px; }

/*
 * 데스크톱에서는 뷰포트가 아니라 "카드 영역(1300px)" 의 가운데에 옵니다.
 * 왼쪽 사이드바만큼 기준선이 밀려 있으므로 그 절반을 더합니다.
 *   카드 영역 중심 = 사이드바(340) + (뷰포트 − 340) / 2 = 50vw + 170px
 *
 * ⚠️ 이 규칙은 반드시 위의 기본 규칙보다 "뒤에" 있어야 합니다.
 *    미디어쿼리라도 선택자 우선순위가 같으면 나중에 선언된 쪽이 이깁니다.
 */
@media (min-width: 1024px) {
  .float-cta { left: calc(50% + var(--sidebar-w) / 2); }
}

/* ── 맨 위로 ─────────────────────────────────────────────────
   스크롤 타임라인을 못 쓰면 항상 보입니다(기능이 사라지지 않게). */

.to-top {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 60;
  display: grid;
  place-items: center;
  width: 48px; height: 48px;
  border-radius: 50%;
  background: #222;
  color: #fff;
  font-size: 1.25rem;
  box-shadow: 0 8px 20px rgb(0 0 0 / 0.28);
  transition: background-color var(--dur-fast) var(--ease-out), box-shadow var(--dur) var(--ease-out),
              scale var(--dur-fast) var(--ease-out);
}
.to-top:hover {
  background: #000;
  box-shadow: 0 12px 26px rgb(0 0 0 / 0.38);
  scale: 1.08;
}
.to-top:active { scale: .96; }

/*
 * 문의 버튼이 콘텐츠 가운데에 있으므로 데스크톱에서는 겹치지 않습니다.
 * 좁은 화면에서 문의 버튼이 가로 전체를 차지할 때만 위로 올립니다(아래 미디어쿼리).
 */
.to-top--stacked { bottom: 24px; }

@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .to-top {
      animation: to-top-in linear both;
      animation-timeline: scroll(root block);
      animation-range: 320px 640px;
    }
    @keyframes to-top-in {
      from { translate: 0 96px; }
      to   { translate: 0 0; }
    }
  }
}

@media (max-width: 720px) {
  .float-cta {
    left: 16px;
    right: 16px;                           /* 좁은 화면에서는 가로 전체 */
    transform: none;
    bottom: 16px;
    padding: 16px 24px;
    font-size: 1.0625rem;
    line-height: 26px;
  }
  .float-cta__icon { width: 20px; height: 20px; }
  .to-top { right: 16px; bottom: 16px; width: 44px; height: 44px; }
  .to-top--stacked { bottom: 90px; }       /* CTA 높이 58 + 간격 16 */
}

/* ── 등장 애니메이션 ────────────────────────────────────────────
   콘텐츠는 처음부터 보입니다. 폴드 밖 요소만 살짝 올라오게 하고,
   opacity 는 건드리지 않습니다. ([6], [9]) */

@media (prefers-reduced-motion: no-preference) {
  /*
   * 스크롤로 화면에 들어올 때만 살짝 올라옵니다.
   * opacity 는 건드리지 않으므로 첫 페인트에 글자가 비는 일이 없고,
   * 지원하지 않는 브라우저에서는 그냥 한 번 재생되고 끝납니다. ([6])
   */
  .card, .rank, .promo__item {
    animation: rise-in .35s ease-out both;
    animation-timeline: view();
    animation-range: entry 0% cover 18%;
  }
  @keyframes rise-in {
    from { transform: translateY(10px); }
    to   { transform: none; }
  }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }

  /*
   * 전환 시간만 0 으로 만들면 "움직임"이 사라지는 게 아니라 순간이동이 됩니다.
   * 그래서 위치가 바뀌는 효과(들어올리기·확대·미끄러짐)는 아예 끕니다.
   *
   * 반면 색이 바뀌거나 보이고/안 보이고가 의미인 표시(왼쪽 포인트 바)는
   * 그대로 둡니다. 이동이 아니라 상태 변화라 즉시 반영되는 게 맞습니다.
   */
  /* 글자는 구르지 않고 제자리에 — 색만 바뀝니다 */
  .row:hover .roll__inner { translate: none; }
  .row:hover .row__arrow, .row:focus-visible .row__arrow { translate: none; }

  .card:hover, .card:focus-within { translate: none; }
  .card:hover .card__hero-img { scale: none; }

  .rank:hover, .rank:focus-within { translate: none; }
  .snav__item:hover .snav__icon, .snav__item:focus-visible .snav__icon { translate: none; }
  a.promo__item:hover, a.promo__item:focus-visible { translate: none; }
  a.promo__item:hover .promo__img, a.promo__item:focus-visible .promo__img { scale: none; }
  .btn:active, .btn--accent:hover, .btn--accent:active { translate: none; }
  .related__list a:hover, .link-list a:hover { translate: none; }
  .hero-search__submit:hover, .hero-search__submit:active { translate: none; }
  .hero-search__submit:hover .hero-search__submit-arrow { translate: none; }
  .hero-search:focus-within::before { scale: none; }   /* 빛무리는 그대로 */
  .sidebar__brand:hover .sidebar__logo { scale: none; }
  .to-top { animation: none; translate: 0 0; }
  .to-top:hover, .to-top:active { scale: none; }
  .float-cta { animation: none; }
  .float-cta::after { content: none; }
  .float-cta:hover, .float-cta:active { translate: none; }
  a.shortcuts__link:hover, a.shortcuts__link:focus-visible { translate: none; }
  a.shortcuts__link:hover .shortcuts__img { scale: none; }
  .row:hover .row__badge::after { translate: -130% 0; }   /* 빛 스침 없음 */
}
