.app-grid {
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 1200px;
  margin: 0 auto;
  padding: 16px 20px 0;
}

.top-clock { text-align: center; }
/* 년월일요일 다음에 시간, 한 줄로 — 둘 다 시간과 같은 큰 글씨 크기라야
   멀리서도(교탁 반대편) 한눈에 읽힌다. */
.clock-line {
  display: flex; align-items: baseline; justify-content: center;
  gap: 14px; flex-wrap: wrap;
}
.top-clock #clockNow,
.top-clock #clockDate {
  font-size: 3rem; font-weight: bold; letter-spacing: 2px; color: #fff;
}
.top-clock #clockDate { color: #ffcc00; }

.morning-banner {
  background: #ffcc00; color: #111; border-radius: 14px;
  padding: 18px 20px; text-align: center; font-size: 1.2rem; font-weight: bold;
}
.morning-banner[hidden] { display: none; }

/* 왼쪽 30% 학생 / 가운데 40% 수업 알리미·알림장 / 오른쪽 30% 시간표 */
.three-col-row {
  display: grid;
  /* %가 아니라 fr을 쓴다 — %는 grid gap을 빼지 않고 계산돼 30%+40%+30%+gap
     만큼 컨테이너 폭을 넘어간다. fr은 gap을 먼저 뺀 나머지를 3:4:3으로 나눠
     정확히 30/40/30 비율이 되면서도 넘치지 않는다. */
  grid-template-columns: 3fr 4fr 3fr;
  gap: 16px;
  align-items: start;
}
@media (max-width: 900px) {
  .three-col-row { grid-template-columns: 1fr; }
}

.center-section { display: flex; flex-direction: column; gap: 16px; }

.student-section {
  background: #1a2233; border-radius: 14px; padding: 20px;
}
.student-list { display: flex; flex-direction: column; gap: 8px; }
/* 학생 한 명 = 아코디언 한 칸. 헤더(이름)를 누르면 1인1역/해야할일/제출할것
   세 칸(.s-details)이 펼쳐지거나 접힌다 — 학생 수가 많은 반에서 목록 전체가
   한눈에 들어오도록 기본은 접힌 상태로 시작한다(관리자 모드에서 바꿀 수 있음). */
