:root{
  --sky:#EAF4FA; --paper:#FEFBF2; --white:#FFFFFF;
  --ink:#4A3F35; --ink-soft:#8A7B6C; --ink-faint:#B3A697;
  --red:#E0563F; --green:#4E9A4E; --blue:#3D7FD1; --yellow:#F5C542; --orange:#E9A13B;
  --yellow-soft:#FDEEBF;
  --line:#EDE4D3;
  --card-shadow:0 2px 0 rgba(74,63,53,.06);
  --sans:"Pretendard","Apple SD Gothic Neo","Malgun Gothic",system-ui,sans-serif;
  --disp:"Jua",var(--sans);
  --mono:"IBM Plex Mono",ui-monospace,monospace;
  --maxw:1480px;
  --ease:180ms ease;
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:linear-gradient(180deg,var(--sky) 0,var(--paper) 320px);background-attachment:fixed;color:var(--ink);font-family:var(--sans);line-height:1.5;word-break:keep-all;-webkit-font-smoothing:antialiased}
h1,h2,h3,h4{font-family:var(--disp);font-weight:400;margin:0;line-height:1.2;letter-spacing:0}
p{margin:0}
a{color:inherit}
button{font-family:var(--sans);cursor:pointer}
img{max-width:100%;display:block}
.boot{padding:80px 20px;text-align:center;color:var(--ink-soft)}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 clamp(16px,3.5vw,28px)}
.mono{font-family:var(--mono)}
.hidden{display:none!important}

