/* Flocking Hangul 데모 — 화면 전체를 쓰는 레이아웃 (모바일 · 태블릿 · PC) */
:root { --ink: 255, 255, 255; --pad-b: max(18px, env(safe-area-inset-bottom)); }
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; height: 100%; overflow: hidden; background: #1c60aa; overscroll-behavior: none; }
body { position: fixed; inset: 0; -webkit-tap-highlight-color: transparent; }

/* 바다(WebGL)와 새(p5) 두 캔버스를 화면 전체에 겹친다 */
#sea, canvas.p5Canvas { position: fixed; left: 0; top: 0; width: 100vw !important; height: 100vh !important; height: 100dvh !important; display: block;
  object-fit: cover; object-position: 50% 50%; }   /* 창 크기가 바뀌는 순간 캔버스 비율이 아직 옛것이어도 늘리지 않고 비율대로 덮는다 (가장자리만 살짝 잘림) */
#sea { z-index: 0; }
canvas.p5Canvas { z-index: 1; touch-action: none; }

/* 실시간 입력: 가운데 아래. 키보드가 올라오면 app.js 가 --kb 만큼 올린다. ?liveY= 로 높이를 정하면 --live-b (app.js setLiveY) */
#live { position: fixed; left: 50%; bottom: calc(var(--live-b, calc(var(--pad-b) + 22px)) + var(--kb, 0px)); transform: translateX(-50%); z-index: 5; width: min(86vw, calc(720px * var(--ui, 1))); margin: 0; transition: bottom .2s ease; }
#liveInput {
  display: block; width: 100%; margin: 0; padding: 6px 0; border: 0; outline: 0; background: transparent; box-shadow: none; border-radius: 0;
  -webkit-appearance: none; appearance: none; text-align: center; resize: none; overflow: hidden;   /* 여러 줄: 글 높이에 맞춰 늘어난다 (app.js) */
  font: 500 calc(clamp(16px, min(4.6vw, 3.4vh), 30px) * var(--ui, 1)) / 1.3 -apple-system, system-ui, "Apple SD Gothic Neo", "Noto Sans KR", sans-serif;   /* --ui: 입력창 크기 (?uiScale=, app.js) */
  color: rgb(var(--ink)); caret-color: rgb(var(--ink));   /* 입력 중인 글씨는 완전 불투명 흰색 */
  /* 바다·구름 위에서도 또렷하게: 짧은 그림자 + 넓고 옅은 그림자 */
  text-shadow: var(--type-shadow, 0 1px 2px rgba(0, 22, 55, .6), 0 2px 12px rgba(0, 22, 55, .4));   /* 「B — 중간」 (demo/shadow.html, tune/type-shadow.json) */
}
/* 고정 해상도(?dpr=, fixed/ 페이지): 글씨를 화면 높이에 따라 바꾸지 않고 30px 로 고정 → 「입력창 크기」(배율)를 바꾸면 입력칸 전체가 그 비율대로 커진다 */
html.fixed-dpr #liveInput { font-size: calc(30px * var(--ui, 1)); }
/* 확정한 뒤 남아 있는 흐린 글자(안내 글자)는 예전처럼 옅은 그림자 */
#liveInput:placeholder-shown { text-shadow: 0 1px 6px rgba(6, 40, 88, .45); }
/* 제출한 뒤 남는 글자: 흰색 불투명도 .4, 그림자 없음 (색은 app.js 의 --ph — 2초 뒤 0 으로 서서히 사라진다) */
#liveInput.committed::placeholder { text-shadow: none; transition: color .5s ease; }
#liveInput::placeholder { color: var(--ph, rgba(var(--ink), .5)); }

/* 입력 중 바닥 그늘: 입력칸에 포커스가 가면 화면 아래부터 입력칸 위까지 검은 그라디언트가 서서히 깔린다 (높이는 app.js 가 입력칸에 맞춘다) */
#veil { position: fixed; left: 0; right: 0; bottom: 0; height: var(--veil-h, 30vh); z-index: 3; pointer-events: none; opacity: 0;
  background: linear-gradient(to top, rgba(0, 0, 0, .62) 0%, rgba(0, 0, 0, .42) 45%, rgba(0, 0, 0, 0) 100%); transition: opacity .45s ease; }
body.typing #veil { opacity: 1; }