.student-row { background: #0e1420; border-radius: 8px; overflow: hidden; }
.s-header {
  width: 100%; display: flex; align-items: center; justify-content: space-between;
  padding: 10px 12px; background: none; border: none; cursor: pointer; text-align: left;
  font: inherit; color: inherit;
}
.s-header .s-name { font-weight: bold; color: #ffcc00; font-size: 1.05rem; }
.s-header .s-chevron { color: #9aa7bd; font-size: 0.8rem; }
.s-details { display: flex; flex-direction: column; gap: 8px; padding: 0 12px 12px; }
.s-details[hidden] { display: none; }
.s-field { display: flex; flex-direction: column; gap: 2px; font-size: 0.75rem; color: #9aa7bd; }
.s-field input {
  width: 100%; color: #fff; font-size: 0.9rem;
  background: transparent; border: none; border-bottom: 1px solid #2a344a; padding: 4px 2px;
}

.notice-section {
  background: #1a2233; border-radius: 14px; padding: 20px;
}
.notice-general {
  min-height: 2.4em; padding: 10px; border-radius: 8px; background: #0e1420;
  color: #fff; margin-bottom: 14px; white-space: pre-wrap;
  outline: 1px dashed #ffcc00; /* 편집모드와 무관하게 항상 입력 가능이라 항상 표시 */
}
.hiclass-btn {
  padding: 10px 16px; border-radius: 8px; border: none;
  background: #34495e; color: #fff; font-weight: bold; cursor: pointer;
}
.notice-footer-status {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 10px;
}
.notice-footer-status .bell-running-status { margin-top: 0; }

/* 시간표 패널 + (편집모드일 때만 보이는) 편집 폼을 세로로 묶는 오른쪽 열 */
.timetable-col {
  display: flex; flex-direction: column; gap: 10px;
}
.timetable-panel {
  background: #1a2233; border-radius: 14px; padding: 10px;
  display: flex; flex-direction: column; gap: 5px;
}
/* 시간+교시(왼쪽)와 과목(오른쪽)을 같은 글씨 크기로 맞추고, 두 칸을 각각
   고정 폭으로 나눠서 그 안에서 가운데 정렬한다. 칸 폭을 고정하지 않으면
   행마다 글자 길이가 달라(예: "중간놀이시간" vs "1교시") 시간·과목 줄이
   행마다 다른 위치에서 시작해 표처럼 안 보인다 — 고정 폭이라야 여러 행에
   걸쳐 시간 칸끼리, 과목 칸끼리 세로선이 맞는다.
   패딩/글씨 크기는 일부러 작게 잡았다 — 교시 수가 많은 날(8교시까지)도
   화면을 스크롤하지 않고 오른쪽 시간표 전체가 한눈에 들어오게 하기 위해서다. */
.timetable-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-radius: 8px;
  background: #0e1420;
}
.timetable-row.current { background: #ffcc00; color: #111; }
.timetable-row .tt-left {
  /* "오전 10:30~10:50"/"중간놀이시간" 같은 가장 긴 라벨도 안 접히게 여유를
     두고 고정한다 — 이 값이 실제 글자 폭보다 좁으면(예: 나중에 폰트를 키우면)
     flex의 기본 min-width가 다시 콘텐츠 크기로 늘려버려 조용히 어긋난다.
     그래서 폭을 고정하는 것과 함께 줄바꿈 자체를 막아(white-space) 항상
     이 폭 안에서 한 줄로 유지되게 한다. 12시간(오전/오후) 표기로 바꾸면서
     24시간 표기보다 길어져 108px에서 124px로 다시 넓혔다. */
  flex: 0 0 124px;
  display: flex; flex-direction: column; align-items: center; text-align: center;
  line-height: 1.25;
}
.timetable-row .tt-time,
.timetable-row .tt-label,
.timetable-row .tt-subject-text {
  font-size: 1rem; font-weight: bold;
}
.timetable-row .tt-time,
.timetable-row .tt-label { white-space: nowrap; }
.timetable-row .tt-time { color: #9aa7bd; font-weight: normal; font-size: 0.85rem; }
.timetable-row.current .tt-time { color: #333; }
.timetable-row .tt-subject {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; align-items: center; text-align: center;
  line-height: 1.25;
}
.timetable-row .tt-note {
  font-size: 0.75rem; font-weight: normal; color: #9aa7bd; margin-top: 1px;
}
.timetable-row.current .tt-note { color: #333; opacity: 0.85; }

.toolbar {
  max-width: 1200px; margin: 16px auto 0; padding: 0 20px 20px;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.toolbar button {
  padding: 10px 16px; border-radius: 8px; border: none; background: #34495e;
  color: #fff; font-weight: bold; cursor: pointer;
}
/* 엑셀 업로드·홈화면 추가·PIN 변경은 관리자 모드일 때만 보인다.
   PC 플로팅 위젯 버튼은 여기 포함되지 않고 항상 보인다. */
.admin-only-controls { display: none; align-items: center; gap: 10px; flex-wrap: wrap; }
body.edit-mode .admin-only-controls { display: flex; }
.pin-change { display: flex; gap: 6px; }
.pin-change input {
  width: 110px; padding: 8px; border-radius: 8px; border: 1px solid #3a4864;
  background: #0e1420; color: #fff;
}
.install-message { color: #9aa7bd; font-size: 0.9rem; }
.install-message.show { color: #ffcc00; }
.toolbar-link {
  padding: 10px 16px; border-radius: 8px; background: #34495e; color: #fff;
  font-weight: bold; text-decoration: none; font-size: 0.9rem;
}

.room-code-display {
  padding: 10px 12px; border-radius: 8px; background: #0e1420; color: #ffcc00;
  font-weight: bold; font-size: 0.9rem;
}

.room-select-inner { width: min(420px, 92vw); text-align: left; }
.room-select-inner > p:first-child { text-align: center; font-size: 1.1rem; margin-bottom: 12px; }
#createRoomBtn { width: 100%; margin-bottom: 14px; padding: 12px; font-size: 1rem; }
.room-join-row { display: flex; gap: 8px; }
.room-join-row input {
  flex: 1; padding: 10px; border-radius: 8px; border: 1px solid #3a4864;
  background: #0e1420; color: #fff; font-size: 1rem; text-transform: uppercase;
}
.room-join-row button { padding: 10px 16px; border-radius: 8px; border: none; background: #4285F4; color: #fff; font-weight: bold; cursor: pointer; }
.room-share-box { margin-top: 16px; padding-top: 14px; border-top: 1px dashed #3a4864; }
.room-share-box p { margin: 6px 0; }
.room-share-box strong { color: #ffcc00; font-size: 1.3rem; letter-spacing: 2px; }
.room-share-link { font-size: 0.78rem; color: #9aa7bd; word-break: break-all; }
#roomShareContinueBtn { width: 100%; margin-top: 10px; padding: 10px; }

.pin-modal {
  position: fixed; inset: 0; background: rgba(0,0,0,0.6);
  display: flex; align-items: center; justify-content: center; z-index: 1000;
}
.pin-modal[hidden] { display: none; }
.pin-modal-inner {
  position: relative; background: #1a2233; padding: 24px; border-radius: 14px; text-align: center;
}
.pin-modal-inner input {
  display: block; margin: 12px auto; padding: 10px; font-size: 1.4rem;
  text-align: center; width: 140px; border-radius: 8px; border: 1px solid #3a4864;
  background: #0e1420; color: #fff;
}
.pin-modal-inner button {
  padding: 10px 20px; border-radius: 8px; border: none; background: #ffcc00;
  color: #111; font-weight: bold; cursor: pointer;
}
.pin-cancel-btn {
  position: absolute; top: 8px; right: 8px; width: 32px; height: 32px; padding: 0 !important;
  border-radius: 50% !important; background: #33405c !important; color: #fff !important;
  font-weight: normal !important; font-size: 1rem; line-height: 1;
}

body.edit-mode .s-role,
body.edit-mode .s-todo,
body.edit-mode .s-submit {
  outline: 1px dashed #ffcc00;
}
/* 배너는 노란 바탕이라 노란 점선이 보이지 않으므로 어두운 점선을 쓴다.
   비어 있어도 눌러서 입력할 수 있도록 최소 높이를 준다. */
body.edit-mode #morningBannerText {
  outline: 1px dashed #111; min-height: 1.4em;
}
/* 저장 시 innerText로 줄바꿈을 보존하므로(js/main.js) 화면에도 그대로 보이게 한다. */
#morningBannerText { white-space: pre-wrap; }

.timetable-edit-form {
  background: #1a2233; border-radius: 14px;
  padding: 14px; display: none; flex-direction: column; gap: 8px;
}
.timetable-edit-form[hidden] { display: none; }
.timetable-edit-form label { display: flex; flex-direction: column; font-size: 0.85rem; color: #9aa7bd; gap: 4px; }
.timetable-edit-form select, .timetable-edit-form input[type="text"] {
  padding: 8px; border-radius: 8px; border: 1px solid #3a4864; background: #0e1420; color: #fff;
}
.timetable-edit-form button {
  padding: 10px; border-radius: 8px; border: none; background: #ffcc00; color: #111;
  font-weight: bold; cursor: pointer;
}
body.edit-mode .timetable-edit-form { display: flex; }

.tt-edit-hint { margin: 0; font-size: 0.8rem; color: #9aa7bd; }

/* 오늘 시간표 패널: 편집모드일 때만 칸을 눌러 "오늘만" 내용을 바꿀 수 있다. */
.timetable-panel.editable .timetable-row { cursor: pointer; }
.timetable-panel.editable .timetable-row:hover { outline: 1px dashed #ffcc00; }
.timetable-row.overridden { background: #3a2f1a; }
.timetable-row.overridden.current { background: #ffcc00; }
.tt-override-badge {
  display: inline-block; margin-left: 6px; padding: 1px 6px; border-radius: 6px;
  background: #ffcc00; color: #111; font-size: 0.7rem; font-weight: bold; vertical-align: middle;
}

/* 관리자 모드의 요일×교시 전체 시간표 — 클릭하면 아래 요일/교시 선택이
   자동으로 채워진다(실제 저장·적용은 그 아래 폼에서 그대로 한다). */
.weekly-grid {
  display: grid;
  grid-template-columns: 2.4em repeat(5, 1fr);
  gap: 4px;
  font-size: 0.78rem;
}
.weekly-grid .wg-cell {
  padding: 6px 4px; border-radius: 6px; background: #0e1420; text-align: center;
  cursor: pointer; line-height: 1.3; min-height: 2.6em;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.weekly-grid .wg-cell:hover { outline: 1px dashed #ffcc00; }
.weekly-grid .wg-cell.wg-selected { background: #ffcc00; color: #111; }
.weekly-grid .wg-head { background: transparent; cursor: default; font-weight: bold; color: #9aa7bd; }
.weekly-grid .wg-head:hover { outline: none; }
.weekly-grid .wg-period-label { background: transparent; cursor: default; color: #9aa7bd; font-weight: bold; }
.weekly-grid .wg-period-label:hover { outline: none; }
.weekly-grid .wg-empty { color: #55617a; }

.override-modal-inner { width: min(360px, 90vw); text-align: left; }
.override-modal-inner p { text-align: center; }
.override-field { display: block; font-size: 0.85rem; color: #9aa7bd; margin: 10px 0 4px; }
.override-field input {
  width: 100%; margin-top: 4px; padding: 8px; border-radius: 8px; border: 1px solid #3a4864;
  background: #0e1420; color: #fff; font-size: 1rem; text-align: left;
}
.override-actions { display: flex; gap: 8px; margin-top: 14px; }
.override-actions button { flex: 1; }
.override-reset-btn { background: #555 !important; color: #fff !important; }

.bell-running-status {
  display: block; margin-top: 4px; font-size: 0.85rem; color: #e74c3c;
}
.bell-running-status.on { color: #2ecc71; }

.conn-status { display: block; margin-top: 4px; font-size: 0.85rem; color: #e74c3c; }
.conn-status[hidden] { display: none; }
/* 좁은 화면(교실 태블릿)에서는 편집모드가 아니면 연결 끊김 경고를 숨긴다 —
   학생들이 보는 화면에 굳이 경고를 띄울 필요는 없고, 교사가 편집모드로
   들어가거나 PC(넓은 화면)로 열었을 때만 보이면 충분하다. */
@media (max-width: 900px) {
  .conn-status { display: none; }
  body.edit-mode .conn-status:not([hidden]) { display: block; }
}

/* 저장 실패는 "읽은 내용이 오래됐다"는 연결 끊김과 성격이 달라서(방금 입력한
   게 사라질 수 있다는 뜻) 화면 폭·편집모드와 무관하게 항상 보이게 둔다. */
.save-status {
  display: block; margin-top: 4px; font-size: 0.85rem; font-weight: bold; color: #e74c3c;
}
.save-status[hidden] { display: none; }

.student-add-form { display: none; margin-top: 10px; gap: 8px; flex-wrap: wrap; }
body.edit-mode .student-add-form { display: flex; }
.student-add-form input {
  flex: 1; min-width: 0; padding: 8px; border-radius: 8px; border: 1px solid #3a4864;
  background: #0e1420; color: #fff;
}
.student-add-form input[type="number"] { flex: 0 0 70px; }
.student-add-form button {
  padding: 8px 14px; border-radius: 8px; border: none; background: #34495e;
  color: #fff; font-weight: bold; cursor: pointer;
}

/* 타이머는 새 창이 아니라 이 페이지 안 모달(index.html의 #timerModal)로
   뜬다 — 새 창을 열면 브라우저가 이 페이지를 백그라운드로 취급해 수업종
   알림 체크가 늦어지거나 멈출 수 있기 때문(js/bell.js는 이 문서의 타이머가
   계속 살아있어야 정상 동작한다). */
.timer-modal-inner { width: min(320px, 90vw); }
.timer-modal-inner .timer-presets {
  display: flex; align-items: center; justify-content: center; gap: 6px; flex-wrap: wrap; margin-bottom: 10px;
}
.timer-modal-inner .timer-presets button,
.timer-modal-inner #timerCustomSetBtn {
  padding: 6px 12px; border-radius: 8px; border: none; background: #34495e;
  color: #fff; cursor: pointer; font-size: 0.85rem; font-weight: normal;
}
#timerCustomMinutes {
  width: 60px; padding: 6px; border-radius: 8px; border: 1px solid #3a4864;
  background: #0e1420; color: #fff; text-align: center;
}
.timer-display {
  font-size: 2.2rem; font-weight: bold; color: #ffcc00; text-align: center; margin: 14px 0;
}
.timer-display.done { color: #e74c3c; }
.timer-modal-inner .timer-controls {
  display: flex; gap: 6px; justify-content: center;
}
.timer-modal-inner .timer-controls button {
  padding: 8px 14px; border-radius: 8px; border: none; background: #34495e; color: #fff;
  font-weight: bold; cursor: pointer;
}

.toolbar button:disabled { background: #333; color: #777; cursor: not-allowed; }

/* 알리미 켜기/끄기/음성테스트는 누구나 상시 사용하고, 알림 시간·문구를
   고치는 목록만 관리자 모드에서만 보이게 한다. */
#bellAdminSection { display: none; }
body.edit-mode #bellAdminSection { display: block; }
