/* xn-ui.css — 도구 사이트 공용 디자인 키트 (opt-in)

   쓰는 법: <link rel="stylesheet" href="/static/shared/xn-ui.css?v=5"> 를 넣고
   <body class="xn-app">(어두운 바탕, 포털 계열) 또는 <body class="xn-app xn-app-light">(밝은 바탕).
   모든 규칙이 .xn-app / .xn-app-light 아래에만 걸리므로 이 파일을 링크만 하고 클래스를 안 붙인
   사이트는 아무것도 바뀌지 않는다. 컴포넌트 선택자는 :where() 로 감싸 특이도가 0 이다 —
   사이트 <style> 의 아무 규칙이나 이긴다.

   사이트 개성은 --accent / --accent-2 / --grad 세 개만 덮어쓴다(필요하면 H1 에만 쓸 --font-display).
   공용 조각(_site_guide·_related·_site_foot·_channel)이 읽는 --text·--muted·--border·--card·--accent·--accent2
   를 여기서 정하므로, 밝은 테마에서도 설명·FAQ·관련 도구 글자가 바탕에 묻히지 않는다.
   폰트(Pretendard)는 _site_theme.html 이 이미 불러온다. Tailwind 클래스는 쓰지 않는다. */

/* ── 1. 토큰 ───────────────────────────────────────────── */
:where(.xn-app, .xn-app-light) {
  --bg: #0b0d17; --surface: #11141f; --surface-2: #171b29; --card: var(--surface);
  --border: #242a3d; --border-strong: #343c55;
  --text: #eef0f6; --text-sub: #c3c8d6; --muted: #8f96ab; --faint: #848ba1;
  --accent: #6366f1; --accent-2: #a855f7; --accent2: var(--accent-2); --accent-3: #38bdf8;
  --grad: linear-gradient(135deg, var(--accent), var(--accent-2));
  --on-accent: #fff;
  --ok: #22c55e; --warn: #f59e0b; --bad: #ef4444; --up: #f04452; --down: #3182f6;
  --r-sm: 10px; --r-md: 14px; --r-lg: 20px; --r-pill: 999px;
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 24px; --sp-6: 32px;
  --fs-cap: 12px; --fs-sm: 13px; --fs-body: 15px; --fs-lg: 17px; --fs-h2: 20px;
  --fs-h1: clamp(24px, 5.2vw, 32px); --fs-num: clamp(28px, 7vw, 44px);
  --font: "Pretendard", "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-num: "Pretendard", ui-monospace, "SF Mono", monospace;
  --font-display: var(--font);
  --tap: 44px; --ring: 0 0 0 3px rgba(99, 102, 241, .35);
  --shadow: 0 10px 30px -12px rgba(0, 0, 0, .55);
  --chev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%23aab0c2' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  color-scheme: dark;
}
@supports (color: color-mix(in srgb, red, blue)) {
  :where(.xn-app, .xn-app-light) { --ring: 0 0 0 3px color-mix(in srgb, var(--accent) 38%, transparent); }
}
.xn-app-light {
  --bg: #f6f7fb; --surface: #fff; --surface-2: #f1f3f8; --card: var(--surface);
  --border: #e2e6ef; --border-strong: #cfd5e2;
  --text: #111827; --text-sub: #374151; --muted: #5b6474; --faint: #6b7280;
  --shadow: 0 8px 24px -14px rgba(15, 23, 42, .28);
  --chev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%23525b6b' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  color-scheme: light;
}

/* ── 2. 바탕 ─────────────────────────────────────────────
   wrapper(보통 body) 자체에 바탕·글자·글꼴을 준다. */
:where(.xn-app, .xn-app-light) {
  background: var(--bg); color: var(--text); font-family: var(--font);
  font-size: var(--fs-body); line-height: 1.6; -webkit-font-smoothing: antialiased;
}
:where(.xn-app, .xn-app-light) :where(*, *::before, *::after) { box-sizing: border-box; }
:where(.xn-app, .xn-app-light) :where(h1, h2, h3) { letter-spacing: -.02em; line-height: 1.3; }
:where(.xn-app, .xn-app-light) :where(button, input, select, textarea) { font: inherit; color: inherit; }
:where(.xn-app, .xn-app-light) :where(a, button, input, select, textarea, summary, [tabindex]):focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; box-shadow: var(--ring); }

