/* ============================================================================
   Notyx design system — public/css/system.css
   ============================================================================
   Ground-up rewrite (2026-08-01). Spec: DESIGN.md — an achromatic, "paper not
   glass" system. Every non-highlight, non-status colour token below satisfies
   max(R,G,B) - min(R,G,B) <= 3 out of 255 — a warm, barely-there paper cast,
   not a hue. The only chromatic colours anywhere in this file are the amber
   highlighter wash (--ny-hl) and the three functional status tokens
   (--ny-success / --ny-warning / --ny-danger). Status colour is always paired
   with an icon and a word in markup — never colour alone.

   State changes render on the same frame. No interpolated hover, no spinner
   rotation, no scroll easing, no entrance effect anywhere in this file — the
   spinner ships as a static ring and the skeleton as a flat block. Depth is
   expressed by a single 1px hairline border weight and by value contrast
   only: no drop shadow, no gradient fill, no blur.

   Prefix contract: every selector and every custom property below is
   `ny-`-prefixed except the small set of documented exceptions in §6 — the
   legacy `:root` in index.html loads after this file and will silently win
   any unprefixed custom-property name.
   ============================================================================ */

/* ============================================================================
   §1 Tokens
   ============================================================================
   Bare <html> (no class) is the dark theme, so :root holds dark colour
   values. <html class="light"> overrides them. Non-colour tokens (spacing,
   radius, type, font stack, container) are theme-independent and live once,
   here in :root only.
   ============================================================================ */

:root {
  /* colour — dark (bare <html>) */
  --ny-canvas: #0f0e0d;
  --ny-canvas-alt: #161514;
  --ny-surface: #1b1a19;
  --ny-surface-sunken: #121110;
  --ny-border: #2b2a28;
  --ny-border-strong: #3e3d3b;
  --ny-text: #ebeae9;
  --ny-text-muted: #a2a19f;
  --ny-text-faint: #6e6d6b;
  --ny-text-inverse: #0f0e0d;
  --ny-fill-strong: #ebeae9;
  --ny-fill-strong-hover: #ffffff;
  --ny-fill-subtle: #242322;
  --ny-scrim: rgba(0, 0, 0, 0.6);
  --ny-hl: rgba(251, 191, 36, 0.3);
  --ny-success: #4ade80;
  --ny-warning: #fbbf24;
  --ny-danger: #f87171;

  /* spacing — 8px base scale */
  --ny-space-1: 4px;
  --ny-space-2: 8px;
  --ny-space-3: 12px;
  --ny-space-4: 16px;
  --ny-space-5: 24px;
  --ny-space-6: 32px;
  --ny-space-7: 48px;
  --ny-space-8: 64px;
  --ny-space-9: 96px;

  /* radius */
  --ny-radius-xs: 4px;
  --ny-radius-sm: 6px;
  --ny-radius-md: 10px;
  --ny-radius-lg: 14px;
  --ny-radius-pill: 999px;

  /* 랜딩 진입 모션 — #landingView 전용 (2026-08-06 결정 기록).
     랜딩 밖은 여전히 모션 0이라 이 파일에는 transition/keyframe이 없다.
     모션을 도는 주체가 GSAP 하나뿐이므로 --ny-motion-ease는 CSS 이징이 아니라
     GSAP 이징 이름을 담는다. 소비자가 하나면 값도 하나여야 드리프트가 없다. */
  --ny-motion-rise: 10px;
  --ny-motion-dur: 200ms;
  --ny-motion-stagger: 50ms;
  --ny-motion-ease: power2.out;
  --ny-motion-hl-dur: 420ms;
  --ny-motion-hl-delay: 280ms;

  /* type family — already loaded by index.html, no new font added */
  --ny-font: 'Pretendard Variable', Pretendard, -apple-system, BlinkMacSystemFont,
    'Apple SD Gothic Neo', 'Segoe UI', system-ui, sans-serif;

  /* type scale — see DESIGN.md §3 for weight / line-height / tracking per role */
  --ny-text-hero-size: clamp(1.875rem, 5.2vw, 3.5rem);
  --ny-text-h2-size: clamp(1.375rem, 3vw, 2.125rem);
  --ny-text-h3-size: 1.125rem;
  --ny-text-lead-size: clamp(0.9375rem, 1.6vw, 1.0625rem);
  --ny-text-body-size: 0.9375rem;
  --ny-text-caption-size: 0.8125rem;
  --ny-text-badge-size: 0.75rem;

  /* layout */
  --ny-container: 68rem;
  --ny-measure: 36rem;
}

