/* ==========================================================================
   표면 재질 계약 — 떠 있는 표면(플로팅)의 단일 정의처

   Mist 디자인 시스템은 "blur는 떠 있는 표면의 특권"이라는 원칙 위에 서 있고,
   테마(clevi-mist-*)는 그 재질을 `.clc-dialog` / `.clc-dropdown-panel` 같은
   디자인 시스템 컴포넌트 클래스에만 직접 입힌다.

   문제는 앱이 손수 만든 플로팅 표면(챗봇 선택 패널·액션 메뉴·각종 팝업)이다.
   이들은 배경 토큰만 빌려 쓰기 때문에 "반투명하기만 하고 뒤가 안 흐린" 상태가
   된다 — 재질 토큰이 색만 공급하고 blur는 별도 속성이기 때문.

   그래서 여기서 두 가지를 고정한다.
     1) 재질 토큰의 기본값. Mist가 아닌 테마에서도 토큰이 항상 "정의됨"을 보장해
        소비처가 폴백 없이 참조할 수 있게 한다.
     2) 표면 시맨틱 토큰과 유틸리티 클래스. 커스텀 플로팅 표면은 색/블러/헤어라인/
        그림자/모서리를 직접 고르지 않고 이 계약만 소비한다.

   새로 만드는 플로팅 표면은 `.clv-surface-overlay` 클래스만 붙이면 되고,
   스코프드 CSS(.razor.css)라 클래스를 붙이기 어려운 기존 표면은
   `--clv-overlay-*` 토큰을 소비한다.

   같은 결함의 두 번째 얼굴이 **크롬**(L2⁺)이다. 툴바 pill·커버 액션·캐러셀 nav·
   sticky 바처럼 콘텐츠 **위에 겹치는 작은 표면**은 스스로를 오버레이라고 여기지 않아
   카드 재질(L2 종이)을 빌려 쓴다. 종이는 계약상 "blur 없는 반투명"이라 캔버스 위에
   놓이는 카드에는 맞지만, 콘텐츠를 덮으면 뒤 글자가 그대로 비친다.
   판정 기준은 크기가 아니다 — `position: absolute/fixed/sticky` 로 **다른 콘텐츠를
   덮는가**다. 덮으면 `--clv-chrome-*`(또는 불투명), 놓이면 `--clv-card-*`.
   회귀 방지는 `CssFloatingSurfaceContractTests` 가 맡는다.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. 재질 토큰 기본값

   `html`(0,0,1)에 정의한다. 테마는 `:root`(0,1,0)에 정의하므로 링크 순서와
   무관하게 테마가 항상 이긴다 — 즉 여기 값은 "테마가 재질을 말해주지 않을 때"만
   쓰이는 바닥값이다. Mist는 이 전부를 아크릴 값으로 덮어쓴다.

   비-Mist 테마의 바닥값은 불투명 + blur 없음이다. 반투명은 재질을 정의한
   테마만 감당할 수 있고, 어설픈 반투명은 가독성만 해친다.
   -------------------------------------------------------------------------- */
