/* /design/styles/tokens.css */
/* ============================================================================
   SnapHolo 디자인 토큰
   ----------------------------------------------------------------------------
   생성물 — 정본은 docs/design/tokens/snapholo.tokens.json, 손으로 고치지 마라.
   다시 만들기: python scripts/build_tokens.py
   (docs/design/styles/tokens.css 와 docs/design/ds-bundle/tokens.css 는 같은 바이트다.)

   다른 CSS 파일에 hex 리터럴을 적지 마라 — 그게 v3 가 죽은 경로다.
   프레임워크 중립: 순수 CSS 커스텀 프로퍼티다. 빌드 없는 정적 HTML 은 <link> 로 읽는다.
   대비 실측은 정본 JSON 의 contrast 표에 있고 tests/test_design_tokens.py 가 다시 잰다.
   ========================================================================== */

:root {
  /* ══════════════════════════════════════════════════════════════════════════
     1층 · PRIMITIVE — 값 그 자체. 의미를 담지 않는다.
     ══════════════════════════════════════════════════════════════════════════ */

  /* 브랜드 홀로 4색 — logo.ai 마스터에서 나온 값. 새로 만들지 않는다. */
  --holo-aqua: #5bc9d5;
  --holo-iris: #8c77da;
  --holo-blossom: #ef94b8;
  --holo-amber: #ffd88e;
  --ink: #17232c; /* 브랜드 잉크 — brand/master/*.svg 의 fill 값과 동일 */

  /* 중성 램프 (hue 220) — 흰 지면 대비 실측은 contrast 표 */
  --slate-950: #1e2534;
  --slate-800: #333b4c;
  --slate-700: #4d576a;
  --slate-600: #65718b; /* 본문 최소선 */
  --slate-400: #9ca4b4; /* 비텍스트 전용 */
  --slate-300: #cacfd8;
  --slate-200: #e1e4ea;
  --slate-100: #eef0f4;
  --slate-50: #f7f8fa;
  --white: #ffffff;

  /* 아이리스 — 브랜드 보라(옛). v0 시안에 흩어져 있던 7종을 이 넷으로 수렴했다
     (#7174d4 #7c79dc #7476d3 #6e73d1 #8081dc #7777d6 #4f55b5) */
  --iris-700: #5f62cf; /* 글자로 쓸 수 있는 유일한 보라
       legacy — 2026-10-02 대표 결정 d2 — 2단계에서 민트로 */
  --iris-500: #7174d4; /* 텍스트로 쓰지 마라. 채움 전용
       legacy — 2026-10-02 대표 결정 d2 — 2단계에서 민트로 */
  --iris-300: #8b8ddc; /* 보더·밑줄 전용
       legacy — 2026-10-02 대표 결정 d2 — 2단계에서 민트로 */
  --iris-50: #f0f0ff; /* legacy — 2026-10-02 대표 결정 d2 — 2단계에서 민트로 */

  /* 상태색 — 지면·카드 양쪽에서 4.5:1 을 넘도록 낮춘 값 */
  --green-600: #3a7e63;
  --amber-700: #9f6432;
  --red-700: #b42318; /* 오류 원색 · 흰 바탕 6.57:1 */
  --red-50: #fdeceb; /* 오류 옅은 바탕 */
  --pink-700: #c01f68; /* 내림 원색 · 흰 바탕 5.77:1, 옛 차트색 #d62a76 4.72:1 대체 */

  /* 알파 — 그림자·오버레이. 색상 토큰과 섞지 않는다 */
  --alpha-card-shadow: rgba(116, 118, 216, 0.2);
  --alpha-art-shadow: rgba(41, 55, 90, 0.33);
  --alpha-text-shadow: rgba(0, 0, 0, 0.2);
  --alpha-white-strong: rgba(255, 255, 255, 0.7);
  --alpha-white-soft: rgba(255, 255, 255, 0.33);

  /* ══════════════════════════════════════════════════════════════════════════
     2층 · SEMANTIC — 화면은 이것만 쓴다.
     다크 모드를 얹을 때 재정의하는 것도 이 층뿐이다(1층은 그대로).
     ══════════════════════════════════════════════════════════════════════════ */

  /* 지면 */
  --color-bg: var(--slate-50);
  --color-surface: var(--white);
  --color-surface-sunken: var(--slate-50);

  /* 글자 — 세 단. 그 아래는 없다 */
  --color-text: var(--slate-950); /* 제목·값 */
  --color-text-secondary: var(--slate-700); /* 본문·설명 */
  --color-text-muted: #5c6880; /* 라벨·보조 */

  /* 선 */
  --color-border: var(--slate-200);
  --color-border-strong: var(--slate-300);
  --color-border-dashed: var(--slate-200);

  /* 강조 — legacy(옛 보라). 옛 화면 9개 전용 — 새 화면은 아래 브랜드 강조(민트)만 쓴다 */
  --color-accent: var(--iris-700); /* 링크·강조 텍스트 — 세 지면 모두 통과
       legacy — 2026-10-02 대표 결정 d2 — 2단계에서 민트로 */
  --color-accent-fill: var(--iris-500); /* 채움(아바타·칩) — 텍스트 아님
       legacy — 2026-10-02 대표 결정 d2 — 2단계에서 민트로 */
  --color-accent-line: var(--iris-300); /* 보더·활성 밑줄 — 텍스트 아님
       legacy — 2026-10-02 대표 결정 d2 — 2단계에서 민트로 */
  --color-accent-soft: var(--iris-50); /* 배지·노트 지면
       legacy — 2026-10-02 대표 결정 d2 — 2단계에서 민트로 */

  /* 브랜드 강조 — 민트 (2026-10-02 대표 결정 d2). 액션 채움과 텍스트 링크를 구분한다 */
  --color-brand-action-fill: #1bd3ce; /* 액션 채움 — 에메랄드 바탕. 텍스트·아이콘은 brand.action.on(흰색). */
  --color-brand-action-on: #ffffff; /* 에메랄드 액션 버튼의 텍스트·아이콘 — 흰색(2026-10-07 사용자 지시) */
  --color-brand-link-text: #00777d; /* 텍스트 링크 — 민트 글자로 작은 링크를 만들지 않고 이 진한 색을 쓴다(UI-GUIDE 03). 아이스 지면 미달 — contrast 예외 */
  --color-brand-symbol-mint: #24d5cb; /* 심볼 민트 — 심볼 위쪽 그라디언트 시작색 · 홈 강조 */

  /* 상태 */
  --color-state-known: var(--green-600);
  --color-state-uncollected: var(--amber-700);
  --color-state-live: var(--green-600);
  --color-danger: var(--red-700);
  --color-danger-soft: var(--red-50);
  --color-rise: #327055;
  --color-fall: var(--pink-700);

  /* 홀로 그라디언트 — 정의는 여기 하나뿐이다.
     허용 자리 세 곳 (README 로고 규칙 4, 2026-08-21 개정):
       ① 어두운 지면의 워드마크  ② 실제 포일 판본의 카드 표면
       ③ 상단 3px 브랜드 밴드
     그 외에 쓰지 마라. */
  --gradient-holo: linear-gradient(
    57deg,
    var(--holo-aqua),
    var(--holo-iris) 33.3%,
    var(--holo-blossom) 66.7%,
    var(--holo-amber)
  );
  --on-gradient: var(--ink); /* 그라디언트 위 글자는 잉크다. 흰 글자는 금지 — 대비 실측은 contrast 표 */

  /* 그림자 */
  --shadow-card: 0 24px 50px var(--alpha-card-shadow);
  --shadow-art-text: 0 15px 22px var(--alpha-art-shadow);

  /* ── 차트 계열색 — 마감 3종. 순서 고정, 순환 금지 ──
     색은 마감(엔티티)을 따라간다. 필터로 계열이 줄어도 남은 것의 색은 안 바뀐다.
     dataviz 검증기 실측(지면 #ffffff):
       명도대역 PASS · 채도하한 PASS · 정상시각 ΔE 20.3 PASS · 지면대비 PASS
       CVD 최악쌍 리버스↔홀로 ΔE 7.7(deutan) — 6~8 구간이라
       **선 끝 직접 라벨이 필수**다. 범례만으로는 안 된다.
     다크(지면 #191e2a): 명도대역·채도·정상시각 ΔE 17.4·지면대비 PASS / CVD 최악쌍 7.7(deutan)
       → 라이트와 같은 이유로 직접 라벨 필수 */
  --chart-finish-base: #6f5bd8;
  --chart-finish-holo: #0a97a6;
  --chart-finish-reverse: #d62a76;
  --chart-grid: var(--slate-100);
  --chart-axis: var(--slate-300);

  /* ══════════════════════════════════════════════════════════════════════════
     활자 — 서체 · 크기 · 행간 · 자간 · 굵기
     ══════════════════════════════════════════════════════════════════════════ */

  /* 서체 — IBM Plex 한 가족으로 Latin·한글·일본어·태국어를 덮는다.
     중국어(TC/SC)만 IBM Plex 에 없어 Noto 로 보충한다.
     ⚠️ 스크립트별 스택은 아래 :lang() 이 갈아 끼운다 — 한 줄로 다 나열하면
        한자가 겹쳐서 중국어가 일본어 글리프로 나온다. */
  --font-sans: "IBM Plex Sans", "IBM Plex Sans KR", "IBM Plex Sans JP", sans-serif;
  --font-display: var(--font-sans);
  --font-mono: "IBM Plex Mono", "IBM Plex Sans KR", ui-monospace, SFMono-Regular, monospace;

  /* Shared service scale: body 16, supporting text 14, captions 12; desktop/mobile headings use the same roles in every language. */
  --text-display: 3.5rem; /* 3.5rem desktop / 2rem mobile */
  --text-hero: 2rem; /* 2rem desktop / 1.625rem mobile */
  --text-h2: 1.5rem; /* 24.0px */
  --text-h3: 1.125rem; /* 18.0px */
  --text-body: 1rem; /* 16px */
  --text-data: 0.875rem; /* 14.0px */
  --text-label: 0.75rem; /* 12 — 절대 하한 */
  --text-price: 2.25rem; /* 36.0px */
  --text-price-sub: 1.25rem; /* 20.0px */
  --leading-tight: 1.25;
  --leading-snug: 1.4;
  --leading-normal: 1.6;
  --tracking-display: -0.02em;
  --tracking-kicker: 0.04em;
  --weight-regular: 400;
  --weight-medium: 500;
  --weight-bold: 700;
  --weight-black: 800;
  --weight-semibold: 600;

  /* ══════════════════════════════════════════════════════════════════════════
     간격 — 4px 기반 12단. v0 시안의 padding 24종 · gap 20종을 여기 스냅했다.
     ══════════════════════════════════════════════════════════════════════════ */
  --space-1: 0.25rem; /* 4px */
  --space-2: 0.5rem; /* 8px */
  --space-3: 0.75rem; /* 12px */
  --space-4: 1rem; /* 16px */
  --space-5: 1.25rem; /* 20px */
  --space-6: 1.5rem; /* 24px */
  --space-7: 2rem; /* 32px */
  --space-8: 2.5rem; /* 40px */
  --space-9: 3rem; /* 48px */
  --space-10: 4rem; /* 64px */
  --space-11: 5rem; /* 80px */
  --space-12: 6rem; /* 96px */

  /* 반경 — v0 의 5·8·9·10·12·17·26·999 를 다섯 단으로 */
  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-xl: 16px;
  --radius-full: 999px;

  /* 레이아웃 */
  --layout-max: 1184px;
  --layout-pad: var(--space-7); /* 모바일(≤760px)에서 space-5 */
  --layout-pad-sm: var(--space-5);
  --topbar-height: 74px;

  /* 모션 — 150~300ms. 의미 없는 장식 애니메이션은 두지 않는다.
     들어올 때는 ease-out(빠르게 시작해 부드럽게 안착), 나갈 때는 ease-in 으로 더 짧게.
     transform 과 opacity 만 애니메이션한다 — width/height/top/left 는 매 프레임 레이아웃을 다시 계산한다. */
  --motion-fast: 0.15s; /* 줄이기 설정에서 0.01ms */
  --motion-base: 0.25s; /* 줄이기 설정에서 0.01ms */
  --motion-ease: cubic-bezier(0.4, 0, 0.2, 1); /* 표준 */
  --motion-enter: 0.2s; /* 손에 잡히는 순간 */
  --motion-leave: 0.14s; /* 놓는 건 더 빨라야 미련이 없다 */
  --ease-out: cubic-bezier(0.22, 0.9, 0.3, 1); /* 들어올 때 */
  --ease-in: cubic-bezier(0.4, 0, 1, 1); /* 나갈 때 */

  /* 카드를 집어 올리는 눈금. 이 셋이 「손으로 집었다」의 전부다 —
     더 올리면 카드가 화면에서 뜯겨 나가고, 더 틀면 그리드가 흔들려 보인다. */
  --lift-y: -10px; /* 뜨는 높이 */
  --lift-tilt: -2.5deg; /* 왼쪽이 들린다(반대각). 기존 기울기에 더해진다.
       ⚠️ 음수 = 반시계 = 왼쪽 들림.
       +2.5 로 되돌리지 마라 (2026-08-23 대표) */
  --lift-scale: 1.03; /* 눈에 가까워진 만큼 */
  --press-scale: 0.97; /* 손가락 아래서 눌리는 정도 */
  --shadow-rest: 0 6px 16px var(--alpha-card-shadow);
  --shadow-lift: 0 22px 40px var(--alpha-card-shadow);

  /* 나머지 모션의 눈금. 전부 짧다 — 이 화면은 표와 그리드라 오래 끌면 읽을 수가 없다 */
  --motion-tint: 0.12s; /* 색만 바뀌는 것(행·버튼·테두리) */
  --motion-press: 0.08s; /* 누름 */
  --motion-drop: 0.16s; /* 메뉴 열림 (닫힘은 --motion-press) */
  --motion-reveal: 0.32s; /* 스크롤 진입 — 한 번만 */
  --reveal-y: 12px; /* 진입할 때 아래에서 올라오는 거리 */
  --reveal-step: 0.04s; /* 줄줄이 들어올 때 한 칸 간격 */
  --set-bg: #f3f7f9; /* 아이스 */
  --set-line: #dee8ee;
  --set-panel: #eaf1f5;
  --set-focus: #6e66d7;
  --set-fan-duration: 400ms;
  --brand-foil-cyan: #32dce8;
  --brand-foil-violet: #8374f3;
  --brand-foil-pink: #ef8fda;
  --brand-foil-gold: #ffe9a1;
  --brand-foil-green: #7ae1c0;
  --brand-foil-blue: #57c9ee;
  --brand-foil-mask-solid: #000;
  --brand-foil-mask-soft: #000c;
  --brand-foil-light-cyan: #b7eeff55;
  --brand-foil-light-white: #fff;
  --brand-foil-light-soft: #fff9;
  --brand-foil-light-pink: #fcd9ff66;
  --brand-foil-glow-soft: #fff5;
  --brand-foil-pin: #718d98;
  --motion-foil-sweep: 8s;

  /* Service UI typography roles. Hero and cinematic card prices retain their own scale. */
  --ui-page-size: var(--text-h2);
  --ui-page-line: var(--space-7);
  --ui-section-size: var(--text-h3);
  --ui-group-size: var(--text-body);
  --ui-body-size: var(--text-body);
  --ui-body-line: var(--space-6);
  --ui-support-size: var(--text-data);
  --ui-support-line: var(--space-5);
  --ui-label-size: var(--text-label);
  --ui-label-line: var(--space-4);
  --ui-summary-size: var(--text-h2);
  --ui-summary-line: var(--space-7);
  --ui-section-line: 1.625rem;

  /* Shared service components: compact/descriptive rows, groups, summary, FAQ and contact form. */
  --ui-gutter: var(--space-4);
  --ui-group-radius: var(--radius-lg);
  --ui-group-padding: var(--space-5);
  --ui-group-gap: var(--space-3);
  --ui-section-gap: var(--space-6);
  --ui-label-gap: var(--space-3);
  --ui-row-compact: var(--space-9);
  --ui-row-descriptive: var(--space-10);
  --ui-row-pad-y: var(--space-2);
  --ui-icon-slot: var(--space-7);
  --ui-icon-size: var(--space-6);
  --ui-icon-gap: var(--space-3);
  --ui-trailing-size: var(--space-4);
  --ui-text-gap: var(--space-1);
  --ui-control-height: 2.75rem;
  --ui-control-radius: var(--radius-sm);
  --ui-field-gap: var(--space-6);
  --ui-chart-width: var(--space-12);
  --ui-page-max: 40rem;
  --ui-touch-min: 2.75rem;
  --ui-submit-height: 3.25rem;
  --ui-area-padding: var(--space-6);

  /* 2026-10-18 user decision: one dominant hue per purpose, tonal light/shadow only. Replaces rainbow-per-icon rule. */
  --icon-discovery: var(--color-brand-symbol-mint);
  --icon-market: var(--color-brand-symbol-mint);
  --icon-library: var(--color-brand-symbol-violet);
  --icon-interest: var(--color-brand-symbol-pink);
  --icon-premium: var(--color-brand-symbol-gold);
  --icon-support: var(--holo-aqua);
  --icon-account: #4c8fe6; /* Account/settings blue. Replaces gray after user feedback 2026-10-18. */
  --color-brand-symbol-violet: #7760f5;
  --color-brand-symbol-pink: #f08bda;
  --color-brand-symbol-gold: #ffd17c;
  --color-page-bg: #f3f7f9;
  --color-panel: #eaf1f5;
  --color-area-fill-start: #ffffff;
  --color-area-stroke: #ffffff;
  --color-scan-attention: #c2410c;
}