/* 본문 폭. 한 칸 도구 = .xn-wrap, 두 칸 = .xn-wrap.xn-wrap--wide + .xn-layout */
:where(.xn-app, .xn-app-light) :where(.xn-wrap) { width: 100%; max-width: 560px; margin: 0 auto; padding: var(--sp-5) var(--sp-4) var(--sp-6); }
:where(.xn-app, .xn-app-light) :where(.xn-wrap--wide) { max-width: 1080px; }

/* ── 3. 히어로 ─────────────────────────────────────────── */
:where(.xn-app, .xn-app-light) :where(.xn-hero) { text-align: center; margin: var(--sp-2) 0 var(--sp-5); }
:where(.xn-app, .xn-app-light) :where(.xn-hero__icon) {
  width: 56px; height: 56px; margin: 0 auto var(--sp-3); border-radius: 16px;
  display: flex; align-items: center; justify-content: center; font-size: 28px; line-height: 1;
  background: var(--grad); color: var(--on-accent); box-shadow: 0 10px 24px -10px var(--accent);
}
:where(.xn-app, .xn-app-light) :where(.xn-hero__title, .xn-hero h1) {
  font-family: var(--font-display); font-size: var(--fs-h1); font-weight: 800; margin: 0; color: var(--text);
}
:where(.xn-app, .xn-app-light) :where(.xn-hero__sub) { margin: var(--sp-2) auto 0; max-width: 34em; font-size: 14px; color: var(--text-sub); }
:where(.xn-app, .xn-app-light) :where(.xn-hero__badge) {
  display: inline-flex; align-items: center; gap: 6px; margin-top: var(--sp-3); padding: 5px 12px;
  border-radius: var(--r-pill); border: 1px solid var(--border); background: var(--surface-2);
  font-size: var(--fs-cap); font-weight: 700; color: var(--text-sub);
}

/* ── 4. 카드 ───────────────────────────────────────────── */
:where(.xn-app, .xn-app-light) :where(.xn-card) {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: var(--sp-4); box-shadow: var(--shadow);
}
:where(.xn-app, .xn-app-light) :where(.xn-card + .xn-card) { margin-top: var(--sp-4); }
:where(.xn-app, .xn-app-light) :where(.xn-card--inset) { background: var(--surface-2); box-shadow: none; }
:where(.xn-app, .xn-app-light) :where(.xn-card__title) { font-size: var(--fs-lg); font-weight: 800; margin: 0 0 var(--sp-3); color: var(--text); }
@media (min-width: 600px) { :where(.xn-app, .xn-app-light) :where(.xn-card) { padding: 20px; } }