:root.light {
  --ny-canvas: #ffffff;
  --ny-canvas-alt: #f7f6f5;
  --ny-surface: #ffffff;
  --ny-surface-sunken: #f2f1f0;
  --ny-border: #e6e5e3;
  --ny-border-strong: #d4d3d1;
  --ny-text: #1c1b1a;
  --ny-text-muted: #5e5d5b;
  --ny-text-faint: #8e8d8b;
  --ny-text-inverse: #ffffff;
  --ny-fill-strong: #1c1b1a;
  --ny-fill-strong-hover: #373634;
  --ny-fill-subtle: #f2f1f0;
  --ny-scrim: rgba(28, 27, 26, 0.45);
  --ny-hl: rgba(251, 191, 36, 0.42);
  --ny-success: #15803d;
  --ny-warning: #a16207;
  --ny-danger: #b91c1c;
}

/* ============================================================================
   §2 Primitives
   ============================================================================ */

/* ── ny-btn ──────────────────────────────────────────────────────────────── */

.ny-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--ny-space-2);
  min-height: 2.75rem; /* 44px */
  padding: 0.55rem 1rem;
  border-radius: var(--ny-radius-xs);
  border: 1px solid transparent;
  font-family: var(--ny-font);
  font-size: var(--ny-text-body-size);
  font-weight: 500;
  line-height: 1.4;
  cursor: pointer;
}

a.ny-btn {
  text-decoration: none;
  justify-content: center;
}

.ny-btn:disabled {
  opacity: 0.4;
  pointer-events: none;
}

.ny-btn-primary {
  background: var(--ny-fill-strong);
  color: var(--ny-text-inverse);
  border-color: transparent;
}
.ny-btn-primary:hover {
  background: var(--ny-fill-strong-hover);
}
.ny-btn-primary:active {
  background: var(--ny-fill-strong);
}

.ny-btn-secondary {
  background: var(--ny-surface);
  border-color: var(--ny-border);
  color: var(--ny-text);
}
.ny-btn-secondary:hover {
  border-color: var(--ny-border-strong);
}
.ny-btn-secondary:active {
  background: var(--ny-fill-subtle);
}

.ny-btn-ghost {
  background: transparent;
  border-color: transparent;
  color: var(--ny-text-muted);
}
.ny-btn-ghost:hover {
  background: var(--ny-fill-subtle);
  color: var(--ny-text);
}
.ny-btn-ghost:active {
  background: var(--ny-fill-subtle);
}

.ny-btn-danger {
  background: transparent;
  border-color: var(--ny-danger);
  color: var(--ny-danger);
}
/* Dark: white-on-#f87171 is only ~2.6:1, so dark keeps the outline look on
   hover and only raises the fill one neutral step. Light: white-on-#b91c1c
   is 6.4:1, so light fills solid — see the :root.light override below. */
.ny-btn-danger:hover {
  background: var(--ny-fill-subtle);
}
:root.light .ny-btn-danger:hover {
  background: var(--ny-danger);
  color: #ffffff; /* one documented literal exception, DESIGN.md §4 */
}

.ny-btn-icon {
  width: 2.75rem; /* 44px */
  height: 2.75rem;
  padding: 0;
  background: transparent;
  border-color: transparent;
  color: var(--ny-text-muted);
}
.ny-btn-icon:hover {
  background: var(--ny-fill-subtle);
}
.ny-btn-icon.ny-btn-lg {
  width: 3rem; /* 48px */
  height: 3rem;
}

.ny-btn-sm {
  min-height: 2rem; /* 32px — desktop-only chrome, never a touch target */
  padding: 0.35rem 0.75rem;
}

.ny-btn-lg {
  min-height: 3rem; /* 48px */
  padding: 0.7rem 1.25rem;
}

/* ── payment dialog ---------------------------------------------------------
   Payment controls use the same button geometry as the rest of Notyx. */

.ny-payment-overlay {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--ny-space-4);
  background: var(--ny-scrim);
}

.ny-payment-dialog {
  width: min(100%, 27rem);
  max-height: calc(100vh - (2 * var(--ny-space-4)));
  overflow-y: auto;
  padding: var(--ny-space-6);
  border: 1px solid var(--ny-border);
  border-radius: var(--ny-radius-lg);
  background: var(--ny-surface);
  color: var(--ny-text);
  box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.28);
}

.ny-payment-title {
  margin: 0 0 var(--ny-space-2);
  color: var(--ny-text);
  font-size: 1.25rem;
  line-height: 1.35;
  letter-spacing: -0.02em;
}