/* ══════════════════════════════════════════════════════════════════════════
   다크 — 2층(semantic)만 다시 정의한다. 1층 primitive 는 건드리지 않는다(예외: 알파 그림자 2개).
   대비는 **패널 지면(--color-surface) 기준**으로 맞췄다 — 실측과 미달 예외는 정본 JSON 의 contrast 표.

   세 갈래를 모두 받는다:
     ① 사용자가 다크를 명시   → :root[data-theme="dark"]
     ② 시스템 설정이 다크     → prefers-color-scheme (라이트 명시는 제외)
     ③ 클래스 토글            → .dark
   ══════════════════════════════════════════════════════════════════════════ */

:root[data-theme="dark"],
.dark {
  color-scheme: dark;
  --color-bg: #10151e;
  --color-surface: #191e2a;
  --color-surface-sunken: #0c1018;
  --color-text: #d8dbe1;
  --color-text-secondary: #a1a9b8;
  --color-text-muted: #7b869b;
  --color-border: #313949;
  --color-border-strong: #454f63;
  --color-border-dashed: #313949;
  --color-accent: #797cd6;
  --color-accent-fill: #7174d4;
  --color-accent-line: #585bcd;
  --color-accent-soft: #25264b;
  --color-state-known: #449373;
  --color-state-uncollected: #b9753a;
  --color-state-live: #449373;
  --color-danger: #f2867e;
  --color-danger-soft: #3a1d22;
  --color-rise: #5fb38e;
  --color-fall: #f07aa8;

  /* 그라디언트와 그 위 글자는 다크에서도 그대로다 — 대비는 contrast 표 */

  /* 차트 계열색 (다크) — 근거는 정본 JSON semantic.chart */
  --chart-finish-base: #8274e0;
  --chart-finish-holo: #0f9dad;
  --chart-finish-reverse: #e05f92;
  --chart-grid: #232b3a;
  --chart-axis: #3b4557;
  --on-gradient: var(--ink);

  /* 다크에서는 보라 그림자가 탁해 보인다. 검정 기반으로 바꾼다 */
  --alpha-card-shadow: rgba(0, 0, 0, 0.55);
  --alpha-art-shadow: rgba(0, 0, 0, 0.5);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --color-bg: #10151e;
    --color-surface: #191e2a;
    --color-surface-sunken: #0c1018;
    --color-text: #d8dbe1;
    --color-text-secondary: #a1a9b8;
    --color-text-muted: #7b869b;
    --color-border: #313949;
    --color-border-strong: #454f63;
    --color-border-dashed: #313949;
    --color-accent: #797cd6;
    --color-accent-fill: #7174d4;
    --color-accent-line: #585bcd;
    --color-accent-soft: #25264b;
    --color-state-known: #449373;
    --color-state-uncollected: #b9753a;
    --color-state-live: #449373;
    --color-danger: #f2867e;
    --color-danger-soft: #3a1d22;
    --color-rise: #5fb38e;
    --color-fall: #f07aa8;

    /* 그라디언트와 그 위 글자는 다크에서도 그대로다 — 대비는 contrast 표 */

    /* 차트 계열색 (다크) — 근거는 정본 JSON semantic.chart */
    --chart-finish-base: #8274e0;
    --chart-finish-holo: #0f9dad;
    --chart-finish-reverse: #e05f92;
    --chart-grid: #232b3a;
    --chart-axis: #3b4557;
    --on-gradient: var(--ink);

    /* 다크에서는 보라 그림자가 탁해 보인다. 검정 기반으로 바꾼다 */
    --alpha-card-shadow: rgba(0, 0, 0, 0.55);
    --alpha-art-shadow: rgba(0, 0, 0, 0.5);
  }
}

