/* 발표회 참여 보드 공통 규격 — 세 화면(학부모·교실 TV·선생님)이 같이 쓴다.
   번역 보드(dnue-translate)의 테마 「따슴이 노랑」(2026-10-11)을 그대로 이어 쓴다. 같은 학교의 화면이라 한 얼굴로 보이게.
   색은 따슴이에서 뽑았다 — 몸 노랑 #F7D96B(바탕), 뿔 갈색 #5A3A1E(머리 막대),
   넥타이 초록 #008738(누르는 것·켜진 것·응원. 교표 초록과 같다), 코 빨강 #C33F2A(「지금 발표」 한 곳에만 — --now).
   누르는 것에 빨강을 쓰지 않는다: 오류가 빨강(--danger)이라 겹친다.
   글자 크기는 --t0~--t5, 간격은 --s1~--s7 계단만 쓴다. 손으로 잡은 값을 넣지 않는다. */
:root{
  --brand:#5A3A1E; --brand-ink:#FFFFFF; --brand-soft:#F3E7C4;
  --accent:#008738; --accent-ink:#FFFFFF; --accent-soft:#DDF2E4; --accent-deep:#006B2C; --now:#C33F2A;
  --paper:#F7D96B; --card:#FFF9EC; --ink:#2B2622; --sub:#4A3F33; --mute:#655848; --line:#DDCFA9;
  --warn:#9A5B00; --warn-soft:#FFF1D6; --danger:#B3261E; --danger-soft:#FBE3E1;
  --t0:11px; --t1:13px; --t2:15px; --t3:20px; --t4:28px; --t5:36px;
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px; --s6:32px; --s7:48px;
  --r1:8px; --r2:14px; --r3:20px; --pill:999px;
  --shadow:0 1px 2px rgba(90,58,30,.12), 0 4px 12px rgba(90,58,30,.10);
  --font:system-ui,-apple-system,"Segoe UI",Roboto,"Noto Sans","Apple SD Gothic Neo","Malgun Gothic",sans-serif;
  color-scheme:light;
}
:root[data-theme=dark]{
  --brand:#2B1C0E; --brand-soft:#3A2A1A;
  --accent:#3CCB7F; --accent-ink:#06210F; --accent-soft:#143524; --accent-deep:#5BD894; --now:#FF8A6B;
  --paper:#1F1710; --card:#2E2318; --ink:#F6EFE2; --sub:#D2C6B4; --mute:#A89B88; --line:#46382A;
  --warn:#F2B84B; --warn-soft:#3A2E12; --danger:#FF8A80; --danger-soft:#42191A;
  --shadow:0 1px 2px rgba(0,0,0,.4), 0 4px 12px rgba(0,0,0,.3);
  color-scheme:dark;
}
*{box-sizing:border-box}
html,body{height:100%}
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--font);font-size:var(--t2);line-height:1.5;
  -webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}
button,input,textarea,select{font:inherit;color:inherit}
button{cursor:pointer}
[hidden]{display:none !important}
[lang=ko],:lang(ko){word-break:keep-all}
p,h1,h2,h3{margin:0}
/* 옛 사파리(아이폰)는 color-mix·dvh·overflow-wrap:anywhere 를 모른다 — 앞줄에 대체 값을 먼저 적는다 */
::selection{background:var(--accent-soft);color:var(--ink)}
:focus-visible{outline:3px solid var(--accent);outline-offset:2px;border-radius:var(--r1)}
input,textarea{caret-color:var(--accent)}

/* ---------- 머리 막대: 교표 + 제목 + 상태 ---------- */
.appbar{display:flex;align-items:center;gap:var(--s3);padding:var(--s2) var(--s4);padding-top:max(var(--s2),env(safe-area-inset-top));
  background:var(--brand);color:var(--brand-ink)}