.ny-payment-copy {
  margin: 0 0 var(--ny-space-5);
  color: var(--ny-text-muted);
  font-size: var(--ny-text-body-size);
  line-height: 1.7;
}

.ny-payment-options {
  display: grid;
  gap: var(--ny-space-3);
  margin-bottom: var(--ny-space-5);
}

.ny-payment-option {
  display: block;
  width: 100%;
  min-height: 5rem;
  padding: var(--ny-space-4);
  border: 1px solid var(--ny-border);
  border-radius: var(--ny-radius-md);
  background: var(--ny-surface-sunken);
  color: var(--ny-text);
  font-family: var(--ny-font);
  text-align: left;
  cursor: pointer;
}

.ny-payment-option:hover {
  border-color: var(--ny-border-strong);
  background: var(--ny-fill-subtle);
}

.ny-payment-option-primary {
  border-color: var(--ny-text);
  background: var(--ny-fill-subtle);
}

.ny-payment-option-title {
  display: block;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.4;
}

.ny-payment-option-detail {
  display: block;
  margin-top: var(--ny-space-1);
  color: var(--ny-text-muted);
  font-size: var(--ny-text-caption-size);
  line-height: 1.55;
}

.ny-payment-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ny-space-2);
  margin: var(--ny-space-4) 0 var(--ny-space-5);
}

.ny-payment-actions .ny-btn {
  flex: 1 1 12rem;
}

.ny-payment-close {
  width: 100%;
}

/* ── ny-seg (segmented control) ─────────────────────────────────────────── */

.ny-seg {
  display: inline-flex;
  background: var(--ny-surface-sunken);
  border: 1px solid var(--ny-border);
  border-radius: var(--ny-radius-md);
  padding: 3px;
  gap: 2px;
}

.ny-seg-btn {
  background: transparent;
  border: none;
  border-radius: calc(var(--ny-radius-md) - 3px);
  color: var(--ny-text-muted);
  font-family: var(--ny-font);
  font-size: var(--ny-text-body-size);
  font-weight: 500;
  padding: 0.4rem 0.9rem;
  cursor: pointer;
}
.ny-seg-btn:hover {
  color: var(--ny-text);
}
.ny-seg-btn.active {
  background: var(--ny-surface);
  color: var(--ny-text);
  font-weight: 600;
}

/* ── ny-tabs / ny-tab ────────────────────────────────────────────────────── */

.ny-tabs {
  display: flex;
  border-bottom: 1px solid var(--ny-border);
}

.ny-tab {
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  color: var(--ny-text-muted);
  font-family: var(--ny-font);
  font-size: var(--ny-text-body-size);
  font-weight: 500;
  padding-block: var(--ny-space-3);
  padding-inline: var(--ny-space-4);
  cursor: pointer;
}
.ny-tab:hover {
  color: var(--ny-text);
}
.ny-tab.active {
  color: var(--ny-text);
  border-bottom-color: var(--ny-text);
}

/* ── ny-card ─────────────────────────────────────────────────────────────── */

.ny-card {
  background: var(--ny-surface);
  border: 1px solid var(--ny-border);
  border-radius: var(--ny-radius-lg);
  padding: var(--ny-space-5);
}
.ny-card-hover:hover {
  border-color: var(--ny-border-strong);
}
.ny-card-selected {
  border-color: var(--ny-border-strong);
  background: var(--ny-fill-subtle);
}

/* ── ny-scrim + ny-modal ─────────────────────────────────────────────────── */

.ny-scrim {
  position: fixed;
  inset: 0;
  background: var(--ny-scrim);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--ny-space-4);
  overflow-y: auto;
  z-index: 10050;
}

.ny-modal {
  width: 100%;
  max-width: 30rem; /* md — the default */
  max-height: calc(100vh - 2 * var(--ny-space-4));
  display: flex;
  flex-direction: column;
  background: var(--ny-surface);
  border: 1px solid var(--ny-border);
  border-radius: var(--ny-radius-lg);
}
.ny-modal-sm {
  max-width: 22.5rem;
}
.ny-modal-lg {
  max-width: 45rem;
}

.ny-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ny-space-3);
  padding: var(--ny-space-4) var(--ny-space-5);
  font-size: var(--ny-text-h3-size);
  font-weight: 600;
  color: var(--ny-text);
}
.ny-modal-body {
  padding: 0 var(--ny-space-5) var(--ny-space-5);
  overflow-y: auto;
  flex: 1;
  color: var(--ny-text);
}
.ny-modal-foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--ny-space-3);
  padding: var(--ny-space-4) var(--ny-space-5);
  border-top: 1px solid var(--ny-border);
}
.ny-modal-close {
  color: var(--ny-text-muted); /* apply alongside .ny-btn-icon */
}