@media (max-width: 760px) {
  :root {
    --text-display: 2rem;
    --text-hero: 1.625rem;
    --text-body: 1rem;
    --text-price: 1.75rem;
    --layout-pad: var(--space-5);
    --ui-section-gap: 0.5rem;
    --ui-area-padding: 0.5rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-fast: 0.01ms;
    --motion-base: 0.01ms;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   언어별 서체 — 한자가 겹치므로 스크립트마다 스택을 갈아 끼운다.
   카드 이름처럼 본문 언어와 다른 조각에는 그 자리에 lang 속성을 준다:
     <span lang="ja">熱風のアリーナ</span>
   ══════════════════════════════════════════════════════════════════════════ */

:lang(ko) {
  --font-sans: "IBM Plex Sans KR", "IBM Plex Sans", "IBM Plex Sans JP", sans-serif;
}

:lang(ja) {
  --font-sans: "IBM Plex Sans JP", "IBM Plex Sans", "IBM Plex Sans KR", sans-serif;
}

:lang(th) {
  --font-sans: "IBM Plex Sans", "IBM Plex Sans Thai", system-ui, sans-serif;
}

:lang(zh-Hant),
:lang(zh-TW) {
  --font-sans: "IBM Plex Sans", "Noto Sans TC", system-ui, sans-serif;
}

:lang(zh-Hans),
:lang(zh-CN) {
  --font-sans: "IBM Plex Sans", "Noto Sans SC", system-ui, sans-serif;
}

:lang(en) {
  --font-sans: "IBM Plex Sans", "IBM Plex Sans KR", "IBM Plex Sans JP", sans-serif;
  font-family: var(--font-sans);
}

:lang(ko),
:lang(ja),
:lang(th),
:lang(zh-Hant),
:lang(zh-TW),
:lang(zh-Hans),
:lang(zh-CN) {
  font-family: var(--font-sans);
}

/* /css/scan.css */
/* 카드 스캔 시제품 /{lang}/lens/ — T14 시안(docs/design/concepts/2026-10-card-scan/scan.css)을 옮긴 것.
   시안과 다른 곳: 카메라 자리 = 실제 <video> · 시안 전용 회색 카드(.frame-card) 삭제 · 썸네일 그림 ·
   보내는 중 점 깜빡임 · 카메라 없을 때(data-nocam) · debug 줄 · 버튼이 된 쌓인 줄 링크 ·
   오류 알림 안 「다시 시도」(.text-btn — 검색 링크와 같은 모양) · 대체 화면의 지원 범위 이름표(.tag).
   판 고르기 칩은 시안 자리 그대로(결과판 1위 줄 바로 아래 · 단추 줄은 맨 아래)이고, 시안과 다른 곳 둘(2026-10-05 결정):
   ① 결과판 칩 줄은 줄바꿈 대신 한 줄 가로 스크롤 — 판이 몇 개여도 결과판 높이 · 안내 틀이 시안 후보 상태(칩 줄 한 줄)와 같다.
     긴 칩은 최대 폭에서 말줄임(전체 글자는 title · aria-label), 데스크톱(hover)은 얇은 스크롤바.
   ② 후보 시트의 칩은 긴 글자를 칩 안에서 두 줄까지 줄바꿈하고, 두 줄이면 알약 대신 radius-md(시안 nowrap 그대로면
     320px 에서 문서가 넘친다).
   색은 /design/styles/tokens.css 의 변수만 쓴다(이 파일에 hex·rgb 0).
   민트 = --color-brand-*. 옛 보라 강조색 계열은 쓰지 않는다 — 포커스 링만 승인 보라(--set-focus).
   얼음색 지면·선·판(--set-bg · --set-line · --set-panel)은 탐색 화면 승인 값과 같은 바이트다.
   새 화면은 라이트만(guide/07 C4) — 카메라 자리가 어두운 것은 테마가 아니라 영상이다. */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family:var(--font-sans);
  font-size: var(--text-body);
  line-height: var(--leading-normal);
  color: var(--color-text);
  background: var(--slate-950);
  -webkit-font-smoothing: antialiased;
}
/* 줄바꿈은 낱말 가운데서 끊지 않는다 — 한국어는 어절, 일본어는 구(guide/03 글자 하한). */
:lang(ko) { word-break: keep-all; }
:lang(ja) { line-break: strict; word-break: auto-phrase; }
button, input { font: inherit; color: inherit; }
button { cursor: pointer; }
svg {
  width: 24px; height: 24px; flex-shrink: 0;
  fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
:focus-visible { outline: 3px solid var(--set-focus); outline-offset: 4px; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
[hidden] { display: none !important; }

/* ── 버튼 · 칩 · 표 — 탐색·상세의 모양(44px · 에메랄드 바탕 + 흰색 글자) ───────────── */
.btn {
  min-height: 44px; min-width: 0;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  padding: 0 var(--space-4);
  border: 1px solid var(--set-line); border-radius: var(--radius-md);
  background: var(--set-bg); color: var(--color-text);
  font-size: var(--text-data); font-weight: 500; line-height: var(--leading-snug);
  text-decoration: none; text-align: center; cursor: pointer;
  transition: background-color var(--motion-tint), border-color var(--motion-tint);
}
.btn svg { width: 20px; height: 20px; }
.btn.primary {
  background: var(--color-brand-action-fill); border-color: var(--color-brand-action-fill);
  color: var(--color-brand-action-on); font-weight: 600;
}
.btn.lg { min-height: 52px; font-size: var(--text-body); }
/* 판 고르기 칩 — 시안 그대로 */
.chip {
  min-height: 44px;
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 0 var(--space-4);
  border: 1px solid var(--set-line); border-radius: var(--radius-full);
  background: var(--color-surface); color: var(--color-text);
  font-size: var(--text-data); font-weight: 500; white-space: nowrap;
  transition: background-color var(--motion-tint), border-color var(--motion-tint);
}
.chip[aria-pressed="true"] {
  background: var(--color-brand-action-fill); border-color: var(--color-brand-action-fill);
  color: var(--color-brand-action-on); font-weight: 600;
}
.text-btn {
  min-height: 44px;
  display: inline-flex; align-items: center; gap: var(--space-1);
  padding: 0 var(--space-2);
  border: 0; background: none;
  color: var(--color-brand-link-text); font-size: var(--text-data); font-weight: 600;
  text-decoration: none; white-space: nowrap;
}
.text-btn svg { width: 18px; height: 18px; }
.icon-btn {
  width: 44px; height: 44px; flex-shrink: 0;
  display: inline-grid; place-items: center;
  border: 0; border-radius: 50%; color: var(--color-text); text-decoration: none;
}
.icon-btn.plain { background: var(--set-bg); }
.icon-btn:disabled { cursor: default; opacity: .5; }
.glass {
  background: color-mix(in srgb, var(--white) 92%, transparent);   /* 흐림(backdrop-filter) 없음 — 카메라 영상 위에서 저사양 폰을 매 프레임 붙잡았다(2026-10-23) */
  color: var(--color-text);
  box-shadow: 0 4px 16px color-mix(in srgb, var(--ink) 18%, transparent);
}
.tag {
  min-height: 28px;
  display: inline-flex; align-items: center;
  padding: 0 var(--space-3);
  border: 1px solid var(--set-line); border-radius: var(--radius-full);
  background: var(--set-bg); color: var(--color-text-secondary);
  font-size: var(--text-label); font-weight: 600; white-space: nowrap;
}
.tag.action {
  gap: 2px; padding-right: var(--space-2);
  border-color: var(--color-brand-action-fill); background: var(--color-surface); color: var(--color-brand-link-text);
}
.tag svg { width: 14px; height: 14px; stroke-width: 2; }
@media (hover: hover) and (pointer: fine) {
  .btn:hover, .chip:hover { background: var(--set-panel); }
  .btn.primary:hover, .chip[aria-pressed="true"]:hover {
    background: color-mix(in srgb, var(--color-brand-action-fill) 82%, var(--white));
  }
  .result:hover, .row:hover, .others a:hover, .tile:hover { background: var(--set-bg); }
}

/* ── 카드 글자 묶음 — 그림 자리 · 이름 · 세트·번호·희귀도 · 가격 ─────────────────── */
.thumb {
  position: relative; overflow: hidden;
  display: block; aspect-ratio: 63 / 88;
  border-radius: var(--radius-sm);
  background: var(--slate-200);
  box-shadow: inset 0 0 0 1px var(--slate-300);
}
.thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* 테두리(안쪽 그림자)가 그림에 가리지 않게 그림 위에 한 번 더 그린다 */
.thumb::after { content: ''; position: absolute; inset: 0; border-radius: inherit; box-shadow: inherit; pointer-events: none; }
.text { min-width: 0; display: grid; gap: 2px; }
.name {
  font-size: var(--text-h3); font-weight: 600; line-height: var(--leading-snug);
  overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* 세트 · 번호 · 희귀도 — 좁으면 세트 이름만 줄고(…) 번호·희귀도는 늘 보인다. 판을 고를 때 가장 필요한 정보다. */
.meta {
  display: flex; min-width: 0;
  font-size: var(--text-data); color: var(--color-text-muted);
  white-space: nowrap;
}
.meta .set { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.meta .no { flex: none; }
.price {
  font-size: var(--text-h2); font-weight: 700; letter-spacing:var(--tracking-display); line-height: var(--leading-snug);
  font-variant-numeric: tabular-nums;
}
.price.none { font-size: var(--text-body); font-weight: 400; color: var(--color-text-muted); }
.mark {
  width: 32px; height: 32px; flex-shrink: 0;
  display: grid; place-items: center; border-radius: 50%;
  background: var(--color-brand-action-fill); color: var(--color-brand-action-on);
}
.mark svg { width: 18px; height: 18px; stroke-width: 2.4; }

/* ── 스캐너 — 상단 줄 · 카메라 무대(63:88 안내 틀) · 고정 결과판 ───────────────────── */
.scanner {
  position: relative;
  display: grid; grid-template-rows: auto minmax(0, 1fr) auto;
  height: 100vh; height: 100dvh;
}
/* 카메라 영상 — 화면을 꽉 채운다(object-fit: cover). scan.js 가 같은 계산으로 안내 틀 자리를 영상 픽셀로 바꾼다.
   영상이 오기 전·카메라가 없을 때는 아래 바탕이 보인다. */
.camera {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  background:
    radial-gradient(80% 55% at 50% 40%, var(--slate-600), transparent 72%),
    linear-gradient(180deg, var(--slate-800), var(--slate-950));
}
.scan-top {
  position: relative; z-index: 2;
  display: flex; align-items: center; gap: var(--space-2);
  padding: max(var(--space-3), env(safe-area-inset-top)) var(--space-4) var(--space-3);
}
.scan-top .spacer { flex: 1; }
.status {
  min-height: 44px; min-width: 0; margin: 0;
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 0 var(--space-4); border-radius: var(--radius-full);
  font-size: var(--text-data); font-weight: 600; white-space: nowrap;
}
.status .dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--color-brand-action-fill);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-brand-action-fill) 30%, transparent);
}
body:not([data-paused]) .when-paused,
body[data-paused] .when-running { display: none; }
body[data-paused] .status .dot { background: var(--slate-400); box-shadow: none; }
/* 인식 서버에 보내는 중 — 점이 깜빡인다(움직임 줄이기 설정이면 멈춤) */
body[data-sending] .status .dot { animation: scan-sending var(--motion-reveal) var(--motion-ease) infinite alternate; }
@keyframes scan-sending { to { opacity: .3; } }
@media (prefers-reduced-motion: reduce) { body[data-sending] .status .dot { animation: none; } }
/* 카메라 없이 사진 올리기만 — 스캔 중 표시·일시정지·플래시를 내린다 */
body[data-nocam] .status, body[data-nocam] #pause, body[data-nocam] #flash { display: none; }
@media (min-width: 768px) {
  body[data-nocam] .scanner { grid-template-rows: auto 0 auto; align-content: start; }
  body[data-nocam] .frame { display: none; }
}

.stage {
  position: relative; z-index: 1; min-height: 0;
  display: grid; place-items: center;
  container-type: size;
}
.frame {
  position: relative;
  width: min(calc(100cqw - 2 * var(--space-6)), calc((100cqh - 2 * var(--space-6)) * 63 / 88), 360px);
  aspect-ratio: 63 / 88;
}
.frame > i { position: absolute; width: 30px; height: 30px; border: 0 solid var(--color-brand-action-fill); }
.frame > i:nth-of-type(1) { top: 0; left: 0; border-width: 3px 0 0 3px; border-top-left-radius: var(--radius-lg); }
.frame > i:nth-of-type(2) { top: 0; right: 0; border-width: 3px 3px 0 0; border-top-right-radius: var(--radius-lg); }
.frame > i:nth-of-type(3) { bottom: 0; left: 0; border-width: 0 0 3px 3px; border-bottom-left-radius: var(--radius-lg); }
.frame > i:nth-of-type(4) { bottom: 0; right: 0; border-width: 0 3px 3px 0; border-bottom-right-radius: var(--radius-lg); }
body[data-frame="empty"] .frame > i,
body[data-paused] .frame > i { border-color: var(--white); }
.badges { position: absolute; top: 0; left: 50%; transform: translate(-50%, -50%); z-index: 1; }
.badge {
  min-height: 36px; margin: 0;
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 0 var(--space-4); border-radius: var(--radius-full);
  font-size: var(--text-data); font-weight: 600; white-space: nowrap;
}
.badge::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--amber-700); }
.cover { position: absolute; inset: 0; z-index: 1; background: color-mix(in srgb, var(--ink) 50%, transparent); }
.resume { position: absolute; top: 50%; left: 50%; z-index: 2; transform: translate(-50%, -50%); white-space: nowrap; }

/* 고정 결과판 — 폰은 아래에 붙고, 768px 이상은 가운데 떠 있는 판. 카드를 따라다니지 않는다. */
.board {
  position: relative; z-index: 2; min-width: 0;
  display: grid; gap: var(--space-3);
  padding: var(--space-4) var(--space-4) max(var(--space-4), env(safe-area-inset-bottom));
  background: var(--color-surface);
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  box-shadow: 0 -10px 30px color-mix(in srgb, var(--ink) 22%, transparent);
}
.board:not([data-tier="final"]) .if-final,
.board:not([data-tier="provisional"]) .if-provisional,
.board:not([data-tier="candidate"]) .if-candidate,
.board:not([data-tier="none"]) .if-none,
.board[data-tier="provisional"] .result .price,
.board[data-tier="none"] .result,
.board[data-tier="empty"] .result,
.board[data-tier="empty"] .stack-row { display: none; }
.result {
  display: grid; grid-template-columns: 56px minmax(0, 1fr) auto; gap: var(--space-3); align-items: center;
  margin: calc(-1 * var(--space-1)); padding: var(--space-1);
  border-radius: var(--radius-lg); color: inherit; text-decoration: none;
}
.result .thumb { width: 56px; }
.price-wait { display: block; width: 104px; height: 22px; margin: 5px 0 4px; border-radius: var(--radius-sm); background: var(--slate-100); }
.pick { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
/* 결과판 칩 줄 — 시안 자리에 한 줄 · 가로 스크롤(넘치는 것은 이 줄뿐, 문서 폭 · 결과판 높이는 그대로). 안쪽 7px 는 포커스 링
   (3px + 띄움 4px)이 스크롤 영역에 잘리지 않을 자리이고, 같은 만큼 음수 바깥 여백으로 자리는 시안 그대로 둔다.
   칩 최대 폭은 줄 폭보다 4rem 좁다 — 첫 칩이 길어도 둘째 칩 앞머리가 늘 보인다(「더 있음」). 넘친 글자는 말줄임. */
.board .pick {
  flex-wrap: nowrap;
  margin: -7px; padding: 7px; scroll-padding-inline: 7px;
  overflow-x: auto; overscroll-behavior-x: contain;
}
.board .chip { flex: none; max-width: min(16rem, 100% - 4rem); }
.board .chip > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* 폰은 스크롤바 없이 손가락으로, 데스크톱(마우스)은 얇은 스크롤바로 옆에 더 있음을 보인다. 스크롤바는 자리를 차지하므로
   (Windows 크롬 thin 10px) 줄 높이를 칩 + 위 7px + 아래 12px 로 고정하고 아래 12px 는 음수 바깥 여백으로 결과판 틈(12px)에
   둔다 — 칩이 넘쳐 스크롤바가 생겨도 결과판 높이 · 안내 틀이 그대로(그때는 포커스 링 아래 변이 스크롤바 뒤로 든다) */
@media (hover: none) {
  .board .pick { scrollbar-width: none; }
  .board .pick::-webkit-scrollbar { display: none; }
}
@media (hover: hover) {
  .board .pick {
    height: calc(44px + 7px + 12px); margin-bottom: -12px; overflow-y: hidden; align-items: flex-start;
    scrollbar-width: thin; scrollbar-color: var(--slate-300) transparent;
  }
}
.none-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); }
.none-row strong { font-size: var(--text-h3); font-weight: 600; }
.stack-row {
  min-width: 0;
  display: flex; align-items: center; gap: var(--space-3);
  padding-top: var(--space-3); border-top: 1px solid var(--set-line);
}
.stack {
  flex: 1; min-width: 0;
  display: flex; gap: var(--space-2);
  margin: 0; padding: 0 0 2px; list-style: none;
  overflow-x: auto; scrollbar-width: none;
}
.stack::-webkit-scrollbar { display: none; }
.stack a { position: relative; display: block; width: 44px; border-radius: var(--radius-sm); }   /* 숨은 이름(sr-only)이 줄 스크롤 안에 갇히게 — 밖이면 7장째부터 문서가 가로로 넘친다 */
.stack .thumb { width: 44px; }
.stack li:first-child .thumb { box-shadow: inset 0 0 0 2px var(--color-brand-action-fill); }
.stack-link {
  flex-shrink: 0; min-height: 44px;
  display: inline-flex; align-items: center; gap: var(--space-1);
  padding: 0; border: 0; background: none;
  color: var(--color-text); font-size: var(--text-data); font-weight: 600; text-decoration: none; white-space: nowrap;
}
.stack-link b { font-weight: 600; font-variant-numeric: tabular-nums; }
.stack-link svg { width: 18px; height: 18px; color: var(--color-text-muted); }
.actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2); }
.alert {
  margin: 0;
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--set-line); border-left: 4px solid var(--amber-700); border-radius: var(--radius-md);
  background: var(--color-surface);
  font-size: var(--text-data); font-weight: 500; line-height: var(--leading-snug);
}
.alert svg { width: 20px; height: 20px; color: var(--amber-700); }
/* 단추 둘(다시 시도 · 카드 검색하기)은 한 묶음으로 줄을 바꾼다 — 넓으면 글 옆 한 줄(글은 그 안에서 접힘), 좁으면 글 아래 한 줄.
   하나씩 넘어가면 알림이 시안보다 한 줄 커져 안내 틀이 줄어든다(시안 대조 390px 93.5% → 묶음 뒤 98.9%).
   알림 안 단추는 옆 여백 4px · 사이 8px(높이 44px · 누르는 자리 사이 8px 그대로) — 흔한 안드로이드 폭 360px 에서도 시안처럼
   글 옆 한 줄(ko · en). 글은 줄 길이를 고르게, ja 문구는 구 경계(再試行して|ください)에 줄바꿈 자리(사전의 U+200B) — 좁아도
   마지막 줄에 「い。」만 남지 않는다 */
