/* 화면 토큰 — 허브·메뉴(site.css)와 놀이 화면(app.css)이 공유하는 단일 출처.
   config.js의 NOTES·PALETTE가 소리의 단일 출처인 것과 같은 역할이다.

   두 CSS가 이 파일을 각자 <link>로 함께 읽는다. @import를 쓰지 않는 이유는
   왕복이 하나 더 생겨 첫 화면이 늦게 그려지기 때문이다. */
:root {
  /* ---- 색 ----
     3단이다. "덜 중요함"을 흐린 색으로 표현하지 않는다 — 크기·위치·배경으로
     표현한다. 폐기한 #7c72a8은 배경 대비 4.24:1로 WCAG AA(4.5:1)에 못 미쳤고,
     그 색이 쓰인 곳이 모두 12.5-13px 글씨여서 부모 가독성 불만의 직접 원인이었다. */
  --bg: #141127;
  --bg-sheet: radial-gradient(120% 100% at 50% 0%, #241d45 0%, #141127 70%);
  --bg-raised: rgba(157, 146, 201, 0.12);
  --bg-raised-active: rgba(157, 146, 201, 0.2);
  --border-raised: rgba(157, 146, 201, 0.22);
  --ink: #f5efdf; /* 제목·본문·강조 · 친구의 크림색 외곽선 */
  --ink-muted: #9d92c9; /* 보조 설명 — 배경 대비 6.48:1 */
  --accent: #ffd97a; /* 포커스 링·계속하기 버튼 */
  --ink-on-accent: #4a2410; /* 밝은 면(계속하기 버튼) 위에 얹히는 글자 */

  /* ---- 시작 화면의 시트 ----
     --bg-sheet와 달리 반투명이다. 시작 전에도 장면이 뒤에서 계속 돌아야 하기
     때문이다 — 글자를 못 읽는 아이에게 "무슨 놀이인가"를 말해 주는 것은 그림뿐이다.

     투명도의 하한은 부모 안내의 가독성이 정한다. 가장 밝은 장면 하늘(풍선의
     그러데이션 위쪽) 위에 이 시트를 겹치고 그 위에 --bg-raised 안내 패널을 얹으면
     --ink-muted가 4.5:1을 겨우 넘긴다. 더 투명하게 만들면 부모가 안내를 읽지 못한다.
     이 계산은 play/tests/test_css_tokens.py가 대신 해 준다 — 장면이 하늘을 밝히면
     그쪽에서 먼저 실패한다.

     backdrop-filter로 뒤를 흐리는 안은 접었다. 오버레이는 놀이 중에도 opacity: 0으로
     남아 있을 뿐 사라지지 않으므로, 블러가 매 프레임 캔버스를 다시 흐리는 비용을
     놀이 내내 물게 된다. */
  --bg-veil: radial-gradient(120% 100% at 50% 0%, rgba(36, 29, 69, 0.8) 0%, rgba(20, 17, 39, 0.93) 62%);
  /* 부모 일시정지 화면은 읽는 화면이다 — 장면은 기척만 남기고 글자에 자리를 준다. */
  --bg-veil-strong: radial-gradient(120% 100% at 50% 0%, rgba(36, 29, 69, 0.93) 0%, rgba(20, 17, 39, 0.97) 62%);

  /* ---- 친구의 얼굴 ----
     둥근 윤곽·큰 눈·볼터치의 배열이 '귀엽다'는 지각을 만든다. 채도를 올려서
     아기자기해지지 않는다 — 형태가 만든다. 얼굴 색이 대표 색과 따로 있는 이유는
     눈과 볼이 놀이마다 달라지면 친구들이 한 식구로 보이지 않기 때문이다. */
  --blush: #ff9ec4; /* 볼터치 */
  --pupil: #2b1a3f; /* 눈동자·입 — 밤 배경보다도 어두워 어느 대표 색 위에서도 선다 */

  /* ---- 타이포 ----
     본문 하한이 16px다. 부모가 아이에게 기기를 건네기 전, 팔 뻗은 거리에서
     읽어야 하는 글씨다. */
  --fs-display: clamp(32px, 8vw, 52px); /* 화면 제목 */
  --fs-title: clamp(20px, 5vw, 26px); /* 카드 제목 */
  --fs-body: clamp(16px, 4vw, 19px); /* 설명·안내 */
  --fs-label: 16px; /* 부모용 버튼 라벨 — 하한 */

  /* 한글은 단어 중간에서 줄이 바뀌면 읽는 속도가 눈에 띄게 떨어진다
     ("다른 놀 / 이"). keep-all은 공백에서만 끊는다. */
  --wrap-ko: keep-all;

  --font-stack: -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo", "Pretendard",
    sans-serif;

  /* ---- 터치 타겟 ----
     캔버스의 "후한 판정" 원칙(목표물은 짧은 변의 8% 이상, 판정 반경은 시각
     크기의 1.5배 이상)을 문서형 화면으로 확장한 것이다. --tap-parent는 하한이며
     예외를 두지 않는다 — 예외를 두면 규칙이 규칙이 아니게 된다.

     --tap-child는 #45의 가로형 카드(폭이 화면 전체)를 기준으로 잡은 값이고,
     지금은 메뉴 책장(#67)의 표지 높이 하한이다. 표지는 한 줄에 두세 권이 서므로
     폭이 화면 전체이던 가로형 카드보다 작다 — 그래서 이 값은 "표지가 이보다
     낮아지지 않는다"는 바닥으로만 쓰고, 실제 높이는 그 위에서 화면 높이를 따라
     자란다 (site.css의 --book-height가 max()로 이 바닥을 깐다). 하한을 지운
     것이 아니라 자를 높이 쪽에 남겨둔 것이며, 좁은 쪽 변인 폭도 격자의
     minmax()가 따로 받친다. */
  --tap-parent: 56px; /* 부모용 컨트롤 최소 변 — #44 */
  --tap-child: clamp(120px, 18vh, 160px); /* 아이용 표지 최소 높이 — #45 · #67 */

  /* ---- 책장 (메뉴) ----
     표지가 앞을 보고 꽂힌 책장이다. 책등만 보이면 글자를 못 읽는 아이는 고를
     수 없으므로 표지를 앞으로 돌린다.

     --cover-tint는 대표 색이 밤 배경(--bg) 위에 얹히는 두께다. 대표 색을 원색
     그대로 칠하지 않는 이유가 둘이다. 밤의 세계관이 표지 넉 장에 뚫리고, 크림색
     제목이 밝은 원색 위에서 1.2-2.5:1까지 떨어져 읽히지 않는다. 0.42에서 네 대표
     색의 합성 표지 위 대비가 5.09-7.75:1이 된다 (램프 열 색 전부 5.09:1 이상).
     이 계산은 play/tests/test_bookshelf.py가 대신하므로, 두께를 올리거나 램프를
     밝히면 그쪽에서 먼저 실패한다.

     알파를 섞으려면 color-mix가 필요한데 사파리 16.2 미만이 그 규칙을 통째로
     버리므로, --bg 위에 대표 색을 그대로 칠하고 불투명도로 낮춘다 (놀이 화면의
     빛무리와 같은 방식). 그래서 표지의 바탕은 --bg-sheet가 아니라 --bg다 —
     합성색이 화면 위치에 따라 달라지면 위 대비 계산이 성립하지 않는다. */
  --cover-tint: 0.42; /* 대표 색이 밤 배경 위에 얹히는 두께 */
  --cover-edge: rgba(245, 239, 223, 0.55); /* 표지의 크림 테두리 — 보드북의 흰 가장자리 */
  --shelf-face: rgba(157, 146, 201, 0.16); /* 선반 판 */
  --shelf-edge: rgba(245, 239, 223, 0.24); /* 선반 앞모서리에 걸리는 빛 */

  /* ---- 모서리 ----
     둥근 윤곽은 각진 윤곽보다 선호되고 접근 행동을 부른다. 유아용 물건에
     모서리가 없는 것은 안전 때문만이 아니다. 그래서 반경을 아까워하지 않는다. */
  --radius-panel: 32px; /* 안내 패널 같은 큰 판 */
  --radius-button: 36px; /* 부모용 큰 버튼 — 높이의 절반이라 실제로는 알약이다 */

  /* 놀이별 대표 색. 실제 값은 games.py의 band가 정하고 템플릿이 요소에
     실어준다 (style="--accent-band: var(--band-N)"). 여기 있는 것은 놀이가
     아닌 화면 — 허브 카드 — 이 쓰는 기본값이다.

     인라인으로만 정의하지 않는 이유는 그러면 이 파일만 봐서는 토큰의 존재를
     알 수 없기 때문이다. 단일 출처는 목록이 완전할 때만 단일 출처다. */
  --accent-band: var(--ink-muted);

  /* ---- 음높이 대응 색 ----
     config.js의 PALETTE 사본이다. 사본인 것이 마음에 들지는 않지만, JS가
     getComputedStyle로 CSS를 읽게 만들면 부팅 순서가 얽히고 CSS 로드 실패 시
     색이 통째로 사라진다. 대신 어긋남을 테스트가 잡는다 —
     play/tests/test_css_tokens.py.

     램프의 규칙은 셋이다.
     - 색상(oklch)이 33°에서 303°까지 30°씩 고르게 오른다. 간격이 고르지 않으면
       어떤 이웃은 어른 눈에도 겨우 갈린다 (옛 band 2↔3이 oklch 13°였다)
     - 각 색을 자기 채도 정점 가까이 둔다. 아이는 채도 문턱값이 청소년기까지
       성숙하지 않아 어른에게 알맞은 채도를 한 단계 흐리게 본다
     - --bg 대비 6:1이 하한이다. 밝기 대비 감도는 4개월에도 어른의 약 1/30이라,
       형태를 세우는 것은 색상이 아니라 밝기 대비다. 이 하한도 테스트가 잡는다 */
  --band-0: #f57055;
  --band-1: #f49937;
  --band-2: #f4ce43;
  --band-3: #bbe444;
  --band-4: #4cf591;
  --band-5: #4cedd9;
  --band-6: #48ddf8;
  --band-7: #35a7f3;
  --band-8: #8297f4;
  --band-9: #b480f4;
}