/* ── ny-input / ny-select / ny-textarea / ny-field ──────────────────────── */

.ny-input,
.ny-select,
.ny-textarea {
  display: block;
  width: 100%;
  min-height: 2.75rem;
  background: var(--ny-surface-sunken);
  border: 1px solid var(--ny-border);
  border-radius: var(--ny-radius-xs);
  padding: 0.5rem 0.75rem;
  font-family: var(--ny-font);
  font-size: var(--ny-text-body-size);
  color: var(--ny-text);
}
.ny-input:hover,
.ny-select:hover,
.ny-textarea:hover {
  border-color: var(--ny-border-strong);
}
.ny-input:disabled,
.ny-select:disabled,
.ny-textarea:disabled {
  opacity: 0.5;
}
.ny-input::placeholder,
.ny-textarea::placeholder {
  color: var(--ny-text-faint);
}

.ny-field {
  display: block;
}
.ny-field > label {
  display: block;
  font-size: var(--ny-text-caption-size);
  font-weight: 600;
  color: var(--ny-text-muted);
  margin-bottom: var(--ny-space-1);
}

/* ── ny-badge / ny-chip ──────────────────────────────────────────────────── */

.ny-badge {
  display: inline-flex;
  align-items: center;
  padding: 0.3rem 0.65rem;
  border-radius: var(--ny-radius-pill);
  background: var(--ny-fill-subtle);
  border: 1px solid transparent;
  color: var(--ny-text-muted);
  font-size: var(--ny-text-badge-size);
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: 0.06em;
}
/* Status modifiers stay on the two-exception colour budget: background is
   left neutral, only the border and text move to the status colour. Pair
   with an icon and the status word in markup — colour never carries meaning
   alone. */
.ny-badge-success {
  color: var(--ny-success);
  border-color: var(--ny-success);
}
.ny-badge-warning {
  color: var(--ny-warning);
  border-color: var(--ny-warning);
}
.ny-badge-danger {
  color: var(--ny-danger);
  border-color: var(--ny-danger);
}

.ny-chip {
  display: inline-flex;
  align-items: center;
  padding: 0.35rem 0.75rem;
  border: 1px solid var(--ny-border);
  border-radius: var(--ny-radius-pill);
  background: var(--ny-surface);
  color: var(--ny-text-muted);
  font-family: var(--ny-font);
  font-size: var(--ny-text-caption-size);
  font-weight: 500;
  cursor: pointer;
}
.ny-chip:hover {
  border-color: var(--ny-border-strong);
}
.ny-chip.active {
  background: var(--ny-fill-strong);
  color: var(--ny-text-inverse);
  border-color: transparent;
}

/* ── ny-row ──────────────────────────────────────────────────────────────── */

.ny-row {
  display: flex;
  align-items: center;
  gap: var(--ny-space-3);
  min-height: 2.75rem; /* 44px */
  padding: 0.625rem 0.75rem;
  border-radius: var(--ny-radius-sm);
  color: var(--ny-text);
}
.ny-row:hover {
  background: var(--ny-fill-subtle);
}
.ny-row.active {
  background: var(--ny-fill-subtle);
  font-weight: 600;
}

/* ── ny-toast ────────────────────────────────────────────────────────────── */

.ny-toast {
  position: fixed;
  bottom: var(--ny-space-6);
  left: 50%;
  transform: translateX(-50%); /* static centring offset, not motion */
  background: var(--ny-surface);
  border: 1px solid var(--ny-border);
  border-radius: var(--ny-radius-md);
  padding: var(--ny-space-3) var(--ny-space-5);
  color: var(--ny-text);
  font-size: var(--ny-text-body-size);
  z-index: 10060;
}
.ny-toast-success {
  border-left: 2px solid var(--ny-success);
  color: var(--ny-success);
}
.ny-toast-warning {
  border-left: 2px solid var(--ny-warning);
  color: var(--ny-warning);
}
.ny-toast-danger {
  border-left: 2px solid var(--ny-danger);
  color: var(--ny-danger);
}

/* ── ny-progress / ny-spinner / ny-skeleton ─────────────────────────────── */

.ny-progress {
  background: var(--ny-surface-sunken);
  border: 1px solid var(--ny-border);
  border-radius: var(--ny-radius-pill);
  height: 6px;
  overflow: hidden;
}
.ny-progress-fill {
  background: var(--ny-text);
  height: 100%;
  /* width set inline per instance — dynamic value */
}