/* 오른쪽 아래 저작권 표시(lib/credit.js): 입력하는 동안은 서서히 숨긴다 — 화면에 따라 입력칸 자리와 겹쳐 긴 글이 그 위로 지나가므로 */
#fh-credit { transition: opacity .45s ease; }
body.inputting #fh-credit { opacity: 0; }

/* 오른쪽 위 i 단추 ↔ X (열려 있으면 X) */
#infoBtn { position: fixed; z-index: 20; top: max(14px, env(safe-area-inset-top)); right: max(14px, env(safe-area-inset-right)); width: 38px; height: 38px; padding: 0; border-radius: 50%;
  border: 1.5px solid rgba(255, 255, 255, .85); background: rgba(0, 22, 55, .22); color: #fff; cursor: pointer; -webkit-tap-highlight-color: transparent;
  box-shadow: 0 1px 6px rgba(0, 22, 55, .3); transition: background .25s ease, border-color .25s ease; }
#infoBtn:hover { background: rgba(0, 22, 55, .4); }
#infoBtn:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
#infoBtn svg { position: absolute; left: 50%; top: 50%; width: 22px; height: 22px; margin: -11px 0 0 -11px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; transition: opacity .25s ease, transform .3s ease; }
#infoBtn .ic-i circle { fill: currentColor; stroke: none; }
#infoBtn .ic-x { opacity: 0; transform: rotate(-45deg); }
body.info-open #infoBtn { border-color: rgba(255, 255, 255, .6); background: transparent; box-shadow: none; }
body.info-open #infoBtn .ic-i { opacity: 0; transform: rotate(45deg); }
body.info-open #infoBtn .ic-x { opacity: 1; transform: none; }

/* 설명 막: 검은 반투명이 화면을 덮고 가운데에 설명·크레딧 */
#info { position: fixed; inset: 0; z-index: 15; display: flex; align-items: center; justify-content: center; overflow-y: auto;
  padding: max(64px, env(safe-area-inset-top)) max(24px, env(safe-area-inset-right)) max(40px, env(safe-area-inset-bottom)) max(24px, env(safe-area-inset-left));
  background: rgba(0, 0, 0, .62); color: #fff; opacity: 0; visibility: hidden; transition: opacity .35s ease, visibility 0s linear .35s; }
body.info-open #info { opacity: 1; visibility: visible; transition: opacity .35s ease, visibility 0s; }
#info .panel { max-width: 520px; margin: auto; word-break: keep-all; overflow-wrap: break-word; font: 400 15px/1.7 -apple-system, system-ui, "Apple SD Gothic Neo", "Noto Sans KR", sans-serif; transform: translateY(8px); transition: transform .45s cubic-bezier(.2, .7, .2, 1); }
body.info-open #info .panel { transform: none; }
#info h1 { margin: 0 0 12px; font-size: 24px; font-weight: 600; letter-spacing: .01em; }
#info .lead { margin: 0 0 22px; color: rgba(255, 255, 255, .92); }
/* 인스타그램: 눈에 띄는 둥근 단추 */
#info .insta { display: inline-flex; align-items: center; gap: 9px; margin: 0 0 28px; padding: 9px 18px 9px 14px; border-radius: 999px;
  border: 1.5px solid rgba(255, 255, 255, .85); color: #fff; text-decoration: none; font-size: 15px; font-weight: 600; letter-spacing: .01em;
  transition: background .2s ease, color .2s ease; }
#info .insta:hover { background: #fff; color: #10131a; }
#info .insta:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
#info .insta svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.9; }
#info .insta svg .dot { fill: currentColor; stroke: none; }
#info .credits { border-top: 1px solid rgba(255, 255, 255, .2); padding-top: 14px; color: rgba(255, 255, 255, .6); font-size: 12.5px; line-height: 1.6; }
#info .credits p { margin: 0 0 4px; }
#info a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
/* 열려 있는 동안 입력칸 · 안내 상자 · 아래 그늘 · 오른쪽 아래 저작권은 숨긴다 (visibility 로 숨겨 포커스도 안 간다) */
#live { transition: bottom .2s ease, opacity .3s ease, visibility 0s linear 0s; }
body.info-open #live { opacity: 0; visibility: hidden; transition: bottom .2s ease, opacity .3s ease, visibility 0s linear .3s; }
body.info-open .fh-intro-bg, body.info-open #veil, body.info-open #fh-credit { opacity: 0 !important; }