/* ── 5. 입력 ───────────────────────────────────────────── */
:where(.xn-app, .xn-app-light) :where(.xn-field) { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
:where(.xn-app, .xn-app-light) :where(.xn-field + .xn-field) { margin-top: var(--sp-3); }
:where(.xn-app, .xn-app-light) :where(.xn-field > label, .xn-label) { font-size: var(--fs-cap); font-weight: 700; color: var(--muted); }
:where(.xn-app, .xn-app-light) :where(.xn-hint) { font-size: var(--fs-cap); color: var(--muted); }
:where(.xn-app, .xn-app-light) :where(.xn-fields) { display: grid; gap: var(--sp-3); grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
:where(.xn-app, .xn-app-light) :where(.xn-fields) > :where(.xn-field + .xn-field) { margin-top: 0; }

:where(.xn-app, .xn-app-light) :where(.xn-input, .xn-select, .xn-textarea) {
  width: 100%; min-height: var(--tap); padding: 10px 14px; border-radius: var(--r-md);
  background: var(--surface-2); border: 1px solid var(--border); color: var(--text);
  font-family: var(--font); font-size: 16px; /* 16px 미만이면 iOS 가 확대한다 */
  font-variant-numeric: tabular-nums; transition: border-color .15s ease, box-shadow .15s ease;
}
:where(.xn-app, .xn-app-light) :where(.xn-input, .xn-select, .xn-textarea)::placeholder { color: var(--faint); }
:where(.xn-app, .xn-app-light) :where(.xn-input, .xn-select, .xn-textarea):hover { border-color: var(--border-strong); }
:where(.xn-app, .xn-app-light) :where(.xn-input, .xn-select, .xn-textarea):focus { outline: none; border-color: var(--accent); box-shadow: var(--ring); }
:where(.xn-app, .xn-app-light) :where(.xn-textarea) { min-height: 120px; resize: vertical; line-height: 1.55; }
:where(.xn-app, .xn-app-light) :where(.xn-select) {
  -webkit-appearance: none; appearance: none; padding-right: 38px; cursor: pointer;
  background-image: var(--chev); background-repeat: no-repeat; background-position: right 14px center;
}
:where(.xn-app, .xn-app-light) :where(input[type=date].xn-input, input[type=time].xn-input) { -webkit-appearance: none; appearance: none; }
/* 단위 붙은 입력: <div class="xn-input-wrap"><input class="xn-input"><span class="xn-unit">원</span></div> */
:where(.xn-app, .xn-app-light) :where(.xn-input-wrap) { position: relative; }
:where(.xn-app, .xn-app-light) :where(.xn-input-wrap > .xn-input) { padding-right: 48px; }
:where(.xn-app, .xn-app-light) :where(.xn-unit) {
  position: absolute; right: 14px; top: 50%; transform: translateY(-50%);
  font-size: 14px; font-weight: 600; color: var(--muted); pointer-events: none;
}

/* ── 6. 버튼 ─────────────────────────────────────────────
   한 화면에 주 버튼(.xn-btn) 하나. 나머지는 --ghost. */
:where(.xn-app, .xn-app-light) :where(.xn-btn) {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 48px; padding: 12px 20px; border: 0; border-radius: var(--r-md);
  background: var(--grad); color: var(--on-accent); font-size: var(--fs-body); font-weight: 700;
  text-decoration: none; cursor: pointer; user-select: none;
  box-shadow: 0 10px 22px -12px var(--accent); transition: transform .15s ease, box-shadow .15s ease, filter .15s ease;
}
:where(.xn-app, .xn-app-light) :where(.xn-btn):hover { filter: brightness(1.06); box-shadow: 0 14px 26px -12px var(--accent); }
:where(.xn-app, .xn-app-light) :where(.xn-btn):active { transform: translateY(1px); }
:where(.xn-app, .xn-app-light) :where(.xn-btn):disabled, :where(.xn-app, .xn-app-light) :where(.xn-btn[aria-disabled=true]) { opacity: .5; cursor: not-allowed; box-shadow: none; }
:where(.xn-app, .xn-app-light) :where(.xn-btn--block) { display: flex; width: 100%; }
:where(.xn-app, .xn-app-light) :where(.xn-btn--ghost) { background: var(--surface-2); color: var(--text); border: 1px solid var(--border); box-shadow: none; }
:where(.xn-app, .xn-app-light) :where(.xn-btn--ghost):hover { border-color: var(--accent); filter: none; box-shadow: none; }
:where(.xn-app, .xn-app-light) :where(.xn-btn--sm) { min-height: 36px; padding: 6px 14px; font-size: 14px; border-radius: var(--r-sm); }
:where(.xn-app, .xn-app-light) :where(.xn-btns) { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-4); }
:where(.xn-app, .xn-app-light) :where(.xn-btns > .xn-btn) { flex: 1 1 140px; }

/* ── 7. 세그먼트(탭·단위 고르기) ─────────────────────────
   <div class="xn-seg" role="group"><button aria-pressed="true">월</button><button>년</button></div>
   켜진 칸: aria-pressed="true" | aria-selected="true" | .is-active. 넘치면 가로로 밀린다. */
:where(.xn-app, .xn-app-light) :where(.xn-seg) {
  display: flex; gap: 4px; padding: 4px; border-radius: var(--r-pill); background: var(--surface-2);
  border: 1px solid var(--border); overflow-x: auto; scrollbar-width: none; max-width: 100%;
}
:where(.xn-app, .xn-app-light) :where(.xn-seg)::-webkit-scrollbar { display: none; }
:where(.xn-app, .xn-app-light) :where(.xn-seg > button, .xn-seg > a, .xn-seg > label) {
  flex: 1 0 auto; min-height: calc(var(--tap) - 8px); padding: 6px 14px; border: 0; border-radius: var(--r-pill);
  background: transparent; color: var(--text-sub); font-size: 14px; font-weight: 700; white-space: nowrap;
  cursor: pointer; text-decoration: none; display: inline-flex; align-items: center; justify-content: center;
  transition: background .15s ease, color .15s ease;
}
:where(.xn-app, .xn-app-light) :where(.xn-seg > :hover) { color: var(--text); }
:where(.xn-app, .xn-app-light) :where(.xn-seg > [aria-pressed=true], .xn-seg > [aria-selected=true], .xn-seg > .is-active) {
  background: var(--accent); color: var(--on-accent);
}

/* ── 8. 숫자 타일 ─────────────────────────────────────────
   <div class="xn-stats"><div class="xn-stat"><span class="xn-stat__label">월 실수령</span>
   <b class="xn-stat__value">2,840,000</b><span class="xn-stat__delta up">+3.2%</span></div></div> */
:where(.xn-app, .xn-app-light) :where(.xn-stats) { display: grid; gap: var(--sp-3); grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
:where(.xn-app, .xn-app-light) :where(.xn-stat) {
  display: flex; flex-direction: column; gap: 4px; min-width: 0; padding: 14px 16px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r-md);
}
:where(.xn-app, .xn-app-light) :where(.xn-stat__label) { font-size: var(--fs-cap); font-weight: 600; color: var(--muted); }
:where(.xn-app, .xn-app-light) :where(.xn-stat__value) {
  font-family: var(--font-num); font-size: clamp(22px, 5vw, 28px); font-weight: 800; line-height: 1.15;
  font-variant-numeric: tabular-nums; color: var(--text); overflow-wrap: anywhere;
}
:where(.xn-app, .xn-app-light) :where(.xn-stat__delta) {
  align-self: flex-start; padding: 2px 8px; border-radius: var(--r-pill); font-size: var(--fs-cap); font-weight: 700;
  background: var(--surface); color: var(--muted); font-variant-numeric: tabular-nums;
}
:where(.xn-app, .xn-app-light) :where(.xn-stat__delta.up, .xn-up) { color: var(--up); }
:where(.xn-app, .xn-app-light) :where(.xn-stat__delta.down, .xn-down) { color: var(--down); }

/* ── 9. 결과 패널(계산기의 답) ───────────────────────────
   <div class="xn-result" aria-live="polite"><div class="xn-result__label">실수령액</div>
   <div class="xn-result__value">2,840,000<small>원</small></div><div class="xn-result__sub">…</div></div> */
:where(.xn-app, .xn-app-light) :where(.xn-result) {
  position: relative; overflow: hidden; padding: 18px 18px 18px 21px; border-radius: var(--r-lg);
  background: var(--surface-2); border: 1px solid var(--border);
}
:where(.xn-app, .xn-app-light) :where(.xn-result)::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--grad); }
:where(.xn-app, .xn-app-light) :where(.xn-result__label) { font-size: var(--fs-sm); font-weight: 700; color: var(--muted); }
:where(.xn-app, .xn-app-light) :where(.xn-result__value) {
  margin-top: 4px; font-family: var(--font-num); font-size: var(--fs-num); font-weight: 800; line-height: 1.1;
  font-variant-numeric: tabular-nums; color: var(--text); overflow-wrap: anywhere;
}
:where(.xn-app, .xn-app-light) :where(.xn-result__value small) { margin-left: 4px; font-size: .45em; font-weight: 700; color: var(--text-sub); }
:where(.xn-app, .xn-app-light) :where(.xn-result__sub) { margin-top: 8px; font-size: 14px; color: var(--text-sub); }
:where(.xn-app, .xn-app-light) :where(.xn-result + .xn-stats, .xn-result + .xn-card) { margin-top: var(--sp-3); }