/* Static three-quarter ring — communicates "busy" without spinning. Pair
   with a text label ("분석 중…") and a determinate .ny-progress wherever
   real progress exists. */
.ny-spinner {
  width: 1.1rem;
  height: 1.1rem;
  border-radius: 50%;
  border: 2px solid var(--ny-border);
  border-top-color: var(--ny-text-muted);
}

/* Flat block, no pulse — the skeleton does not move. */
.ny-skeleton {
  background: var(--ny-fill-subtle);
  border-radius: var(--ny-radius-sm);
}

/* ── ny-empty / ny-dropzone / ny-divider ─────────────────────────────────── */

.ny-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--ny-space-2);
  padding: var(--ny-space-7);
  color: var(--ny-text-muted);
  text-align: center;
}
.ny-empty > :first-child {
  font-weight: 600;
  color: var(--ny-text);
}

/* ── ny-demo-cta (로그아웃 데모의 퀴즈/분류/질문 로그인 유도) ───────────── */

.ny-demo-cta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--ny-space-2);
  max-width: var(--ny-measure);
  margin-inline: auto;
  padding-top: var(--ny-space-7);
  text-align: center;
}
.ny-demo-cta p {
  margin: 0;
  color: var(--ny-text-muted);
  line-height: 1.7;
}
.ny-demo-cta p:last-of-type {
  font-size: var(--ny-text-caption-size);
  color: var(--ny-text-faint);
}

/* ── ny-demo-credit (데모 뷰어 안 CC BY 4.0 표기) ────────────────────────── */

.ny-demo-credit {
  margin: 0 0 var(--ny-space-3);
  font-size: var(--ny-text-caption-size);
  color: var(--ny-text-muted);
}
.ny-demo-credit a {
  color: inherit;
  text-decoration: underline;
}

.ny-dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--ny-space-2);
  border: 1px dashed var(--ny-border);
  border-radius: var(--ny-radius-lg);
  padding: var(--ny-space-6);
  text-align: center;
  color: var(--ny-text-muted);
}
.ny-dropzone.drag-over {
  border: 1px solid var(--ny-border-strong);
  background: var(--ny-fill-subtle);
}

.ny-divider {
  height: 1px;
  background: var(--ny-border);
  border: none;
}

/* ── ny-hl (형광펜 — the signature) ──────────────────────────────────────── */