.appbar .crest{width:36px;height:36px;flex:none;border-radius:50%;background:#fff;padding:3px;object-fit:contain}
.appbar h1{flex:1;min-width:0;font-size:var(--t2);font-weight:700;line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.appbar h1 small{display:block;font-size:var(--t0);font-weight:400;opacity:.8;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* 상태 알약: 색 + 점 모양 + 글자 셋으로 말한다 */
.state{display:inline-flex;align-items:center;gap:var(--s2);max-width:46vw;padding:var(--s1) var(--s3);border-radius:var(--pill);
  background:rgba(255,255,255,.14);color:#fff;font-size:var(--t1);line-height:1.4;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.state::before{content:"";flex:none;width:8px;height:8px;border-radius:50%;background:#F2B84B}
.state[data-state=ok]::before{background:#5BE39A}
.state[data-state=bad]{background:#fff;color:var(--danger);font-weight:700}
.state[data-state=bad]::before{background:var(--danger);border-radius:2px}

/* ---------- 단추 ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--s2);min-height:44px;padding:var(--s2) var(--s4);
  border:1px solid var(--line);border-radius:var(--r2);background:var(--card);color:var(--ink);font-weight:500;white-space:nowrap}
a.btn{text-decoration:none}
.btn:active{transform:translateY(1px)}
.btn.primary{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);font-weight:700}
.btn.quiet{background:transparent;border-color:transparent;color:var(--sub)}
.btn.danger{color:var(--danger);border-color:var(--danger)}
.btn:disabled{opacity:.5;cursor:default}
.btn svg{width:20px;height:20px;flex:none}

/* ---------- 아래에서 올라오는 판 ---------- */
.sheet{position:fixed;inset:0;z-index:20;display:flex;flex-direction:column;justify-content:flex-end;background:rgba(43,28,14,.5)}
.sheet>.panel{width:100%;max-width:560px;margin:0 auto;max-height:88vh;max-height:88dvh;overflow-y:auto;background:var(--card);color:var(--ink);
  border-radius:var(--r3) var(--r3) 0 0;padding:var(--s2) var(--s4) max(var(--s4),env(safe-area-inset-bottom));
  display:flex;flex-direction:column;gap:var(--s3);box-shadow:0 -8px 32px rgba(43,28,14,.25);animation:sheet-up .18s ease-out}
.sheet .grip{align-self:center;width:36px;height:4px;border-radius:var(--pill);background:var(--line)}
.sheet h2{font-size:var(--t3);line-height:1.3}
.sheet .label{font-size:var(--t1);font-weight:700;color:var(--sub);margin-top:var(--s2)}
.sheet .hint{font-size:var(--t1);color:var(--mute)}
@keyframes sheet-up{from{transform:translateY(24px);opacity:0}to{transform:none;opacity:1}}

/* 고르는 줄: 켜짐은 색 + 체크 표시 + 굵기 */
.pick{display:flex;gap:var(--s2)}
.pick button{flex:1;min-width:0;min-height:48px;padding:var(--s2) var(--s1);white-space:nowrap;border:1.5px solid var(--line);border-radius:var(--r2);background:var(--card);color:var(--sub);
  display:flex;align-items:center;justify-content:center;gap:var(--s1);font-size:var(--t2)}
.pick button[aria-pressed=true],.pick button[aria-checked=true]{border-color:var(--accent);background:var(--accent-soft);color:var(--ink);font-weight:700}
.pick button[aria-pressed=true]::before,.pick button[aria-checked=true]::before{content:"";flex:none;width:12px;height:7px;margin-top:-4px;
  border-left:2.5px solid var(--accent-deep);border-bottom:2.5px solid var(--accent-deep);transform:rotate(-45deg)}

.field{width:100%;min-height:48px;padding:var(--s3) var(--s4);border:1.5px solid var(--line);border-radius:var(--r2);background:var(--card);font-size:16px}
.field:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
textarea.field{min-height:112px;resize:none;line-height:1.5}

/* ---------- 대화방 바탕 무늬(코덱스로 구운 선 그림을 화면 색으로 다시 입힌 것) ---------- */
.wall{background-image:url(/img/wall-light.png);background-size:360px 360px}
:root[data-theme=dark] .wall{background-image:url(/img/wall-dark.png)}

/* ---------- 말풍선 ---------- */
.bubble{background:var(--card);border-radius:var(--s1) var(--r3) var(--r3) var(--r3);padding:var(--s3) var(--s4);box-shadow:var(--shadow);overflow-wrap:break-word;overflow-wrap:anywhere}
.bubble.mine{background:var(--accent);color:var(--accent-ink);border-radius:var(--r3) var(--s1) var(--r3) var(--r3);box-shadow:none}
.dots{display:inline-flex;gap:var(--s1);align-items:center}
.dots i{width:8px;height:8px;border-radius:50%;background:var(--accent);animation:dot 1.2s infinite ease-in-out}
.dots i:nth-child(2){animation-delay:.15s}
.dots i:nth-child(3){animation-delay:.3s}
@keyframes dot{0%,60%,100%{transform:none;opacity:.35}30%{transform:translateY(-4px);opacity:1}}
@keyframes pop{from{transform:translateY(8px);opacity:0}to{transform:none;opacity:1}}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none !important;transition:none !important}
}

/* ================= 발표회 보드에만 있는 것 ================= */
.num{font-variant-numeric:tabular-nums}

/* 반 고르기: 학년 한 줄에 반 단추 셋. 이름표(학년)는 고정 폭 열 */
.classgrid{display:grid;gap:var(--s2)}
.classgrid .row{display:grid;grid-template-columns:72px repeat(3,1fr);gap:var(--s2);align-items:center}
.classgrid .row>b{font-size:var(--t2);color:var(--ink);white-space:nowrap}
.classgrid button{min-height:52px;border:1.5px solid var(--line);border-radius:var(--r2);background:var(--card);font-size:var(--t2);font-weight:700;color:var(--ink)}
.classgrid button:hover{border-color:var(--accent)}
.classgrid button[aria-current=true]{border-color:var(--accent);background:var(--accent-soft)}

/* 글의 갈래: 색 + 글자(응원/질문) 둘로 말한다 */
.tag{display:inline-flex;align-items:center;gap:var(--s1);padding:2px var(--s2);border-radius:var(--pill);font-size:var(--t0);font-weight:700;line-height:1.5;white-space:nowrap}
.tag.cheer{background:var(--accent-soft);color:var(--accent-deep)}
.tag.ask{background:var(--brand-soft);color:var(--brand)}
.tag.mine{background:var(--accent);color:var(--accent-ink)}
.tag.off{background:var(--danger-soft);color:var(--danger)}
.tag.now{background:var(--now);color:#fff}

/* 「지금 발표」 점: 빨간 점이 숨 쉬듯 — 움직임 줄이기를 켜면 멈춘다 */
.live{display:inline-flex;align-items:center;gap:var(--s2);font-weight:700;color:var(--now)}
.live::before{content:"";width:10px;height:10px;border-radius:50%;background:var(--now);animation:breathe 1.6s infinite ease-in-out}
@keyframes breathe{0%,100%{box-shadow:0 0 0 0 rgba(195,63,42,.45)}50%{box-shadow:0 0 0 6px rgba(195,63,42,0)}}

/* 글 한 건. 들어올 때 위치만 움직인다 — 투명도까지 움직이면 그리기가 늦은 화면에서 흐린 채로 멈춘다 */
@keyframes rise{from{transform:translateY(8px)}to{transform:none}}
.post{background:var(--card);border-radius:var(--r2);padding:var(--s3) var(--s4);box-shadow:var(--shadow);animation:rise .2s ease-out;
  overflow-wrap:break-word;overflow-wrap:anywhere;word-break:keep-all}
.post p{font-size:var(--t2);line-height:1.6;text-wrap:pretty;white-space:pre-wrap}
.post .meta{display:flex;align-items:center;gap:var(--s2);margin-bottom:var(--s1);font-size:var(--t1);color:var(--sub)}
.post .meta time{margin-left:auto;font-size:var(--t0);color:var(--mute)}
.post.ask{border-left:4px solid var(--brand)}
.post.mine{box-shadow:var(--shadow),0 0 0 2px var(--accent)}
.post.hidden{opacity:.55;box-shadow:none;border:1.5px dashed var(--line);background:transparent}

/* 박수 터지는 손: 누른 자리에서 위로 떠오르며 사라진다 */
.burst{position:fixed;z-index:30;pointer-events:none;font-size:28px;animation:float-up .9s ease-out forwards}
@keyframes float-up{from{transform:translate(-50%,-50%) scale(.8);opacity:1}to{transform:translate(-50%,-160%) scale(1.3);opacity:0}}
@keyframes bump{0%{transform:scale(1)}40%{transform:scale(1.18)}100%{transform:scale(1)}}
.bump{animation:bump .35s ease-out}

/* ================= 움직임(motion.js 와 짝) — 아이폰처럼 절제 =================
   곡선은 둘뿐: --spring(살짝 넘었다 멈춤: 누름·튕김) · --ios(판·화면 넘김). 시간은 0.2~0.45초. */
:root{--ios:cubic-bezier(.32,.72,0,1);--spring:cubic-bezier(.32,.72,0,1)}
@supports (transition-timing-function:linear(0,1)){
  :root{--spring:linear(0, 0.06 2%, 0.23 5%, 0.48 9%, 0.71 13.5%, 0.87 18%, 0.97 23%, 1.02 28%, 1.035 33%, 1.03 39%, 1.01 50%, 0.998 62%, 1)}
}

/* 누르는 것: 눌리면 살짝 작아졌다가 튕겨 돌아온다(색만 바꾸지 않고 모양으로도 답한다) */
.btn,.pick button,.classgrid button,.tlist button,.filter button{transition:transform .32s var(--spring),background-color .2s,border-color .2s,box-shadow .2s}
.btn:active,.pick button:active,.classgrid button:active,.tlist button:active,.filter button:active{transform:scale(.96);transition-duration:.08s}

/* 굴러가는 숫자 */
.odo-d{display:inline-block;height:1.15em;overflow:hidden;vertical-align:top;line-height:1.15em}
.odo-s{display:flex;flex-direction:column;transition:transform .6s var(--spring)}
.odo-s i{display:block;height:1.15em;font-style:normal;text-align:center}
.odo-c{display:inline-block;line-height:1.15em}

/* 튀는 조각 */
.chip-fly{position:fixed;z-index:40;pointer-events:none;line-height:1;will-change:transform,opacity}

/* 알림 띠: 화면 위 가운데의 검은 알약. 내려오며 커지고, ✓ 가 그려진다(다이내믹 아일랜드처럼) */
.island{position:fixed;left:50%;top:calc(env(safe-area-inset-top) + 10px);z-index:50;display:flex;align-items:center;gap:var(--s2);
  max-width:calc(100vw - 32px);padding:10px 18px 10px 14px;border-radius:var(--pill);background:#1C1A17;color:#fff;font-size:var(--t2);font-weight:600;
  box-shadow:0 10px 30px rgba(0,0,0,.25);transform:translate(-50%,-140%) scale(.6);opacity:0;pointer-events:none;
  transition:transform .5s var(--spring),opacity .25s}
.island.show{transform:translate(-50%,0) scale(1);opacity:1}
.island svg{width:22px;height:22px;flex:none}
.island .check{fill:none;stroke:#5BE39A;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:24;stroke-dashoffset:24}
.island.show .check{animation:draw .45s .18s var(--ios) forwards}
@keyframes draw{to{stroke-dashoffset:0}}
.island .ring{width:18px;height:18px;flex:none;border-radius:50%;border:2.5px solid rgba(255,255,255,.25);border-top-color:#fff;animation:spin .8s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.island .bang{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;background:#FF8A6B;color:#1C1A17;font-size:13px}

/* 새로 들어온 글: 초록 테두리가 한 번 빛났다가 사라진다 */
.post.just{animation:glow 1.6s ease-out}
@keyframes glow{0%{box-shadow:var(--shadow),0 0 0 3px var(--accent)}100%{box-shadow:var(--shadow),0 0 0 0 transparent}}
.post.mine.just{animation:none}

/* 자리 잡기 상자(불러오는 동안) */
.skel{position:relative;overflow:hidden;background:var(--card);border-radius:var(--r2);box-shadow:var(--shadow)}
.skel i{display:block;height:12px;margin:var(--s3) var(--s4);border-radius:6px;background:var(--brand-soft)}
.skel i:nth-child(2){width:70%}
.skel i:nth-child(3){width:45%}
.skel::after{content:"";position:absolute;inset:0;background:linear-gradient(100deg,transparent 30%,rgba(255,255,255,.6) 50%,transparent 70%);
  transform:translateX(-100%);animation:shimmer 1.4s infinite}
@keyframes shimmer{to{transform:translateX(100%)}}

/* 쉬는 동안 숨 쉬는 따슴이(빈 화면) */
.breath{animation:breath 3.2s ease-in-out infinite;transform-origin:50% 100%}
@keyframes breath{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-4px) scale(1.015)}}
