← 실습 자료

20분 현장 연수 리허설

강사·프로젝터·참가자 역할과 막힘 흐름을 실제로 확인하는 사례입니다.

HTML 복사하기

HTML 직접 보기
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>20분 현장 연수 리허설</title>
<style>
*{box-sizing:border-box}body{margin:0;background:#f5f7fb;color:#17283f;font-family:system-ui,-apple-system,"Noto Sans KR",sans-serif;line-height:1.5}.page{width:min(980px,calc(100% - 32px));margin:32px auto}.head{display:flex;justify-content:space-between;gap:20px;align-items:center}.head span{color:#5d44bd;font-weight:900}.head h1{margin:6px 0;font-size:clamp(32px,6vw,52px)}.timer{min-width:140px;padding:18px;border-radius:18px;background:#211d38;color:#fff;text-align:center}.timer strong{display:block;font-size:34px}.roles{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-top:24px}.role{padding:22px;border:1px solid #dce2ec;border-radius:20px;background:#fff}.role span{display:inline-grid;place-items:center;width:38px;height:38px;border-radius:12px;background:#eeeaff;color:#5d44bd;font-weight:950}.role h2{margin:14px 0 8px}.role p{color:#5b6b80}.flow{margin-top:16px;padding:24px;border-radius:20px;background:#fff;border:1px solid #dce2ec}.flow h2{margin-top:0}.steps{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}.steps button{min-height:92px;border:1px solid #d5ddea;border-radius:14px;background:#f8f9fc;padding:12px;color:#17283f;font:inherit;font-weight:850;cursor:pointer}.steps button:focus-visible,.start:focus-visible{outline:3px solid #f0a600;outline-offset:3px}.steps button[aria-pressed=true]{border-color:#5d44bd;background:#eeeaff}.result{margin:18px 0 0;font-weight:900;color:#5d44bd}.start{border:0;border-radius:999px;background:#5d44bd;color:#fff;padding:12px 18px;font:inherit;font-weight:900;cursor:pointer}@media(max-width:760px){.roles,.steps{grid-template-columns:1fr}.head{align-items:start;flex-direction:column}.timer{width:100%}}
</style>
</head>
<body>
<main class="page">
  <header class="head"><div><span>VibeClass 운영 흐름 예시</span><h1>세 화면, 세 역할, 한 흐름</h1></div><div class="timer"><small>리허설</small><strong>20:00</strong><button class="start" type="button">타이머 시작</button></div></header>
  <section class="roles"><article class="role"><span>강</span><h2>강사 화면</h2><p>예시 하나를 띄우고 다음 차시를 시작하며 막힘 요청을 해결합니다.</p></article><article class="role"><span>큰</span><h2>프로젝터</h2><p>결과, 지금 할 일, 실제 예시만 크게 보여 줍니다.</p></article><article class="role"><span>참</span><h2>참가자 화면</h2><p>같은 자료를 자기 진도에서 열고 실습·도움·완료를 진행합니다.</p></article></section>
  <section class="flow"><h2>20분 리허설 흐름</h2><div class="steps"><button type="button">0–5분<br>수정·재게시</button><button type="button">5–10분<br>입장·예시</button><button type="button">10–18분<br>개인 실습</button><button type="button">18–20분<br>막힘·완료</button></div><p class="result" aria-live="polite">0 / 4 확인</p></section>
</main>
<script>
let remaining=1200,timerId;const output=document.querySelector(".timer strong"),start=document.querySelector(".start"),steps=[...document.querySelectorAll(".steps button")],result=document.querySelector(".result");function paint(){const minutes=String(Math.floor(remaining/60)).padStart(2,"0"),seconds=String(remaining%60).padStart(2,"0");output.textContent=`${minutes}:${seconds}`;}start.addEventListener("click",()=>{if(timerId)return;start.textContent="진행 중";timerId=setInterval(()=>{remaining=Math.max(0,remaining-1);paint();if(remaining===0){clearInterval(timerId);timerId=null;start.textContent="리허설 완료";}},1000);});steps.forEach(button=>button.addEventListener("click",()=>{button.setAttribute("aria-pressed",String(button.getAttribute("aria-pressed")!=="true"));const count=steps.filter(item=>item.getAttribute("aria-pressed")==="true").length;result.textContent=count===4?"4 / 4 확인 · 실제 연수 준비 완료":`${count} / 4 확인`;}));paint();
</script>
</body>
</html>