.alert > span { flex: 1 1 7em; min-width: 0; }
[data-alert="error"] > span { text-wrap: balance; }   /* 혼잡 알림은 초가 바뀔 때마다 줄이 흔들리지 않게 그대로 */
.alert .alert-actions { flex: 0 0 auto; display: inline-flex; flex-wrap: wrap; gap: 0 var(--space-2); }
.alert .text-btn { padding: 0 var(--space-1); }
/* ?debug=1 — 서버 took_ms · 끝단 시간(숫자만) */
.debug { margin: 0; font-family:var(--font-sans); font-size: var(--text-label); color: var(--color-text-muted); font-variant-numeric: tabular-nums; }
@media (max-width: 360px) {
  .actions .btn { gap: 6px; padding: 0 var(--space-2); }
}
/* 키 작은 화면(320×640 등) — 안내 틀이 너무 작아지지 않게 판을 줄인다. 터치 44px 는 그대로. */
@media (max-height: 700px) {
  .scan-top { padding-top: max(var(--space-2), env(safe-area-inset-top)); padding-bottom: var(--space-2); }
  .board { gap: var(--space-2); padding-top: var(--space-3); }
  .result { grid-template-columns: 44px minmax(0, 1fr) auto; }
  .result .thumb { width: 44px; }
  .result .price { font-size: 1.25rem; }
  .stack-row { padding-top: var(--space-2); }
}
@media (min-width: 768px) {
  .scan-top { padding: var(--space-5) var(--space-6); }
  .board {
    justify-self: center; width: min(560px, calc(100% - 2 * var(--space-6)));
    margin-bottom: var(--space-6); padding-bottom: var(--space-4);
    border-radius: var(--radius-xl);
    box-shadow: 0 16px 40px color-mix(in srgb, var(--ink) 28%, transparent);
  }
}

/* ── 시트 — 폰은 아래에서 올라오고, 1024px 이상은 오른쪽에 선다(카메라는 뒤에서 계속 돈다) ── */
.scrim { position: fixed; inset: 0; z-index: 10; background: color-mix(in srgb, var(--ink) 48%, transparent); }
.sheet {
  position: fixed; z-index: 11; left: 0; right: 0; bottom: 0;
  max-height: calc(100dvh - var(--space-9));
  overflow-y: auto; overscroll-behavior: contain;
  padding: 0 var(--space-4) max(var(--space-6), env(safe-area-inset-bottom));
  background: var(--color-surface); color: var(--color-text);
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  box-shadow: 0 -12px 40px color-mix(in srgb, var(--ink) 24%, transparent);
}
.sheet-head {
  position: sticky; top: 0; z-index: 1;
  display: flex; align-items: center; gap: var(--space-2);
  padding: var(--space-5) 0 var(--space-3);
  background: var(--color-surface);
}
.sheet-head::before {
  content: ''; position: absolute; top: var(--space-2); left: 50%;
  width: 36px; height: 4px; margin-left: -18px;
  border-radius: var(--radius-full); background: var(--slate-300);
}
.sheet-head h2 { margin: 0; min-width: 0; font-size: var(--text-h3); font-weight: 700; }
.sheet-head .count { margin-left: var(--space-1); color: var(--color-text-muted); font-weight: 500; }
.sheet-head .close { margin-left: auto; }
@media (min-width: 768px) {
  .sheet { left: 50%; right: auto; width: min(640px, 100%); transform: translateX(-50%); padding-inline: var(--space-6); }
}
@media (min-width: 1024px) {
  .sheet {
    top: 0; bottom: 0; left: auto; right: 0; width: 440px; max-height: none; transform: none;
    border-radius: var(--radius-xl) 0 0 var(--radius-xl);
    box-shadow: -12px 0 40px color-mix(in srgb, var(--ink) 24%, transparent);
  }
  .sheet-head::before { display: none; }
}

/* 후보 시트 — 1위는 선택된 채 맨 위, 같은 그림 다른 판은 칩, 다른 후보는 줄 */
.top-pick {
  display: grid; gap: var(--space-3);
  padding: var(--space-3);
  border: 2px solid var(--color-brand-action-fill); border-radius: var(--radius-lg);
}
.row {
  display: grid; grid-template-columns: 64px minmax(0, 1fr) auto; gap: var(--space-3); align-items: center;
  border-radius: var(--radius-md); color: inherit; text-decoration: none;
}
.row .thumb { width: 64px; }
/* 시트의 칩은 줄을 바꿔 놓이고, 긴 글자(카탈로그 글자)는 칩 안에서 두 줄까지(넘치면 말줄임 · 전체 글자는 title · aria-label).
   두 줄이 된 칩은 알약이 긴 타원이 되지 않게 radius-md — 줄 수는 그려진 뒤에 scan.js 가 data-wrap 으로 단다(한 줄이면 44px 알약) */
.top-pick .chip { max-width: 100%; padding-block: var(--space-1); white-space: normal; overflow-wrap: anywhere; text-align: left; }
.top-pick .chip > span { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.top-pick .chip[data-wrap] { border-radius: var(--radius-md); }
.others { margin: var(--space-4) 0 0; padding: 0; list-style: none; }
.others a {
  min-height: 44px;
  display: grid; grid-template-columns: 48px minmax(0, 1fr) auto; gap: var(--space-3); align-items: center;
  padding: var(--space-3) 0;
  border-top: 1px solid var(--set-line);
  color: inherit; text-decoration: none;
}
.others .thumb { width: 48px; }
.others .price { font-size: var(--text-body); font-weight: 600; }
.others .price.none { font-weight: 400; }
.notfound {
  display: grid; gap: var(--space-3);
  margin-top: var(--space-4); padding-top: var(--space-4);
  border-top: 1px solid var(--set-line);
}
.notfound h3 { margin: 0; font-size: var(--text-data); font-weight: 600; color: var(--color-text-secondary); }
.search-box {
  min-height: 53px;
  display: flex; align-items: center; gap: var(--space-3);
  padding: 0 var(--space-1) 0 var(--space-4);
  border: 1px solid var(--set-line); border-radius: var(--radius-lg);
  background: var(--color-surface); color: var(--color-text-muted);
}
.search-box:focus-within {
  border-color: var(--color-brand-action-fill);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-brand-action-fill) 18%, transparent);
  outline: 3px solid var(--set-focus); outline-offset: 2px;
}
.search-box input {
  flex: 1; min-width: 0;
  border: 0; outline: 0; background: transparent;
  color: var(--color-text); font-size: var(--text-body);
}
.search-box input::placeholder { color: var(--color-text-muted); }
.search-box button { width: 44px; height: 44px; display: grid; place-items: center; border: 0; background: none; color: var(--color-text-muted); }