.ny-hl,
mark.ny-hl {
  background: var(--ny-hl);
  color: inherit;
  padding: 0 0.15em;
  border-radius: var(--ny-radius-xs);
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

/* 획을 긋는 모드 — JS가 「지금 그린다」고 결정했을 때만 붙인다.
   붙이는 순간 mark 자신의 배경을 넘겨받은 .ny-hl-wash 가 대신 칠하고,
   그걸 scaleX 로 왼쪽부터 늘린다. 그리기 전 상태(scaleX 0)가 마크업 기본값이
   아니라 이 클래스 안에만 있는 이유가 그거다 — JS가 실패하면 애초에 안 붙는다.
   셀렉터가 mark.ny-hl.ny-hl-draw 형태인 이유: 위 mark.ny-hl (0,1,1)을
   특이도로 이겨야 하기 때문 — .ny-hl-draw 단독(0,1,0)이면 진다. */
mark.ny-hl.ny-hl-draw,
.ny-hl.ny-hl-draw {
  position: relative;
  z-index: 0;
  background: transparent;
}

/* 실제 마커는 글자 왼쪽 조금 앞에서 시작해 오른쪽 끝을 넘겨 멈춘다.
   좌우 오프셋이 비대칭인 게 그 오버슈트다. 선단이 완전한 직각이면
   CSS 애니메이션으로 읽히므로 skewX 로 살짝 눕힌다 (gradient는 금지 게이트라 못 쓴다). */
.ny-hl-wash {
  position: absolute;
  z-index: -1;
  top: 0.04em;
  right: -0.34em;
  bottom: -0.06em;
  left: -0.22em;
  background: var(--ny-hl);
  border-radius: 3px 7px 4px 6px / 6px 4px 7px 3px;
  transform: skewX(-9deg) scaleX(0);
  transform-origin: left center;
  pointer-events: none;
}

/* ============================================================================
   §3 Layout helpers
   ============================================================================ */

.ny-container {
  max-width: var(--ny-container);
  margin-inline: auto;
  padding-inline: var(--ny-space-5);
}

.ny-section {
  padding-block: clamp(3rem, 7vw, 6rem);
}
.ny-section-alt {
  background: var(--ny-canvas-alt);
}

.ny-stack {
  display: flex;
  flex-direction: column;
  gap: var(--ny-space-4);
}

.ny-grid,
.ny-grid-cards {
  display: grid;
  gap: var(--ny-space-4);
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
}

.ny-measure {
  max-width: var(--ny-measure);
  margin-inline: auto;
}

.ny-eyebrow {
  font-size: var(--ny-text-badge-size);
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: 0.06em;
  color: var(--ny-text-muted);
}

/* ============================================================================
   §4 Landing screen (#landingView)
   ============================================================================ */

.ny-landing {
  font-family: var(--ny-font);
  background: var(--ny-canvas);
  color: var(--ny-text);
  min-height: 100vh;
  word-break: keep-all;
  overflow-wrap: break-word;
}

/* -- nav ------------------------------------------------------------------ */

.ny-nav {
  position: sticky;
  top: 0;
  background: var(--ny-canvas);
  border-bottom: 1px solid var(--ny-border);
  z-index: 10;
}
.ny-nav-inner {
  max-width: var(--ny-container);
  margin-inline: auto;
  padding-inline: var(--ny-space-5);
  min-height: 3.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.ny-nav-brand {
  display: flex;
  align-items: center;
  min-height: 2.75rem; /* 44px */
  gap: var(--ny-space-2);
  font-weight: 700;
  color: var(--ny-text);
  text-decoration: none;
}
.ny-nav-mark {
  display: inline-flex;
  width: 1.25rem;
  height: 1.25rem;
  color: currentColor;
}
.ny-nav-actions {
  display: flex;
  align-items: center;
  gap: var(--ny-space-2);
}

/* -- generic section head -------------------------------------------------- */

.ny-section-head {
  text-align: center;
  margin-bottom: var(--ny-space-7);
}
.ny-section-title {
  font-size: var(--ny-text-h2-size);
  font-weight: 700;
  line-height: 1.28;
  letter-spacing: -0.025em;
  color: var(--ny-text);
  text-wrap: balance;
}
.ny-section-sub {
  font-size: var(--ny-text-lead-size);
  font-weight: 400;
  line-height: 1.75;
  color: var(--ny-text-muted);
  max-width: var(--ny-measure);
  margin-inline: auto;
  text-wrap: pretty;
}

/* -- hero -------------------------------------------------------------------
   Extra top padding clears the sticky nav; the bottom half matches the
   normal section rhythm. */
.ny-hero {
  padding-block: clamp(4rem, 10vw, 8rem) clamp(3rem, 7vw, 6rem);
}
.ny-hero-inner {
  max-width: 48rem;
  margin-inline: auto;
  text-align: center;
}
.ny-hero-title {
  font-size: var(--ny-text-hero-size);
  font-weight: 700;
  line-height: 1.18;
  letter-spacing: -0.035em;
  color: var(--ny-text);
  margin-bottom: var(--ny-space-5);
  text-wrap: balance;
}
.ny-hero-sub {
  font-size: var(--ny-text-lead-size);
  font-weight: 400;
  line-height: 1.75;
  color: var(--ny-text-muted);
  max-width: 38rem;
  margin-inline: auto;
  text-wrap: pretty;
}
.ny-hero-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--ny-space-3);
  margin-top: var(--ny-space-6);
}
.ny-hero-cta .ny-btn {
  min-width: 10rem;
}
.ny-hero-note {
  margin-top: var(--ny-space-3);
  font-size: var(--ny-text-caption-size);
  color: var(--ny-text-muted);
}

/* -- product preview -------------------------------------------------------- */

