/* 글꼴은 tools/subset-fonts.py 가 원본(assets-src/fonts)에서 깎아 만든다.
   원본은 한 벌에 750~860KB라 그대로 보내면 첫 화면이 글꼴만 3.2MB다. 글꼴 파일을 바꾸려면
   원본을 assets-src 에 넣고 그 스크립트를 다시 돌린다(여기 파일을 직접 갈아 끼우지 말 것).
   GF Sans 세 굵기에는 저장소 글에 나오는 글자만 담았다(뼈대, 한 벌 약 105KB).
   별명은 아이가 직접 쓰니 뼈대에 없는 글자가 올 수 있다. 그때만 GF Sans Full(음절 전부)을
   받아 오도록 아래 :scope 의 글꼴 차례에 GF Sans Full 을 끼워 두었다.
   GF Sans Full 은 보통 굵기 한 벌뿐이라 굵기를 400으로 적어 굵은 글씨 속에서는 브라우저가 굵게 흉내 낸다
   (100~900으로 적으면 굵은 글씨 속 그 글자만 얇다, 10-20 「닉」). 한글 음절에만 쓰도록 범위를 묶었다:
   두 GF Sans 모두에 없는 기호(메뉴의 ▸ 같은 것) 하나 때문에 627KB를 받지 않게.
   사이트 글을 고쳐 새 글자가 생기면 tests/unit/fonts.test.mjs 가 잡는다.
   도현체·주아체는 게임이 글자를 캔버스에 그려서 음절을 하나도 빼지 않았다(포장만 woff2). */
@font-face { font-family:GF Sans; src:url('../assets/fonts/gf-sans-400.woff2') format('woff2'); font-weight:400; font-display:swap; }
@font-face { font-family:GF Sans; src:url('../assets/fonts/gf-sans-700.woff2') format('woff2'); font-weight:700; font-display:swap; }
@font-face { font-family:GF Sans; src:url('../assets/fonts/gf-sans-900.woff2') format('woff2'); font-weight:900; font-display:swap; }
@font-face { font-family:GF Sans Full; src:url('../assets/fonts/gf-sans-full.woff2') format('woff2'); font-weight:400; font-display:swap; unicode-range:U+AC00-D7A3; }
@font-face { font-family:Sora; src:url('../assets/fonts/sora.woff2') format('woff2'); font-weight:100 800; font-display:swap; }
@font-face { font-family:DoHyeon; src:url('../assets/fonts/dohyeon.woff2') format('woff2'); font-weight:400; font-display:swap; }
:root {
 --gf-bg:#fff9e9; --gf-panel:#fffef8; --gf-panel2:#f3ead2; --gf-line:#d1c3a2;
 --gf-ink:#3c382e; --gf-sub:#665d4c; --gf-acc:#ffe17b; --gf-acc-hi:#f2c94b;
 --gf-gold:#765408; --gf-sky:#245e4a; --gf-mint:#cce5ca; --gf-edge:#b6a783;
 --gf-white:#ffffff; --gf-green:#397a58; --gf-yellow:#ffe17b;
 --gf-shadow:0 5px 16px #57452920; --gf-gradient:linear-gradient(180deg,transparent 20%,#211c1599 48%,#211c15f5 100%);
 --gf-overlay:#30291ed9; --gf-hud:#3c382eee; --gf-hud-line:#b6a783; --gf-cream:#fff9e9;
 --gf-dot1:#527d67; --gf-dot2:#b5804b; --gf-dot3:#647b98; --gf-dot4:#97697d; --gf-dot-light:#fff9e933;
 --gf-band:76px;
}
/* 화면 폭 따라 글자·칸이 같이 커진다(2026-10-14 대장 고르기 1가): 1366 이하 16px, 1920에서 약 20px, 2560에서 24px.
   사이트 쪽 CSS가 rem으로 쓴 길이만 따라 커진다. 놀이판 게임은 iframe 안이라 영향이 없다. */
