/* ── 디자인 토큰 (SportsMallTheme.cs와 동기 유지) ───────────── */
:root {
    --sm-bg: #F7F9FB;
    --sm-surface: #FFFFFF;
    /* WCAG AA 대비 확보 — SportsMallTheme.cs의 Primary와 동기화. 흰 글자 대비 실측 5.47:1
       (기준 4.5:1). 기존 #0D9488은 3.74:1로 미달 — Task 9가 axe color-contrast로 검출해
       SportsMallTheme.cs의 Primary는 그때 고쳤지만 이 토큰(--sm-teal)은 갱신을 놓쳐, 위 1행의
       "동기 유지" 약속이 한동안 깨져 있었다(이 값에 흰 글자를 얹는 .cart-count·헤더 검색
       버튼·구글 G 마크 등 여러 곳이 계속 3.74:1로 미달이었다 — task-9-report.md 참고).
       이번에 다시 맞췄다. 되돌리지 말 것. */
    --sm-teal: #0F766E;
    /* WCAG AA 대비 확보 — SportsMallTheme.cs의 PrimaryDarken과 동기화. 흰 글자 대비 실측
       7.58:1(기준 4.5:1). 위 --sm-teal과 같은 값(#0F766E)이었던 적이 있었는데, 그러면
       .consent-submit:hover·::deep .admin-submit:hover(배경을 --sm-teal→--sm-teal-dark로
       바꿔 어두워지는 hover 효과)가 안 보이게 된다 — SportsMallTheme.cs의 Primary/
       PrimaryDarken 충돌과 같은 문제라 같은 방식(teal-700 다음 단계인 teal-800)으로 피했다.
       되돌리지 말 것. */
    --sm-teal-dark: #115E59;
    --sm-teal-tint: #F0FDFA;
    --sm-ink: #0F172A;
    --sm-muted: #64748B;
    --sm-border: #E2E8F0;
    --sm-amber: #F59E0B;
    --sm-radius-card: 14px;
    --sm-radius-btn: 10px;
    --sm-shadow-card: 0 1px 2px rgba(15, 23, 42, .06);
    --sm-shadow-hover: 0 8px 24px rgba(13, 148, 136, .14);
    --sm-container: 1200px;
}

html {
    background: var(--sm-bg);
}

body {
    margin: 0;
    color: var(--sm-ink);
    background: var(--sm-bg);
}

/* 키보드 포커스 명확화 (PRD UX-004 P0 — "키보드 탐색, 포커스 표시"). */
:focus-visible {
    outline: 3px solid var(--sm-teal);
    outline-offset: 2px;
    border-radius: 4px;
}