.ny-preview {
  max-width: 56rem;
  margin-inline: auto;
  background: var(--ny-surface);
  border: 1px solid var(--ny-border);
  border-radius: var(--ny-radius-lg);
  overflow: hidden;
}
.ny-preview-bar {
  display: flex;
  align-items: center;
  gap: var(--ny-space-2);
  padding: var(--ny-space-3) var(--ny-space-4);
  background: var(--ny-surface-sunken);
  border-bottom: 1px solid var(--ny-border);
}
.ny-preview-dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--ny-border-strong);
}
.ny-preview-name {
  font-size: var(--ny-text-caption-size);
  color: var(--ny-text-muted);
}
.ny-preview-body {
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  gap: 1px;
  background: var(--ny-border); /* the 1px gap reads as the dividing hairline */
}
.ny-preview-slide {
  display: flex;
  flex-direction: column;
  gap: var(--ny-space-3);
  padding: var(--ny-space-5);
  background: var(--ny-surface-sunken);
}
.ny-preview-slide-frame {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: var(--ny-space-3);
  padding: var(--ny-space-4);
  border: 1px solid var(--ny-border);
  border-radius: var(--ny-radius-sm);
  aspect-ratio: 16 / 10;
}
.ny-preview-slide-line {
  height: 0.5rem;
  background: var(--ny-border);
  border-radius: var(--ny-radius-pill);
}
.ny-preview-slide-line.is-short {
  width: 55%;
}
.ny-preview-slide-line.is-head {
  height: 0.75rem;
  width: 70%;
  background: var(--ny-border-strong);
}
.ny-preview-note {
  display: flex;
  flex-direction: column;
  gap: var(--ny-space-3);
  padding: var(--ny-space-5);
  background: var(--ny-surface);
}
.ny-preview-note-h {
  font-size: var(--ny-text-h3-size);
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: -0.01em;
  color: var(--ny-text);
}
.ny-preview-note-p {
  font-size: var(--ny-text-body-size);
  font-weight: 400;
  line-height: 1.7;
  color: var(--ny-text-muted);
}
.ny-preview-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--ny-space-2);
  font-size: var(--ny-text-body-size);
  line-height: 1.7;
  color: var(--ny-text);
}
.ny-preview-list li::before {
  content: '· ';
  color: var(--ny-text-faint);
}
.ny-preview-lead {
  font-size: var(--ny-text-body-size);
  line-height: 1.7;
  color: var(--ny-text);
}
.ny-preview-rule {
  height: 0;
  margin: 0;
  border: 0;
  border-top: 1px solid var(--ny-border);
}
.ny-preview-note-sub {
  font-size: var(--ny-text-body-size);
  font-weight: 600;
  line-height: 1.5;
  color: var(--ny-text);
}
.ny-preview-sublist {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--ny-space-1);
  margin-top: var(--ny-space-1);
  padding-inline-start: var(--ny-space-4);
  font-size: var(--ny-text-caption-size);
  color: var(--ny-text-muted);
}
/* 랜딩 미리보기는 정적이다 — 칩은 실제 노트와 같은 클래스로 모양만 재현하고
   data-slide를 달지 않아 ui.js의 전역 위임 클릭이 발화하지 않는다. 손 모양
   커서는 열리지 않는 오버레이를 약속하므로 여기서만 되돌린다. hover도
   기본 배경(--primary-dim)으로 되돌려서 색이 바뀌는 것처럼 보이지 않게 한다. */
#ny-preview .page-cite-chip {
  cursor: default;
}
#ny-preview .page-cite-chip:hover {
  background: var(--primary-dim);
}
.ny-preview-cta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--ny-space-2);
  margin-top: var(--ny-space-5);
}
.ny-preview-cta-note {
  font-size: var(--ny-text-caption-size);
  color: var(--ny-text-muted);
}
.ny-preview-credit {
  max-width: 56rem;
  margin: var(--ny-space-3) auto 0;
  font-size: var(--ny-text-caption-size);
  color: var(--ny-text-muted);
  text-align: center;
}
.ny-preview-credit a {
  color: inherit;
  text-decoration: underline;
}

/* -- content blocks ---------------------------------------------------------- */

.ny-list-check {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--ny-space-3);
  font-size: var(--ny-text-body-size);
  line-height: 1.7;
  color: var(--ny-text);
}
.ny-list-check li::before {
  content: '— ';
  color: var(--ny-text-faint);
}

.ny-feature {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--ny-space-4);
}
.ny-feature-num {
  font-size: var(--ny-text-h3-size);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ny-text-muted);
}
.ny-feature-body {
  display: flex;
  flex-direction: column;
  gap: var(--ny-space-1);
}
.ny-feature-title {
  font-size: var(--ny-text-h3-size);
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: -0.01em;
  color: var(--ny-text);
}
.ny-feature-desc {
  font-size: var(--ny-text-body-size);
  font-weight: 400;
  line-height: 1.7;
  color: var(--ny-text-muted);
}

/* -- closing ------------------------------------------------------------------ */

.ny-closing {
  text-align: center;
}
.ny-closing-title {
  font-size: var(--ny-text-h2-size);
  font-weight: 700;
  line-height: 1.28;
  letter-spacing: -0.025em;
  color: var(--ny-text);
  text-wrap: balance;
}
.ny-closing-note {
  margin-top: var(--ny-space-3);
  font-size: var(--ny-text-caption-size);
  color: var(--ny-text-muted);
}

/* -- footer (document-level <footer>, see §6.d) ------------------------------- */