html { font-size:clamp(16px, calc(16px + (100vw - 1366px) * .0067), 24px); }
/* 기본 스크롤 막대는 운영체제 꼴이라 사이트와 겉돈다. 같은 크림·나무 색으로 맞춘다. */
*{scrollbar-width:thin;scrollbar-color:#c3ae84 transparent}
*::-webkit-scrollbar{width:10px;height:10px}
*::-webkit-scrollbar-track{background:transparent}
*::-webkit-scrollbar-thumb{background:#c3ae84;border:3px solid transparent;border-radius:999px;background-clip:padding-box}
*::-webkit-scrollbar-thumb:hover{background:#a68f63}
*::-webkit-scrollbar-corner{background:transparent}
.gf-lock-shake{animation:gf-locked-shake .3s ease-in-out}
.gf-lock-reason{font-weight:900!important;color:#392a20!important;background:#fff0a9;border-radius:6px;animation:gf-locked-reason .6s ease-in-out 2}
.gf-lock-target{outline:4px solid #e7ad13!important;outline-offset:3px;box-shadow:0 0 16px #ffdc65!important}
body:is(.gf-stage,.play-page) .sv-prose{font-family:GF Sans,sans-serif}
@keyframes gf-locked-shake{25%,75%{translate:-5px 0}50%{translate:5px 0}}
@keyframes gf-locked-reason{50%{background:#ffd76b}}
@media(prefers-reduced-motion:reduce){.gf-lock-shake,.gf-lock-reason{animation:none}}
@scope (body.home-page, body.list-page, body.opening-page, body.play-page, body.ranks-page, body.stamps-page, body:has(script[src*="js/admin.js"])) {
* { box-sizing:border-box; }
:scope { margin:0; font-family:GF Sans,GF Sans Full,sans-serif; color:var(--gf-ink); background:var(--gf-bg); line-height:1.6; }
main,header,footer { margin:0; padding:1.25rem 1.6rem; }
h1,h2,h3 { font-family:DoHyeon,GF Sans,sans-serif; font-weight:400; line-height:1.25; }
button,input,select,.link-button { font:inherit; min-height:2.75rem; min-width:2.75rem; padding:.5rem .9rem; }
button,.link-button { border:1px solid var(--gf-line); background:var(--gf-panel2); color:var(--gf-ink); cursor:pointer; border-radius:12px; font-weight:700; }
button[aria-pressed=true],.btn { background:var(--gf-yellow); }
a { color:var(--gf-ink); }
.link-button,.btn { display:inline-flex; align-items:center; justify-content:center; text-decoration:none; min-height:2.75rem; padding:.5rem 1rem; border-radius:.75rem; font-weight:700; }
button:disabled { cursor:default; }
:focus-visible { outline:3px solid var(--gf-green); outline-offset:3px; }
label { display:grid; gap:6px; }
input,select { background:var(--gf-panel); color:var(--gf-ink); border:1px solid var(--gf-line); border-radius:10px; }
.row { display:flex; flex-wrap:wrap; gap:12px; align-items:center; margin-bottom:16px; }
.grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(240px,1fr)); gap:16px; }
.box,.card,.stamp { padding:20px; border:1px solid var(--gf-line); background:var(--gf-panel); border-radius:18px; box-shadow:var(--gf-shadow); }
.card { text-align:left; width:100%; }
.info-cover { display:block; width:100%; height:210px; object-fit:cover; border-radius:14px; }
dialog { width:min(600px,calc(100% - 32px)); max-height:calc(100dvh - 40px); padding:24px; color:var(--gf-ink); background:var(--gf-bg); border:1px solid var(--gf-line); border-radius:22px; box-shadow:var(--gf-shadow); }
dialog::backdrop { background:var(--gf-overlay); }
dialog form { display:grid; gap:12px; }
dialog>button { margin:6px 6px 0 0; }
[data-test=school-choices] { display:grid; gap:8px; max-height:180px; overflow:auto; }
[data-test=name-error] { color:var(--gf-gold); font-weight:700; }
.play-page { overflow:hidden; } .play-page main { padding:0; }
.game-frame { border:0; width:100vw; height:100dvh; display:block; }
.exit-button { position:fixed; z-index:2; }
.top-left { top:12px; left:12px; } .top-right { top:12px; right:12px; }
.bottom-left { bottom:12px; left:12px; } .bottom-right { bottom:12px; right:12px; }
.notice { position:fixed; bottom:20px; left:20px; padding:12px; background:var(--gf-panel); border:1px solid var(--gf-line); z-index:3; }
.stamp[data-earned=true] { background:var(--gf-mint); border:2px solid var(--gf-green); } .stamp { border-style:dashed; }
small { display:inline-block; margin-left:6px; }
table { border-collapse:collapse; width:100%; } th,td { padding:8px; border:1px solid var(--gf-line); text-align:left; }
.table-wrap { overflow-x:auto; } [hidden] { display:none!important; }
[data-test=rank-rows] p { padding:12px; margin:0; border-bottom:1px solid var(--gf-line); }
[data-test=stamp-count] { font:32px DoHyeon; }
/* MattoLAB 워드마크: mattolab-brand/brand.css 가 원본이다. 글꼴·굵기·색은 브랜드 고정값이라 바꾸지 않는다
   (18px = 가로 90px, 브랜드 문서가 정한 최소 크기). 어두운 바탕에서만 Matto 를 크림으로 바꿔 쓴다. */
.labmark { margin:0; font-family:Sora,GF Sans,sans-serif; font-size:18px; letter-spacing:-.012em; line-height:1; }
.labmark i { font-style:normal; font-weight:500; color:#1E1E1E; }
.labmark b { font-weight:800; color:#E8590C; }
@media(max-width:600px) { main,header,footer { padding:1rem; } .grid { grid-template-columns:1fr; } .row { align-items:stretch; } .row>label { width:100%; } }

}
/* 닉네임 창: 낮은 가로(아이폰 사파리 280px 안팎)에서는 한 줄로 쌓으면 「저장」이 잘린다.
   왼쪽에 학교 찾기, 오른쪽에 학년 · 닉네임 · 단추를 둔다. */
@media (orientation: landscape) and (max-height: 500px){
 dialog[data-test="nametag"][open]{width:min(720px,calc(100% - 24px));max-height:calc(100dvh - 16px);padding:12px 16px}
 dialog[data-test="nametag"][open] h2{margin:0 0 6px;font-size:18px}
 dialog[data-test="nametag"][open] form{grid-template-columns:minmax(0,1.1fr) minmax(0,.5fr) minmax(0,.5fr);grid-template-rows:repeat(5,auto);gap:6px 12px;align-items:start}
 dialog[data-test="nametag"][open] form>*{grid-column:2/4}
 dialog[data-test="nametag"][open] form>label:first-child{grid-column:1;grid-row:1}
 /* 검색 결과(최대 30개)는 오른쪽 줄들이 만든 높이 안에서만 스크롤한다. contain:size라 목록 길이가 줄 높이를 늘리지 않는다. */
 dialog[data-test="nametag"][open] [data-test="school-choices"]{grid-column:1;grid-row:2/5;align-self:stretch;min-height:0;contain:size;overflow:auto}
 dialog[data-test="nametag"][open] [data-test="school-selected"]{grid-column:1;grid-row:5}
 dialog[data-test="nametag"][open] form>label:nth-of-type(2){grid-row:1}
 dialog[data-test="nametag"][open] form>label:nth-of-type(3){grid-row:2}
 dialog[data-test="nametag"][open] form>p:not([data-test]){grid-row:3}
 dialog[data-test="nametag"][open] [data-test="name-error"]{grid-row:5}
 dialog[data-test="nametag"][open] form>label{display:flex;align-items:center;gap:8px;font-size:14px}
 dialog[data-test="nametag"][open] form>label>:is(input,select){flex:1;min-height:40px}
 dialog[data-test="nametag"][open] form>p{font-size:13px}
 dialog[data-test="nametag"][open] [data-test="name-error"]:empty{display:none}
 dialog[data-test="nametag"][open] form>button{min-height:44px}
 dialog[data-test="nametag"][open] [data-test="name-save"]{grid-column:2;grid-row:4}
 dialog[data-test="nametag"][open] [data-test="name-save"]:last-child{grid-column:2/4}
 dialog[data-test="nametag"][open] [data-test="name-cancel"]{grid-column:3;grid-row:4}
}