/* 결과 목록 — 세트별 묶음 · 장수(합계 금액 없음) */
.group + .group { margin-top: var(--space-6); }
.group-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); margin: 0 0 var(--space-3); }
.group-head h3 { margin: 0; min-width: 0; font-size: var(--text-h3); font-weight: 600; overflow-wrap: anywhere; }
.group-head span { font-size: var(--text-data); color: var(--color-text-muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.tiles {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: var(--space-4) var(--space-3);
  margin: 0; padding: 0; list-style: none;
}
.tile {
  min-width: 0;
  display: grid; gap: 2px;
  padding: var(--space-1); margin: calc(-1 * var(--space-1));
  border-radius: var(--radius-md); color: inherit; text-decoration: none;
}
.tile .thumb { position: relative; width: 100%; margin-bottom: var(--space-2); }
.tile strong {
  font-size: 0.875rem; font-weight: 600; line-height: var(--leading-snug); overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.tile small { font-size: var(--text-label); color: var(--color-text-muted); }
.tile .price { font-size: 0.875rem; font-weight: 600; letter-spacing:0; }
.tile .price.none { font-weight: 400; }
.qty {
  position: absolute; top: var(--space-1); right: var(--space-1);
  min-height: 24px; display: inline-flex; align-items: center;
  padding: 0 var(--space-2); border-radius: var(--radius-full);
  background: var(--color-surface); color: var(--color-text);
  font-size: var(--text-label); font-weight: 600; font-variant-numeric: tabular-nums;
  box-shadow: 0 2px 6px color-mix(in srgb, var(--ink) 16%, transparent);
}

/* ── 카메라를 못 쓸 때 — 권한 거부 · 카메라 없음 · 인앱 브라우저 ─────────────────────── */
.fallback {
  position: fixed; inset: 0; z-index: 20;
  display: grid; place-items: center;
  padding: var(--space-10) var(--space-5) var(--space-6);
  overflow-y: auto;
  background: var(--set-bg);
}
.fallback > .close { position: absolute; top: max(var(--space-3), env(safe-area-inset-top)); left: var(--space-4); background: var(--color-surface); }
.fallback-body { width: min(360px, 100%); display: grid; gap: var(--space-3); text-align: center; }
.fallback-icon {
  width: 72px; height: 72px; margin: 0 auto;
  display: grid; place-items: center; border-radius: 50%;
  border: 1px solid var(--set-line); background: var(--color-surface); color: var(--color-text-secondary);
}
.fallback-icon svg { width: 32px; height: 32px; }
.fallback .warn { margin: var(--space-2) 0 var(--space-3); font-size: var(--text-h3); font-weight: 600; }
.fallback .btn:not(.primary) { background: var(--color-surface); }
/* 지원 범위 이름표 — 화면 맨 아래 한 줄(가운데 묶음은 시안 자리 그대로). 좁으면 이름표 안에서 줄바꿈, 키가 작은 화면은
   단추 아래로 들어온다(겹치지 않게) */
.fallback .support {
  position: absolute; left: 50%; bottom: max(var(--space-5), env(safe-area-inset-bottom)); transform: translateX(-50%);
  width: max-content; max-width: calc(100% - 2 * var(--space-5)); margin: 0;
  white-space: normal; text-align: center;
}
@media (min-width: 1024px) { .fallback .support { display: none; } }
@media (max-height: 600px) {
  .fallback .support { position: static; transform: none; justify-self: center; margin-top: var(--space-2); }
}

/* Continuous scanning: review only when the user opens the list. */
.stack-link{display:grid;grid-template-columns:auto 18px;gap:2px 4px;max-width:55%;white-space:normal;text-align:right}
.stack-link>span{font-size:14px}.stack-link>b{grid-column:1;font-size:12px;line-height:1.4}.stack-link>svg{grid-column:2;grid-row:1/3}
.stack .needs-review .thumb{outline:2px solid var(--amber-700);outline-offset:1px}
.review-hint{margin:12px 0;font-size:13px;line-height:1.5;color:var(--color-text-muted)}
.review-tabs{display:flex;gap:8px;margin-top:12px}
.review-tabs button{min-height:44px;padding:8px 14px;border:1px solid var(--set-line);border-radius:var(--radius-md);background:var(--color-surface);color:var(--color-text);font-size:14px}
.review-tabs button[aria-pressed=true]{background:var(--color-brand-action-fill);color:var(--color-brand-action-on)}
.scan-list,.candidate-options{list-style:none;padding:0;margin:0}
.scan-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:12px;align-items:center;min-height:106px;padding:12px 0;border-bottom:1px solid var(--set-line)}
.scan-row-card{display:flex;gap:12px;align-items:center;min-width:0}
.candidate-option{display:flex;gap:12px;align-items:center;min-width:0;min-height:44px;border:0;padding:0;background:transparent;color:var(--color-text);text-align:left;font:inherit}
.scan-review{position:relative;justify-self:start;min-height:28px;padding:0 6px;border:1px solid var(--color-brand-action-fill);border-radius:6px;background:var(--color-surface);color:var(--color-text);font:inherit;font-size:12px;white-space:nowrap;cursor:pointer}
.scan-review[hidden]{display:none}.scan-review::after{content:'';position:absolute;inset:-8px -6px}
.scan-row .thumb,.candidate-option .thumb{width:48px;flex:none}
.scan-row-text{display:grid;gap:4px;min-width:0}.scan-row-text strong,.scan-row-name{font-size:15px;font-weight:700;line-height:1.4;overflow-wrap:anywhere}.scan-row-name{color:inherit;text-decoration:underline;text-decoration-color:var(--set-line);text-underline-offset:3px}.scan-row-text small{font-size:12px;line-height:1.4;color:var(--color-text-muted);overflow-wrap:anywhere}
.scan-row .scan-row-name{font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.scan-row .scan-row-text small{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.scan-row-actions{display:grid;gap:6px;justify-items:end}.scan-row-actions .price{font-size:20px;line-height:1.3;font-weight:600;font-variant-numeric:tabular-nums;white-space:nowrap}.scan-row-actions .price.none{font-size:13px;font-weight:400;color:var(--color-text-muted)}
.scan-row-actions .scan-controls{display:flex;gap:4px;align-items:center}.scan-stepper{display:flex;align-items:center;border:1px solid var(--set-line);border-radius:6px}
.scan-controls button{position:relative;display:grid;place-items:center;width:44px;height:44px;padding:0;border:0;border-radius:6px;background:transparent;color:var(--color-text-secondary);font:inherit;font-size:16px;cursor:pointer}.scan-controls button:disabled{opacity:.4;cursor:default}.scan-quantity{width:24px;text-align:center;font-size:13px;font-variant-numeric:tabular-nums}.scan-delete svg{width:16px;height:16px;stroke:currentColor;stroke-width:1.7;fill:none;stroke-linecap:round;stroke-linejoin:round}
.scan-review:hover,.scan-controls button:hover{background:var(--color-surface-sunken)}.scan-review:focus-visible,.scan-controls button:focus-visible{outline:2px solid var(--color-text);outline-offset:2px}
@media(max-width:400px){.scan-row,.scan-row-card{gap:8px}.scan-row .thumb{width:38px}.scan-row .scan-row-name{font-size:15px}.scan-row-actions .price{font-size:19px}}
.review-empty{padding:24px 0;text-align:center;font-size:14px;color:var(--color-text-muted)}
.scan-undo{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-top:12px;font-size:13px}.scan-undo button{min-height:44px;border:0;background:transparent;color:var(--color-brand-link-text);font:inherit}
#candidates .top-pick,#candidates .others,#candidates>h3{display:none}
.candidate-option{width:100%;border:1px solid var(--set-line);border-radius:var(--radius-md);padding:12px;margin-bottom:8px}
.candidate-option[aria-pressed=true]{border-color:var(--color-brand-action-fill);box-shadow:inset 0 0 0 1px var(--color-brand-action-fill);background:var(--color-surface-sunken)}
#confirm-candidate{width:100%;margin-top:12px;color:var(--color-brand-action-on)}
.scan-save-footer{position:sticky;bottom:0;background:var(--color-surface);border-top:1px solid var(--set-line);padding:12px 0 max(16px,env(safe-area-inset-bottom));margin-top:12px}.scan-save-footer p{font-size:12px;line-height:1.5;color:var(--color-text-secondary);margin:0 0 10px}.scan-save-footer>div{display:grid;grid-template-columns:1fr 1.5fr;gap:8px}.scan-save-footer button{min-height:44px;border:1px solid var(--set-line);border-radius:var(--radius-md);background:var(--color-surface);color:var(--color-text);font:inherit;font-size:14px}.scan-save-footer .primary{background:var(--color-brand-action-fill);color:var(--color-brand-action-on);border:0}.scan-save-footer button:disabled,#open-save:disabled{opacity:.45;cursor:default}

.scan-review{display:inline-flex;align-items:center;gap:4px}
.scan-review svg{width:14px;height:14px}
.scan-list-count,.scan-pending-count{display:inline-flex;align-items:center;gap:4px;padding:4px 6px;border-radius:6px}
.scan-list-count svg,.scan-pending-count svg{width:18px;height:18px}
.scan-pending-count{background:var(--set-panel);color:var(--color-brand-link-text);border:1px solid var(--color-brand-action-fill)}
.stack-link{display:inline-flex;max-width:none;white-space:nowrap}.stack-link>.scan-pending-count{color:var(--color-brand-link-text)}

.save-count{display:inline-flex;align-items:center;justify-content:center;min-width:22px;height:22px;padding:0 5px;border-radius:6px;background:color-mix(in srgb,currentColor 20%,transparent);font-size:12px;font-weight:600;font-variant-numeric:tabular-nums}

/* 바닥 사업자 줄(대표 결정 2026-10-10) — 스캐너(100dvh) 아래 문서 끝. 값은 global-header.css 의 .legal-foot · .biz 와 같고 색만 토큰.
   대체 화면은 화면 고정 덮개라 문서 끝을 늘 가렸다 — 첫 화면 높이만 덮게 해 스크롤하면 바닥이 보인다(맨 위에서는 그대로). */
.fallback { position: absolute; height: 100vh; height: 100dvh; }
.legal-foot { padding: var(--space-4) max(24px, calc((100% - 1152px) / 2)) 28px; font-size: 13px; color: var(--color-text-muted); background: var(--set-bg); }
@media (max-width: 760px) { .legal-foot { padding-inline: 18px; } }
.legal-foot p { margin: 0; font-size: 12px; line-height: 1.5; overflow-wrap: anywhere; }
.legal-foot nav { display: flex; flex-wrap: wrap; gap: 0 20px; }
.legal-foot a { display: inline-flex; align-items: center; min-height: 44px; color: inherit; font-weight: 600; }
.legal-foot .biz { margin-top: 6px; }
p.biz,.biz span{font-family:system-ui,-apple-system,sans-serif}.biz span{display:inline-block}.biz span:not(:last-child)::after{content:" ·"}

/* /css/quota-sheet.css */
/* Approved quota A (950:410283). Shared assets; server usage only; guest login remains independent. */
dialog.quota-sheet{box-sizing:border-box;width:100%;max-width:100%;max-height:calc(100dvh - 32px);margin:auto auto 0;padding:0;overflow-y:auto;overscroll-behavior:contain;border:0;border-radius:16px 16px 0 0;background:var(--color-page-bg);color:var(--color-text);font:14px/20px var(--font-sans);text-align:left;box-shadow:none}
dialog.quota-sheet::backdrop{background:color-mix(in srgb,var(--color-text) 48%,transparent)}
.quota-sheet:lang(ko){word-break:keep-all}.quota-sheet:lang(ja){line-break:strict;word-break:auto-phrase}
.quota-sheet *,.quota-sheet *::before{box-sizing:border-box}.quota-sheet [hidden]{display:none!important}
.quota-body{position:relative;padding:24px 16px max(16px,env(safe-area-inset-bottom))}
.quota-body::before{content:'';position:absolute;top:8px;left:calc(50% - 18px);width:36px;height:4px;border-radius:999px;background:var(--color-border)}
.quota-sheet #quota-title{margin:0;font-size:18px;line-height:26px;font-weight:600;color:var(--color-text)}
.quota-note{margin:4px 0 0;font-size:13px;line-height:18px;color:var(--color-text-muted)}
.quota-usage{display:flex;align-items:center;gap:12px;margin:12px 0 16px}
.quota-progress{display:block;flex:1;min-width:0;width:100%;height:8px;border:0;border-radius:999px;overflow:hidden;appearance:none;accent-color:var(--color-scan-attention);background:color-mix(in srgb,var(--color-scan-attention) 12%,transparent)}
.quota-progress::-webkit-progress-bar{background:color-mix(in srgb,var(--color-scan-attention) 12%,transparent);border-radius:999px}.quota-progress::-webkit-progress-value{background:var(--color-scan-attention);border-radius:999px}.quota-progress::-moz-progress-bar{background:var(--color-scan-attention);border-radius:999px}
.quota-usage-text{flex:none;font-size:13px;line-height:18px;font-weight:500;font-variant-numeric:tabular-nums}
.quota-pro{margin-top:16px;padding:12px 16px 16px;border:1px solid var(--color-area-stroke);border-radius:16px;background:linear-gradient(135deg,var(--color-area-fill-start) 35%,var(--color-panel));text-align:center}
.quota-pro-art{display:block;width:100%;height:140px;max-width:310px;object-fit:contain;margin:0 auto}
.quota-pro-title{margin:0;font-size:24px;line-height:32px;font-weight:600}
.quota-pro-lead{margin:4px 0 0;color:var(--color-text-muted);font-size:14px;line-height:20px}
.quota-benefits{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:20px;text-align:left}
.quota-benefit{display:flex;align-items:center;gap:8px;min-width:0}.quota-benefit-icon{display:grid;place-items:center;flex:none;width:32px;height:32px;border:1px solid var(--color-area-stroke);border-radius:6px;background:var(--color-page-bg)}.quota-benefit-icon img{display:block;width:24px;height:24px}
.quota-benefit>div{min-width:0;flex:1}.quota-benefit span:not(.quota-benefit-icon){overflow-wrap:anywhere;display:block;color:var(--color-text-muted);font-size:12px;line-height:16px}.quota-benefit strong{display:block;font-size:14px;line-height:20px;font-weight:600}
.quota-signin{display:flex;flex-direction:column;gap:12px;margin-top:16px}.quota-install{margin-top:16px}
.quota-saved{margin:0 0 4px;font-size:13px;line-height:18px;font-weight:600;color:var(--color-text)}
.quota-close{display:flex;align-items:center;justify-content:center;width:100%;min-height:44px;margin:16px 0 0;padding:8px 16px;border:1px solid var(--color-border);border-radius:6px;background:transparent;color:var(--color-text);font:600 14px/20px var(--font-sans);cursor:pointer;text-decoration:none}
.quota-sheet :focus-visible{outline:2px solid var(--color-brand-link-text);outline-offset:2px}
@media(min-width:768px){dialog.quota-sheet{width:390px;max-width:calc(100% - 48px);margin:auto;border-radius:16px}.quota-body::before{display:none}}
@media(max-width:359px){.quota-benefits{gap:8px}.quota-pro{padding-inline:12px}}
/* 무료 정책 시안 A·B·C(대표 2026-10-23) — FREE 배지 + 앱 아이콘 + 큰 숫자(앱 하루 30장). 판은 위 quota-pro 판과 같은 바탕 */
.free{margin-top:16px;padding:16px;border:1px solid var(--color-area-stroke);border-radius:16px;background:linear-gradient(135deg,var(--color-area-fill-start) 35%,var(--color-panel));display:grid;justify-items:center;gap:6px;text-align:center}
.free-top{display:flex;flex-direction:column;align-items:center;gap:8px}   /* FREE 배지 · 앱 아이콘 = 줄을 나눠 가운데(대표 2026-10-23) */
.free-badge{display:inline-flex;align-items:center;height:24px;padding:0 10px;border-radius:999px;background:var(--color-brand-action-fill);color:var(--color-brand-action-on);font:700 13px/1 var(--font-sans);letter-spacing:.12em}
.free-app{display:block;width:72px;height:72px;border-radius:16px;background:#fff;border:1px solid var(--color-border);box-shadow:0 1px 3px color-mix(in srgb,var(--color-text) 12%,transparent)}
.free-num{display:flex;align-items:baseline;gap:6px;color:var(--color-text)}
.free-num b{font:700 72px/1 var(--font-sans);letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.free-num span{font:600 18px/1 var(--font-sans)}
.free-sub{margin:0;font-size:13px;line-height:18px;color:var(--color-text-muted)}
.free-install{width:100%;margin-top:6px}.free-install .app-get-label{display:none}
.free-or{display:flex;align-items:center;gap:12px;margin:16px 0 0;color:var(--color-text-muted);font-size:12px;line-height:18px}
.free-or:before,.free-or:after{content:"";flex:1;height:1px;background:var(--color-border)}
.free-web{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:8px;margin:12px 0 0;font-weight:600;font-size:14px;line-height:20px;color:var(--color-text)}
.free-web .free-badge{height:20px;padding:0 8px;font-size:11px}.free-web b{font-size:22px;line-height:1}
.free-pro{margin:12px 0 0;text-align:center;font-size:13px;line-height:18px;font-weight:500;color:var(--color-text-muted)}
/* 모바일(웹)은 위 글까지 전부 가운데(대표 2026-10-23) */
@media(max-width:767px){.quota-sheet #quota-title,.quota-note,.quota-saved,.quota-sheet .acct-legal{text-align:center}.quota-sheet .acct-check{justify-content:center}}
/* 가입 직후 친구 초대 한 줄(Figma 2판 D 1037:309221) — 시트 맨 위 한 판 */
.quota-invite{display:grid;gap:12px;margin:0 0 16px;padding:16px;border-radius:16px;background:linear-gradient(135deg,var(--color-area-fill-start) 38%,var(--color-panel));text-align:center}.quota-invite p{margin:0;font-size:16px;line-height:24px;font-weight:600;color:var(--color-text)}.quota-invite a{display:flex;align-items:center;justify-content:center;min-height:44px;padding:8px 20px;border-radius:6px;background:var(--color-brand-action-fill);color:var(--color-brand-action-on);font-size:16px;line-height:24px;font-weight:600;text-decoration:none}.quota-invite a:focus-visible{outline:3px solid var(--set-focus,#6e66d7);outline-offset:3px}

/* /css/typography.css */
/* All customer pages share Plex and the canonical type scale. */

html { font-size: 100%; -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: var(--leading-normal);
  letter-spacing: 0;
}
body :where(button, input, select, textarea, text) { font-family: var(--font-sans); }
body input:not([type=checkbox]):not([type=radio]), body textarea {
  font-size: var(--text-body);
  line-height: var(--leading-snug);
  letter-spacing: 0;
}
body :where(h1, h2, h3) {
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-display);
  font-weight: var(--weight-bold);
}

body .copy h1, body .story h1 { font-size: var(--text-display); }
body .intro h1, body .set-intro h1, body .stage-title h1,
body .my-welcome h1, body .acct h1 {
  font-size: var(--text-hero);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-display);
}
body .set-intro h1 { overflow-wrap: anywhere; }
body .section-heading h2, body .detail-copy h2, body .questions h2,
body .closing h2, body .history-head h2, body .settings-heading h2,
body .panel-title h2, body .detail-layout h2, body .story h2 {
  font-size: var(--text-h2);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-display);
}
body .set-intro h2, body .set-intro .compact-set-heading h2,
body .set-intro .desktop-set-heading h2 { font-size: var(--text-h2); line-height: var(--leading-tight); letter-spacing: var(--tracking-display); }
body .steps h3, body .spotlight-info h3, body .settings-panel h3,
body .answers h3, body .pack-tile h2, body .my-empty h3 {
  font-size: var(--text-h3);
  line-height: var(--leading-snug);
  font-weight: var(--weight-semibold);
}
body .copy .intro, body .section-heading > p, body .steps p,
body .detail-copy p, body .answers p, body .closing p, body .story .description {
  font-size: var(--text-body);
  line-height: var(--leading-normal);
  letter-spacing: 0;
}
body .intro > p, body .acct-legal, body .acct-note,
body .data-note, body .guide-note { font-size: var(--text-data); line-height: var(--leading-normal); }
body .cta, body .text-link, body .idp, body .btn,
body .collection-tabs button, body .control {
  font-size: var(--text-data);
  line-height: var(--leading-snug);
  letter-spacing: 0;
  font-weight: var(--weight-semibold);
}
body > header.global-header > nav { font-size: var(--text-data); line-height: var(--leading-snug); letter-spacing: 0; }
body .spotlight-price, body .value-summary .total-value strong,
body .stage .current-price, body .stage .attached-tag .current-price,
body .art .current-price, body .story .price strong {
  font-size: var(--text-price);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-display);
  font-variant-numeric: tabular-nums;
}
body .stage .no-price, body .art .no-price { font-size: var(--text-body); font-weight: var(--weight-regular); }
body .album-slot strong, body .card-item strong, body .set-card strong,
body .my-card-link strong, body .discovery-info strong { font-size: var(--text-data); line-height: var(--leading-snug); }
body .album-slot .card-price, body .album.list .card-price,
body .card-item .card-price, body .my-table .value, body .set-card .card-price,
body .discovery-info b {
  font-size: var(--text-body);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}
/* The 3D experience is an exported page; keep its type overrides here. */
body .story :where(.eyebrow, .stage-top, .object-caption, .counter, .price > div,
  .price p, .example, .quiet, .detail-note > span, .detail-note p,
  .scan-state small, .scroll-cue) {
  font-family: var(--font-sans);
  font-size: var(--text-label);
  line-height: var(--leading-snug);
  letter-spacing: var(--tracking-kicker);
}
body .story .object-caption span + span { font-size: var(--text-label); letter-spacing: 0; }

@media (max-width: 760px) {
  body .history-head .periods { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); width:100%; }
  body .history-head .periods button { min-width:0; padding:8px 4px; }
  body .set-intro .intro-heading { width: 55%; }
  body .stage .tag-hanger > .attached-tag { width: 132px; }
  body .stage .attached-tag .price-tag { min-height: 70px; }
}
@media (max-width: 360px) {
  body .stage .tag-hanger > .attached-tag { width: 116px; }
  body > header.global-header > a:first-child img { width: 100px; }
  body > header.global-header > nav { margin-left: 8px; }
  body > header.global-header .acm-end { margin-left: auto; }
}

/* /css/scan-holo.css */

:root { --scan-holo-orbit:4s; --scan-holo-candidate:1100ms; --scan-card-enter:520ms; --scan-thumb-enter:650ms; --scan-card-ease:cubic-bezier(.16,1,.3,1); }
.scan-top { justify-content:space-between; padding:16px 20px; }
.scan-top .status:not(.guest-hint) { position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); padding:0; }
/* 손님 안내는 보인다(앱과 같게) — 긴 en 문구는 두 줄로 접어 390 머리줄을 넘지 않게 */
.scan-top .status.guest-hint { flex:0 1 auto; white-space:normal; line-height:1.2; padding:4px var(--space-3); }
.scan-top .icon-btn { background:rgba(15,23,42,.6); border:1px solid rgba(255,255,255,.16); border-radius:12px; color:white; box-shadow:none; }
.scan-top .icon-btn svg { width:20px; height:20px; }
.scan-top .spacer { flex:1; }
.frame { width:min(70cqw,calc((100cqh - 64px)*63/88),320px); border-radius:12px; isolation:isolate; }
.frame > i { width:22px; height:22px; border-color:rgba(255,255,255,.65)!important; border-width:2px; }
.frame > i:nth-of-type(1){border-width:2px 0 0 2px;border-top-left-radius:12px}
.frame > i:nth-of-type(2){border-width:2px 2px 0 0;border-top-right-radius:12px}
.frame > i:nth-of-type(3){border-width:0 0 2px 2px;border-bottom-left-radius:12px}
.frame > i:nth-of-type(4){border-width:0 2px 2px 0;border-bottom-right-radius:12px}
/* 무지개 테두리 빛 — 테 모양(마스크)은 가만히 두고 안의 원뿔 그림만 transform 으로 돌린다: 합성 단계만 돌아 매 프레임 다시 그리지 않는다
   (옛 @property 각도 애니메이션 + blur 번짐은 저사양 폰에서 초당 60번 다시 그렸다 — 2026-10-23 대표: 스캔 화면이 저사양에서 느림).
   번짐은 정적 그림자로. 정사각 175% = 틀(63:88)의 대각선보다 커서 돌아도 테를 덮는다 */
.frame { box-shadow:0 0 14px rgba(22,204,204,.22); }
.frame .holo { position:absolute; inset:0; border-radius:inherit; pointer-events:none; padding:2px; overflow:hidden; -webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0); -webkit-mask-composite:xor; mask-composite:exclude; }
.frame .holo::before { content:''; position:absolute; left:50%; top:50%; width:175%; aspect-ratio:1; margin:-87.5% 0 0 -87.5%; background:conic-gradient(rgba(255,255,255,.10) 0deg 230deg,#16cccc 270deg,#b4f5ef 285deg,#a8a0ff 305deg,#edb5df 320deg,rgba(255,255,255,.1) 345deg); animation:holo-orbit var(--scan-holo-orbit) linear infinite; will-change:transform; }
body[data-paused] .frame .holo::before { animation-play-state:paused; }
body[data-paused] .frame .holo { opacity:.15; }
body[data-paused] .frame { box-shadow:none; }
body[data-paused] .frame > i { opacity:.4; }

@keyframes holo-orbit { to { transform:rotate(360deg); } }
@media(prefers-reduced-motion:reduce) { .frame .holo::before { animation:none; transform:rotate(280deg); } }


.board{z-index:5}
#holo-particles{position:fixed;inset:0;width:100%;height:100%;z-index:4;pointer-events:none;opacity:0}
#result .mark{display:none}
body[data-recognition=candidate] .frame .holo::before{background:linear-gradient(135deg,#7760F5,#24D5CB,#7760F5);animation:none}
body[data-recognition=candidate] .frame .holo{animation:scan-candidate var(--scan-holo-candidate) ease-in-out both}
@keyframes scan-candidate{0%,45%,100%{opacity:.2}22%,72%{opacity:.85}}
@media(prefers-reduced-motion:reduce){body[data-recognition=candidate] .frame .holo{animation:none}}

/* The original concept's result/thumb entrances, synchronized with recognition. */
body[data-recognition] #result{animation:recognition-result var(--scan-card-enter) var(--scan-card-ease) both}
body[data-recognition] #result .thumb{animation:recognition-card var(--scan-thumb-enter) var(--scan-card-ease) both;transform-origin:50% 85%}
@keyframes recognition-result{from{opacity:.25;transform:translateY(18px)}to{opacity:1;transform:none}}
@keyframes recognition-card{0%{opacity:0;transform:translateY(24px) scale(.78) rotate(-9deg)}58%{opacity:1;transform:translateY(-4px) scale(1.04) rotate(2deg)}100%{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){
 body[data-recognition] #result,body[data-recognition] #result .thumb,body[data-recognition] .frame .holo,body[data-recognition] .frame .holo::before{animation:none}
 #holo-particles{display:none}
}

/* /css/ui-system.css */
/* Service UI components. Values: docs/design/tokens/snapholo.tokens.json.
   Opt in by class; cinematic home and card-stage typography are separate. */
.ui-page{box-sizing:border-box;width:calc(100% - 2 * var(--ui-gutter));max-width:var(--ui-page-max);margin:var(--space-6) auto 0;color:var(--color-text);font-family:var(--font-sans)}
.ui-page *{box-sizing:border-box}
.ui-page-title{font-size:var(--ui-page-size);line-height:var(--ui-page-line);font-weight:var(--weight-semibold);letter-spacing:var(--tracking-display);margin:0 0 var(--space-6)}
.ui-section{margin-block:var(--ui-section-gap)}
.ui-section-label{font-size:var(--ui-support-size);line-height:var(--ui-support-line);font-weight:var(--weight-medium);color:var(--color-text-muted);margin:0 0 var(--ui-label-gap);padding-inline:var(--ui-group-padding)}
.ui-surface,.ui-menu-group,.ui-faq{background:var(--color-surface);border:0;border-radius:var(--ui-group-radius)}
.ui-menu-group{padding-block:var(--space-2);overflow:hidden}
.ui-menu-row{display:grid;grid-template-columns:var(--ui-icon-slot) minmax(0,1fr) auto;align-items:center;column-gap:var(--ui-icon-gap);min-height:var(--ui-row-compact);padding:var(--ui-row-pad-y) var(--ui-group-padding);color:inherit;text-decoration:none;transition:background-color var(--motion-fast) var(--motion-ease)}
.ui-menu-row--descriptive{min-height:var(--ui-row-descriptive)}
.ui-menu-icon{display:flex;align-items:center;justify-content:center;width:var(--ui-icon-slot);height:var(--ui-icon-slot);flex:none}
.ui-menu-icon>img{width:var(--ui-icon-size);height:var(--ui-icon-size);object-fit:contain}
.ui-row-copy{display:grid;gap:var(--ui-text-gap);min-width:0}
.ui-menu-label{font-size:var(--ui-body-size);line-height:var(--ui-body-line);font-weight:var(--weight-medium);overflow-wrap:anywhere}
.ui-menu-tail{display:flex;align-items:center;justify-content:flex-end;gap:var(--space-2);color:var(--color-text-muted);font-size:var(--ui-support-size);line-height:var(--ui-support-line);text-align:right;max-width:12ch;overflow-wrap:anywhere}
.ui-menu-description,.ui-field-note{display:block;color:var(--color-text-secondary);font-size:var(--ui-support-size);line-height:var(--ui-support-line);font-weight:var(--weight-regular)}
.ui-menu-row .chevron{width:var(--ui-trailing-size);height:var(--ui-trailing-size);flex:none}
.ui-back{display:inline-flex;align-items:center;gap:var(--space-2);min-height:var(--ui-touch-min);color:var(--color-text-secondary);font-size:var(--ui-support-size);line-height:var(--ui-support-line);text-decoration:none;margin-bottom:var(--space-3)}
.ui-page :where(a,button,input,select,textarea,summary):focus-visible{outline:3px solid var(--set-focus);outline-offset:3px}
.ui-form{display:grid;gap:var(--ui-field-gap);padding:var(--ui-group-padding)}
.ui-field{display:grid;gap:var(--space-2)}
.ui-field>label{font-size:var(--ui-support-size);line-height:var(--ui-support-line);font-weight:var(--weight-medium)}
.ui-input{width:100%;min-height:var(--ui-control-height);padding:calc(var(--space-3) - 1px) var(--space-3);border:1px solid var(--color-border);border-radius:var(--ui-control-radius);background:var(--color-surface-sunken);color:var(--color-text);font:inherit;font-size:var(--ui-body-size);line-height:var(--ui-body-line)}
textarea.ui-input{resize:vertical;min-height:calc(var(--ui-control-height) * 3)}
.ui-button{display:inline-flex;justify-content:center;align-items:center;gap:var(--space-2);min-height:var(--ui-control-height);padding:var(--space-3) var(--space-5);border:0;border-radius:var(--ui-control-radius);background:var(--color-brand-action-fill);color:var(--color-brand-action-on);font:inherit;font-size:var(--ui-body-size);line-height:var(--ui-body-line);font-weight:var(--weight-semibold);cursor:pointer}
.ui-button--submit{min-height:var(--ui-submit-height)}
.ui-button:disabled{opacity:.6;cursor:wait}
.ui-faq{overflow:hidden;margin-bottom:var(--ui-group-gap)}
.ui-faq details+details{border-top:1px solid var(--color-border)}
.ui-faq summary{cursor:pointer;font-size:var(--ui-body-size);line-height:var(--ui-body-line);font-weight:var(--weight-medium);padding:var(--space-3) var(--ui-group-padding);min-height:var(--ui-row-compact)}
.ui-faq p{font-size:var(--ui-support-size);line-height:var(--ui-support-line);color:var(--color-text-secondary);margin:0;padding:0 var(--ui-group-padding) var(--ui-group-padding)}
@media(hover:hover){.ui-menu-row:hover{background:var(--color-surface-sunken)}}
@media(prefers-reduced-motion:reduce){.ui-menu-row{transition:none}}

/* Controls own interaction states; the passive icon frame never does. */
.ui-button,.ui-button:hover,.ui-button:focus-visible,.ui-button:active{text-decoration:none}
.ui-button:focus-visible{outline:3px solid var(--set-focus);outline-offset:3px}
.ui-button:not(:disabled):active{transform:translateY(1px)}
@media(hover:hover){.ui-button:not(:disabled):hover{background:color-mix(in srgb,var(--color-brand-action-fill) 92%,black)}}

.ui-button--outline{background:transparent;border:1px solid var(--color-border-strong);color:var(--color-text)}
.ui-button.ui-button--outline .sh-ui-icon{filter:none}
@media(hover:hover){.ui-button--outline:not(:disabled):hover{background:var(--color-surface-sunken)}}

/* /css/ui-icons.css */
/* Passive icon frame: fixed visual canvas, never a control by itself. */
.sh-icon-frame{display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;flex:none;vertical-align:middle;width:var(--ui-icon-slot,2rem);height:var(--ui-icon-slot,2rem);border:1px solid var(--color-border,#dee8ee);border-radius:var(--ui-control-radius,.375rem);background:transparent;box-shadow:none;pointer-events:none}
.sh-icon-frame>.sh-ui-icon,.sh-icon-frame>img{display:block;width:var(--ui-icon-size,1.5rem);height:var(--ui-icon-size,1.5rem);object-fit:contain;margin:0}
/* SnapHolo customer icon family. Color for destinations, ink for tiny operations. */
.sh-ui-icon{display:inline-block;vertical-align:middle;flex:none;width:24px;height:24px;object-fit:contain}
.control .sh-ui-icon,.cta .sh-ui-icon{margin-right:7px}.control .sh-ui-icon[src*="/plus.svg"]{width:18px;height:18px}
.ui-button .sh-ui-icon,.primary .sh-ui-icon,.cta .sh-ui-icon,.glass .sh-ui-icon{filter:brightness(0) invert(1)}
.icon-button .sh-ui-icon,.icon-btn .sh-ui-icon,.page-share .sh-ui-icon{margin:0}
body>header:is(.brand-header,.global-header){height:64px;min-height:64px;gap:12px}
body>header:is(.brand-header,.global-header)>a:first-child img{width:160px}
body>header:is(.brand-header,.global-header)>nav{display:flex;align-self:center;align-items:center;gap:10px;margin-left:auto;height:44px}
body>header:is(.brand-header,.global-header)>nav>a{display:flex!important;align-items:center;justify-content:center;width:44px!important;height:44px;padding:0!important;border:0!important;background:transparent!important;box-shadow:none!important;border-radius:0}
body>header:is(.brand-header,.global-header)>nav>a .sh-ui-icon{width:20px;height:20px}
body>header:is(.brand-header,.global-header)>nav>a.active:after{bottom:-8px;left:13px;right:13px;height:2px;background:#10b7ba}
body>header:is(.brand-header,.global-header) .acm-moved{position:absolute!important;width:1px!important;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}
@media(max-width:760px){body>header:is(.brand-header,.global-header){height:56px;min-height:56px;padding-inline:8px}body>header:is(.brand-header,.global-header)>a:first-child img{width:130px}body>header:is(.brand-header,.global-header)>nav{gap:4px}body>header:is(.brand-header,.global-header)>nav>a.active:after{bottom:-4px}}
@media(max-width:360px){body>header:is(.brand-header,.global-header){padding-inline:8px;gap:4px}body>header:is(.brand-header,.global-header)>a:first-child img{width:100px}body>header:is(.brand-header,.global-header)>nav{gap:0}}
@media(min-width:1024px){body>header:is(.brand-header,.global-header)>nav{gap:24px}body>header:is(.brand-header,.global-header)>nav>a{width:auto!important;padding-inline:4px!important}}

@media(max-width:760px){:root{--site-gutter:8px}}

/* /css/service-ui.css */
/* Service screens share a density and control scale; the home/card art stages keep their own layout. */
body.service-ui :where(button,input,select,textarea){font-family:var(--font-sans)}
body.service-ui :where(main h1){font-size:var(--ui-page-size);line-height:var(--ui-page-line);font-weight:var(--weight-semibold);letter-spacing:var(--tracking-display)}
.ui-page{margin-top:var(--space-4)}.ui-page-title{margin-bottom:var(--space-4)}.ui-back{margin-bottom:var(--space-2)}
.ui-button{min-height:var(--ui-touch-min);padding-block:var(--space-2)}.ui-button .sh-ui-icon{width:20px;height:20px}
.ui-icon-button{display:inline-flex;align-items:center;justify-content:center;width:44px;min-width:44px;height:44px;min-height:44px;padding:var(--space-2);border:1px solid var(--color-border);border-radius:var(--ui-control-radius);background:transparent;cursor:pointer;color:var(--color-text);font:inherit}
.ui-icon-button img{width:16px;height:16px}.collection-add.ui-button{padding:var(--space-2);width:44px;height:44px;min-height:44px}.collection-tools .ui-button{padding:var(--space-2);width:44px;height:44px}
body.service-ui .catalog-page{padding-block:var(--space-4) var(--space-6)}body.service-ui .catalog-page h1{margin:0 0 var(--space-4)}
body.service-ui .market-toolbar{gap:var(--space-3);margin-bottom:var(--space-3)}body.service-ui .market-basis{margin:var(--space-2) 0 var(--space-3);font-size:var(--ui-label-size);line-height:var(--ui-label-line)}body.service-ui .market-board{gap:var(--space-3)}
body.service-ui .market-panel{border-radius:var(--ui-group-radius)}body.service-ui .market-switch{border-radius:var(--ui-control-radius)}body.service-ui .market-switch button{border-radius:var(--ui-control-radius)}body.service-ui .market-card{min-height:92px;padding-block:var(--space-3)}
body.service-ui .market-numbers strong{font-weight:var(--weight-semibold)}
body.service-ui .acct{padding:var(--space-5) var(--ui-gutter) var(--space-6)}body.service-ui .acct h1{margin-bottom:var(--space-4)}body.service-ui .acct h2{font-size:var(--ui-section-size);line-height:var(--ui-section-line);font-weight:var(--weight-semibold);margin:var(--space-5) 0 var(--space-3)}
body.service-ui .acct-who{gap:var(--space-3);margin-bottom:var(--space-4)}body.service-ui .acct-who img{width:40px;height:40px}body.service-ui .acct-who span{font-size:var(--ui-body-size);font-weight:var(--weight-semibold)}body.service-ui .rows{border-radius:var(--ui-group-radius)}body.service-ui .rows>li{padding:var(--space-3) var(--space-4)}body.service-ui .row__name{font-weight:var(--weight-medium)}body.service-ui :where(.btn,.idp,.acct-note){border-radius:var(--ui-control-radius)}
body.service-ui .hero{padding:var(--space-5) 0 var(--space-6)}body.service-ui .hero h1{margin:0 0 var(--space-3)}body.service-ui .lead{font-size:var(--ui-body-size);line-height:var(--ui-body-line)}body.service-ui .sec{gap:var(--space-3);padding-block:var(--space-5)}body.service-ui .sec h2{font-size:var(--ui-section-size);line-height:var(--ui-section-line);font-weight:var(--weight-semibold)}
body.service-ui .support-intro{margin-bottom:var(--space-4)}body.service-ui .hub-footer{margin-top:var(--space-4);padding-bottom:var(--space-5)}
body.service-ui .site-foot{margin-top:var(--space-6)}
/* A sheet title and a close action share one header. Fixed glyph size does not shrink touch targets. */
dialog.ui-dialog,dialog#collection-dialog,dialog#profile-dialog,dialog#guide-dialog{width:calc(100% - 2 * var(--ui-gutter));max-width:32rem;max-height:85dvh;margin:auto;padding:var(--ui-group-padding);border:0;border-radius:var(--ui-group-radius);background:var(--color-surface);color:var(--color-text);font-family:var(--font-sans);overflow:auto}
dialog .dialog-head{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);margin-bottom:var(--space-3)}dialog .dialog-head h2{margin:0;font-size:var(--ui-section-size);line-height:var(--ui-section-line);font-weight:var(--weight-semibold)}
dialog :where(.close,.dialog-close,.sheet-close,.my-icon,#close-profile){width:44px;height:44px;min-width:44px;min-height:44px;padding:var(--space-2);border-radius:var(--ui-control-radius)}dialog :where(.close,.dialog-close,.sheet-close,.my-icon,#close-profile) .sh-ui-icon{width:16px;height:16px}
dialog .collection-actions{display:grid;gap:var(--space-3);margin:0}dialog .collection-actions a{display:flex;align-items:center;justify-content:center;gap:var(--space-2);min-height:44px;border:1px solid var(--color-border);border-radius:var(--ui-control-radius);background:transparent;color:var(--color-text);text-decoration:none;font-size:var(--ui-body-size)}
dialog :where(input,select,textarea){border-radius:var(--ui-control-radius);font:inherit;font-size:var(--ui-body-size)}
dialog.quota-sheet{border-radius:var(--ui-group-radius) var(--ui-group-radius) 0 0}.quota-pro{border-radius:var(--ui-control-radius);margin-top:var(--space-4)}.quota-body{padding:var(--space-5) var(--ui-group-padding) max(var(--space-5),env(safe-area-inset-bottom))}.quota-sheet :where(.quota-app,.quota-close,.quota-login){border-radius:var(--ui-control-radius)}
.my-tile-wrap{position:relative}.is-managing .my-tile-wrap{padding-bottom:var(--space-9)}
@media(min-width:768px){dialog.quota-sheet{border-radius:var(--ui-group-radius)}}
@media(hover:hover){.collection-row:hover,.pro-option:hover{background:var(--color-surface-sunken)}}

/* News has one category navigation; sidebar branding/tags repeated the same destinations. */
:root[data-snapholo-news] .s-sidebar-about,:root[data-snapholo-news] .s-sidebar-tags,:root[data-snapholo-news] .s-latest-head .s-quick-filters{display:none}
:root[data-snapholo-news]{--corner-radius:var(--ui-control-radius);--corner-radius-lg:var(--ui-group-radius)}
:root[data-snapholo-news] .s-news-tabs{min-height:44px;padding-block:0}
:root[data-snapholo-news] .s-content{padding-top:var(--space-4)}
:root[data-snapholo-news] .s-latest-head{margin-bottom:var(--space-3);gap:var(--space-3)}
:root[data-snapholo-news] .s-sidebar-content{padding:var(--space-4);border-radius:var(--ui-group-radius)}
:root[data-snapholo-news] .s-home-top{gap:var(--space-5)}
:root[data-snapholo-news] .s-card-content{padding:var(--space-4)}

:root[data-snapholo-news] .s-content.s-home{margin-top:0}
:root[data-snapholo-news] .s-container{row-gap:var(--space-5)}
@media(max-width:700px){
 body.service-ui .market-numbers{display:grid;gap:var(--space-1)}
 body.service-ui .market-before{display:none}
 body.service-ui .market-numbers small:after{content:none}
 body.service-ui .market-identity strong{font-size:var(--ui-body-size);line-height:var(--ui-body-line);white-space:normal;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
 body.service-ui .market-numbers strong{font-size:var(--ui-section-size);line-height:var(--ui-section-line)}
}
body.service-ui .money-currency{font-size:var(--ui-label-size);font-weight:var(--weight-regular);line-height:1;color:var(--color-text-secondary)}

body.service-ui :where(a.control,a.btn,a.cta):is(:hover,:focus-visible,:active){text-decoration:none}
dialog.sheet,body[data-frame] .sheet{border-radius:var(--ui-group-radius) var(--ui-group-radius) 0 0}
body[data-frame] .sheet{padding-inline:var(--ui-group-padding)}body[data-frame] .sheet-head h2{font-size:var(--ui-section-size);line-height:var(--ui-section-line);font-weight:var(--weight-semibold)}
body[data-frame] :where(.top-pick,.candidate-option){border-radius:var(--ui-control-radius)}
body[data-frame] :where(.scan-save-footer button,.review-tabs button,.btn){border-radius:var(--ui-control-radius)}
@media(min-width:1024px){body[data-frame] .sheet{border-radius:var(--ui-group-radius) 0 0 var(--ui-group-radius)}}

body.service-ui .editions button{min-width:44px;min-height:44px;flex-shrink:0}body.service-ui .editions button[data-edition=all]{padding-inline:8px}

/* Account status and actions use natural text height, including browser text zoom. */
body.service-ui .acct .btn,body.service-ui .acct .idp{padding-block:var(--space-3);white-space:normal;text-align:center}body.service-ui .acct .badge{white-space:normal;border-radius:var(--ui-control-radius);font-weight:var(--weight-medium)}
body.service-ui .account-methods{background:var(--color-surface);border-radius:var(--ui-group-radius);margin-top:var(--space-3);overflow:hidden}body.service-ui .account-methods h2{margin:0;padding:var(--space-4) var(--space-4) var(--space-2);font-size:var(--ui-support-size)}body.service-ui .account-methods .rows{border:0}body.service-ui .acct .row__act{max-width:100%}
body.service-ui .grade-table{margin-top:var(--space-4);margin-bottom:var(--space-4)}body.service-ui .grade-table caption{font-size:var(--ui-section-size);font-weight:var(--weight-semibold);color:var(--color-text)}body.service-ui .grade-table tbody td:nth-child(2){font-size:var(--ui-section-size);font-weight:var(--weight-semibold)}
/* Shared Figma role: the currency symbol and amount form one number. */
body.service-ui .money-currency{font:inherit;color:inherit;line-height:inherit}
body.service-ui{background-color:var(--color-page-bg)}

/* Approved density: keep readable text and control hit areas, remove nested gutters. */
dialog .dialog-head{position:relative;justify-content:center;min-height:44px;padding-inline:52px}
dialog .dialog-head h2{flex:1;text-align:center}
dialog .dialog-head :is(.close,.dialog-close,.sheet-close,#close-profile){position:absolute;right:0;top:50%;transform:translateY(-50%)}
.quota-body{text-align:center}.quota-pro{display:flex;flex-direction:column;align-items:center}.quota-actions{justify-content:center}
@media(max-width:767px){
 body.service-ui .ui-page{margin-top:8px}
 body.service-ui :is(.ui-page-title,.support-intro){margin-bottom:8px}
 body.service-ui :is(.ui-section,.group.ui-menu-group){margin-block:8px}
 body.service-ui .ui-section-label{padding-inline:8px}
 body.service-ui .ui-form{gap:8px}
 body.service-ui .acct{padding-block:8px}
 body.service-ui .rows>li{padding-inline:8px}
 body.service-ui .sec{padding-block:8px;gap:8px}
 body.service-ui .site-foot{margin-top:8px}
}

@media(max-width:767px){
 :root[data-snapholo-news] :is(.s-content,.s-container){padding-inline:8px;column-gap:8px;row-gap:8px}
 :root[data-snapholo-news] :is(.s-card-content,.s-sidebar-content){padding:8px}
}

/* /css/scan-redesign.css */
/* Approved 21 scanner improvements, 942/943/946. Recognition effects stay in scan-holo.css. */
body:not([data-nocam]){overflow:hidden}
body:not([data-nocam])>.site-foot{display:none!important}
.board{padding:16px;gap:12px;background:var(--color-page-bg);border-radius:16px 16px 0 0;box-shadow:none}
.board #result{position:relative;display:grid;grid-template-columns:72px minmax(0,1fr) auto;gap:12px;align-items:center;padding:12px;background:linear-gradient(135deg,var(--color-area-fill-start) 35%,var(--color-panel));border:1px solid var(--color-area-stroke);border-radius:16px}
.board #result .thumb{width:72px;height:100px}
.board #result .name{font-size:18px;line-height:24px}
.board #result .meta{font-size:13px;line-height:18px}
.board #result .price{font-size:28px;line-height:36px;font-weight:600;letter-spacing:0}
.board[data-tier=final] #result .mark{display:grid;position:absolute;right:12px;top:12px;width:20px;height:20px}
.board[data-tier=final] #result .mark svg{width:12px;height:12px}
.board[data-tier=candidate] #result,.board[data-tier=empty] #result,.board[data-tier=none] #result,.board>.pick{display:none!important}
#candidate-strip{padding:12px;border-radius:16px;border:1px solid var(--color-area-stroke);background:linear-gradient(135deg,var(--color-area-fill-start) 35%,var(--color-panel));min-width:0}
.inline-candidate-head{display:flex;align-items:center;gap:8px;margin-bottom:12px;color:var(--color-text-muted);font-size:13px;line-height:18px}
.inline-pending{display:inline-flex;align-items:center;gap:4px;flex:none;color:var(--color-scan-attention);background:color-mix(in srgb,var(--color-scan-attention) 10%,transparent);border-radius:999px;padding:3px 6px;font-size:12px;font-weight:600}
.inline-pending b{width:16px;height:16px;display:grid;place-items:center;border-radius:50%;background:var(--color-scan-attention);color:white;font-size:12px}
#inline-options{list-style:none;display:flex;overflow-x:auto;gap:8px;scrollbar-width:none;margin:0;padding:0 0 1px}
#inline-options li{flex:none;width:94px}
.inline-candidate{display:flex;flex-direction:column;width:94px;gap:4px;text-align:left;padding:8px;border:1px solid var(--color-border);border-radius:12px;background:var(--color-page-bg);color:var(--color-text);font-family:inherit;cursor:pointer}
.inline-candidate[aria-pressed=true]{border-color:var(--color-brand-action-fill);box-shadow:inset 0 0 0 1px var(--color-brand-action-fill)}
.inline-candidate .thumb{width:76px;height:106px;border-radius:6px}
.inline-candidate small{font-size:13px;line-height:18px;color:var(--color-text-muted);white-space:nowrap}
.inline-candidate strong{font-size:13px;line-height:18px;font-weight:600;max-width:100%;overflow-wrap:anywhere}
@media(min-width:1024px){body{background:color-mix(in srgb,var(--color-text) 40%,var(--color-page-bg))}.scanner{width:min(880px,calc(100% - 48px));height:calc(100dvh - 40px);margin:20px auto;border-radius:16px;overflow:hidden}.scanner .board{width:min(560px,calc(100% - 48px));margin-bottom:24px;border-radius:16px}body[data-scan-list] .scanner{width:min(880px,calc(100% - 488px));margin-left:max(24px,calc((100vw - 1320px)/2));margin-right:464px}}
.sheet{background:var(--color-page-bg);box-shadow:none;scrollbar-width:none;max-height:calc(100dvh - 64px)}
.sheet::-webkit-scrollbar{display:none}
.sheet-head{background:var(--color-page-bg);padding:20px 0 0;min-height:24px;touch-action:pan-x}
.sheet-head h2{font-size:20px;font-weight:600}
#results{padding-top:24px;height:440px;display:flex;flex-direction:column;gap:0}
#results.expanded{height:calc(100dvh - 64px)}
#results[hidden]{display:none}
#results>.sheet-head{position:absolute;right:16px;top:8px;z-index:3;padding:0;background:transparent}
#results>.sheet-head::before{display:none}
.sheet-drag{position:absolute;top:0;left:calc(50% - 44px);width:88px;height:24px;border:0;background:transparent;padding:0;display:grid;place-items:start center;touch-action:none;z-index:2;cursor:grab}
.sheet-drag span{margin-top:8px;width:36px;height:4px;border-radius:999px;background:var(--color-border)}
.scan-summary,.scan-edit-card,.scan-edit-quantity{background:linear-gradient(135deg,var(--color-area-fill-start) 35%,var(--color-panel));border:1px solid var(--color-area-stroke);border-radius:16px;padding:12px}
.scan-summary{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:0;min-height:86px}
.scan-summary>div{display:grid;align-content:center;gap:4px;min-width:0}
.scan-summary span{font-size:12px;line-height:16px;color:var(--color-text-muted)}
.scan-summary strong{font-size:24px;line-height:32px;font-weight:600;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
.review-tabs{margin:0;min-height:26px;align-items:center}
.review-tabs button{padding:0;min-height:26px;border:0;background:transparent;color:var(--color-scan-attention);font-size:12px;line-height:18px;text-decoration:underline}
.review-tabs button[aria-pressed=true]{background:transparent;color:var(--color-scan-attention);font-weight:600}
#groups{flex:1;overflow-y:auto;scrollbar-width:none;min-height:0;border-radius:16px;background:linear-gradient(135deg,var(--color-area-fill-start) 35%,var(--color-panel));border:1px solid var(--color-area-stroke);padding:0 12px}
.scan-row{grid-template-columns:minmax(0,1fr) auto;gap:8px;min-height:72px;padding:8px 0;border-color:var(--color-border)}
.scan-row:last-child{border-bottom:0}
.scan-row-card{gap:10px}
.scan-row .thumb{width:36px;height:50px}
.scan-row-text{gap:0;min-width:0;line-height:18px}
.scan-row-name{border:0;background:transparent;text-align:left;padding:0;color:var(--color-text);font-family:inherit;font-weight:600;cursor:pointer;text-decoration:none;font-size:15px!important;line-height:20px!important;min-width:0;max-width:100%}
.scan-row-text small{font-size:13px;line-height:17px}
.scan-row .price{font-size:13px;line-height:17px;font-weight:600;color:var(--color-text)}
.scan-row-actions{display:flex;gap:0;align-items:center}
.scan-copies{font-size:13px;color:var(--color-text-muted);white-space:nowrap}
.scan-copies .scan-quantity{width:44px;height:44px;border:1px solid var(--color-border-strong);border-radius:6px;background:transparent;padding:0;color:inherit;cursor:pointer;font:inherit}
.scan-review,.scan-delete{width:44px;height:44px;min-height:44px;padding:0;border:0;background:transparent;display:grid;place-items:center;position:relative;color:var(--color-text-muted);cursor:pointer;border-radius:6px}
.scan-review::after{inset:0}
.scan-review[hidden],.scan-status[hidden]{display:none}
.scan-delete svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.6}
.scan-attention,.scan-status{display:grid;place-items:center;width:18px;height:18px;border-radius:50%;font-size:13px;line-height:1;font-weight:600;color:white;background:var(--color-scan-attention);border:1px solid white}
.scan-status{background:var(--color-brand-action-fill);margin:0 13px}
.scan-review:focus-visible,.scan-delete:focus-visible,.scan-row-name:focus-visible{outline:2px solid var(--set-focus);outline-offset:2px}
.scan-save-footer{flex:none;margin:0;background:var(--color-page-bg);border:0;padding:12px 0 max(16px,env(safe-area-inset-bottom))}
.scan-save-footer>div{grid-template-columns:auto 1fr}
.scan-save-footer button{padding-inline:16px;border-radius:6px;font-weight:600}
.scan-save-footer .primary svg,.scan-save-footer .primary .sh-ui-icon{display:none}
.scan-save-footer p:empty{display:none}
.scan-undo{flex:none}
.stack-row{height:76px;padding-top:8px;border:0;gap:8px}
.stack{gap:8px;mask-image:linear-gradient(to right,#000 85%,transparent)}
.stack li{margin:0;flex:none}
.stack a,.stack .thumb{width:44px;height:61px;border-radius:6px}
.stack .needs-review .thumb{outline:0}
.stack a>.scan-attention{position:absolute;top:-2px;right:-2px;width:16px;height:16px;font-size:12px}
.stack-link{gap:8px;max-width:50%;font-size:16px;line-height:24px}
.scan-list-count{padding:0;position:absolute;left:0;bottom:0;transform:translate(-20%,15%);min-width:20px;height:20px;justify-content:center;border-radius:50%;background:var(--color-brand-action-fill);color:white;font-size:12px;z-index:1}
.scan-list-count svg,#stack-pending{display:none!important}
#stack-value{font-size:16px;line-height:24px;font-weight:600;white-space:nowrap}
.stack-link>svg{width:16px;flex:none}
.stack-row{position:relative}
.scan-edit-card{margin-top:12px;display:grid;grid-template-columns:72px minmax(0,1fr);gap:12px;align-items:center}
.scan-edit-card .thumb{width:72px;grid-row:1/3}
.scan-edit-card small{font-size:13px;color:var(--color-text-muted)}
.scan-edit-card strong{font-size:18px;font-weight:600;text-align:right}
.scan-edit-quantity{display:flex;align-items:center;gap:12px;margin-top:12px;font-size:15px}
.scan-edit-quantity .scan-stepper{margin-left:auto;border:0;gap:8px}
.scan-edit-quantity button{width:44px;height:44px;border:0;background:transparent;font:inherit;font-size:20px;color:var(--color-text)}
.scan-edit-quantity output{min-width:24px;text-align:center;font-size:16px}
#scan-edit .sheet-head .close{margin-left:0}
#scan-edit .sheet-head h2{flex:1}
#edit-detail{margin-left:auto;flex:none}
#candidates{display:flex;flex-direction:column;height:calc(100dvh - 64px);padding-bottom:max(16px,env(safe-area-inset-bottom))}
#candidates[hidden]{display:none}
#candidates .review-hint{flex:none;font-size:13px}
.candidate-options{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;overflow-y:auto;min-height:0;flex:1}
.candidate-option{display:flex;flex-direction:column;align-items:stretch;border:1px solid var(--color-area-stroke);background:linear-gradient(135deg,var(--color-area-fill-start),var(--color-panel));border-radius:12px;padding:12px;margin:0;height:100%;gap:8px}
.candidate-option .thumb{width:100%;aspect-ratio:63/88}
.candidate-option .thumb img{object-fit:contain;width:100%;height:100%}
.candidate-option[aria-pressed=true]{border-color:var(--color-brand-action-fill);box-shadow:inset 0 0 0 1px var(--color-brand-action-fill)}
.candidate-option .scan-row-text strong{font-size:15px;font-weight:600}
.candidate-option .scan-row-text small{white-space:normal;font-size:13px}
#confirm-candidate{flex:none;min-height:44px}
@media(min-width:768px){#scan-edit{left:50%;right:auto;top:50%;bottom:auto;transform:translate(-50%,-50%);width:440px;max-height:calc(100dvh - 64px);border-radius:16px}#candidates{width:440px}}
@media(min-width:1024px){#results,#results.expanded{top:0;max-height:100dvh;height:100dvh;width:440px;padding-top:32px}#results>.sheet-head{top:8px}.sheet-drag{display:none}#candidates{height:min(720px,calc(100dvh - 64px));top:50%;bottom:auto;left:50%;right:auto;transform:translate(-50%,-50%);border-radius:16px}}