/* ===== 숫자 배지 (포스터의 1~6) ===== */
.nr-num,.gnum{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;flex:none;border-radius:14px;background:var(--c,var(--red));color:#fff;font-family:var(--disp);font-size:1.45rem;line-height:1;box-shadow:inset 0 -3px 0 rgba(0,0,0,.14)}
.gnum{width:26px;height:26px;border-radius:8px;font-size:.9rem}

/* ===== 헤더 ===== */
.bar{position:sticky;top:0;z-index:20;background:rgba(255,255,255,.94);border-bottom:2px solid var(--line)}
.barin{display:flex;align-items:center;justify-content:space-between;gap:14px;min-height:56px;padding:8px clamp(16px,3.5vw,28px)}
.brand{font-family:var(--disp);font-size:1.22rem;text-decoration:none;white-space:nowrap}
.brand .b1{color:var(--red)}
.brand .b2{color:var(--green)}
.bnav{display:flex;align-items:center;gap:16px;font-size:.82rem;color:var(--ink-soft)}
.backlink{display:inline-flex;align-items:center;gap:5px;background:var(--green);color:#fff;text-decoration:none;font-weight:700;font-size:.88rem;border-radius:12px;padding:8px 16px;box-shadow:inset 0 -2px 0 rgba(0,0,0,.14)}
.backlink:hover{filter:brightness(1.06)}
.subline{color:var(--ink-soft)}
.live{display:inline-flex;align-items:center;gap:5px;font-weight:600;font-size:.76rem;color:var(--green)}
.live i{width:7px;height:7px;border-radius:50%;background:var(--green);display:inline-block;animation:pulse 2s infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.35}}
.navlink{color:var(--ink);text-decoration:none;font-weight:600;background:var(--white);border:2px solid var(--line);border-radius:10px;padding:5px 12px}
.navlink:hover{border-color:var(--ink-faint)}
@media(max-width:560px){.bnav{gap:10px}.subline{display:none}.brand{font-size:1.05rem}}

section.view{padding:clamp(20px,3.5vw,32px) 0 56px}

/* ===== 히어로 ===== */
.hero{padding:clamp(26px,5vw,48px) 0 clamp(10px,2vw,16px);text-align:center}
.hero h1{font-size:clamp(1.7rem,5vw,2.9rem);text-wrap:balance}
.hero .hb{color:var(--red)}
.hero .hg{color:var(--blue)}
.hero .hr{color:var(--green)}
.heropill{display:inline-block;margin-top:14px;background:var(--yellow-soft);border:2px solid var(--yellow);border-radius:999px;padding:7px 18px;font-size:.88rem;font-weight:600;color:var(--ink)}
.heropill b{font-weight:800}

/* ===== 정림 마을 ===== */
.village{margin-top:16px;background:var(--white);border:2px solid var(--line);border-radius:16px;padding:12px 12px 12px;box-shadow:var(--card-shadow)}
.vhead{display:flex;align-items:center;gap:10px;padding:2px 4px 10px;flex-wrap:wrap}
.vhead .sectitle{margin-bottom:0}
.vsub{font-size:.8rem;color:var(--ink-soft);flex:1}
.vpct{font-family:var(--disp);font-size:1.4rem;color:var(--orange)}
.vpreview{border:2px solid var(--orange);background:var(--white);color:var(--orange);border-radius:999px;padding:5px 14px;font-weight:700;font-size:.78rem;transition:background var(--ease),color var(--ease)}
.vpreview.on{background:var(--orange);color:#fff}
.vsvg{width:100%;height:auto;display:block;border-radius:12px}
.vtxt{font-family:var(--disp)}
.vi{opacity:0;transform:scale(.2);transform-origin:center bottom;transform-box:fill-box;transition:transform .6s cubic-bezier(.34,1.56,.64,1),opacity .35s ease}
.vi.on{opacity:1;transform:scale(1)}
.wmblades{transform-box:fill-box;transform-origin:0 -14px;animation:vspin 14s linear infinite}
@keyframes vspin{to{transform:rotate(360deg)}}
/* 살아있는 마을 — 잔잔한 배경 애니메이션 */
.vsway{transform-box:fill-box;transform-origin:center bottom;animation:vsway 5s ease-in-out infinite alternate}
@keyframes vsway{from{transform:rotate(-1.6deg)}to{transform:rotate(1.8deg)}}
.vsmoke .sp{fill:#FFFFFF;opacity:0;transform-box:fill-box}
.vsmoke .s1{animation:vsm 3.4s linear infinite}
.vsmoke .s2{animation:vsm 3.4s linear infinite 1.15s}
.vsmoke .s3{animation:vsm 3.4s linear infinite 2.3s}
@keyframes vsm{0%{transform:translate(0,0) scale(.6);opacity:.7}100%{transform:translate(7px,-32px) scale(1.6);opacity:0}}
.vflut{transform-box:fill-box;transform-origin:left center;animation:vflut 1.5s ease-in-out infinite alternate}
@keyframes vflut{from{transform:skewY(-4deg) scaleX(.96)}to{transform:skewY(5deg) scaleX(1.03)}}
.vrays{transform-box:fill-box;transform-origin:center;animation:vspin 46s linear infinite}
.vcloud1{animation:vdrift 26s ease-in-out infinite alternate}
.vcloud2{animation:vdrift 34s ease-in-out infinite alternate-reverse}
.vcloud3{animation:vdrift 30s ease-in-out infinite alternate}
@keyframes vdrift{from{transform:translateX(-14px)}to{transform:translateX(18px)}}
.vballoon{animation:vfloat 4.5s ease-in-out infinite alternate}
@keyframes vfloat{from{transform:translateY(0)}to{transform:translateY(-12px)}}
.vballoonx{animation:vdriftx 44s ease-in-out infinite alternate}
@keyframes vdriftx{from{transform:translateX(0)}to{transform:translateX(70px)}}
.vbirds{animation:vfly 38s linear infinite}
@keyframes vfly{0%{transform:translate(-80px,96px);opacity:0}6%{opacity:1}94%{opacity:1}100%{transform:translate(1040px,52px);opacity:0}}
.vwalk.w1{animation:vw1 42s linear infinite}
@keyframes vw1{0%{transform:translate(80px,368px);opacity:0}4%{opacity:1}96%{opacity:1}100%{transform:translate(900px,350px);opacity:0}}
.vwalk.w2{animation:vw2 56s linear infinite 8s;opacity:0}
@keyframes vw2{0%{transform:translate(910px,350px) scaleX(-1);opacity:0}4%{opacity:1}96%{opacity:1}100%{transform:translate(100px,367px) scaleX(-1);opacity:0}}
.vbob{transform-box:fill-box;transform-origin:center bottom;animation:vbob .5s ease-in-out infinite alternate}
@keyframes vbob{from{transform:translateY(0) rotate(-2deg)}to{transform:translateY(-1.8px) rotate(2deg)}}
.vglint{opacity:0;animation:vblink 2.6s infinite}
.vglint.g2{animation-delay:1.2s}
@keyframes vblink{0%,55%,100%{opacity:0}68%,84%{opacity:.95}}
.vglow{animation:vglow 2s ease-in-out infinite alternate}
.vglow.w2{animation-delay:.5s}.vglow.w3{animation-delay:1s}
@keyframes vglow{from{opacity:.45}to{opacity:1}}
.vstar{transform-box:fill-box;transform-origin:center;animation:vtwinkle 2.2s ease-in-out infinite}
.vstar.st2{animation-delay:.7s}.vstar.st3{animation-delay:1.4s}
@keyframes vtwinkle{0%,100%{opacity:.25;transform:scale(.7)}50%{opacity:1;transform:scale(1.15)}}
.vballoonx2{animation:vdriftx 52s ease-in-out infinite alternate-reverse}
.vwings{transform-box:fill-box;transform-origin:center;animation:vflap .34s ease-in-out infinite alternate}
@keyframes vflap{from{transform:scaleX(1)}to{transform:scaleX(.35)}}
.vbfly.bf1{animation:vbf1 20s ease-in-out infinite}
@keyframes vbf1{0%{transform:translate(180px,296px)}25%{transform:translate(300px,258px)}50%{transform:translate(470px,300px)}75%{transform:translate(340px,246px)}100%{transform:translate(180px,296px)}}
.vbfly.bf2{animation:vbf2 24s ease-in-out infinite}
@keyframes vbf2{0%{transform:translate(830px,270px)}30%{transform:translate(730px,240px)}55%{transform:translate(880px,290px)}80%{transform:translate(920px,250px)}100%{transform:translate(830px,270px)}}
#vfw{opacity:0;pointer-events:none;transition:opacity .4s}
#vfw.on{opacity:1}
.fwb{transform-box:fill-box;transform-origin:center;transform:scale(0)}
#vfw.on .fwb{animation:fwb 1.6s ease-out infinite}
#vfw.on .fwb.d1{animation-delay:.45s}
#vfw.on .fwb.d2{animation-delay:.9s}
@keyframes fwb{0%{transform:scale(.1);opacity:0}25%{opacity:1}75%{transform:scale(1);opacity:.9}100%{transform:scale(1.2);opacity:0}}
.vlegend{display:flex;flex-wrap:wrap;gap:8px;align-items:center;padding:10px 4px 2px}
.vchip{display:inline-flex;align-items:center;gap:6px;border:2px solid var(--line);border-radius:999px;padding:4px 12px;font-size:.78rem;font-weight:700;text-decoration:none;color:var(--ink);background:var(--white);transition:border-color var(--ease)}
.vchip:hover{border-color:var(--c)}
.vchip i{width:9px;height:9px;border-radius:50%;background:var(--c)}
.vnext{margin-left:auto;font-size:.76rem;color:var(--ink-soft)}
@media(max-width:640px){.vnext{margin-left:0;width:100%}}
.vconfetti{position:fixed;inset:0;pointer-events:none;z-index:70;overflow:hidden}
.vconfetti i{position:absolute;top:-16px;width:9px;height:14px;border-radius:2px;animation:vfall linear forwards}
@keyframes vfall{to{transform:translateY(106vh) rotate(560deg)}}
/* 학생별 기여(내가 세운 것) */
.vcontrib{background:var(--white);border:2px solid var(--line);border-radius:16px;padding:16px 18px;margin-bottom:22px;box-shadow:var(--card-shadow)}
.vcontrib .ch2{display:flex;align-items:baseline;gap:8px;margin-bottom:10px}
.vcontrib h2{font-size:1.05rem}
.vcontrib .cnt{font-size:.78rem;color:var(--ink-soft)}
.cchips{display:flex;flex-wrap:wrap;gap:8px}
.cchip{display:inline-flex;align-items:center;gap:6px;border:2px solid var(--line);border-radius:999px;padding:5px 13px;font-size:.8rem;font-weight:700;background:var(--white)}
.cchip i{width:9px;height:9px;border-radius:50%;background:var(--c,var(--green))}
.cchip small{font-weight:400;color:var(--ink-faint);font-size:.7rem}
.cchip.gold{background:#FFF4D6;border-color:#F2C94C;color:#8A6217}
.chint{margin-top:10px;font-size:.78rem;color:var(--ink-soft);line-height:1.6}

/* ===== 미션 배너 · 명예의 전당 · 학년 대항 ===== */
.toprow{display:grid;grid-template-columns:5fr 7fr;gap:14px;align-items:stretch;margin-top:14px}
.toprow .village{margin-top:0;min-width:0}
.campaignphoto{border-radius:20px;overflow:hidden;border:2px solid var(--line);box-shadow:var(--card-shadow);background:var(--white)}
.campaignphoto img{width:100%;height:100%;object-fit:cover;display:block}
@media(max-width:940px){.toprow{grid-template-columns:1fr}.campaignphoto{max-width:560px;margin:0 auto;width:100%}.campaignphoto img{height:auto}}
.photoslot{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;text-align:center;background:var(--white);border:2px dashed var(--line);border-radius:16px;padding:24px;min-height:170px}
.photoslot b{font-size:1rem;color:var(--ink)}
.photoslot span{font-size:.82rem;color:var(--ink-soft)}
.photoslot.tall{min-height:240px;margin-bottom:14px}
.photoslot.rules{max-width:520px;margin:0 auto}
.campaignphoto.photoslot{overflow:visible}
.missionbar{display:flex;align-items:center;gap:10px;background:#FFF4D6;border:2px solid #F2C94C;border-radius:14px;padding:12px 16px;margin-bottom:14px;font-size:.95rem}
.missionbar .mtag{flex:none;background:var(--yellow);color:#6B4E0E;border-radius:999px;padding:3px 12px;font-weight:800;font-size:.76rem}
.hallstrip{display:flex;align-items:center;gap:10px;flex-wrap:wrap;background:var(--white);border:2px solid var(--line);border-radius:14px;padding:10px 16px;margin-top:14px;font-size:.84rem}
.hallstrip .htag{background:var(--ink);color:#fff;border-radius:999px;padding:3px 12px;font-weight:700;font-size:.72rem}
.hallstrip .hseason{color:var(--ink-soft);font-weight:600}
.battlebar{display:flex;align-items:center;gap:6px;flex-wrap:wrap;background:#FFF4D6;border:1.5px solid #F2C94C;border-radius:10px;padding:7px 12px;margin-bottom:10px;font-size:.8rem;color:#6B4E0E}
.battlebar a{color:#8A6217;font-weight:700;text-decoration:none;margin-left:auto}

/* ===== 박수·알리기 ===== */
.pacts{display:flex;align-items:center;gap:8px;margin-top:6px}
.clapbtn{border:1.5px solid var(--line);background:var(--paper);border-radius:999px;padding:2px 10px;font-size:.76rem;font-weight:700;color:var(--ink);transition:transform .15s ease}
.clapbtn.pop{animation:clappop .35s ease}
@keyframes clappop{40%{transform:scale(1.25)}}
.pacts .tm{margin-top:0}
.repbtn{margin-left:auto;border:none;background:none;color:var(--ink-faint);font-size:.68rem;text-decoration:underline;padding:2px}

/* ===== 배지 · 실천 달력 · 공유 카드 ===== */
.sharebtn{margin-left:auto;border:2px solid var(--green);background:var(--white);color:var(--green);border-radius:12px;padding:9px 16px;font-weight:800;font-size:.84rem}
.sharebtn:hover{background:var(--green);color:#fff}
@media(max-width:560px){.phead{flex-wrap:wrap}.sharebtn{margin-left:0;width:100%}}
.bchip{display:inline-flex;flex-direction:column;gap:1px;border:2px solid var(--c,var(--line));border-radius:12px;padding:6px 12px;font-size:.82rem;font-weight:800;background:var(--white);color:var(--c,var(--ink))}
.bchip i{display:none}
.bchip small{font-weight:400;color:var(--ink-soft);font-size:.66rem}
.scal{display:flex;gap:3px;overflow-x:auto;padding:4px 0}
.scol{display:flex;flex-direction:column;gap:3px}
.scal i{width:13px;height:13px;border-radius:3px;background:#EFEAD9;flex:none}
.scal i.l1{background:#B9DCA4}.scal i.l2{background:#7FBE68}.scal i.l3{background:#3E8C48}.scal i.f{background:transparent;border:1px dashed var(--line)}

/* ===== 통계 ===== */
.statgrid{display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media(max-width:760px){.statgrid{grid-template-columns:1fr}}
.statgrid .vcontrib{margin-bottom:0}
.chart14{display:flex;align-items:flex-end;gap:4px;height:150px;padding-top:14px}
.chart14 .cbar{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;height:100%;gap:3px;min-width:0}
.chart14 .cbar i{width:100%;max-width:26px;height:var(--h);min-height:2px;background:var(--green);border-radius:5px 5px 0 0}
.chart14 .cbar b{font-size:.66rem;color:var(--ink-soft)}
.chart14 .cbar span{font-size:.6rem;color:var(--ink-faint);white-space:nowrap}
.chart14.wk .cbar i{background:var(--blue,#3D7FD1)}
.brow{display:flex;align-items:center;gap:10px;padding:7px 0;font-size:.86rem}
.brank{width:26px;height:26px;border-radius:50%;background:var(--paper);border:1.5px solid var(--line);display:grid;place-items:center;font-size:.74rem;font-weight:800;flex:none}
.brank.top{background:#FFF4D6;border-color:#F2C94C}
.bbar{flex:1;height:10px;border-radius:99px;background:var(--paper);overflow:hidden;min-width:60px}
.bbar i{display:block;height:100%;width:var(--w);background:var(--green);border-radius:99px}
.bnum{font-size:.74rem;color:var(--ink-soft);white-space:nowrap}

/* ===== TV 전시 모드 ===== */
body.tvmode{overflow:hidden}
body.tvmode .sitefoot{display:none}
.tv{position:fixed;inset:0;background:var(--paper);z-index:40}
.tvexit{position:absolute;top:14px;right:16px;z-index:45;color:var(--ink-faint);text-decoration:none;font-size:1.3rem;padding:8px}
.tvfull{position:absolute;top:16px;right:56px;z-index:45;border:1.5px solid var(--line);background:var(--white);border-radius:999px;padding:6px 14px;font-size:.78rem;font-weight:700;color:var(--ink-soft)}
.tvslide{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;padding:3vh 2vw;opacity:0;transition:opacity .8s ease;pointer-events:none}
.tvslide.cur{opacity:1;pointer-events:auto}
.tvtitle{font-family:var(--disp);font-size:clamp(1.8rem,4vw,3.2rem);color:var(--ink);text-align:center;line-height:1.15}
.tvtitle span{display:block;font-family:var(--sans);font-size:clamp(.9rem,1.7vw,1.25rem);color:var(--ink-soft);font-weight:600;margin-top:6px}
.tvslide #vmap{width:min(96vw,calc((100vh - 240px)*2.5),1860px)}
.tvslide #vmap svg{width:100%;height:auto;border-radius:20px}
.tvbig{font-size:clamp(1.2rem,2.6vw,2rem);color:var(--ink-soft)}
.tvbig b{font-family:var(--disp);color:var(--orange);font-size:1.3em}
.tvphotos{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;width:min(96vw,1720px)}
.tvphotos figure{margin:0;background:var(--white);border:2px solid var(--line);border-radius:18px;overflow:hidden;box-shadow:var(--card-shadow)}
.tvphotos img{width:100%;aspect-ratio:4/3;object-fit:cover}
.tvphotos figcaption{padding:12px 18px;font-size:clamp(.9rem,1.6vw,1.2rem)}
.tvboard{width:min(94vw,1500px);display:flex;flex-direction:column;gap:14px}
.tvrow{display:flex;align-items:center;gap:16px;background:var(--white);border:2px solid var(--line);border-radius:18px;padding:18px 28px;font-size:clamp(1.1rem,2.4vw,1.8rem)}
.tvrow.top{border-color:#F2C94C;background:#FFF9E6}
.tvrow .r{width:40px;text-align:center;font-weight:800}
.tvrow .n{margin-left:auto;color:var(--ink-soft);font-size:.8em}
.tvrow .bbar{height:14px}

/* ===== 결산 리포트 ===== */
.rpt{background:var(--white);border:2px solid var(--line);border-radius:18px;padding:clamp(20px,4vw,40px)}
.rpthead{display:flex;align-items:flex-start;gap:14px;flex-wrap:wrap;border-bottom:2px solid var(--line);padding-bottom:18px;margin-bottom:20px}
.rpthead h1{font-size:clamp(1.4rem,3.4vw,2rem)}
.rpthead p{color:var(--ink-soft);font-size:.88rem;margin-top:6px;width:100%}
.rpthead .btn{margin-left:auto}
.rptstats{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:24px}
@media(max-width:640px){.rptstats{grid-template-columns:1fr 1fr}}
.rptstats div{background:var(--paper);border-radius:14px;padding:16px;text-align:center}
.rptstats b{display:block;font-family:var(--disp);font-size:1.7rem;color:var(--green)}
.rptstats span{font-size:.76rem;color:var(--ink-soft)}
.rpt h2{font-size:1.05rem;margin:22px 0 8px}
@media print{
  .bar,.sitefoot,.noprint{display:none!important}
  body{background:#fff}
  .rpt{border:none}
  section.view{padding:0}
}

/* ===== 폰프리 선언문 ===== */
.declframe{position:relative;max-width:560px;margin:16px auto;background:#FFFDF6;border:3px double #C9A227;border-radius:6px;padding:clamp(26px,5vw,46px) clamp(20px,5vw,42px);box-shadow:0 6px 24px -12px rgba(120,90,20,.35)}
.declframe::before{content:"";position:absolute;inset:7px;border:1px solid #E2CC85;border-radius:3px;pointer-events:none}
.dcorner{position:absolute;width:26px;height:26px;border:2.5px solid #C9A227;pointer-events:none}
.dcorner.c1{top:-3px;left:-3px;border-right:none;border-bottom:none;border-radius:6px 0 0 0}
.dcorner.c2{top:-3px;right:-3px;border-left:none;border-bottom:none;border-radius:0 6px 0 0}
.dcorner.c3{bottom:-3px;left:-3px;border-right:none;border-top:none;border-radius:0 0 0 6px}
.dcorner.c4{bottom:-3px;right:-3px;border-left:none;border-top:none;border-radius:0 0 6px 0}
.dtitle{font-family:var(--disp);text-align:center;font-size:clamp(1.6rem,4.5vw,2.2rem);letter-spacing:.35em;margin-bottom:20px;color:#1D1D1B}
.dbody{font-size:.95rem;line-height:1.9;margin-bottom:14px;color:#2A2620;word-break:keep-all}
.dbody b{color:#8A6217}
.ddate{text-align:center;margin-top:22px;font-size:.95rem;color:#2A2620}
.dname{text-align:center;margin-top:10px;font-family:var(--disp);font-size:1.25rem;letter-spacing:.3em;color:#1D1D1B}
.plchip{cursor:pointer}
.pkrow{display:flex;gap:8px;flex-wrap:wrap}
.pkrow select,.pkrow input{border:2px solid var(--line);border-radius:10px;padding:9px 11px;font-size:.88rem;background:var(--white);font-family:var(--sans);color:var(--ink)}
.pkrow select{min-width:120px}

/* ===== 100일 기록지 ===== */
.tsummary{display:flex;gap:8px;flex-wrap:wrap;margin:10px 0}
.tchip{border:2px solid var(--line);border-radius:999px;padding:4px 12px;font-size:.8rem;font-weight:700;background:var(--white)}
.tchip.s{color:#B4790F;border-color:#E9CE8B}.tchip.t{color:#3D7FD1;border-color:#B9D2F0}.tchip.r{color:#E0563F;border-color:#F2C4BB}
.tgrid{display:grid;grid-template-columns:repeat(10,1fr);gap:6px;margin-top:6px}
@media(max-width:560px){.tgrid{grid-template-columns:repeat(5,1fr)}}
.tcell{position:relative;aspect-ratio:1;border:2px solid var(--line);border-radius:10px;background:var(--white);cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;transition:border-color var(--ease),transform var(--ease)}
.tcell:hover:not(.locked){border-color:#6C5B8C;transform:translateY(-1px)}
.tcell .td{position:absolute;top:3px;left:6px;font-size:.6rem;color:var(--ink-faint);font-weight:700}
.tcell .ts{font-size:1.25rem;line-height:1;font-weight:800}
.tcell .tm2{position:absolute;bottom:3px;right:5px;font-size:.56rem;color:var(--ink-soft);font-variant-numeric:tabular-nums}
.tcell.st-star{background:#FFF4D6;border-color:#E9CE8B}.tcell.st-star .ts{color:#B4790F}
.tcell.st-tri{background:#EAF2FC;border-color:#B9D2F0}.tcell.st-tri .ts{color:#3D7FD1}
.tcell.st-re{background:#FDEEEA;border-color:#F2C4BB}.tcell.st-re .ts{color:#E0563F}
.tcell.locked{opacity:.4;cursor:default;background:var(--paper)}
.tcell.today{outline:3px solid var(--yellow);outline-offset:1px}
.tpick{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
.tpb{border:2px solid var(--line);border-radius:12px;background:var(--white);padding:12px 6px;font-size:1.4rem;font-weight:800;display:flex;flex-direction:column;align-items:center;gap:3px;cursor:pointer}
.tpb small{font-size:.68rem;font-weight:600;color:var(--ink-soft)}
.tpb.s{color:#B4790F}.tpb.t{color:#3D7FD1}.tpb.r{color:#E0563F}
.tpb.on{border-color:currentColor;background:#FFFDF4;box-shadow:inset 0 -3px 0 rgba(0,0,0,.06)}

/* ===== 관리자 확장 ===== */
.oprow{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:12px 16px;font-size:.84rem}
.oprow b{color:var(--green)}
.obtn{border:1.5px solid var(--line);background:var(--white);border-radius:10px;padding:7px 13px;font-size:.78rem;font-weight:700;color:var(--ink);text-decoration:none}
.obtn:first-of-type{border-color:var(--orange);color:var(--orange)}
.prow.isHidden{background:#FFF2EF}
.hbd{font-size:.66rem;font-weight:800;color:#fff;background:var(--red);border-radius:999px;padding:2px 8px;margin-left:6px}
.clapn{font-size:.72rem;color:var(--ink-soft);white-space:nowrap}

@media(prefers-reduced-motion:reduce){
  .wmblades,#vfw.on .fwb,.vsway,.vsmoke .sp,.vflut,.vrays,.vcloud1,.vcloud2,.vcloud3,.vballoon,.vballoonx,.vballoonx2,.vbirds,.vwalk.w1,.vwalk.w2,.vbob,.vglint,.vglow,.vstar,.vwings,.vbfly.bf1,.vbfly.bf2,.vconfetti i,.clapbtn.pop{animation:none}
  .vi{transition:opacity .3s}
}

/* ===== 대시보드 목차 (섹션별 3열 카드) ===== */
.navsec{margin-top:16px}
.sectitle{font-size:1.15rem;margin-bottom:10px;display:flex;align-items:center;gap:8px}
.sectitle::before{content:"";width:6px;height:20px;border-radius:4px;background:var(--yellow)}
.navgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
@media(max-width:640px){.navgrid{grid-template-columns:1fr}}
.navrow{display:flex;flex-direction:column;gap:8px;background:var(--white);border:2px solid var(--line);border-radius:16px;padding:14px 16px;text-decoration:none;color:inherit;box-shadow:var(--card-shadow);transition:border-color var(--ease),transform var(--ease)}
.navrow:hover{border-color:var(--c);transform:translateY(-1px)}
.nr-top{display:flex;align-items:center;gap:10px;min-width:0}
.nr-top b{font-family:var(--disp);font-weight:400;font-size:1.08rem;line-height:1.25;flex:1;min-width:0}
.nr-stats{font-size:.78rem;color:var(--ink-soft);line-height:1.5}
.nr-bar{display:block;height:6px;border-radius:99px;background:var(--line);position:relative;overflow:hidden}
.nr-bar::after{content:"";position:absolute;left:0;top:0;bottom:0;width:var(--w);background:var(--c);border-radius:99px}
.nr-pct{font-family:var(--disp);font-size:1.3rem;color:var(--c);white-space:nowrap}
.nr-pct small{font-size:.8rem;margin-left:1px}
.nr-go{font-size:1.05rem;color:var(--ink-faint);transition:transform var(--ease)}
.navrow:hover .nr-go{transform:translateX(3px);color:var(--c)}
@media(max-width:900px){.nr-top b{font-size:1rem}.nr-num{width:38px;height:38px;font-size:1.25rem}}

/* ===== 하단 2단 패널 ===== */
.strip{margin-top:18px;display:grid;grid-template-columns:5fr 7fr;gap:14px;align-items:stretch}
@media(max-width:760px){.strip{grid-template-columns:1fr}}
.panel{background:var(--white);border:2px solid var(--line);border-radius:16px;padding:16px 18px;box-shadow:var(--card-shadow);display:flex;flex-direction:column}
.panel .ph{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:12px;gap:8px}
.panel .ph .t{font-family:var(--disp);font-size:.95rem;color:var(--ink)}
.panel .ph .c{font-weight:800;color:var(--orange);font-size:.82rem;white-space:nowrap}

.proster{display:flex;flex-wrap:wrap;gap:7px;max-height:180px;overflow:auto}
.pchip{display:inline-flex;align-items:center;gap:6px;padding:4px 10px 4px 4px;border:2px solid var(--line);border-radius:999px;text-decoration:none;color:var(--ink);font-size:.78rem;font-weight:600;background:var(--white);transition:border-color var(--ease)}
.pchip:hover{border-color:var(--blue)}
.pchip .pav{width:20px;height:20px;border-radius:50%;display:grid;place-items:center;font-weight:700;font-size:.68rem;flex:none;background:var(--blue);color:#fff}

.groups{display:grid;grid-template-columns:repeat(3,1fr);gap:7px;flex:1;align-content:center}
@media(max-width:520px){.groups{grid-template-columns:repeat(2,1fr)}}
@media(max-width:340px){.groups{grid-template-columns:1fr}}
.gband{background:var(--paper);border:2px solid var(--line);border-radius:12px}
.grow{width:100%;display:flex;align-items:center;gap:7px;border:none;background:none;padding:8px 10px;font-size:.84rem;font-weight:700;color:var(--ink);text-align:left}
.grow .gcnt{margin-left:auto;font-weight:400;font-size:.74rem;color:var(--ink-soft)}
.grow .gchev{font-size:.9rem;color:var(--ink-faint);transition:transform var(--ease)}
.gband.open .grow .gchev{transform:rotate(45deg)}
.gkids{display:none;flex-wrap:wrap;gap:6px;padding:8px 10px 10px;border-top:2px dashed var(--line)}
.gband.open .gkids{display:flex}

.recent{display:grid;grid-template-columns:1fr 1fr;column-gap:18px;flex:1;align-content:center}
@media(max-width:560px){.recent{grid-template-columns:1fr}}
.proster{flex:1;align-content:center}
.recent .row{display:flex;align-items:center;gap:10px;font-size:.84rem;text-decoration:none;color:inherit;padding:8px 0;border-bottom:2px dashed var(--line)}
.recent .row:last-child{border-bottom:none}
.recent .th{width:34px;height:34px;flex:none;background:var(--paper);object-fit:cover;border-radius:10px}
.recent .row b{font-weight:700}
.recent .row .dm{margin-left:auto;font-size:.72rem;color:var(--ink-faint)}

/* ===== 영역 벽 ===== */
.dhead{display:flex;align-items:center;gap:14px;margin-bottom:18px;background:var(--white);border:2px solid var(--line);border-radius:16px;padding:14px 18px;box-shadow:var(--card-shadow);flex-wrap:wrap}
.dhead .nr-num{--c:var(--c)}
.dh-txt{flex:1;min-width:140px}
.dh-txt h1{font-size:clamp(1.3rem,3vw,1.7rem)}
.dh-txt p{color:var(--ink-soft);font-size:.82rem;margin-top:2px}
.dh-cta{text-align:right}
.btn{display:inline-flex;align-items:center;color:#fff;background:var(--green);border:none;border-radius:12px;padding:11px 18px;font-weight:700;font-size:.9rem;box-shadow:inset 0 -3px 0 rgba(0,0,0,.14)}
.btn[disabled]{opacity:.55}
.dh-cta .hint{display:block;margin-top:6px;font-size:.72rem;color:var(--ink-soft)}
@media(max-width:640px){.dh-cta{width:100%;text-align:left}}

.roster{background:var(--white);border:2px solid var(--line);border-radius:14px;padding:12px 14px;margin-bottom:16px;box-shadow:var(--card-shadow)}
.roster .rh{display:flex;justify-content:space-between;align-items:center;gap:8px;margin-bottom:8px}
.roster .rh .t{font-size:.82rem;font-weight:700}
.roster .rh .clear{font-size:.72rem;color:var(--blue);background:none;border:none;text-decoration:underline}
.chips{display:flex;flex-wrap:wrap;gap:6px;max-height:110px;overflow:auto}
.chip{font-size:.76rem;padding:4px 11px;border:2px solid var(--line);background:var(--white);color:var(--ink-soft);border-radius:999px;font-weight:600}
.chip.sel{background:var(--ink);color:#fff;border-color:var(--ink)}

.wall{columns:5;column-gap:12px}
@media(max-width:1000px){.wall{columns:4}}
@media(max-width:760px){.wall{columns:3}}
@media(max-width:520px){.wall{columns:2}}
.pcard{break-inside:avoid;margin-bottom:12px;border:2px solid var(--line);border-radius:14px;overflow:hidden;background:var(--white);box-shadow:var(--card-shadow)}
.pcard .ph{width:100%;display:block;background:var(--paper)}
.pcard .meta{padding:8px 11px}
.pcard .meta .nm{font-weight:700;font-size:.82rem}
.pcard .meta .nm a{color:inherit;text-decoration:none}
.pcard .meta .nm a:hover{text-decoration:underline}
.pcard .meta .cap{color:var(--ink-soft);font-size:.77rem;margin-top:2px}
.pcard .meta .tm{color:var(--ink-faint);font-size:.68rem;margin-top:4px}
.addcard{break-inside:avoid;margin-bottom:12px;border:2px dashed var(--ink-faint);border-radius:14px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;padding:24px 12px;text-align:center;background:var(--white);width:100%}
.addcard .p{font-size:1.4rem;line-height:1;font-weight:400;color:var(--green)}
.addcard b{font-size:.86rem}
.addcard span{font-size:.7rem;color:var(--ink-soft)}
.morebar{margin-top:18px;text-align:center}
.more{border:2px solid var(--line);background:var(--white);border-radius:12px;padding:10px 22px;font-weight:700;font-size:.86rem;color:var(--ink)}
.empty{padding:36px 16px;text-align:center;color:var(--ink-faint)}
.empty.small{padding:12px 0;font-size:.84rem;text-align:left}

/* ===== 학생별 기록 ===== */
.phead{display:flex;align-items:center;gap:14px;margin-bottom:22px;background:var(--white);border:2px solid var(--line);border-radius:16px;padding:14px 18px;box-shadow:var(--card-shadow)}
.phead .pav{width:52px;height:52px;border-radius:14px;background:var(--blue);color:#fff;display:grid;place-items:center;font-family:var(--disp);font-size:1.5rem;flex:none;box-shadow:inset 0 -3px 0 rgba(0,0,0,.14)}
.phead h1{font-size:1.45rem}
.phead p{color:var(--ink-soft);font-size:.85rem;margin-top:2px}
.ptimeline{display:flex;flex-direction:column;gap:26px}
.pdom h2{display:flex;align-items:center;gap:9px;font-size:1.08rem;margin-bottom:12px}
.pdom h2 .cnt{margin-left:auto;font-family:var(--sans);font-size:.74rem;color:var(--ink-soft)}
.tl{position:relative;padding-left:22px}
.tl::before{content:"";position:absolute;left:4px;top:6px;bottom:6px;width:2px;background:var(--line)}
.tlrow{position:relative;display:flex;gap:12px;align-items:flex-start;padding-bottom:16px}
.tlrow:last-child{padding-bottom:0}
.tdot{position:absolute;left:-22px;top:5px;width:8px;height:8px;border-radius:50%;background:var(--orange);box-shadow:0 0 0 3px var(--paper)}
.tth{width:54px;height:54px;border-radius:12px;object-fit:cover;flex:none;background:var(--paper);cursor:zoom-in;border:2px solid var(--line)}
.tmeta{padding-top:2px;min-width:0}
.tcap{font-size:.88rem;font-weight:600}
.tdate{font-size:.72rem;color:var(--ink-faint);margin-top:2px}

/* ===== 정림초 소개 / 폰프리 규칙 ===== */
.ahead{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-bottom:18px}
.ahead h1{font-size:clamp(1.35rem,3.4vw,1.8rem)}
.ahead p{width:100%;color:var(--ink-soft);font-size:.88rem}
.aphoto{margin-bottom:6px}
.aphoto img{width:100%;display:block;border:2px solid var(--line);border-radius:16px}
.aphoto .acap{display:block;margin:6px 2px 18px;font-size:.74rem;color:var(--ink-soft)}
.aphoto.rules{max-width:480px;margin:0 auto}
.abadgebox{background:var(--white);border:2px solid var(--line);border-radius:16px;padding:16px 18px;margin-bottom:18px;box-shadow:var(--card-shadow)}
.abadges{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:8px}
.abadge{display:flex;align-items:center;justify-content:center;text-align:center;font-size:.8rem;font-weight:700;color:var(--ink);background:var(--yellow-soft);border:2px solid var(--yellow);border-radius:999px;padding:8px 12px}

/* ===== 모달 ===== */
.overlay{position:fixed;inset:0;z-index:50;background:rgba(74,63,53,.5);display:flex;align-items:center;justify-content:center;padding:16px}
.modal{width:min(440px,100%);max-height:92vh;overflow:auto;background:var(--white);border:2px solid var(--line);border-radius:18px}
.modal .mh{position:sticky;top:0;background:var(--white);padding:15px 18px;border-bottom:2px solid var(--line);display:flex;align-items:center;justify-content:space-between}
.modal .mh h3{font-size:1.1rem}
.modal .mh .x{border:none;background:none;color:var(--ink-faint);font-size:1.35rem;line-height:1}
.modal .mb{padding:18px;display:flex;flex-direction:column;gap:14px}
.drop{border:2px dashed var(--blue);border-radius:14px;background:var(--sky);padding:24px;text-align:center;color:var(--ink-soft);position:relative}
.drop b{display:block;font-size:.9rem;color:var(--ink)}
.drop span{font-size:.73rem;color:var(--ink-soft);display:block;margin-top:3px}
.drop input[type=file]{position:absolute;inset:0;opacity:0;cursor:pointer}
.drop img{max-height:180px;margin:0 auto;border-radius:10px}
.field label{font-size:.76rem;color:var(--ink-soft);font-weight:700;display:block;margin-bottom:5px}
.field select,.field input[type=text]{width:100%;border:2px solid var(--line);border-radius:10px;padding:10px 12px;background:var(--white);font-family:var(--sans);font-size:.92rem;color:var(--ink)}
.nologin{background:var(--yellow-soft);border:2px solid var(--yellow);border-radius:10px;padding:10px 12px;font-size:.8rem;color:var(--ink)}
.nologin b{font-weight:800}
.submit{border:none;border-radius:12px;padding:13px;font-weight:800;font-size:.96rem;color:#fff;background:var(--green);box-shadow:inset 0 -3px 0 rgba(0,0,0,.14)}
.submit[disabled]{opacity:.55}

/* ===== 관리자 ===== */
.agrid{display:grid;grid-template-columns:330px 1fr;gap:12px}
@media(max-width:840px){.agrid{grid-template-columns:1fr}}
.card{background:var(--white);border:2px solid var(--line);border-radius:16px;box-shadow:var(--card-shadow);overflow:hidden}
.card .ch{padding:13px 16px;border-bottom:2px solid var(--line);display:flex;align-items:center;justify-content:space-between}
.card .ch h3{font-size:1rem}
.card .ch .cnt{font-size:.76rem;color:var(--ink-soft)}
.addrow{display:flex;flex-wrap:wrap;gap:7px;padding:12px 14px;border-bottom:2px solid var(--line);background:var(--paper)}
.addrow input{border:2px solid var(--line);border-radius:10px;padding:8px 11px;font-size:.84rem;background:var(--white);font-family:var(--sans)}
.addrow .nm{flex:1;min-width:88px}
.addrow .cl{width:84px}
.addrow .add{background:var(--green);color:#fff;border:none;border-radius:10px;padding:0 14px;font-weight:700;font-size:.82rem;box-shadow:inset 0 -2px 0 rgba(0,0,0,.14)}
.addrow select{border:2px solid var(--line);border-radius:10px;padding:8px;font-size:.82rem;background:var(--white);font-family:var(--sans);color:var(--ink);width:104px}
.gcard{margin-bottom:12px}
.glist{max-height:220px;overflow:auto}
.grow-admin{display:flex;align-items:center;gap:8px;padding:9px 15px;border-bottom:2px dashed var(--line);font-size:.84rem}
.grow-admin:last-child{border-bottom:none}
.grow-admin .gname{font-weight:700}
.grow-admin .gcnt2{font-size:.74rem;color:var(--ink-soft)}
.grow-admin .mv{width:26px;height:26px;border:2px solid var(--line);border-radius:8px;background:var(--white);color:var(--ink-soft);font-size:.76rem}
.grow-admin .mv:first-of-type{margin-left:auto}
.grow-admin .mv[disabled]{opacity:.35}
.grow-admin .del{width:26px;height:26px;border:2px solid var(--line);border-radius:8px;color:var(--red);background:var(--white)}
.slist{max-height:420px;overflow:auto}
.srow{display:flex;align-items:center;gap:9px;padding:9px 15px;border-bottom:2px dashed var(--line)}
.srow:last-child{border-bottom:none}
.srow .av{width:26px;height:26px;border-radius:8px;background:var(--blue);color:#fff;display:grid;place-items:center;font-size:.74rem;font-weight:700;flex:none}
.srow .nm{font-weight:700;font-size:.86rem;color:inherit;text-decoration:none}
.srow .nm:hover{text-decoration:underline}
.srow .grp{font-size:.66rem;font-weight:700;color:var(--green);border:2px solid var(--line);border-radius:999px;padding:1px 8px;margin-left:6px}
.srow .cl{font-size:.72rem;color:var(--ink-soft);margin-left:auto;margin-right:6px}
.srow .sedit{width:26px;height:26px;border:2px solid var(--line);border-radius:8px;color:var(--ink-soft);background:var(--white);margin-right:4px;font-size:.8rem}
.srow .del{width:26px;height:26px;border:2px solid var(--line);border-radius:8px;color:var(--red);background:var(--white)}
.atabs{display:flex;gap:6px;padding:12px 14px;border-bottom:2px solid var(--line);flex-wrap:wrap}
.atab{font-size:.78rem;padding:5px 13px;border:2px solid var(--line);border-radius:999px;color:var(--ink-soft);background:var(--white);font-weight:600}
.atab.cur{background:var(--ink);color:#fff;border-color:var(--ink)}
.plist{max-height:520px;overflow:auto}
.prow{display:flex;align-items:center;gap:11px;padding:9px 15px;border-bottom:2px dashed var(--line)}
.prow:last-child{border-bottom:none}
.prow .th{width:42px;height:34px;object-fit:cover;background:var(--paper);flex:none;border-radius:8px}
.prow .who{font-weight:700;font-size:.86rem}
.prow .cap{color:var(--ink-soft);font-size:.8rem}
.prow .bd{font-size:.7rem;padding:3px 10px;border:2px solid var(--line);border-radius:999px;color:var(--ink-soft);font-weight:600}
.prow .date{font-size:.72rem;color:var(--ink-soft);margin-left:auto}
.prow .edit{color:var(--ink);border:2px solid var(--line);border-radius:10px;padding:4px 11px;font-size:.76rem;background:var(--white);font-weight:700}
.prow .del{color:var(--red);border:2px solid var(--line);border-radius:10px;padding:4px 11px;font-size:.76rem;background:var(--white);font-weight:700}
.gate{max-width:340px;margin:70px auto;background:var(--white);border:2px solid var(--line);border-radius:18px;padding:26px;text-align:center;box-shadow:var(--card-shadow)}
.gate h3{font-size:1.15rem;margin-bottom:14px}
.gate input{width:100%;border:2px solid var(--line);border-radius:10px;padding:10px 13px;font-size:.95rem;margin-bottom:10px;font-family:var(--sans)}
.gate button{width:100%;border:none;border-radius:12px;padding:12px;font-weight:800;color:#fff;background:var(--green);box-shadow:inset 0 -3px 0 rgba(0,0,0,.14)}

/* ===== 푸터 ===== */
.sitefoot{text-align:center;padding:14px 16px 26px;font-size:.75rem;color:var(--ink-faint)}
.sitefoot a{color:var(--ink-soft);text-decoration:underline}

/* ===== 토스트 ===== */
.toast{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);z-index:80;background:var(--ink);color:#fff;padding:11px 18px;border-radius:12px;font-size:.88rem;opacity:0;transition:opacity .2s}
.toast.show{opacity:1}
.toast.err{background:var(--red)}
.spin{width:16px;height:16px;border:2px solid rgba(255,255,255,.4);border-top-color:#fff;border-radius:50%;display:inline-block;animation:sp .7s linear infinite;vertical-align:-3px}
@keyframes sp{to{transform:rotate(360deg)}}
@media(prefers-reduced-motion:reduce){.spin,.live i{animation:none}}