/* 위 규칙만으로는 <a>·<button>(MudButton·MudIconButton·MudNavLink·MudLink — Href 유무에 따라
   MudButton/MudLink류는 <a> 아니면 <button>으로 렌더된다)에 전혀 적용되지 않는다. 설치된
   MudBlazor 9.2.0(~/.nuget/packages/mudblazor/9.2.0/staticwebassets/MudBlazor.min.css, 607KB
   전체를 `outline:` 기준으로 전수 grep해 직접 확인 — @layer는 이 파일에도 이 저장소의 어떤
   .css/.razor.css에도 없다, 그래서 명시도 계산이 뒤집히지 않는다)가 이 두 태그의 기본 포커스
   링을 지운다:
     a:focus-visible{outline:none}   — 명시도 (0,1,1) = 클래스급 1(:focus-visible) + 태그 1(a)
     button:focus{outline:none}      — 명시도 (0,1,1) = 클래스급 1(:focus) + 태그 1(button)
                                        (:focus-visible이 아니라 :focus라 마우스 클릭 포커스까지
                                        더 넓게 지운다)
   그 외에 outline을 살리는 규칙은 이 파일 전체에 하나도 없다(.divider:focus의 outline은
   MudBlazor 자체 컴포넌트용이라 a·button과 무관). 위 :focus-visible 규칙은 명시도 (0,1,0)
   (클래스급 1개뿐)이라 이 두 리셋보다 낮다 — App.razor를 보면 app.css가 MudBlazor.min.css
   보다 나중에 링크되지만(<link> 순서: MudBlazor.min.css → app.css → SportsMall.Web.styles.css),
   명시도가 낮으면 로드 순서는 무의미하다. 그래서 지금 <a>·<button>은 포커스 표시가 전무하다 —
   HeroSection.razor의 Href 기반 MudButton("상품 둘러보기" 등, 저장소 전체 25곳 이상)과
   SiteHeader.razor의 MudIconButton(햄버거 메뉴)을 포함해 전부. 아래 :root 규칙이 이를 고친다.

   :root를 앞에 붙여 명시도를 (0,2,1)로 올렸다 — 클래스급 2(:root, :focus-visible) + 태그 1
   (a 또는 button). 이러면 위 두 리셋((0,1,1))보다 명시도 자체가 높아 로드 순서·MudBlazor
   버전업으로 두 리셋의 순서가 바뀌어도 항상 이긴다(순서에 기대지 않는다). MudBlazor가
   개별 컴포넌트에 이미 주는 :focus-visible 강조(예: Filled 버튼의 배경이 Primary→
   PrimaryDarken로 바뀜, SportsMallTheme.cs 참고)는 그대로 유지된다 — outline은 별개의
   박스 속성이라 배경색 규칙을 덮어쓰지 않고 그 위에 "더해진다."

   범위는 클래스가 아니라 태그(a·button) 자체로 잡았다 — MudButton(Filled·Outlined·Text
   전부)·MudIconButton·MudNavLink·MudLink가 전부 최종적으로 이 두 태그 중 하나로 렌더되므로,
   이렇게 하면 지금의 25곳 이상과 앞으로 추가되는 모든 링크·버튼을 한 번에, 클래스명이
   바뀌어도 안전하게 덮는다. 반대급부(너무 넓어서 생기는 위험)로 MudBlazor가 이미 자체
   포커스 표시를 하는 컴포넌트(칩·탭·리스트·별점·슬라이더 등, MudBlazor.min.css의
   :focus-visible 규칙 전수 목록 기준)에 아웃라인이 겹칠 가능성을 검토했다 — 이 저장소가
   실제로 쓰는 컴포넌트를 `.razor` 전체 grep으로 확인한 결과 MudList·MudTabs·MudRating·
   MudSlider·MudMenu는 아예 안 쓰고, MudChip은 쓰지만(admin 목록·QuoteDetailPage 등
   14곳) 전부 상태 배지 용도로 OnClick 없이(클릭 불가능·포커스 불가능 상태) 쓰고 있어
   지금 이 저장소에는 실제 겹침 사례가 없다. 다만 이건 정적 코드 감사이지 브라우저
   렌더링 확인은 아니다(아래 검증 기록의 Browser pane 제약과 같은 이유) — 나중에 이
   컴포넌트들을 클릭 가능하게 쓰기 시작하면 다시 확인이 필요하다.

   outline-offset은 기존 값(2px)을 그대로 따랐다 — Filled 버튼(배경이 var(--mud-palette-
   primary)=--sm-teal과 동일)처럼 버튼 자체 배경이 아웃라인과 같은 색이어도, CSS 스펙상
   outline은 항상 border box 바깥에 그려지므로(offset이 양수면 그만큼 더 바깥) 버튼 자체
   배경 위에 겹쳐 안 보이는 문제는 애초에 생기지 않는다 — 이건 outline의 스펙 정의상
   그런 것이라 별도 실측이 필요한 부분은 아니다. 대신 outline이 그려지는 "바깥" 자리의
   배경색(다크 섹션 여부)은 실측·전수 조사가 필요했다 — 아래 규칙이 그 결과다.

   되돌리면(:root 규칙을 지우면): <a>·<button> 전체가 다시 포커스 표시 없음으로 돌아간다 —
   최소 HeroSection "상품 둘러보기"(Href 기반 MudButton)·.action-link(장바구니 등)·
   .nav-item(종목별 등)·.quick-card·.cat-card·MudIconButton(햄버거 메뉴 등)이 전부 재발한다.
   지우지 말 것. */
:root a:focus-visible,
:root button:focus-visible {
    outline: 3px solid var(--sm-teal);
    outline-offset: 2px;
    border-radius: 4px;
}

/* 위 teal(#0F766E) 아웃라인은 어두운 배경 위에서는 묻힌다 — 직접 계산(WCAG 상대휘도 공식,
   포커스 표시류 비텍스트 대비 기준은 3:1):
     teal on --sm-ink(#0F172A)                 = 3.26:1  (3:1은 통과하지만 여유가 거의 없다)
     teal on --sm-teal 자기 자신(#0F766E)       = 1.00:1  (완전히 안 보임)
     흰(#fff) on --sm-ink                       = 17.85:1
     흰(#fff) on --sm-teal                      = 5.47:1
   흰색은 두 배경 모두 넉넉히 통과한다 — 이 파일에 이미 있던
   .pwa-install-banner button:focus-visible{outline:3px solid #fff}과 같은 판단이다(그 규칙은
   그대로 둔다 — 아래 규칙과 명시도가 같은 (0,2,1)이라도 그 규칙이 이 블록보다 파일 뒤쪽에
   있어 소스 순서로 계속 이긴다).

   아래 목록은 실제로 어두운 배경 위에 포커스 가능한 <a>/<button>이 있는 자리를 저장소
   전체에서 찾은 결과다(--sm-ink·--sm-teal·--sm-teal-dark를 배경으로 쓰는 곳을 전수 확인):
   TopUtilBar(.util-bar, 전체 배경 --sm-ink) 안의 "기관 전용 회원 혜택 안내" 링크,
   SiteFooter(.site-footer, 전체 배경 --sm-ink) 안의 하단 3개 링크, OrderSteps(.steps,
   전체 배경 --sm-ink) 안의 "기관 견적 시작하기"(Href 기반 MudButton). AppPromo의 --sm-ink
   배경(.phone-frame·.phone-notch)은 aria-hidden 장식 안이라 포커스 가능한 자식이 없어
   제외했다(확인함). .sm-skip-link는 스스로가 --sm-ink 배경이라(위 정의) 자기 자신에게
   적용한다 — a.sm-skip-link로 태그를 명시해 위 :root 규칙과 명시도를 (0,2,1)로 맞췄다
   (클래스만 쓰면 (0,2,0)이 되어 위 규칙보다 낮아져 안 먹는다). */