/* ── 10. 두 칸 배치 ───────────────────────────────────────
   960px 이상에서 입력(왼쪽, 320~420px) | 결과·그림(오른쪽). 그 아래는 한 칸.
   <main class="xn-wrap xn-wrap--wide"><div class="xn-layout"><section>입력</section><section>결과</section></div></main> */
:where(.xn-app, .xn-app-light) :where(.xn-layout) { display: grid; gap: var(--sp-4); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 960px) {
  :where(.xn-app, .xn-app-light) :where(.xn-layout) { grid-template-columns: minmax(320px, 420px) minmax(0, 1fr); gap: var(--sp-5); align-items: start; }
  :where(.xn-app, .xn-app-light) :where(.xn-layout > .xn-sticky) { position: sticky; top: 72px; }
}
:where(.xn-app, .xn-app-light) :where(.xn-layout > *) { min-width: 0; }

/* ── 11. 칩(프리셋·태그) ───────────────────────────────── */
:where(.xn-app, .xn-app-light) :where(.xn-chips) { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
:where(.xn-app, .xn-app-light) :where(.xn-chips--scroll) { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
:where(.xn-app, .xn-app-light) :where(.xn-chips--scroll)::-webkit-scrollbar { display: none; }
:where(.xn-app, .xn-app-light) :where(.xn-chip) {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px; min-height: 36px; padding: 6px 14px;
  border-radius: var(--r-pill); border: 1px solid var(--border); background: var(--surface-2);
  color: var(--text-sub); font-size: var(--fs-sm); font-weight: 600; white-space: nowrap; cursor: pointer; text-decoration: none;
  transition: border-color .15s ease, color .15s ease, background .15s ease;
}
:where(.xn-app, .xn-app-light) :where(.xn-chip):hover { border-color: var(--accent); color: var(--text); }
:where(.xn-app, .xn-app-light) :where(.xn-chip[aria-pressed=true], .xn-chip.is-active) { background: var(--accent); border-color: transparent; color: var(--on-accent); }

/* ── 12. 글·보조 ───────────────────────────────────────── */
:where(.xn-app, .xn-app-light) :where(.xn-h2) { font-size: var(--fs-h2); font-weight: 800; margin: var(--sp-5) 0 var(--sp-3); color: var(--text); }
:where(.xn-app, .xn-app-light) :where(.xn-muted) { color: var(--muted); }
:where(.xn-app, .xn-app-light) :where(.xn-note) { font-size: var(--fs-sm); color: var(--muted); line-height: 1.6; margin-top: var(--sp-3); }
:where(.xn-app, .xn-app-light) :where(.xn-divider) { height: 1px; border: 0; background: var(--border); margin: var(--sp-4) 0; }
:where(.xn-app, .xn-app-light) :where(.xn-row) { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
:where(.xn-app, .xn-app-light) :where(.xn-num) { font-family: var(--font-num); font-variant-numeric: tabular-nums; }

@media (prefers-reduced-motion: reduce) {
  :where(.xn-app, .xn-app-light) :where(.xn-btn, .xn-chip, .xn-seg > *, .xn-input, .xn-select, .xn-textarea) { transition: none; }
}

/* ── 13. 연출(v4) ─────────────────────────────────────────
   사이트의 --accent / --accent-2 로 물드는 오로라 바탕·유리 히어로·그라데이션 테두리·버튼 광택.
   전부 CSS 만 쓴다(이미지·JS 없음). 계속 도는 움직임은 바탕 오로라 하나뿐이고(transform 만 — 합성 단계에서 끝난다),
   나머지(히어로·카드·결과의 등장, 버튼 광택)는 한 번 또는 hover 때만 돈다. prefers-reduced-motion 이면 모두 멈춘다.
   등장 애니메이션은 fill-mode 를 backwards 로만 쓴다 — 끝난 뒤 transform 이 남으면 카드 안의 position:fixed
   (모달·토스트)가 카드 기준으로 붙어 버린다.
   테두리 그라데이션은 background 두 겹(padding-box 면 + border-box 그라데이션)이다. 사이트가 background 를 통째로
   덮으면 테두리가 투명해지므로, 그런 사이트는 자기 <style> 에 border-color 를 같이 준다. */
:where(.xn-app, .xn-app-light) {
  --glass: rgba(17, 20, 31, .62); --glass-hi: rgba(255, 255, 255, .07);
  --glow: rgba(99, 102, 241, .45); --title-tint: #c4b5fd;
  --edge-1: var(--border-strong); --edge-2: var(--border-strong);
  --card-top: var(--surface); --result-glow: rgba(99, 102, 241, .14);
  --aurora-1: 26%; --aurora-2: 20%; --aurora-3: 12%;
  --card-shadow: inset 0 1px 0 rgba(255, 255, 255, .045), 0 18px 40px -24px rgba(0, 0, 0, .75);
  --ease-out: cubic-bezier(.2, .8, .2, 1);
  isolation: isolate; /* 바탕 오로라(z-index:-1)가 html 배경을 칠한 사이트에서도 body 배경 위에 오게 */
}
.xn-app-light {
  --glass: rgba(255, 255, 255, .7); --glass-hi: rgba(255, 255, 255, .95);
  --aurora-1: 22%; --aurora-2: 18%; --aurora-3: 12%;
  --card-shadow: 0 1px 2px rgba(15, 23, 42, .05), 0 18px 38px -22px rgba(15, 23, 42, .3);
}
@supports (color: color-mix(in srgb, red, blue)) {
  :where(.xn-app, .xn-app-light) {
    --glow: color-mix(in srgb, var(--accent) 55%, transparent);
    --title-tint: color-mix(in srgb, var(--accent-2) 55%, var(--text));
    --edge-1: color-mix(in srgb, var(--accent) 60%, var(--border));
    --edge-2: color-mix(in srgb, var(--accent-2) 45%, var(--border));
    --card-top: color-mix(in srgb, var(--surface) 93%, var(--accent));
    --result-glow: color-mix(in srgb, var(--accent) 20%, transparent);
    --card-shadow: inset 0 1px 0 rgba(255, 255, 255, .045), 0 18px 40px -24px rgba(0, 0, 0, .75),
                   0 28px 60px -44px color-mix(in srgb, var(--accent) 70%, transparent);
  }
  .xn-app-light {
    --glow: color-mix(in srgb, var(--accent) 42%, transparent);
    --title-tint: color-mix(in srgb, var(--accent) 62%, var(--text));
    --edge-1: color-mix(in srgb, var(--accent) 45%, var(--border));
    --edge-2: color-mix(in srgb, var(--accent-2) 35%, var(--border));
    --card-top: color-mix(in srgb, #fff 96%, var(--accent));
    --card-shadow: 0 1px 2px rgba(15, 23, 42, .05), 0 18px 38px -22px color-mix(in srgb, var(--accent) 35%, rgba(15, 23, 42, .4));
  }

  /* 바탕 오로라 — 화면에 고정, 글 뒤. 화면보다 크게 잡아 천천히 흘러도 가장자리가 안 보인다.
     고정 요소는 문서 스크롤 폭에 들어가지 않으므로 가로 넘침이 생기지 않는다. */
  :where(.xn-app, .xn-app-light)::after {
    content: ''; position: fixed; top: -18vmax; right: -18vmax; bottom: -18vmax; left: -18vmax;
    z-index: -1; pointer-events: none;
    background:
      radial-gradient(42vmax 30vmax at 26% 24%, color-mix(in srgb, var(--accent) var(--aurora-1), transparent), transparent 70%),
      radial-gradient(36vmax 28vmax at 78% 26%, color-mix(in srgb, var(--accent-2) var(--aurora-2), transparent), transparent 70%),
      radial-gradient(44vmax 26vmax at 50% 86%, color-mix(in srgb, var(--accent-2) var(--aurora-3), color-mix(in srgb, var(--accent) var(--aurora-3), transparent)), transparent 72%);
    animation: xn-aurora 32s ease-in-out infinite alternate;
    will-change: transform;
  }
}
/* 휴대폰·느린 화면에서는 바탕 오로라를 멈춘 그림으로 — 화면보다 큰 고정 레이어를 60fps 로 계속 합성하는 비용(모바일 4배 감속,
   5초에 합성 스레드 ~0.8초)을 배터리·발열이 민감한 기기에서 쓰지 않는다. 색과 모양은 같다. */
@media (max-width: 760px), (update: slow) {
  :where(.xn-app, .xn-app-light)::after { animation: none; will-change: auto; }
}
@keyframes xn-aurora {
  from { transform: translate3d(-3%, -2%, 0) rotate(0deg) scale(1); }
  to   { transform: translate3d(3%, 3%, 0) rotate(6deg) scale(1.1); }
}
@keyframes xn-rise { from { opacity: 0; transform: translate3d(0, 14px, 0); } }
@keyframes xn-pop  { from { opacity: 0; transform: scale(.6) rotate(-8deg); } 60% { transform: scale(1.06); } }
@keyframes xn-reveal { from { opacity: 0; transform: translate3d(0, 10px, 0) scale(.98); } }
@keyframes xn-sheen { from { background-position: 100% 0; } to { background-position: 0 0; } }

/* 히어로 — 유리 판 + 위쪽 빛 + 점 무늬 */
:where(.xn-app, .xn-app-light) :where(.xn-hero) {
  position: relative; isolation: isolate; padding: 26px 18px 22px; border-radius: 26px;
  background: linear-gradient(170deg, var(--glass-hi), transparent 46%), var(--glass);
  border: 1px solid var(--edge-1);
  box-shadow: inset 0 1px 0 var(--glass-hi), 0 26px 50px -34px var(--glow);
  animation: xn-rise .6s var(--ease-out) backwards;
}
:where(.xn-app, .xn-app-light) :where(.xn-hero)::before {
  content: ''; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
  background:
    radial-gradient(70% 80% at 50% -10%, var(--glow), transparent 70%),
    radial-gradient(rgba(255, 255, 255, .09) 1px, transparent 1.3px) 0 0 / 16px 16px;
  opacity: .55;
  -webkit-mask-image: linear-gradient(180deg, #000, transparent 88%); mask-image: linear-gradient(180deg, #000, transparent 88%);
}
:where(.xn-app-light) :where(.xn-hero)::before {
  background:
    radial-gradient(70% 80% at 50% -10%, var(--glow), transparent 70%),
    radial-gradient(rgba(15, 23, 42, .1) 1px, transparent 1.3px) 0 0 / 16px 16px;
  opacity: .5;
}
@media (min-width: 600px) { :where(.xn-app, .xn-app-light) :where(.xn-hero) { padding: 32px 28px 28px; } }

:where(.xn-app, .xn-app-light) :where(.xn-hero__icon) {
  position: relative; width: 62px; height: 62px; border-radius: 19px; font-size: 30px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .35), inset 0 0 0 1px rgba(255, 255, 255, .14),
              0 14px 30px -10px var(--glow), 0 0 46px -8px var(--glow);
  animation: xn-pop .7s var(--ease-out) .08s backwards;
}
:where(.xn-app, .xn-app-light) :where(.xn-hero__icon)::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(140deg, rgba(255, 255, 255, .42), rgba(255, 255, 255, 0) 46%);
}
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  :where(.xn-app, .xn-app-light) :where(.xn-hero__title, .xn-hero h1) {
    /* color:transparent 라서, 사이트가 h1 에 color 를 주면 그 색이 그대로 보인다(하위 호환) */
    background: linear-gradient(100deg, var(--text) 18%, var(--title-tint) 58%, var(--text) 96%);
    -webkit-background-clip: text; background-clip: text; color: transparent;
  }
}
:where(.xn-app, .xn-app-light) :where(.xn-hero__badge) {
  border-color: var(--edge-1); background: var(--glass); box-shadow: 0 6px 16px -10px var(--glow);
}

/* 카드 — 그라데이션 테두리 + 깊이 */
:where(.xn-app, .xn-app-light) :where(.xn-card) {
  background: linear-gradient(180deg, var(--card-top), var(--surface) 55%) padding-box,
              linear-gradient(155deg, var(--edge-1), var(--border) 36%, var(--border) 64%, var(--edge-2)) border-box;
  border-color: transparent; box-shadow: var(--card-shadow);
  animation: xn-rise .55s var(--ease-out) .06s backwards;
}
:where(.xn-app, .xn-app-light) :where(.xn-card + .xn-card, .xn-layout > * + *) { animation-delay: .14s; }
:where(.xn-app, .xn-app-light) :where(.xn-card--inset) {
  background: var(--surface-2); border-color: var(--border); box-shadow: none; animation: none;
}
:where(.xn-app, .xn-app-light) :where(.xn-card__title) { letter-spacing: -.01em; }

/* 입력 — 초점에 빛 */
:where(.xn-app, .xn-app-light) :where(.xn-input, .xn-select, .xn-textarea):focus { box-shadow: var(--ring), 0 0 26px -8px var(--glow); }

/* 주 버튼 — 광택(hover·첫 등장 한 번) + 빛 */
:where(.xn-app, .xn-app-light) :where(.xn-btn) {
  position: relative; isolation: isolate;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .28), 0 12px 28px -12px var(--glow), 0 2px 6px -2px var(--glow);
  transition: transform .18s var(--ease-out), box-shadow .18s ease, filter .18s ease;
}
:where(.xn-app, .xn-app-light) :where(.xn-btn)::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(110deg, transparent 35%, rgba(255, 255, 255, .42) 48%, rgba(255, 255, 255, .14) 54%, transparent 65%) no-repeat;
  background-size: 300% 100%; background-position: 100% 0;
  transition: background-position .9s var(--ease-out);
  animation: xn-sheen 1.2s var(--ease-out) .7s backwards;
}
:where(.xn-app, .xn-app-light) :where(.xn-btn):hover {
  filter: brightness(1.07) saturate(1.08); transform: translateY(-1px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .3), 0 18px 36px -12px var(--glow), 0 0 28px -6px var(--glow);
}
:where(.xn-app, .xn-app-light) :where(.xn-btn):hover::after { background-position: 0 0; }
:where(.xn-app, .xn-app-light) :where(.xn-btn):active { transform: translateY(1px) scale(.99); }
:where(.xn-app, .xn-app-light) :where(.xn-btn--ghost, .xn-btn:disabled, .xn-btn[aria-disabled=true])::after { content: none; }
:where(.xn-app, .xn-app-light) :where(.xn-btn--ghost) { box-shadow: inset 0 1px 0 var(--glass-hi); }
:where(.xn-app, .xn-app-light) :where(.xn-btn--ghost):hover { transform: none; box-shadow: 0 0 0 1px var(--accent), 0 10px 24px -14px var(--glow); }
:where(.xn-app, .xn-app-light) :where(.xn-btn):disabled, :where(.xn-app, .xn-app-light) :where(.xn-btn[aria-disabled=true]) { transform: none; filter: none; box-shadow: none; }