/* 처음 불러오는 동안 (#boot): 바다색 단색 바탕 + 오른쪽 위로 무리 지어 나는 새들. 첫 프레임이 그려지면(body.ready) 서서히 걷힌다 */
#boot { position: fixed; inset: 0; z-index: 30; display: flex; align-items: center; justify-content: center; pointer-events: none;
  background: #1c60aa; transition: opacity .9s ease, visibility 0s linear .9s; }
body.ready #boot { opacity: 0; visibility: hidden; }
#boot { --um: 1vmin; --ut: 1vmax; overflow: hidden; }
#boot svg { position: relative; width: min(46vw, 250px); height: auto; overflow: visible; }
/* 구름: 새가 나아가는 반대쪽(왼쪽 아래)으로 끝없이 흘러간다 → 무리가 앞으로 나아가는 느낌. 구름 이미지는 바다 셰이더의 구름을 그대로 뽑은 것 (tools/cloud-sprites.html)
   --um: 크기 단위(짧은 변 1%), --ut: 이동 단위(긴 변 1%). 이미지 1px = 작품 2px 이라 짧은 변 1080 기준으로 맞춘다 */
#boot .clouds { position: absolute; inset: 0; overflow: hidden; }
#boot .clouds img { position: absolute; left: 50%; top: 50%; width: calc(var(--w) * .185 * var(--um)); transform: translate(-50%, -50%);
  animation: boot-cloud var(--dur) linear var(--del) infinite; }
@keyframes boot-cloud {
  from { translate: calc((var(--o) + 70) * var(--ut)) calc((var(--o) - 70) * var(--ut)); }
  to   { translate: calc((var(--o) - 70) * var(--ut)) calc((var(--o) + 70) * var(--ut)); } }
/* 작품 속 새(lib/flock-core.js 헤엄)와 같은 움직임:
   날개 각 = sin(phase) × FLAP_AMP — 큰 모듈 기준 ±18°. 빠르기는 작품(한쪽 0.19~0.29초)보다 느긋하게 한쪽 0.40~0.52초 (새마다 다름)
   날갯짓에 맞춰 앞으로 밀려 나간다 (pos += vel × (1 + 0.25·sin(phase))), 방향은 무리를 따라 천천히 조금씩 흔들린다 */
#boot path { fill: none; stroke: #fff; stroke-width: 2.3; stroke-linecap: round; transform-origin: 0 0;
  animation: var(--t, .24s) cubic-bezier(.37, 0, .63, 1) var(--d, 0s) infinite alternate; }
#boot path.wl { animation-name: boot-wl; } #boot path.wr { animation-name: boot-wr; }
#boot .sh { opacity: .22; } #boot .sh path { stroke: rgb(6, 40, 88); stroke-width: 2.9; }   /* 선은 불투명하게, 투명도는 그림자 묶음에 한 번만 → 날개가 만나는 곳·겹치는 곳이 더 진해지지 않는다 */   /* 새 그림자 (lib/flock-shadow.js 의 높이 나는 새와 같은 거리·색) — 모든 새보다 아래에 */
#boot .surge { animation: boot-surge var(--t, .24s) cubic-bezier(.37, 0, .63, 1) var(--d, 0s) infinite alternate; }
#boot .sway { transform-origin: 0 0; animation: boot-sway 3.4s ease-in-out infinite alternate; }
@keyframes boot-wl { from { transform: rotate(18deg); } to { transform: rotate(-18deg); } }
@keyframes boot-wr { from { transform: rotate(-18deg); } to { transform: rotate(18deg); } }
@keyframes boot-surge { from { transform: translateY(-.8px); } to { transform: translateY(.8px); } }
@keyframes boot-sway { from { transform: rotate(-3deg) translate(-.6px, .6px); } to { transform: rotate(3deg) translate(.6px, -.6px); } }
@media (prefers-reduced-motion: reduce) { #boot path, #boot .surge, #boot .sway, #boot .clouds img { animation: none; } }
/* 그래픽이 뜨기 전에는 입력칸 · 안내 상자 · i 단추 · 저작권을 숨겼다가 함께 나타낸다 */
#infoBtn { transition: background .25s ease, border-color .25s ease, opacity .6s ease .2s; }
body:not(.ready) #live, body:not(.ready) #infoBtn { opacity: 0; pointer-events: none; }
body:not(.ready) .fh-intro-bg, body:not(.ready) #fh-credit { opacity: 0 !important; }

/* 처음 안내 상자(흰 둥근 바탕)는 lib/live-fx.js 가 그린다 */
@media (prefers-reduced-motion: reduce) { #live, #veil { transition: none; } }