.util-bar a:focus-visible, .util-bar button:focus-visible,
.site-footer a:focus-visible, .site-footer button:focus-visible,
.steps a:focus-visible, .steps button:focus-visible,
a.sm-skip-link:focus-visible {
    outline-color: #fff;
}

/* AdminLayout.razor의 MudAppBar(Color="Color.Primary")도 같은 이유로 흰색이 필요하다 — 배경이
   --mud-palette-primary(=--sm-teal, #0F766E)라 위와 같은 1.00:1이다. 안의 두 요소(햄버거 메뉴
   MudIconButton, "로그아웃" MudButton)가 대상이다.

   색상별 클래스가 아니라 `.mud-appbar` 자체로 잡았다 — 원래는 MudBlazor가 Color=Primary에
   실제로 붙이는 클래스(예: `.mud-theme-primary`, MudBlazor.min.css에 `color:...-primary-text
   !important;background-color:...-primary !important`로 정의돼 있어 배경+대비글자를 함께
   주는 "면" 컴포넌트용 클래스로 보인다)까지 좁혀 쓰려 했으나, 관리자 로그인이 MFA(OTP)로
   막혀 있어(시드 계정에 이미 TOTP가 걸려 있고 비밀은 ASP.NET Data Protection으로 암호화돼
   DB에서 못 꺼낸다 — users.mfa_secret_protected, "CfDJ..." 접두사로 확인) 이 세션에서
   실제 렌더된 클래스를 브라우저로 확인하지 못했다. 대신 이 저장소에 MudAppBar 사용처가
   AdminLayout.razor 단 하나뿐이고 그 Color가 하드코딩된 Primary라(조건부 아님, grep으로
   확인) `.mud-appbar`만으로도 오탐 없이 정확히 그 자리만 잡는다 — 확인 못한 클래스 이름을
   추측해 selector에 넣는 것보다 이미 grep으로 존재를 확인한 `.mud-appbar`(MudBlazor.min.css
   전수 확인 — `.mud-appbar`·`.mud-appbar-dense`·`.mud-appbar-fixed-bottom`·
   `.mud-appbar-fixed-top` 4개만 있고 색상별 변형 클래스는 없다)만 쓰는 쪽이 더 안전한
   선택이라 판단했다. 나중에 MudAppBar를 다른 Color로 쓰는 곳이 추가되면 이 규칙이 과하게
   적용될 수 있다 — 그때는 실제 클래스를 확인해 좁혀야 한다. */
.mud-appbar a:focus-visible,
.mud-appbar button:focus-visible {
    outline-color: #fff;
}

/* 본문 건너뛰기 링크 — 키보드 사용자용 */
.sm-skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    background: var(--sm-ink);
    color: #fff;
    padding: 10px 18px;
    border-radius: 0 0 10px 0;
}

.sm-skip-link:focus {
    left: 0;
}

/* 공통 컨테이너 */
.sm-container {
    max-width: var(--sm-container);
    margin: 0 auto;
    padding: 0 20px;
}

/* Blazor 오류 UI (기본 유지) */
#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

.blazor-error-boundary::after {
    content: "오류가 발생했습니다.";
}

/* PWA 설치 안내 (계획 4c). 화면 아래에 고정되며 기본은 숨김 — pwa.js가 연다. */
.pwa-install-banner {
    position: fixed;
    left: 16px;
    right: 16px;
    bottom: 16px;
    z-index: 1400;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
    border-radius: 12px;
    background: var(--sm-ink);
    color: #fff;
    font-size: 14px;
    box-shadow: 0 8px 24px rgb(15 23 42 / 24%);
}

.pwa-install-banner[hidden] {
    display: none;
}

.pwa-install-banner span {
    flex: 1;
}

/* WCAG AA 대비 확보 — 흰 글자 대비 실측 7.58:1 (기준 4.5:1). 기존 var(--sm-teal)(#0D9488)은 3.74:1로 미달 (계획 4c Task 2 접근성 리뷰). --sm-teal-dark 자체도 이후 #0F766E→#115E59로 한 단계 더 어두워졌다(위 :root의 --sm-teal-dark 정의 주석·task-9-report.md 참고). --sm-teal로 되돌리지 말 것. */
.pwa-install-banner button {
    font: inherit;
    padding: 6px 14px;
    border: 0;
    border-radius: 8px;
    background: var(--sm-teal-dark);
    color: #fff;
    cursor: pointer;
}

.pwa-install-banner button:focus-visible {
    outline: 3px solid #fff;
    outline-offset: 2px;
}

.pwa-install-banner .pwa-dismiss {
    background: transparent;
    text-decoration: underline;
    padding: 6px 4px;
}