html {
    --clc-material-shell: var(--clc-sidebar-background-color, var(--clc-base-background-color, #FFFFFF));
    /* `-static`은 살아 있는 토큰을 가리키지 않고 같은 출처를 다시 적는다.
       별칭(`var(--clc-material-shell)`)으로 두면, 효과 끄기가 반대 방향으로
       `--clc-material-shell: var(--clc-material-shell-static)`을 걸 때 순환이 되어
       두 토큰이 함께 무효가 된다. */
    --clc-material-shell-static: var(--clc-sidebar-background-color, var(--clc-base-background-color, #FFFFFF));
    --clc-material-paper: var(--clc-base-background-color, #FFFFFF);
    --clc-material-veil: var(--clv-modal-background, var(--clc-base-background-color, #FFFFFF));
    --clc-material-veil-static: var(--clv-modal-background, var(--clc-base-background-color, #FFFFFF));
    --clc-material-blur-shell: none;
    --clc-material-blur-veil: none;

    /* 크롬 재질(L2⁺) — 콘텐츠 위에 겹쳐 뜨는 작은 표면.
       바닥값이 베일을 가리키는 것은 이 파일의 다른 토큰과 다르다. 이유는 게시 순서다:
       크롬 재질은 Mist 테마에 있고 테마 패키지는 따로 게시되므로, 게시 전에도
       "떠 있는데 안 흐린" 상태가 되면 안 된다. 베일을 가리키면 게시 전에는 L3 값으로
       흐려지고(증상 없음), 게시 후에는 테마가 정의한 크롬 값이 이긴다.
       테마가 재질을 아예 말하지 않는 비-Mist 에서는 베일 바닥값(불투명+blur none)을
       그대로 물려받아 결국 이 파일의 원칙("반투명은 재질을 정의한 테마만")과 같다. */
    --clc-material-chrome: var(--clc-material-veil);
    --clc-material-chrome-static: var(--clc-material-veil-static);
    --clc-material-blur-chrome: var(--clc-material-blur-veil);

    --clc-material-hairline: color-mix(in srgb, var(--clc-text-color, #000) 12%, transparent);
    --clc-material-hairline-strong: color-mix(in srgb, var(--clc-text-color, #000) 22%, transparent);
    --clc-material-specular: transparent;

    /* 입력 재질(L2⁻). 비-Mist 테마의 바닥값은 "오늘과 같게" — 불투명 배경 +
       평범한 테두리다. 파인 자리/뜬 종이는 재질 위계를 정의한 테마만 감당한다. */
    --clc-material-field: var(--clc-base-background-color, #FFFFFF);
    --clc-material-field-border: var(--clc-material-hairline-strong);
    --clc-material-field-raised: var(--clc-base-background-color, #FFFFFF);
    --clc-material-field-raised-border: var(--clc-material-hairline-strong);
    --clc-material-field-raised-shadow: 0 1px 2px color-mix(in srgb, var(--clc-text-color, #000) 12%, transparent);
}

/* --------------------------------------------------------------------------
   2. 표면 시맨틱 토큰

   소비처는 재질 토큰(--clc-material-*)을 직접 읽지 않고 "무슨 표면인가"로 말한다.
   L3 오버레이(팝업·메뉴·드롭다운·시트) / L1 셸(사이드바·독·고정 패널) / 스크림.
   -------------------------------------------------------------------------- */
:root {
    /* L3 — 떠 있는 오버레이 */
    --clv-overlay-surface: var(--clc-material-veil);
    --clv-overlay-blur: var(--clc-material-blur-veil);
    --clv-overlay-border-color: var(--clc-material-hairline);
    --clv-overlay-shadow: var(--clc-shadow-layer2-2, 0 8px 24px rgba(0, 0, 0, 0.16));
    --clv-overlay-radius: 14px;

    /* L2⁺ — 콘텐츠 위에 겹쳐 뜨는 크롬 (툴바 pill · 커버 액션 · 캐러셀 nav ·
       sticky 바 · 썸네일 배지). 오버레이(L3)와 나누는 기준은 크기가 아니라 역할이다:
       오버레이는 화면을 점유하고 뒤를 물리며, 크롬은 콘텐츠 옆에 얹혀 함께 읽힌다.
       그래서 blur 반경이 짧고 모서리도 작다. **콘텐츠를 덮는 표면에 카드 재질
       (--clv-card-surface / --clc-material-paper)을 쓰지 않는다** — 종이는 계약상
       blur 없는 반투명이라 뒤 글자가 비친다. */
    --clv-chrome-surface: var(--clc-material-chrome);
    --clv-chrome-blur: var(--clc-material-blur-chrome);
    --clv-chrome-shadow: var(--clc-material-elevation-2, 0 8px 24px rgba(0, 0, 0, 0.18));
    --clv-chrome-radius: 999px;

    /* L1 — 셸 */
    --clv-shell-surface: var(--clc-material-shell);
    --clv-shell-blur: var(--clc-material-blur-shell);
    /* 셸 가장자리 — 표면·깊이 정책 1항에 따라 헤어라인 보더가 아니라 그림자가
       캔버스와 셸을 나눈다. 폴백은 Mist 라이트 값과 같은 모양이라, 재질을 말하지
       않는 테마에서도 "선이 아니라 깊이"라는 계약은 유지된다. */
    --clv-shell-shadow: var(--clc-material-shell-shadow, 0 1px 2px rgba(20, 14, 45, 0.04), 0 8px 28px rgba(20, 14, 45, 0.06));

    /* L2 — 카드(도킹 콘텐츠 표면). 표면·깊이 정책: Mist는 외곽 보더 대신
       깊이(표면색 + elevation 그림자 + 스펙큘러)로 경계를 만든다 — Mist 테마가
       border-color를 transparent로 덮고 shadow에 elevation을 싣는다.
       여기 바닥값은 "오늘과 같게"(헤어라인 보더 + 명목 그림자)라 비-Mist 테마와
       구 패키지에서 현행 모습이 유지된다. transparent여도 1px 보더 선언은
       남겨 두는 계약이라 테마 전환에도 레이아웃이 흔들리지 않는다. */
    --clv-card-surface: var(--clc-material-paper);
    --clv-card-border-color: var(--clc-material-hairline);
    --clv-card-shadow: inset 0 1px 0 var(--clc-material-specular), 0 1px 2px rgba(0, 0, 0, 0.04);
    --clv-card-shadow-hover: inset 0 1px 0 var(--clc-material-specular), 0 3px 8px rgba(0, 0, 0, 0.08);
    --clv-card-radius: 18px;

    /* L2⁻ — 입력이 놓이는 자리.
       종이 위(카드·다이얼로그 안)에 놓이는 입력은 `field`,
       캔버스 위에 떠 있는 입력(하단 독 옴니박스·채팅 컴포저)은 `field-raised`. */
    --clv-field-surface: var(--clc-material-field);
    --clv-field-border-color: var(--clc-material-field-border);
    --clv-field-radius: 10px;
    --clv-field-raised-surface: var(--clc-material-field-raised);
    --clv-field-raised-border-color: var(--clc-material-field-raised-border);
    --clv-field-raised-shadow: var(--clc-material-field-raised-shadow);

    /* 오버레이 뒤를 덮는 딤 */
    --clv-scrim: var(--clv-modal-overlay, rgba(0, 0, 0, 0.32));
}

/* --------------------------------------------------------------------------
   3. 유틸리티 클래스

   전역 스타일시트라 스코프드 CSS(`.x[b-xxxxx]`, 0,2,0)보다 우선순위가 낮다.
   따라서 기존 표면을 이 클래스로 "덮어쓰는" 용도로는 쓸 수 없고,
   자체 배경을 선언하지 않는 새 표면에 붙이는 용도다.
   -------------------------------------------------------------------------- */
.clv-surface-overlay {
    border: 1px solid var(--clv-overlay-border-color);
    border-radius: var(--clv-overlay-radius);
    background: var(--clv-overlay-surface);
    box-shadow: inset 0 1px 0 var(--clc-material-specular), var(--clv-overlay-shadow);
    -webkit-backdrop-filter: var(--clv-overlay-blur);
    backdrop-filter: var(--clv-overlay-blur);
}

.clv-surface-chrome {
    background: var(--clv-chrome-surface);
    border-radius: var(--clv-chrome-radius);
    box-shadow: inset 0 1px 0 var(--clc-material-specular), var(--clv-chrome-shadow);
    -webkit-backdrop-filter: var(--clv-chrome-blur);
    backdrop-filter: var(--clv-chrome-blur);
}

.clv-surface-shell {
    background: var(--clv-shell-surface);
    box-shadow: inset 0 1px 0 var(--clc-material-specular);
    -webkit-backdrop-filter: var(--clv-shell-blur);
    backdrop-filter: var(--clv-shell-blur);
}

.clv-surface-scrim {
    background: var(--clv-scrim);
}

.clv-surface-card {
    background: var(--clv-card-surface);
    border: 1px solid var(--clv-card-border-color);
    border-radius: var(--clv-card-radius);
    box-shadow: var(--clv-card-shadow);
}

.clv-surface-field {
    background: var(--clv-field-surface);
    border: 1px solid var(--clv-field-border-color);
    border-radius: var(--clv-field-radius);
}

.clv-surface-field-raised {
    background: var(--clv-field-raised-surface);
    border: 1px solid var(--clv-field-raised-border-color);
    border-radius: var(--clv-field-radius);
    box-shadow: var(--clv-field-raised-shadow), inset 0 1px 0 var(--clc-material-specular);
}

/* --------------------------------------------------------------------------
   4. 함정 방지

   조상에 opacity 애니메이션/전환이 걸려 있으면 자식의 backdrop-filter가 무효화된다
   (조상이 backdrop root가 되어 자식이 흐릴 배경 자체가 사라진다).
   등장 연출은 표면 요소 자신에게 걸고, 래퍼에는 걸지 않는다.
   Mist 원칙상 blur 반경 자체는 애니메이션하지 않는다.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    :where(html:not([data-clevi-motion="full"])) .clv-surface-overlay,
    :where(html:not([data-clevi-motion="full"])) .clv-surface-shell {
        transition: none;
    }
}

/* --------------------------------------------------------------------------
   5. 프리즘 — "여기는 AI를 향한다"는 표시

   여기에는 없다. 램프(`--clv-prism-1..4`)와 굴절광 구조(`.clv-prism`)는 둘 다
   Mist 코어(`Clevi.App.Components/themes/_clevi-mist-core.scss`)가 갖는다.

   다른 `--clv-*`처럼 바닥값을 두지 않는 이유는, 이 토큰만으로는 아무것도 그려지지
   않기 때문이다. 구조가 테마에 있으므로 비-Mist 테마에서는 램프가 있어도 층이
   스타일을 못 받는다 — 그럴 바에는 정본을 한 곳에 두는 편이 낫다.

   소비처(채팅 컴포저 · 프로젝트 비서 런처)는 마크업 두 층을 얹고 세기는 상속되는
   커스텀 속성으로만 조절한다. 계약은 위 SCSS 머릿글에 있다.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   6. 화면 효과 선호 — 기기가 아니라 사용자가 정한다

   `theme.js`가 부팅 시점에 documentElement에 얹는 두 속성을 읽는다:
     data-clevi-surface = full(기본) | auto(기기에 맞춤) | minimal(끄기)
     data-clevi-motion  = on(기본)   | full(항상 켬) | reduced(줄이기)

   역할 나누기 — 테마는 <b>값</b>을 갖고, 앱은 <b>언제 쓸지</b>를 정한다.
   예전에는 Mist가 `(pointer: coarse)`이면 스스로 blur를 절반으로 낮췄다. 화면
   크기로 기기 성능을 단정하는 셈이라 좋은 폰을 쓰는 사람까지 흐린 화면을 받았다.
   그래서 테마에서 그 단을 빼고, 절반 값은 `--clc-material-blur-*-lite` 토큰으로
   받아 여기서 `auto`를 고른 사람에게만 적용한다.

   그래서 기본값(`full`)에는 규칙이 없다 — 테마의 `:root` 값이 곧 최대치다.
   여기서 덮어쓸 일이 없으니 blur 수치를 앱에 복사해 두지 않아도 되고, 나중에
   테마가 값을 바꾸면 그대로 따라간다.

   경계 — 이 설정이 뒤집는 것은 "화면 크기로 기기 성능을 짐작한 강등"까지다.
   OS 접근성 설정(`prefers-reduced-motion`·`prefers-reduced-transparency`)은
   기본값에서 그대로 따른다. 사용자가 시스템에 이미 말해 둔 요구이기 때문이다.
   유일한 예외는 사용자가 직접 고른 "항상 켬"(motion=full)이다.
   -------------------------------------------------------------------------- */

/* 기기에 맞춤 — 예전 Mist 사다리 ①단과 같은 조건·같은 값이다. 다만 이제
   모두에게 강제되지 않고 이걸 고른 사람에게만 걸린다. 값은 테마에서 받아 오고,
   토큰이 없는 테마(비-Mist·구 패키지)를 위해 폴백을 함께 적는다. */
@media (pointer: coarse) and (max-width: 820px) {
    html[data-clevi-surface="auto"] {
        --clc-material-blur-shell: var(--clc-material-blur-shell-lite, blur(16px) saturate(1.3));
        --clc-material-blur-veil: var(--clc-material-blur-veil-lite, blur(22px) saturate(1.4));
        --clc-material-blur-chrome: var(--clc-material-blur-chrome-lite, blur(12px) saturate(1.3));
    }
}

    /* 위 규칙은 `html[...]`(0,1,1)이라 테마의 `:root`(0,1,0)를 이긴다 — OS가
       "투명도 줄이기"라고 해서 테마가 blur를 껐어도 다시 켜 버린다. 그래서 뒤에서
       같은 자리를 다시 덮는다. `full`·`minimal`은 이 rule 자체가 없어 해당 없다. */
    @media (prefers-reduced-transparency: reduce) {
        html[data-clevi-surface="auto"] {
            --clc-material-shell: var(--clc-material-shell-static);
            --clc-material-veil: var(--clc-material-veil-static);
            --clc-material-chrome: var(--clc-material-chrome-static);
            --clc-material-blur-shell: none;
            --clc-material-blur-veil: none;
            --clc-material-blur-chrome: none;
        }
    }

/* 끄기 — 저사양 기기용. 테마 사다리의 "투명도 줄이기"와 같은 자리로 내린다.
   반투명만 남기고 blur를 빼면 가독성만 나빠지므로 배경도 불투명으로 함께 바꾼다. */
html[data-clevi-surface="minimal"] {
    --clc-material-shell: var(--clc-material-shell-static);
    --clc-material-veil: var(--clc-material-veil-static);
    --clc-material-chrome: var(--clc-material-chrome-static);
    --clc-material-blur-shell: none;
    --clc-material-blur-veil: none;
    --clc-material-blur-chrome: none;
    --clc-material-specular: transparent;
}

/* 애니메이션 줄이기.

   컴포넌트마다 `prefers-reduced-motion` 블록을 따로 적어 두긴 했지만, 그건 적어 둔
   곳에서만 듣는다. 새로 만든 애니메이션은 대개 빠뜨리므로 "OS 설정을 존중한다"가
   군데군데 구멍이 난다. 그래서 전역에서 한 번에 잡는다 — 아래 두 블록이 앱 전체의
   바닥이고, 컴포넌트가 자기 블록을 적었든 안 적었든 결과가 같아진다.

   0이 아니라 0.001ms인 것은 `animationend`/`transitionend`를 기다리는 코드가
   이벤트를 못 받아 멈추는 것을 막기 위해서다. */

/* ① 사용자가 "줄이기"를 골랐을 때. OS 설정과 무관하게 적용한다. */
html[data-clevi-motion="reduced"] *,
html[data-clevi-motion="reduced"] *::before,
html[data-clevi-motion="reduced"] *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
}

/* ② OS가 움직임을 줄이라고 할 때. 기본값이 여기 걸린다.
   빠져나가는 건 사용자가 직접 고른 "항상 켬"뿐이다. */
@media (prefers-reduced-motion: reduce) {
    html:not([data-clevi-motion="full"]) *,
    html:not([data-clevi-motion="full"]) *::before,
    html:not([data-clevi-motion="full"]) *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }
}