/* 세그먼트·칩 — 켜진 칸은 그라데이션 + 빛 */
:where(.xn-app, .xn-app-light) :where(.xn-seg) { background: var(--glass); box-shadow: inset 0 1px 2px rgba(0, 0, 0, .18); }
:where(.xn-app-light) :where(.xn-seg) { background: var(--surface-2); box-shadow: inset 0 1px 2px rgba(15, 23, 42, .06); }
:where(.xn-app, .xn-app-light) :where(.xn-seg > button, .xn-seg > a, .xn-seg > label) { transition: background .2s ease, color .2s ease, box-shadow .2s ease; }
:where(.xn-app, .xn-app-light) :where(.xn-seg > [aria-pressed=true], .xn-seg > [aria-selected=true], .xn-seg > .is-active,
  .xn-chip[aria-pressed=true], .xn-chip.is-active) {
  background: var(--grad); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 6px 16px -8px var(--glow);
}
:where(.xn-app, .xn-app-light) :where(.xn-chip) { transition: border-color .15s ease, color .15s ease, background .15s ease, transform .15s ease, box-shadow .15s ease; }
:where(.xn-app, .xn-app-light) :where(.xn-chip):hover { transform: translateY(-1px); box-shadow: 0 8px 18px -12px var(--glow); }