.ny-footer {
  text-align: center;
  border-top: 1px solid var(--ny-border);
  padding: var(--ny-space-6) var(--ny-space-5);
  font-family: var(--ny-font);
  font-size: var(--ny-text-caption-size);
  line-height: 1.6;
  color: var(--ny-text-muted);
  background: var(--ny-canvas);
  word-break: keep-all;
  overflow-wrap: break-word;
}
.ny-footer-links {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--ny-space-3);
  margin-bottom: var(--ny-space-1);
}
.ny-footer-links a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding-inline: var(--ny-space-2);
  border-radius: var(--ny-radius-xs);
  color: var(--ny-text-muted);
  text-decoration: none;
}
.ny-footer-links a:hover {
  color: var(--ny-text);
  text-decoration: underline;
}
.ny-footer-legal {
  color: var(--ny-text-muted);
  line-height: 1.8;
}
/* Inline in a sentence — WCAG 2.5.8 exempts inline links from the target-size
   minimum, so this one is intentionally not padded out to 44px. */
.ny-footer-legal a {
  color: var(--ny-text-muted);
  text-decoration: underline;
}

/* -- responsive --------------------------------------------------------------
   Exactly two breakpoints: container padding + hero CTA stacking share one,
   the preview pane collapse owns the other. */
@media (max-width: 599px) {
  .ny-container {
    padding-inline: var(--ny-space-4);
  }
  .ny-hero-cta {
    flex-direction: column;
    align-items: stretch;
  }
  .ny-hero-cta .ny-btn {
    width: 100%;
  }
  .ny-nav-actions {
    gap: var(--ny-space-1);
  }
  .ny-nav-cta {
    padding-inline: var(--ny-space-3);
    font-size: var(--ny-text-caption-size);
  }
  .ny-payment-dialog {
    padding: var(--ny-space-5);
  }
}
@media (max-width: 720px) {
  .ny-preview-body {
    grid-template-columns: 1fr;
  }
}

/* ============================================================================
   §5 Logged-out shell suppression
   ============================================================================
   Logged out, the landing screen is the whole page: no top bar, no sidebar,
   no #mainContent. #mainContent is 100vh with a 240px left margin even when
   every child is hidden, so hiding its children was never enough. These
   nodes stay in the DOM — updateAuthUI, toggleTheme and switchView all
   resolve them by id — they just do not render. !important is required: the
   legacy markup sets display inline. */
html.ny-logged-out #topBar,
html.ny-logged-out #settingsPanel,
html.ny-logged-out #sidebar,
html.ny-logged-out #sidebarOverlay,
html.ny-logged-out #progressWrap,
html.ny-logged-out #batchBuddy,
html.ny-logged-out #mainContent,
html.ny-logged-out #debugToggle,
html.ny-logged-out #debugPanel {
  display: none !important;
}

/* ============================================================================
   §6 Global exceptions
   ============================================================================
   Exactly four documented departures from the ny- prefix rule:
     a. focus ring — scoped under .ny-landing, plus a bare group naming the
        interactive ny- primitives directly (below).
     b. .ny-visually-hidden — a single site-wide utility, not tied to one
        component.
     c. the html.ny-logged-out id block — §5 above.
     d. the document-level legal <footer> — index.html's footer ships without
        any class today, so .ny-footer above only takes effect once that
        markup adopts it in a later pass; not touched this round.
   ============================================================================ */

.ny-landing :focus-visible {
  outline: 2px solid var(--ny-text);
  outline-offset: 2px;
}

.ny-btn:focus-visible,
.ny-chip:focus-visible,
.ny-tab:focus-visible,
.ny-input:focus-visible,
.ny-select:focus-visible,
.ny-textarea:focus-visible,
.ny-row:focus-visible {
  outline: 2px solid var(--ny-text);
  outline-offset: 2px;
}

.ny-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ============================================================================
   §12 prefers-reduced-motion — 협상 대상 아님 (2026-08-06 결정 기록)
   ============================================================================
   JS가 matchMedia로 이미 가드하므로 평소엔 이 블록이 할 일이 없다. 여기 있는
   이유는 OS 설정이 세션 도중에 바뀌는 경우다 — 그때 이미 심어진 wash와 이미
   숨겨진 요소가 그대로 멈춰 있으면 안 된다. GSAP은 인라인 스타일로 쓰므로
   !important 가 필요하다.
   ============================================================================ */

@media (prefers-reduced-motion: reduce) {
  #landingView [data-state] {
    opacity: 1 !important;
    transform: none !important;
  }
  /* 형광펜은 「안 그린 게 아니라 이미 그려져 있다」 */
  .ny-hl-wash {
    transform: skewX(-9deg) scaleX(1) !important;
  }
}