/* 숫자 타일 */
:where(.xn-app, .xn-app-light) :where(.xn-stat) {
  background: linear-gradient(180deg, var(--card-top), var(--surface-2) 70%);
  box-shadow: inset 0 1px 0 var(--glass-hi);
}
:where(.xn-app) :where(.xn-stat__value) { text-shadow: 0 0 22px var(--glow); }
:where(.xn-app-light) :where(.xn-stat__value) { text-shadow: none; }

/* 결과 패널 — 드러나는 느낌: 그라데이션 테두리, 모서리 빛, 숫자 빛 */
:where(.xn-app, .xn-app-light) :where(.xn-result) {
  background: radial-gradient(120% 100% at 100% 0%, var(--result-glow), transparent 60%) padding-box,
              linear-gradient(var(--surface-2), var(--surface-2)) padding-box,
              linear-gradient(135deg, var(--edge-1), var(--border) 45%, var(--edge-2)) border-box;
  border-color: transparent;
  box-shadow: inset 0 1px 0 var(--glass-hi), 0 22px 46px -28px var(--glow);
  animation: xn-reveal .6s var(--ease-out) backwards;
}
:where(.xn-app-light) :where(.xn-result) {
  background: radial-gradient(120% 100% at 100% 0%, color-mix(in srgb, var(--accent) 12%, transparent), transparent 60%) padding-box,
              linear-gradient(#fff, #fff) padding-box,
              linear-gradient(135deg, var(--edge-1), var(--border) 45%, var(--edge-2)) border-box;
}
:where(.xn-app, .xn-app-light) :where(.xn-result)::before { box-shadow: 0 0 18px 1px var(--glow); }
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  :where(.xn-app, .xn-app-light) :where(.xn-result__value) {
    background: linear-gradient(100deg, var(--text) 30%, var(--title-tint) 95%);
    -webkit-background-clip: text; background-clip: text; color: transparent;
  }
}
:where(.xn-app) :where(.xn-result__value) { filter: drop-shadow(0 0 18px var(--glow)); }
:where(.xn-app-light) :where(.xn-result__value) { filter: none; }

@media (prefers-reduced-motion: reduce) {
  :where(.xn-app, .xn-app-light)::after,
  :where(.xn-app, .xn-app-light) :where(.xn-hero, .xn-hero__icon, .xn-card, .xn-result),
  :where(.xn-app, .xn-app-light) :where(.xn-btn)::after { animation: none; }
  :where(.xn-app, .xn-app-light) :where(.xn-btn, .xn-chip), :where(.xn-app, .xn-app-light) :where(.xn-btn)::after { transition: none; }
  :where(.xn-app, .xn-app-light) :where(.xn-btn, .xn-chip):hover { transform: none; }
}
