/* 본문은 Noto Sans KR. 간판만 Jua(주아체) -- 로고의 둥근 느낌을 글자로
   옮기려는 것이고, 본문까지 이 서체로 두면 공부하는 글이 읽기 어려워집니다.
   서체를 바꾸고 싶으면 아래 --font-brand 한 줄만 고치면 됩니다.

   본문 서체는 **내려받지 않습니다**. @import 로 구글에서 Noto Sans KR 을
   받아 오고 있었는데, @import 는 «이 파일을 다 받고 · 읽은 다음에야» 서체
   주소를 알게 만듭니다 -- style.css 106KB 를 기다렸다가 구글에 다시 다녀오는
   두 번 걸음이고, 그동안 화면은 비어 있습니다. 재어 보니 그 두 번째 걸음만
   288ms 였습니다.

   그런데 안드로이드의 기본 한글 서체가 바로 Noto Sans CJK KR 입니다 -- 갤럭시
   태블릿에서 우리가 받아 오던 그 서체를, 기기가 이미 가지고 있습니다. 윈도우
   선생님 화면은 맑은 고딕, 아이패드는 Apple SD Gothic Neo. 그래서 아래 body 의
   차례대로 두면 어느 기기에서나 **기다림 없이** 같은 모양이 나옵니다.

   간판 서체(Jua)만 각 화면 <head> 에서 받아 옵니다. 그것도 화면을 막지 않게
   media="print" 로 받아 두었다가 다 오면 켭니다 -- 간판 한 줄 때문에 아이가
   빈 화면을 250ms 보고 있을 이유가 없습니다. 서체를 바꿀 때는 public/*.html 의
   그 줄과 아래 --font-brand, 두 군데를 고치세요. */

/* Fren English 수지메이플영어학원 포털.
   Palette comes from the academy logo: coral pink + warm grey on paper white.
   Sized for a classroom tablet held in two hands — large touch targets, high
   contrast, nothing that depends on hovering. Works down to a phone. */
:root {
  /* 밝은 화면으로 고정합니다.
     안드로이드 크롬은 태블릿이 어두운 모드일 때 «밝은 웹페이지를 알아서 어둡게»
     칠해 줍니다(Auto Dark Theme). 고맙지만 여기서는 해가 됩니다 -- 레벨 색
     다섯(Orange·Pink·Green·Purple·Blue)은 꾸밈이 아니라 **교재 표지의 실제
     색**이고, 아이가 «내 책» 을 그 색으로 알아봅니다. 기계가 짐작으로 칠하면
     초록이 초록이 아니게 됩니다. 이 한 줄이 그 칠을 끄는 표준 방법입니다.
     (제대로 된 어두운 화면을 만들려면 다섯 색을 어두운 바닥에서도 알아볼 수
     있게 다시 골라야 합니다 -- 그건 색을 고르는 일이지 코드 일이 아닙니다.) */
  color-scheme: light;

  /* 간판 서체. 로고의 둥근 느낌을 글자로 옮긴 것입니다. 다른 것으로 바꾸려면
     파일 맨 위 @import 의 family 와 이 줄, 두 군데만 고치면 됩니다. */
  --font-brand: "Jua", "Gowun Dodum", "Apple SD Gothic Neo", sans-serif;
  --brand: #e75a6e;          /* logo coral, deepened a step for contrast */
  --brand-rgb: 231, 90, 110; /* 같은 색의 세 숫자 -- 옅은 배경에 씁니다.
                                학원 설정에서 색을 바꾸면 js/common.js가
                                이 넷을 한꺼번에 다시 칠합니다. */
  --brand-dark: #d34a5e;
  --brand-soft: #fdeef0;     /* coral at whisper volume, for fills */
  --brand-line: #f6ccd2;
  --brand-lift: #ec6779;     /* 버튼 윗변 -- 대표 색보다 한 톤 밝게 */
  /* 옅은 대표색 바탕(--brand-soft) 위에 **작은 글씨**를 쓸 때의 색. 대표색 그대로
     쓰면 3.07:1 이라 학생 코드 칩이 흐릿했습니다. 학원마다 색이 다르므로 값을
     박아 두지 않고 js/common.js 가 그 학원 색에서 4.5:1 이 되도록 계산해 덮습니다 --
     아래는 우리 코랄 기준 기본값입니다. */
  --brand-ink: #b83548;
  --brand-btn: #e75a6e;      /* 단추 바탕. 흰 글자가 3:1 이 안 되면 js 가 어둡게 덮습니다 */
  /* 머리글 간판(학원 이름) 색. 간판은 그 학원의 얼굴이라 **웬만하면 고른 색 그대로**
     둡니다. 다만 노란색(1.7:1) · 연두(1.8:1) 처럼 흰 종이에서 **읽히지 않는** 색만
     구해 줍니다. 우리 코랄(3.5:1)은 손대지 않습니다. */
  --brand-mark: #e75a6e;
  --ink: #33383f;            /* the logo's grey, darkened for body text */
  /* 흐린 글씨. #767c85 는 종이 바탕에서 3.97:1 이라 기준(4.5:1)에 못 미쳤습니다 --
     «남은 숙제 없음» 같은 안내가 아이에게 흐릿했습니다. 색조는 그대로 두고
     4.5 를 넘기는 가장 밝은 값으로 한 칸만 내렸습니다(종이 4.70 · 카드 4.98). */
  --ink-soft: #6b7079;
  --line: #e8e3dd;           /* warm hairline, not blue-grey */
  --bg: #faf8f5;             /* paper, not screen-white */
  --card: #ffffff;
  /* «맞음 · 끝냄» 초록은 한 집안으로 (2026-10 디자인 정리).
     예전에는 화면마다 초록이 달랐습니다: 진한 글자 #23663f · #1f6b40 · #1f7a46 · #22603c,
     칠 #2e8f5b · #2e9e5b · #1f9d55 · #2f9e5f, 옅은 바탕 #e9f4ee · #e9f6ee · #eef8f1 · #eef9f1 · #eaf7ef.
     같은 «잘했어요» 가 화면마다 다른 초록이라 한 제품처럼 보이지 않았고, 흰 글자를 얹은
     칠(«다 했어요» 단추 · 숙제 끝 띠 · 라이브 코스 카드)은 3.4:1 이라 14~16px 글씨에 모자랐습니다.
     그래서 넷으로 묶습니다. --ok 는 흰 글자 5.3:1 · 흰 바탕 위 글자 5.3:1 · 옅은 바탕 위 4.7:1. */
  --ok: #277a4e;
  --ok-ink: #1f6b40;         /* 옅은 초록 바탕 위의 글자 (5.8:1) */
  --ok-soft: #e9f6ee;        /* 옅은 초록 바탕 */
  --ok-line: #bfe0cd;        /* 옅은 초록 테두리 */
  --bad: #cc4444;
  --warn: #8a5c1c;          /* 옅은 바탕 위 글자로도 4.5:1 (예전 #a8742a 는 3.6 -- 2026-10-30 axe) */
  --line-soft: #f2eeea;      /* an even quieter rule, for rows inside a table */
  --tint: #fbf9f7;           /* card headers and table headers sit on this */
  --radius: 16px;
  /* 카드 «안» 의 판(보기 · 코스 한 줄 · 새 도장 띠)의 둥글기. 예전에는 12 · 14 · 16 이 섞여
     같은 시험 안에서도 보기(14)와 배치고사 보기(16)가 달랐습니다. 테마가 이 값만 덮습니다. */
  --r-md: 14px;
  /* 테두리에 손가락 · 마우스가 올라갔을 때의 색. 테마가 따뜻한 색으로 덮습니다 --
     박아 둔 푸른 회색(#b9c0c9 · #aab2bc)이 메이플 크림 화면에 끼어 있었습니다. */
  --line-hover: #b9c0c9;
  --shadow: 0 1px 2px rgba(51, 56, 63, .05), 0 10px 28px rgba(51, 56, 63, .06);
  --shadow-lift: 0 3px 6px rgba(51, 56, 63, .07), 0 18px 40px rgba(51, 56, 63, .10);
  /* 교재 사다리 다섯 색 -- 책 표지의 그 색 그대로 */
  --lv-orange: #ed892d; --lv-pink: #f25f7c; --lv-green: #3fa05c;
  --lv-purple: #8c5cc4; --lv-blue: #3d7ec8;
}
* { box-sizing: border-box; }
/* 두 손으로 쥔 태블릿에서는 손가락이 화면에 닿아 있는 시간이 깁니다. 문제를
   푸는 중에 두 손가락이 스치면 화면이 확대돼 글자가 잘리고, 아이는 되돌리는
   법을 모릅니다. 확대를 막고 두 번 눌러 확대되는 것도 막습니다.
   (선생님 화면은 표가 많아 확대가 필요할 수 있어 그대로 둡니다.) */
/* 위에서 아래로 잡아당겨 새로고침하는 것을 막습니다.
   이건 문서가 아니라 **앱**입니다(홈 화면 아이콘으로 엽니다). 시험을 푸는
   중에 화면 위쪽에서 손가락이 조금만 미끄러져도 새로고침이 걸리고, 그러면
   브라우저가 «사이트에서 나가시겠습니까 / 변경사항이 저장되지 않을 수
   있습니다» 를 띄웁니다 -- 우리가 문구를 못 바꾸는 유일한 창이고, 아이는
   «변경사항» 이 무슨 말인지 모릅니다. 당기는 동작 자체를 없애면 그 창이
   뜰 일이 없습니다. 진짜 새로고침은 브라우저 차림표로 하면 됩니다.
   html 에 겁니다 -- body 에만 걸면 브라우저가 창 전체로 올려 주지 않는
   경우가 있습니다. */
html { touch-action: pan-x pan-y; -webkit-text-size-adjust: 100%; overscroll-behavior-y: contain; }
button, .chip, .tile, .choice, a { touch-action: manipulation; }
/* 한국어 줄바꿈: 기본값은 글자 사이 어디서든 줄이 바뀝니다 -- «범위 고르/기» · «시험 시/작» 처럼
   낱말 한가운데서 끊겨 읽기 어렵습니다(폰에서 말풍선이 자리를 차지할 때 특히). 낱말(띄어쓴 덩이)
   단위로만 바꾸되, 한 덩이가 줄보다 길면(긴 이름 · 주소) 그때만 끊게 해서 넘치지 않게 합니다. */
html { word-break: keep-all; overflow-wrap: anywhere; }
input, textarea, select, code, pre { word-break: normal; }
/* 줄 나누기 다듬기(지원하는 브라우저에서만 먹고, 안 되는 곳은 그냥 지금처럼 보입니다):
   제목 · 말풍선 · 안내 글은 줄 길이를 고르게(«골라 / 줘!» 처럼 한 낱말만 남지 않게),
   문단은 마지막 줄에 낱말 하나만 남는 것을 피합니다. */
h1, h2, h3, .perch-say, .cheer-say, .bubble, .msg { text-wrap: balance; }
p, li { text-wrap: pretty; }

body {
  margin: 0;
  font: 400 16px/1.6 "Noto Sans KR", "Apple SD Gothic Neo", "Malgun Gothic",
        "맑은 고딕", system-ui, sans-serif;
  color: var(--ink);
  /* 종이 위에 아주 옅은 색 기운 두 번 -- 화면이 밋밋하지 않되 글을 방해하지 않게 */
  background:
    radial-gradient(1000px 460px at 88% -120px, rgba(var(--brand-rgb), .06), transparent 62%),
    radial-gradient(820px 420px at -80px 34%, rgba(61, 126, 200, .045), transparent 60%),
    var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  -webkit-tap-highlight-color: transparent;
}
.wrap { max-width: 860px; margin: 0 auto; padding: 22px 16px 64px; }
/* 스피드 퀴즈처럼 한 열이 좁아야 보기 좋은 화면. 인라인 style 로 두면 가로
   태블릿 규칙이 못 넓혀서 클래스로 뺐습니다. */
.wrap.narrow { max-width: 640px; }

/* ---- header: the academy's own logo, then the page name ---- */
header.bar {
  display: flex; align-items: center; gap: 14px;
  padding: 17px 18px 14px; border-bottom: 1px solid var(--line);
  /* 맨 위 3px는 교재 사다리 다섯 색 -- 포털과 책이 한집임을 한 줄로 말한다 */
  background:
    linear-gradient(90deg,
      var(--lv-orange) 0 20%, var(--lv-pink) 0 40%, var(--lv-green) 0 60%,
      var(--lv-purple) 0 80%, var(--lv-blue) 0 100%) top / 100% 3px no-repeat,
    rgba(255, 255, 255, .86);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  backdrop-filter: saturate(180%) blur(12px);
  position: sticky; top: 0; z-index: 10;
}
header.bar .brand { display: flex; align-items: center; flex: none; }
header.bar .brand img { height: 26px; width: auto; display: block; }
header.bar h1 {
  font-size: 15px; font-weight: 600; margin: 0; flex: 1;
  color: var(--ink-soft); letter-spacing: -0.01em;
  padding-left: 14px; border-left: 1px solid var(--line);
}
/* 머리글의 두 자리는 가는 곳이 다르다.
     로고 -> 홈
     제목 -> 그 화면의 첫 화면(범위 고르기)
   한동안 둘 다 홈으로 갔는데, 시험을 보다가 «단어 시험» 을 눌러 범위를 다시
   고르려던 아이가 홈으로 튕겨 나갔다. 같은 곳으로 가는 문이 둘일 이유가 없다.
   (홈·숙제·내 기록은 첫 화면이 곧 그 화면이라 제목도 자기 자리로 간다.) */
header.bar h1 a {
  color: inherit; text-decoration: none;
  padding: 4px 0; /* 손가락이 닿을 세로 여유 */
}
header.bar h1 a:hover { color: var(--brand); }
header.bar .who {
  font-size: 13px; color: var(--brand-ink); font-weight: 600;
  background: var(--brand-soft); border: 1px solid var(--brand-line);
  padding: 3px 10px; border-radius: 99px;
}

.card {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 24px; margin-bottom: 18px; box-shadow: var(--shadow);
}
h2 {
  display: flex; align-items: center; gap: 10px;
  font-size: 18px; font-weight: 700; margin: 0 0 14px; letter-spacing: -0.015em;
}
h2::before {
  content: ''; flex: none; width: 4px; height: 17px;
  border-radius: 99px; background: var(--brand);
}
h3 {
  display: flex; align-items: center; gap: 8px;
  font-size: 15.5px; font-weight: 700; margin: 28px 0 12px; letter-spacing: -0.01em;
}
h3::before {
  content: ''; flex: none; width: 6px; height: 6px;
  border-radius: 50%; background: var(--brand-line);
}
p.hint { color: var(--ink-soft); font-size: 14px; margin: 8px 0 0; line-height: 1.6; }

label { display: block; font-size: 13px; color: var(--ink-soft); font-weight: 600; margin: 14px 0 6px; }
input, select {
  width: 100%; padding: 12px 14px; font-size: 16px; font-family: inherit;
  border: 1px solid var(--line); border-radius: 9px; background: #fff; color: var(--ink);
}
input:focus, select:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
/* 여러 줄 칸도 한 줄 칸과 같은 옷. 위 규칙에서 빠져 있어서 브라우저 기본(안쪽 2px · 고정폭 글꼴)으로
   그려졌습니다 -- 함께 풀기 영작 칸은 글자가 테두리에 붙었고, 도움말 «무엇이 안 되나요» 와 학부모에게
   보낼 글 칸은 타자기 글꼴이었습니다. 칸마다 따로 정한 것(단어장 붙여넣기의 고정폭 등)은 그대로 이깁니다. */
textarea {
  width: 100%; box-sizing: border-box; padding: 10px 14px; font-size: 16px; font-family: inherit; line-height: 1.5;
  border: 1px solid var(--line); border-radius: 9px; background: #fff; color: var(--ink); resize: vertical;
}
textarea:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }

button {
  font: inherit; font-size: 15px; font-weight: 700; cursor: pointer;
  padding: 13px 20px; border-radius: 9px; border: 1px solid transparent;
  /* --brand-btn 은 «흰 글자가 읽히는 대표색» 입니다. 우리 코랄은 3.45:1 이라 그대로
     쓰이고, 노랑(1.68) · 하늘(2.64) · 연두(1.84) 를 고른 학원에서만 자동으로 어두워
     집니다. 학원이 고른 색을 함부로 바꾸지 않되, 글자가 사라지는 것은 막습니다. */
  background: linear-gradient(180deg, var(--brand-lift), var(--brand-btn));
  color: #fff; min-height: 48px; letter-spacing: -0.01em;
  box-shadow: 0 1px 2px rgba(var(--brand-rgb), .28);
  transition: background .15s, box-shadow .15s, transform .06s;
}
/* :hover 는 마우스가 있는 화면에서만 (아래 ghost · mini 도). 태블릿은 손가락을 뗀 자리에 :hover 가 남아,
   그 자리에 새로 뜬 보기 · 빈칸 낱말이 진한 대표색으로 칠해졌습니다 -- 검은 글씨가 안 읽히고 «이미 고른 것»
   처럼 보였습니다. */
@media (hover: hover) { button:hover { background: var(--brand-dark); } }
button:active { transform: translateY(1px); }
button:disabled { opacity: .45; cursor: default; transform: none; box-shadow: none; }
button.ghost {
  background: #fff; color: var(--ink); border-color: var(--line);
  font-weight: 600; box-shadow: none;
}
@media (hover: hover) { button.ghost:hover { background: var(--bg); border-color: #d9d2ca; } }
button.wide { width: 100%; }

/* The coral drop shadow belongs to the primary button alone. Every other
   button borrows the base rule for its shape and drops the shadow here. */
.choice, .chip-x, .cloze-slot, .cloze-word, .speak-btn, .grade-item button {
  box-shadow: none;
}

/* A row of records should not look like a row of buttons. These sit quietly
   until the pointer or a finger finds them. */
button.mini {
  min-height: 34px; padding: 6px 11px; font-size: 13px; font-weight: 600;
  border-radius: 8px; background: var(--tint); color: var(--ink-soft);
  border: 1px solid transparent; box-shadow: none;
}
@media (hover: hover) { button.mini:hover { background: var(--brand-soft); color: var(--brand); border-color: var(--brand-line); } }
@media (hover: hover) { button.mini.danger:hover { background: #fbeaea; color: var(--bad); border-color: #f0cccc; } }
button.mini.solid { background: var(--brand); color: #fff; border-color: transparent; }
@media (hover: hover) { button.mini.solid:hover { background: var(--brand-dark); color: #fff; } }

/* 되돌릴 수 없는 일의 «확인» 단추. 우리 창(ask · tell)에서 씁니다 --
   «지웁니다» 가 브랜드색이면 «저장» 과 똑같이 생겨서, 손가락이 먼저 갑니다. */
.ask-sheet button.danger {
  background: var(--bad); border-color: var(--bad); color: #fff;
}
.ask-sheet button.danger:hover { background: #b23a3a; border-color: #b23a3a; }
td.acts { text-align: right; white-space: nowrap; }
td.acts button + button { margin-left: 5px; }
.row { display: flex; gap: 10px; flex-wrap: wrap; }
.row > * { flex: 1; min-width: 130px; }
/* 결과 화면 아래 단추 둘: 폰에서 «같은 Day로 새 문제» 만 두 줄로 접혀 옆 단추(한 줄)와 키가 달랐습니다.
   좁으면 옆 여백을 줄이고 한 줄로 둡니다(390px 에서 두 단추가 반씩 149px). */
@media (max-width: 420px) {
  #done .row > * { flex: 1 1 auto; }   /* 반반이 아니라 글자 길이만큼 -- 긴 쪽이 더 받습니다 */
  #done .row > button, #done .row > a > button { white-space: nowrap; padding-left: 12px; padding-right: 12px; }
}
/* 단추 몇 개만 놓는 줄. 늘어나면 «모두 고르기» 가 화면을 가로지릅니다. */
.row.tight > * { flex: 0 0 auto; min-width: 0; }
/* «제 크기 그대로» 라도 상자보다 커지면 안 됩니다. 되돌리기 단추가 학원 이름을
   품고 330px 이 되어 320px 폰에서 화면을 40px 밀어냈습니다. */
.row.tight > * { max-width: 100%; }

/* ---- portal home tiles: line icons, no decoration for its own sake ---- */
/* 타일 열두 개가 폰에서 한 줄에 하나씩 쌓여 홈이 세로 4900px 이었습니다 --
   아이는 «내 기록» 까지 가려고 열두 번 넘게 밀어 내려야 했습니다. 210px 을
   요구하니 폰(쓸 수 있는 폭 380px)에서 두 칸이 안 들어간 것입니다.
   150px 으로 낮추면 폰 두 칸 · 태블릿 세~네 칸이 되고 높이는 절반이 됩니다. */
.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
/* «오늘 할 것» 둘도 두 칸입니다. 한 칸씩 크게 두었더니, 숙제가 없는 날에도
   «남은 숙제 없음» 이 화면 위쪽 200px 을 차지했습니다 -- 아무 일도 없는 칸이
   제일 좋은 자리를 먹고 있었습니다. */
.tiles-today { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
/* 오늘 할 일이 **있을 때만** 눈에 띄게 합니다(js 가 .has 를 붙입니다). */
.tiles-today .tile.has { border-color: var(--tone); box-shadow: var(--shadow-lift); }
.tiles-today .tile.has span { color: var(--tone); font-weight: 700; }
.tile {
  display: block; text-decoration: none; color: inherit; background: var(--card);
  border: 1px solid var(--line); border-radius: var(--radius); padding: 20px;
  box-shadow: var(--shadow);
  transition: border-color .14s, transform .14s, box-shadow .14s;
}
.tile { --tone: var(--brand); }
.tile.t-test   { --tone: var(--brand); }
.tile.t-study  { --tone: var(--lv-purple); }
.tile.t-dict   { --tone: var(--lv-blue); }
.tile.t-read   { --tone: var(--lv-green); }
.tile.t-cloze  { --tone: #1f9a8a; }
.tile.t-sent   { --tone: #7a5cc4; }
.tile.t-speed  { --tone: var(--lv-orange); }
.tile.t-match  { --tone: #c2477a; }
.tile.t-hear   { --tone: #2f8fb5; }
.tile.t-gnote  { --tone: #b0782b; }
.tile.t-review { --tone: #c8783a; }
.tile.t-hw     { --tone: #5f6fd1; }
.tile.t-my     { --tone: #64748b; }
.tile:hover { border-color: var(--tone); transform: translateY(-2px); box-shadow: var(--shadow-lift); }
.tile:active { transform: none; }
.tile { padding: 15px 14px 16px; }
.tiles-today .tile { padding: 15px 14px 16px; }
.tile .big {
  width: 40px; height: 40px; border-radius: 12px;
  background: var(--tone); color: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: inset 0 -2px 0 rgba(0, 0, 0, .12);
}
.tile .big svg { width: 22px; height: 22px; }
.tile b { display: block; margin: 11px 0 2px; font-size: 15.5px; letter-spacing: -0.01em; }
.tile span { color: var(--ink-soft); font-size: 12.5px; line-height: 1.4; display: block; }
.tiles-today .tile b { font-size: 15.5px; margin-top: 11px; }
.tiles-today .tile span { font-size: 12.5px; }
/* 두 칸으로 서면 설명 길이가 달라 타일 키가 들쭉날쭉합니다. 바닥을 맞춥니다. */
.tiles .tile { display: flex; flex-direction: column; }
.tiles .tile span { margin-top: auto; }

/* small icon chip used in lists (homework kinds, etc.) */
.icon-chip {
  flex: none; width: 36px; height: 36px; border-radius: 9px;
  background: var(--brand-soft); color: var(--brand);
  display: flex; align-items: center; justify-content: center;
}
.icon-chip svg { width: 18px; height: 18px; }

/* ---- quiz ---- */
.progress { height: 5px; background: var(--line); border-radius: 99px; overflow: hidden; margin-bottom: 18px; }
.progress i { display: block; height: 100%; background: var(--brand); transition: width .2s; }
.prompt { font-size: clamp(26px, 6vw, 34px); font-weight: 700; text-align: center; padding: 26px 10px; word-break: keep-all; letter-spacing: -0.01em; }
.choices { display: grid; gap: 9px; }
.choice {
  text-align: left; background: #fff; color: var(--ink); border: 1px solid var(--line);
  font-weight: 500; font-size: 16px; padding: 15px 17px;
}
/* :hover 는 마우스가 있는 화면에서만. 태블릿 · 폰은 손가락을 뗀 뒤에도 그 자리에 :hover 가
   남아서, 다음 문제의 첫 보기가 나오자마자 «이미 고른 것» 처럼 칠해져 있었습니다.
   아래 빈칸 낱말 · 문장 카드 · 끊어 읽기 틈 · 문장 읽어 주기도 같은 까닭으로 감쌉니다. */
@media (hover: hover) { .choice:hover { background: var(--bg); border-color: var(--brand); } }
.choice.picked { border-color: var(--brand); background: var(--brand-soft); font-weight: 600; }

/* ---- results ---- */
.score { text-align: center; padding: 10px 0 20px; }
.score .n { font-size: 46px; font-weight: 700; letter-spacing: -0.02em; }
.score .n small { font-size: 19px; color: var(--ink-soft); font-weight: 500; }
ul.answers { list-style: none; margin: 0; padding: 0; }
ul.answers li {
  display: flex; gap: 10px; align-items: baseline;
  padding: 11px 0; border-bottom: 1px solid var(--line); font-size: 15px;
}
ul.answers li:last-child { border-bottom: 0; }
/* 결과 목록의 소리 단추(words-test): 손가락 크기, 줄 맨 끝 */
ul.answers .say-mini {
  order: 9; margin-left: auto; align-self: center; flex: none; min-height: 40px; min-width: 44px; padding: 0 10px;
  background: var(--tint); color: var(--ink); border: 1px solid var(--line); border-radius: 99px; box-shadow: none; font-size: 17px;
}
/* O/X 한 글자이거나 "100%" 세 글자이거나, 뒤따르는 글이 같은 자리에서 시작해야
   눈이 목록을 세로로 훑을 수 있다. */
.mark { flex: none; min-width: 34px; font-weight: 700; }
.mark.o { color: var(--ok); }
.mark.x { color: var(--bad); }
.answers .en { font-weight: 600; }
.answers .sep { color: var(--ink-soft); }
/* 틀린 답은 빨간 줄 긋기로 보여 줍니다. 그런데 앞의 빈칸까지 줄이 그어져서
   «챙기다내 답: 깨끗이 하다» 처럼 정답과 내 답이 붙어 보였습니다 -- 아이가
   어디까지가 정답인지 못 읽습니다. 사이는 여백으로 벌립니다(여백에는 줄이
   안 그어집니다). 답이 아예 없을 때의 «(답 없음)» 도 같습니다. */
.answers .wrong, .answers .muted { margin-left: 8px; }
/* 내 답은 줄을 바꿔 빨간 글씨로만 -- 예전엔 «내 답:» 이름표까지 줄이 그어져 줄바꿈에서 지저분했습니다 */
.answers .wrong { color: var(--bad); display: block; margin-top: 2px; }
/* 리딩: 문제 종류 꼬리표와 해설 */
.qtag { display: inline-block; font-size: 12px; font-weight: 600; color: var(--brand-ink, #b23a4e);
        background: var(--brand-soft, #fdeef0); border-radius: 999px; padding: 1px 9px; vertical-align: 2px; }
.answers details.why { margin-top: 6px; font-size: 14px; color: #555; line-height: 1.55; }
.answers details.why summary { cursor: pointer; color: var(--brand-ink, #b23a4e); font-weight: 600; font-size: 13px; }
.answers details.why div { background: var(--tint); border-radius: 10px; padding: 8px 10px; margin-top: 4px; }

table { width: 100%; border-collapse: collapse; font-size: 14.5px; }
th, td { text-align: left; padding: 12px 12px; border-bottom: 1px solid var(--line-soft); }
th {
  color: var(--ink-soft); font-weight: 600; font-size: 12.5px; letter-spacing: .01em;
  background: var(--tint); border-bottom: 1px solid var(--line); white-space: nowrap;
}
tbody tr { transition: background .12s; }
tbody tr:hover > td { background: var(--tint); }
tbody tr:last-child > td { border-bottom: 0; }

/* Tables live in a framed, scrollable box so a wide one slides sideways
   instead of pushing the whole page off a tablet screen. */
.tbl {
  border: 1px solid var(--line); border-radius: 12px;
  overflow-x: auto; margin-top: 4px;
}
.tbl > table { min-width: 100%; }
.tbl > p { margin: 0; padding: 18px; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
tr.tap { cursor: pointer; }
tr.tap:hover td { background: var(--bg); }

.msg {
  padding: 12px 15px; border-radius: 10px; font-size: 14px; margin: 12px 0;
  border-left: 3px solid currentColor;
}
.msg.bad { background: #fbeaea; color: #a03434; }
.msg.good { background: var(--ok-soft); color: var(--ok-ink); }
.msg.info { background: var(--brand-soft); color: #b34355; }
/* 나쁜 일은 아니지만 그냥 지나치면 안 되는 것. «숨긴 학생을 되살렸습니다» 처럼,
   빨강은 과하고 분홍은 눈에 안 걸리는 자리에 씁니다. */
.msg.warn { background: #fdf6ea; color: var(--warn); }
.pill {
  display: inline-block; padding: 3px 10px; border-radius: 99px;
  font-size: 12px; font-weight: 600; background: #eef0f3; color: var(--ink-soft);
}
.pill.home { background: #f8efe0; color: var(--warn); }
.pill.done { background: var(--ok-soft); color: var(--ok-ink); }

.chip {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--brand-soft); border: 1px solid var(--brand-line); color: var(--ink);
  border-radius: 99px; padding: 7px 8px 7px 14px; margin: 0 8px 8px 0; font-size: 14px;
}
.chip-x {
  background: none; border: 0; color: var(--ink-soft); cursor: pointer;
  font-size: 18px; line-height: 1; padding: 0 6px; min-height: 0;
}
.chip-x:hover { background: none; color: var(--bad); }

/* The card face keeps a fixed height and the buttons keep fixed slots, so
   nothing shifts under a finger between "뜻 보기" and the answer. */
.flash { text-align: center; padding: 22px 12px; min-height: 190px;
         display: flex; flex-direction: column; justify-content: center; }
.flash .word { font-size: 38px; font-weight: 700; word-break: keep-all; letter-spacing: -0.01em; }
.flash .mean { font-size: 25px; color: var(--brand); margin-top: 18px; min-height: 34px; font-weight: 600; }
/* 카드 밀기(words-study): 손가락이 있는 기기에서만 안내를 보이고, 민 쪽으로 테두리 색을 칠합니다 */
.flash { touch-action: pan-y; user-select: none; -webkit-user-select: none; }
.flash.swipe-yes { border-color: var(--ok) !important; box-shadow: inset 0 0 0 2px var(--ok); }
.flash.swipe-no { border-color: #e2a0a0 !important; box-shadow: inset 0 0 0 2px #e2a0a0; }
.swipe-hint { display: none; margin: 6px 0 0; text-align: center; font-size: 13px; color: var(--ink-soft); }
@media (pointer: coarse) { .swipe-hint { display: block; } }
.center { text-align: center; }
.muted { color: var(--ink-soft); }
.hidden { display: none !important; }
/* 함께 풀기 팀 대결 (2026-10) -- 아이 화면 · TV · 선생님 판 */
.team-bar { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 0 0 14px; }
.team-bar .tb { position: relative; display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-radius: 14px; border: 2px solid; font-weight: 800; min-width: 0; white-space: nowrap; }
.team-bar .tb.t0 { border-color: #5b8fe0; background: #eef4fd; color: #1f4f9e; }
.team-bar .tb.t1 { border-color: #e47b7b; background: #fdf0f0; color: #a33232; }
.team-bar .tb i { font-style: normal; }
/* «우리 팀» 은 테두리 위에 붙은 꼬리표 -- 좁은 폰에서도 이름 · 점수 줄을 밀지 않게. */
.team-bar .tb small { position: absolute; top: -10px; left: 12px; font-size: 12px; font-weight: 800; padding: 1px 8px; border-radius: 99px; color: #fff; }   /* «우리 팀» 11px → 하한 12px */
.team-bar .tb.t0 small { background: #4a7fd6; }
.team-bar .tb.t1 small { background: #d96262; }
.team-bar .tb.me { border-width: 3px; }
.team-bar .tb span { margin-left: auto; font-size: 1.3em; font-variant-numeric: tabular-nums; }
.team-bar .tb.win { box-shadow: 0 0 0 4px #f5c84c; }
.team-bar .tb-end { grid-column: 1 / -1; margin: 2px 0 0; text-align: center; font-weight: 800; font-size: 1.1em; }
/* 좁은 폰(360 · 375)에서는 «100점» 이 상자 테두리 밖으로 삐져나왔습니다(줄을 안 바꾸므로).
   점수는 꼭 보여야 하니 팀 이름이 먼저 줄어들고(…), 여백도 조금 줄입니다.
   아주 좁으면(320) 색 점을 뺍니다 -- 상자 색이 이미 팀을 말해 줍니다. TV 는 넓어서 그대로입니다. */
.team-bar .tb b { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 420px) {
  .team-bar { gap: 8px; }
  .team-bar .tb { padding: 8px; gap: 4px; }
  .team-bar .tb span { font-size: 1.1em; }
}
@media (max-width: 340px) { .team-bar .tb i { display: none; } }
.team0::before, .team1::before { content: ''; display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 6px; vertical-align: middle; }
.team0::before { background: #5b8fe0; }
/* 한 명 뽑기 (2026-10) */
.pick-ov { position: fixed; inset: 0; z-index: 90; display: grid; place-items: center; padding: 16px; background: rgba(20, 16, 12, .45); cursor: pointer; }
.pick-ov .pc { background: #fff; border-radius: 28px; padding: 32px 48px; text-align: center; box-shadow: 0 20px 60px rgba(0, 0, 0, .25); max-width: 100%; animation: pick-pop .25s ease-out; }
.pick-ov .pc i { font-style: normal; font-size: 2.6em; display: block; }
.pick-ov .pc b { display: block; font-size: 3.2em; line-height: 1.15; margin: 8px 0 4px; word-break: keep-all; color: var(--brand, #c43d4b); }
/* 회색은 --ink-soft 입니다(.muted 와 같은 색). --muted 라는 변수는 없어서 글이 이름만큼 진했습니다. */
.pick-ov .pc span { display: block; color: var(--ink-soft); font-size: 1.15em; font-weight: 700; }
.pick-ov.rolling .pc b { color: var(--ink-soft); }
.pick-ov.big { font-size: 26px; }
@keyframes pick-pop { from { transform: scale(.85); opacity: 0; } to { transform: none; opacity: 1; } }
.team1::before { background: #e47b7b; }

/* round speaker button on the dictation screen */
.speak-btn {
  width: 84px; height: 84px; border-radius: 50%; margin: 0 auto;
  background: var(--brand-soft); border: 1px solid var(--brand-line); color: var(--brand);
  display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.speak-btn:hover { background: var(--brand-soft); }
.speak-btn svg { width: 36px; height: 36px; }

/* Reading passages: generous measure and leading, read at arm's length. */
.passage {
  font-size: 17.5px; line-height: 1.9; margin: 0;
  word-break: keep-all; overflow-wrap: break-word;
}

/* ---- QR login cards: on screen a preview strip, on paper a card sheet ---- */
#qrSheet {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 10mm;
  max-width: 860px; margin: 0 auto; padding: 16px;
}
.qr-card {
  border: 1px dashed #b9b2a9; border-radius: 10px; padding: 8mm 6mm;
  text-align: center; background: #fff;
  break-inside: avoid; page-break-inside: avoid;
}
.qr-card-logo { width: 34mm; height: auto; display: block; margin: 0 auto 5mm; }
.qr-card-img svg { width: 32mm; height: 32mm; }
.qr-card-code { font-size: 20px; font-weight: 700; letter-spacing: .06em; margin-top: 4mm; }
.qr-card-note { font-size: 11px; color: #767c85; margin-top: 1.5mm; }
/* 인쇄할 때 종이로 나가는 것은 둘 중 하나뿐이다: QR 카드지 또는 인쇄물.
   숨어 있지 않은 쪽만 나간다 -- .hidden 이 display:none !important 이므로. */
/* 법률 문서(동의서 · 개인정보처리방침 · 약관, body.legal)는 본문 <main> 하나가 곧 종이입니다.
   이 규칙이 거기에도 걸려 «인쇄» 를 누르면 빈 종이 한 장만 나갔습니다. */
@media print {
  body:not(.legal) > *:not(#qrSheet):not(#paper) { display: none !important; }
  #qrSheet:not(.hidden) { display: grid !important; }
  #paper:not(.hidden) { display: block !important; }
  html, body { background: #fff !important; }
}
/* 종이 여백은 화면이 정합니다(2026-10-31). 브라우저 인쇄 창에서 여백을 «없음» 으로 두면 시험지의 «이름» 칸과
   «40문항» 이 종이 끝에 붙어 프린터가 잘라 먹었고, «배경 그래픽» 을 켜면 화면의 옅은 무늬가 종이 아래에 찍혔습니다. */
@page { size: A4; margin: 12mm; }

/* ---- 인쇄물: 단어 시험지 · 단어장 · 정답지 -------------------------------
   화면에서는 종이처럼 보이는 미리보기, 인쇄하면 이것만 나간다. */
#paper { max-width: 860px; margin: 18px auto 0; }
.sheet-page {
  background: #fff; border: 1px solid var(--line); border-radius: 10px;
  padding: 22px 26px 28px; margin-bottom: 16px;
}
.sheet-page + .sheet-page { page-break-before: always; }
.ph {
  display: flex; align-items: center; gap: 14px;
  border-bottom: 2px solid var(--ink); padding-bottom: 10px; margin-bottom: 14px;
}
.ph-logo { height: 22px; width: auto; flex: none; }
.ph-mid { flex: 1; display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.ph-mid b { font-size: 17px; letter-spacing: -0.01em; }
.ph-mid span { font-size: 13px; color: var(--ink-soft); }
.ph-right { font-size: 13px; color: var(--ink-soft); flex: none; }
.ph-name {
  display: flex; gap: 22px; flex-wrap: wrap;
  font-size: 13.5px; color: var(--ink-soft);
  padding-bottom: 12px; margin-bottom: 6px; border-bottom: 1px solid var(--line);
}

ol.wl { margin: 0; padding: 0 0 0 4px; list-style: none; counter-reset: wl; }
ol.wl.c2 { column-count: 2; column-gap: 34px; }
ol.wl li {
  counter-increment: wl;
  display: flex; align-items: baseline; gap: 8px;
  padding: 7px 0; break-inside: avoid;
  border-bottom: 1px solid #eee;
}
ol.wl li::before {
  content: counter(wl) "."; flex: none; width: 24px;
  font-size: 12.5px; color: var(--ink-soft); font-variant-numeric: tabular-nums;
}
.wl-q { font-size: 15px; font-weight: 600; flex: none; max-width: 52%; word-break: keep-all; }
.wl-a { flex: 1; font-size: 14.5px; color: var(--ink); min-height: 1.2em; }
/* 답을 쓰는 자리에는 줄을 그어 준다 -- 빈칸이면 어디에 쓰라는 것인지 보여야 한다 */
.wl-a:empty { border-bottom: 1px dotted #b9b2a9; }
.wl-a.key { color: var(--brand); font-weight: 600; }

/* 상담용 한 장: 숫자 넷을 먼저 보여 주고 그 아래 근거를 붙인다 */
.rp-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-bottom: 6px; }
.rp-box {
  border: 1px solid var(--line); border-radius: 8px; padding: 12px 14px; text-align: center;
}
.rp-box b { display: block; font-size: 20px; letter-spacing: -0.02em; }
.rp-box span { display: block; margin-top: 2px; font-size: 12px; color: var(--ink-soft); }
.rp-foot {
  margin-top: 20px; padding-top: 10px; border-top: 1px solid var(--line);
  font-size: 11.5px; color: var(--ink-soft);
}
.sheet-page h3 { margin: 20px 0 8px; }
.sheet-page table { font-size: 13px; }
.sheet-page th { background: none; border-bottom: 1px solid var(--ink); }

/* 성의 없이 낸 시험 -- 점수만으로는 운 좋게 맞은 것과 구분되지 않는다 */
.pill.rush { background: #fbeaea; color: #a03434; }

@media print {
  #paper { max-width: none; margin: 0; }
  .sheet-page { border: 0; border-radius: 0; padding: 0 0 10mm; margin: 0; }
  ol.wl li { border-bottom: 1px solid #ddd; }
  .wl-a.key { color: #000; }
  .rp-box { border-color: #ccc; }
  /* 막대는 배경색으로 그립니다. 브라우저는 인쇄할 때 배경을 지우는 것이
     기본이라, 그대로 두면 부모님께 드리는 장에 **빈 막대만** 나갑니다. */
  .sheet-page .pbar, .sheet-page .pbar i,
  .sheet-page .bk-track, .sheet-page .bk-track i {
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  /* 종이에서는 자라는 시늉이 필요 없습니다(멈춘 순간이 찍히면 짧게 나갑니다) */
  .bk-track i, .run-bar i { animation: none !important; }
}

/* ---- cloze (읽고 채우기) ---- */
.cloze-passage { line-height: 2.15; }
.cloze-slot {
  display: inline-block; min-width: 74px; margin: 0 2px; padding: 3px 10px;
  border: 1.5px dashed #c9c2b9; border-radius: 8px; background: var(--bg);
  color: var(--ink-soft); font: inherit; font-size: 15.5px; min-height: 0;
  vertical-align: baseline;
}
.cloze-slot.active { border-color: var(--brand); border-style: solid; background: var(--brand-soft); color: var(--brand); }
.cloze-slot.filled { border-style: solid; border-color: var(--line); background: #fff; color: var(--ink); font-weight: 600; }
.cloze-slot.filled.active { border-color: var(--brand); }
.cloze-bank { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px; padding-top: 16px; border-top: 1px dashed var(--line); }
.cloze-word {
  background: #fff; color: var(--ink); border: 1px solid var(--line);
  font-weight: 600; font-size: 15.5px; padding: 10px 16px; min-height: 0;
}
@media (hover: hover) { .cloze-word:hover { border-color: var(--brand); background: var(--brand-soft); } }
.cloze-word.used { opacity: .35; text-decoration: line-through; }

/* ---- speed quiz ---- */
.speed-clock {
  font-size: 26px; font-weight: 700; font-variant-numeric: tabular-nums;
  color: var(--ink); background: var(--bg); border: 1px solid var(--line);
  border-radius: 10px; padding: 2px 14px; min-width: 58px; text-align: center;
}
.speed-clock.danger { color: #fff; background: var(--brand); border-color: var(--brand); }
tr.me td { background: var(--brand-soft); font-weight: 700; }

/* ---- paper dictation ---- */
.paper-num { font-size: 40px; font-weight: 700; letter-spacing: -0.02em; margin-bottom: 14px; }
.speak-big { width: 108px; height: 108px; }
.speak-big svg { width: 46px; height: 46px; }
/* 받아쓰기 결과: 틀린 글자 표시 (정답에서 빠뜨린 글자 · 내 답에서 틀리거나 더 쓴 글자) */
.sd-miss { color: var(--brand); background: var(--brand-soft); border-bottom: 3px solid var(--brand); border-radius: 4px 4px 0 0; padding: 0 2px; margin: 0 1px; font-weight: 800; }
.sd-bad { color: #fff; background: var(--brand); border-radius: 4px; padding: 0 3px; margin: 0 1px; font-weight: 800; }
/* 소리가 같은 낱말(meat · meet)일 때만 뜨는 뜻 */
.same-sound { margin: 14px auto 0; display: inline-block; padding: 6px 14px; border-radius: 999px;
  background: var(--brand-soft); color: var(--ink); font-size: 17px; font-weight: 600; }

/* ---- teacher grading queue ---- */
.grade-item { display: flex; align-items: center; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--line); }
.grade-item:last-child { border-bottom: 0; }
.grade-item .txt { flex: 1; font-size: 15px; }
.grade-item button {
  min-height: 36px; padding: 6px 14px; font-size: 14px; flex: none;
  background: #fff; color: var(--ink-soft); border: 1px solid var(--line);
}
.grade-item button.on-o { background: var(--ok-soft); color: var(--ok-ink); border-color: var(--ok-line); }
.grade-item button.on-x { background: #fbeaea; color: #a03434; border-color: #efc7c7; }
.tnav .badge {
  margin-left: auto; background: var(--brand); color: #fff; border-radius: 99px;
  font-size: 11px; padding: 1px 7px; font-weight: 700;
}

/* ---- teacher screen: sidebar + panes ---- */
.teacher-layout { display: grid; grid-template-columns: 184px 1fr; gap: 20px; align-items: start; }
.tnav {
  position: sticky; top: 70px;
  display: flex; flex-direction: column; gap: 3px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 10px; box-shadow: var(--shadow);
}
.tnav button {
  position: relative;
  display: flex; align-items: center; gap: 11px;
  background: none; color: var(--ink-soft); border: 0; border-radius: 9px;
  padding: 11px 12px; min-height: 0; font-size: 14.5px; font-weight: 600;
  text-align: left; width: 100%; box-shadow: none;
  transition: background .14s, color .14s;
}
.tnav button svg { width: 18px; height: 18px; flex: none; }
.tnav button:hover { background: var(--bg); color: var(--ink); }
/* the coral tick marks the pane you are in, the same mark section headings use */
.tnav button.active { background: var(--brand-soft); color: var(--brand); }
.tnav button.active::before {
  content: ''; position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  width: 3px; height: 18px; border-radius: 0 99px 99px 0; background: var(--brand);
}

/* The class picker and the two export buttons: a strip, not another white box. */
.toolbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-bottom: 16px;
}
.toolbar .tb-label { font-size: 13px; font-weight: 600; color: var(--ink-soft); }
.toolbar select {
  width: auto; min-width: 120px; padding: 9px 12px; font-size: 14.5px;
  font-weight: 600; border-radius: 9px;
}
.toolbar .bubble-row { margin: 0; }
.toolbar .tb-right { margin-left: auto; display: flex; gap: 8px; }
.tmain { min-width: 0; }
.pane { display: none; }
.pane.active { display: block; animation: paneIn .2s ease-out both; }
@keyframes paneIn {
  from { opacity: 0; transform: translateY(5px); }
  to   { opacity: 1; transform: none; }
}
/* Anyone who has asked their device to calm down gets none of the above. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
@media (max-width: 860px) {
  .teacher-layout { grid-template-columns: 1fr; }
  /* 예전에는 `overflow-x: auto` 로 옆으로 밀게 했습니다. 메뉴가 일곱 개일 때는
     그럭저럭이었지만 열 개가 되자 1,410px 짜리 줄이 되어, 화면에는 «둘러보기»
     하나만 보이고 나머지는 밀어야 나왔습니다 -- 밀 수 있다는 것을 모르면 메뉴가
     없는 것과 같습니다. 이제 **접어서 다음 줄로 내립니다.** 두 줄이 되더라도
     다 보이는 편이 낫습니다. */
  .tnav { position: static; flex-direction: row; flex-wrap: wrap; overflow-x: visible; padding: 8px; }
  /* `width: 100%` 은 세로 사이드바용입니다. 가로줄에서 그대로 두면 단추 하나가
     한 줄을 통째로 먹어 열 줄이 됩니다(768px 태블릿 세로에서 453px 이 됐습니다).
     가로줄에서는 글자만큼만 차지하게 두고 접히게 합니다. */
  .tnav button { flex: 0 1 auto; width: auto; min-width: 92px; justify-content: center; padding: 10px 6px; }
  .tnav button span { font-size: 13px; }
  .tnav button.active::before {
    left: 12px; right: 12px; top: auto; bottom: 2px; transform: none;
    width: auto; height: 2px; border-radius: 99px;
  }
  .toolbar .tb-right { margin-left: 0; width: 100%; }
  .toolbar .tb-right button { flex: 1; }
}

/* live board */
.stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(128px, 1fr)); gap: 12px; margin-bottom: 18px; }
.stat {
  position: relative; overflow: hidden;
  background: linear-gradient(180deg, #fff, #ffffff);
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 16px 18px; box-shadow: var(--shadow);
}
/* one coral edge per tile, in four tones, so the four numbers are told apart
   at a glance from across the room */
.stat::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--brand);
}
.stat:nth-child(2)::before { background: var(--ok); }
.stat:nth-child(3)::before { background: var(--warn); }
.stat:nth-child(4)::before { background: #8a93a3; }
.stat b {
  display: block; font-size: 30px; font-weight: 700; letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums; line-height: 1.15;
}
.stat span { display: block; margin-top: 3px; color: var(--ink-soft); font-size: 12.5px; }
.live-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 10px; }
/* 격자 안에 든 안내·단추는 칸 하나가 아니라 한 줄을 다 씁니다 --
   «접속 없는 학생 106명 보기» 가 180px 칸에 끼어 두 줄로 접혔습니다. */
.live-grid > .live-span { grid-column: 1 / -1; }
.live-cell {
  position: relative; overflow: hidden;
  border: 1px solid var(--line); border-radius: 12px; padding: 13px 15px;
  background: var(--bg); opacity: .55;
  transition: transform .14s, box-shadow .14s;
}
/* 배정된 교재의 레벨 색을 왼쪽 띠로. 배정이 없는 학생은 띠도 없다. */
.live-cell[style*="--lv"]::after {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--lv);
}
.live-book { margin-top: 9px; }
.live-book .level-chip { font-size: 11.5px; padding: 2px 9px; }
.live-cell.on:hover { transform: translateY(-2px); box-shadow: var(--shadow-lift); }
.live-cell.on { background: #fff; opacity: 1; }
.live-cell.on.work { border-color: var(--brand-line); background: #fffbfb; }
.live-head { display: flex; align-items: center; gap: 7px; }
.live-dot { width: 8px; height: 8px; border-radius: 50%; background: #cfc9c1; flex: none; }
.live-cell.on .live-dot {
  background: var(--ok);
  box-shadow: 0 0 0 0 rgba(46, 143, 91, .45);
  animation: livepulse 2.4s ease-out infinite;
}
@keyframes livepulse {
  0%   { box-shadow: 0 0 0 0 rgba(46, 143, 91, .45); }
  70%  { box-shadow: 0 0 0 7px rgba(46, 143, 91, 0); }
  100% { box-shadow: 0 0 0 0 rgba(46, 143, 91, 0); }
}
.live-act { font-size: 13.5px; margin-top: 6px; color: var(--ink); font-weight: 600; }
.live-cell:not(.on) .live-act { color: var(--ink-soft); font-weight: 500; }
.live-detail { font-size: 12.5px; color: var(--ink-soft); margin-top: 2px; }
.live-prog { font-size: 12.5px; color: var(--brand); font-weight: 700; margin-top: 2px; }

/* ---- camera QR scanner ---- */
.scan-box {
  position: relative; border-radius: 12px; overflow: hidden;
  background: #1c1e22; aspect-ratio: 4 / 3;
}
.scan-box video { width: 100%; height: 100%; object-fit: cover; display: block; }
.scan-frame {
  position: absolute; inset: 0; margin: auto;
  width: 58%; aspect-ratio: 1; border: 2.5px solid rgba(255,255,255,.9);
  border-radius: 14px; box-shadow: 0 0 0 999px rgba(0,0,0,.28);
}
.scan-hint { text-align: center; }

/* login page */
.login-brand { text-align: center; margin-bottom: 28px; }
/* 로그인: 누가 들어오나 (2026-10) */
.role-tabs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; padding: 4px; margin-bottom: 12px;
  border-radius: 99px; background: var(--tint, #f6efe8); border: 1px solid var(--line); }
.role-tab { min-height: 44px; border-radius: 99px; background: transparent; border: 0; box-shadow: none;
  color: var(--ink-soft); font-weight: 700; font-size: 15px; padding: 0 6px; }
.role-tab.on { background: #fff; color: var(--brand-ink); box-shadow: 0 1px 4px rgba(0,0,0,.08); }
.login-brand img { width: min(240px, 70%); height: auto; }
.login-brand p { margin: 12px 0 0; color: var(--ink-soft); font-size: 13.5px; letter-spacing: .16em; }

/* A name field that saves the moment it loses focus has to show that it did.
   Green edge for a beat, then back to normal -- no dialog to dismiss. */
input.saved-flash {
  border-color: var(--ok);
  background: #f3fbf6;
  transition: border-color .2s, background .2s;
}

/* A card inside a card: same shape, no shadow, sitting on the warm tint so it
   reads as a sheet on a desk rather than a second window. */
.subcard {
  background: var(--tint); border: 1px solid var(--line); border-radius: 12px;
  padding: 18px 20px; margin-bottom: 14px;
}
.subcard:last-child { margin-bottom: 0; }

/* ---- 배정 교재 -------------------------------------------------------------
   레벨 칩은 책 표지 규칙 그대로: 색 면 위에 흰 글자. --lv는 js가 심는다. */
.level-chip {
  display: inline-flex; align-items: center;
  padding: 3px 11px; border-radius: 99px;
  font-size: 12.5px; font-weight: 700; letter-spacing: .01em;
  color: #fff; background: var(--lv, #767c85);
  /* 칩 바탕만 그 레벨 색을 한 단계 어둡게(밝기 상한, 못 하는 브라우저는 검정 20%) -- 흰 글자가 Green 3.3:1 · Blue 4.2:1 · Orange 2.6:1 로 작은
     글씨(12.5px)에서 흐렸습니다(2026-11-03 axe). 막대 · 테두리 등 다른 곳의 레벨 색은 그대로입니다. */
  background: color-mix(in srgb, var(--lv, #767c85) 80%, #000);
  /* 되는 브라우저에서는 밝기만 0.55 아래로 눌러(색조 · 채도 그대로) 다섯 레벨 모두 흰 글자 4.5:1 을 넘깁니다 */
  background: oklch(from var(--lv, #767c85) min(l, 0.55) c h);
  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .14);
  white-space: nowrap;
}

/* 진행 막대(내 교재 · 숙제 «몇 개 중 몇 개» · 선생님 화면). 그 레벨 색을 입는다. */
.pbar {
  height: 9px; background: var(--line-soft); border-radius: 99px;
  overflow: hidden; margin-top: 14px;
}
.pbar i {
  display: block; height: 100%; border-radius: 99px;
  background: var(--lv, var(--brand));
  transition: width .5s cubic-bezier(.2, .7, .3, 1);
}

/* ---- 학생 한 명 자세히 보는 창 --------------------------------------------
   페이지를 옮기지 않고 그 자리에서 펼친다: 상담 중에 뒤로가기를 누를 일이
   없어야 한다. 바깥을 누르거나 Esc로 닫힌다. */
.sheet {
  position: fixed; inset: 0; z-index: 50;
  background: rgba(40, 43, 48, .34);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 40px 16px; overflow-y: auto;
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
}
.sheet-panel {
  background: var(--card); border-radius: var(--radius);
  box-shadow: var(--shadow-lift); width: min(720px, 100%);
  animation: sheetIn .18s ease-out both;
}
@keyframes sheetIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.sheet-head {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 18px 22px; border-bottom: 1px solid var(--line);
  position: sticky; top: 0; background: var(--card); z-index: 1;
  border-radius: var(--radius) var(--radius) 0 0;
}
.sheet-head b { font-size: 17px; letter-spacing: -0.01em; }
.sheet-body { padding: 4px 22px 24px; }

/* 이름을 눌러 그 학생을 여는 자리 -- 버튼이지만 글처럼 보인다.
   글자 높이가 22px 라 손가락으로는 자꾸 빗나갔습니다(원장님은 갤럭시로 봅니다).
   보이는 모습은 그대로 두고 **닿는 자리만** 32px 로 넓힙니다 -- 위아래로 5px 씩
   누를 자리를 주고 같은 만큼 바깥 여백을 깎아서 줄 간격은 안 벌어지게. */
button.linky {
  background: none; border: 0; box-shadow: none; min-height: 0;
  padding: 6px 2px; margin: -6px -2px;
  font: inherit; font-weight: 600; color: var(--ink);
  text-align: left; cursor: pointer;
  /* 밑줄이 누를 자리 아래로 떨어지지 않게 글자에 붙입니다 */
  border-bottom: 0;
  text-decoration: underline dashed var(--line) 1px;
  text-underline-offset: 3px;
}
button.linky:hover { background: none; color: var(--brand); text-decoration-color: var(--brand-line); }

/* 표 안에 들어가는 작은 진도 막대: 홈의 큰 막대와 같은 것을 한 칸으로 줄인 것 */
.minibar { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; color: var(--ink-soft); }
.minibar em {
  display: block; width: 54px; height: 6px; flex: none;
  background: var(--line-soft); border-radius: 99px; overflow: hidden;
}
.minibar em i { display: block; height: 100%; border-radius: 99px; }
.minibar b { font-weight: 600; font-variant-numeric: tabular-nums; }

/* 숙제를 한 사람 / 안 한 사람 -- 안 한 쪽이 눈에 먼저 들어와야 한다 */
.hw-chip {
  display: inline-flex; align-items: center; gap: 7px;
  background: #fbeaea; color: #a03434; border: 1px solid #f0cccc;
  border-radius: 99px; padding: 6px 13px; min-height: 0;
  font-size: 13.5px; font-weight: 600; box-shadow: none;
}
.hw-chip:hover { background: #f7dede; color: #8d2c2c; }
.hw-chip.done { background: var(--ok-soft); color: var(--ok-ink); border-color: var(--ok-line); }
.hw-chip.done:hover { background: #ddeee4; color: #1b5333; }
.hw-chip b { font-weight: 700; font-variant-numeric: tabular-nums; opacity: .7; }

/* ---- 문장 만들기 ----------------------------------------------------------
   낱말을 손으로 옮겨 문장을 세운다. 줄에 놓인 것이 곧 답이라 따로 확인 버튼이
   없다 -- 아이가 만든 모양이 그대로 제출된다. */
.sent-line {
  min-height: 82px; margin: 16px 0 14px; padding: 12px;
  display: flex; flex-wrap: wrap; gap: 8px; align-content: flex-start;
  background: var(--tint); border: 1.5px dashed var(--line); border-radius: 12px;
}
.sent-hint { color: var(--ink-soft); font-size: 14px; align-self: center; margin: auto; }
.sent-bank {
  display: flex; flex-wrap: wrap; gap: 8px;
  padding-top: 14px; border-top: 1px dashed var(--line);
}
.sent-card {
  background: #fff; color: var(--ink); border: 1px solid var(--line);
  font-size: 16.5px; font-weight: 600; padding: 10px 15px;
  min-height: 0; box-shadow: none;
}
/* 터치 화면에서는 카드가 위로 올라간 뒤 다음 카드가 손가락 밑으로 미끄러져 와 분홍이 되어
   «올려 놓은 카드(.in)» 와 똑같아 보였습니다 */
@media (hover: hover) { .sent-card:hover { border-color: var(--brand); background: var(--brand-soft); } }
/* 줄에 올라간 카드는 색을 입어서, 어디까지 놓았는지가 한눈에 보인다 */
.sent-card.in { background: var(--brand-soft); border-color: var(--brand-line); color: var(--brand); }
@media (hover: hover) { .sent-card.in:hover { background: var(--brand-soft); } }

/* 시작 안내 -- 처음 세운 포털에서만 보이는 세 단계. 끝난 줄은 조용해지고
   남은 줄만 눈에 들어와야 하므로, 완료 표시는 색이 아니라 무게로 합니다. */
ol.steps { list-style: none; counter-reset: st; margin: 14px 0 0; padding: 0; }
ol.steps li {
  counter-increment: st;
  position: relative; padding: 12px 0 12px 42px;
  border-top: 1px solid var(--line-soft);
}
ol.steps li:first-child { border-top: 0; }
ol.steps li::before {
  content: counter(st);
  position: absolute; left: 0; top: 12px;
  width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 13px; font-weight: 700;
  background: var(--brand-soft); color: var(--brand);
}
ol.steps li.done::before { content: '✓'; background: var(--ok-soft); color: var(--ok-ink); }
ol.steps li b { display: block; font-size: 15.5px; }
ol.steps li.done b { color: var(--ink-soft); font-weight: 600; }
ol.steps li span { display: block; font-size: 13.5px; color: var(--ink-soft); margin-top: 3px; }

/* 앱 아이콘 고르기 -- 로고를 넣은 것, 머리글자, 기본. 실제로 홈 화면에 붙는
   모양 그대로 보여 줘야 고를 수 있으므로 둥근 사각형으로 미리 깎아 둡니다. */
.iconpick { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 12px; }
.iconopt {
  background: none; border: 2px solid transparent; border-radius: 14px;
  padding: 8px; box-shadow: none; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
}
.iconopt:hover { background: var(--tint); }
.iconopt.on { border-color: var(--brand); background: var(--brand-soft); }
.iconopt img {
  width: 72px; height: 72px; border-radius: 16px;
  border: 1px solid var(--line); background: #fff; display: block;
}
.iconopt span { font-size: 12.5px; font-weight: 600; color: var(--ink-soft); }
.iconopt.on span { color: var(--brand); }

/* 맡은 반 고르기 -- 눌러서 켜고 끄는 작은 단추들. 아무것도 안 켜면 '모든 반'입니다. */
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.chips .chip {
  cursor: pointer; border: 1px solid var(--line); background: #fff;
  color: var(--ink-soft); font-weight: 600; box-shadow: none;
  /* 손가락 기준은 44px 입니다. 34px 로 두었더니 실제로 36px 이었고, 초등학생이
     옆 칸을 누릅니다. 40px 로 올려도 줄마다 4px 밖에 안 늘어납니다. */
  min-height: 40px; padding: 9px 13px; border-radius: 999px; font-size: 13.5px;
  /* 기본 .chip(지울 수 있는 범위 칩)의 margin 0 8px 8px 0 을 끕니다. .chips 는
     gap 으로 띄우므로 이 여백은 줄마다 8px 을 그냥 먹기만 했습니다 -- 가로
     태블릿에서 고르개가 534px 을 넘던 이유의 셋 중 하나였습니다. */
  margin: 0;
}
.chips .chip:hover { border-color: var(--brand-line); }
/* 고른 칩의 글자. 대표색 그대로 쓰면 옅은 바탕 위에서 3.07:1 이라, 아이가 «내가
   무슨 범위를 골랐는지» 를 흐릿하게 봅니다. --brand-ink 는 학원 색에서 계산됩니다. */
.chips .chip.on { background: var(--brand-soft); border-color: var(--brand); color: var(--brand-ink); }

/* 계정 표는 칸이 좁아 이름과 권한이 두 줄로 갈라졌습니다. 셋 다 한 줄로 둡니다. */
#stfList td:nth-child(1), #stfList td:nth-child(2), #stfList td:nth-child(3),
#stfList td:nth-child(4), #stfList td:nth-child(5) { white-space: nowrap; }
#stfList td:last-child { white-space: nowrap; text-align: right; }

/* 문장 받아쓰기 타일 -- 공책에 쓰는 활동이라 종이 느낌의 남색 계열로 둡니다. */
.tile.t-write .big { background: #eef2fb; color: #3c5a99; }

/* ---- 낮은 화면 (태블릿 가로) ------------------------------------------------
   갤럭시탭 A9 를 가로로 눕히면 높이가 534px 밖에 안 됩니다. 로그인 화면이
   «들어가기» 단추부터 잘려서, 아이가 스크롤할 생각을 못 하고 멈춥니다.
   화면이 낮을 때만 위아래를 조입니다 -- 세로로 쓰는 기기는 그대로입니다. */
@media (max-height: 640px) {
  .wrap { padding-top: 8px !important; padding-bottom: 10px; }
  .login-brand { margin-bottom: 14px; }
  .login-brand img { width: min(170px, 46%); }
  .login-brand p { margin: 6px 0 0; font-size: 12px; }   /* 하한 12px */
  .card { padding: 16px 18px; margin-bottom: 12px; }
  h2 { font-size: 17px; }
  label { margin-top: 10px; }
  input, select, textarea, button { min-height: 42px; }
  button { padding: 10px 18px; }
  /* 자판이 올라오면 더 낮아집니다. 그때도 아래가 보이도록. */
  body { overscroll-behavior-y: contain; }
}

/* 아주 낮을 때(자판이 올라온 상태)는 로고를 아예 접습니다 -- 로그인 칸이
   먼저 보여야 합니다. */
@media (max-height: 460px) {
  .login-brand img { width: min(130px, 36%); }
  .login-brand p { display: none; }
  .wrap { padding-top: 6px !important; }
}

/* 소리가 나는 동안은 «다시 듣기» 를 잠급니다. 예전에는 누를 때마다 새로 시작해
   두 소리가 겹쳐 들렸고, 받아쓰기에서는 무슨 낱말인지 알 수 없게 됐습니다. */
.speak-btn.speaking { opacity: .55; pointer-events: none; }
button.speaking { opacity: .55; }

/* 학생 창이 열린 동안은 뒤 화면을 잠급니다. 태블릿에서 손가락으로 밀면
   뒤가 움직이고 창은 제자리라, 창 아래쪽에 닿을 수가 없었습니다. */
body.sheet-open { overflow: hidden; }
.sheet { overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
@media (max-height: 700px) { .sheet { padding: 12px 10px; } }

/* 「시험 시작」 을 화면 안에 붙들어 둡니다.

   범위 고르개가 길어서, 아이가 범위를 다 고르고 나면 시작 단추가 화면 밖에
   있습니다. 재 보니 폰 세로에서 여덟 화면 중 넷, 1280x800 태블릿에서 다섯이
   그랬습니다 -- 받아쓰기는 1761px 자리라 한참 내려야 나옵니다. 아이 눈에는
   «다 골랐는데 다음이 없는» 화면입니다.

   position: sticky 는 **필요할 때만** 붙습니다. 내용이 화면보다 짧으면(가로
   태블릿 1024x600 이 그렇습니다) 아무 일도 하지 않고 제자리에 있습니다.
   그래서 켜고 끄는 코드가 없습니다. */
.start-dock {
  position: sticky; bottom: 0; z-index: 3;
  /* 단추 밑으로 글이 비쳐 지나가면 지저분합니다. 카드 색으로 받칩니다.
     (종이색 --bg 로 받쳤더니 흰 카드 안에 베이지 띠가 늘 떠 있었습니다.) */
  padding: 10px 0 12px;
  background: linear-gradient(180deg, transparent, var(--card) 22%, var(--card));
}
/* 고르개를 두 칸으로 눕히는 가로 화면에서는 시작 단추가 이미 오른쪽 위에 보입니다.
   거기서 바닥에 붙이면 자리만 먹습니다. */
@media (min-width: 760px) and (max-height: 820px) {
  .start-dock { position: static; padding: 0; background: none; }
}

/* 묻는 창(common.js 의 ask)은 큰 패널과 쓰임이 다릅니다.
   큰 패널(학생 상세 · 수업 기록)은 위에 붙어 아래로 흐르는 것이 맞습니다 -- 내용이
   길고 스크롤하며 읽으니까요. 묻는 창은 한 줄 묻고 단추 둘입니다. 위에 붙여 두었더니
   화면 꼭대기에 뜨고, 아이 눈과 손가락은 가운데에 있습니다(2026-09-27 원장님 지적).

   태블릿 가로가 주로 쓰는 자리입니다. 가로는 세로로 짧아서, 가운데 두면서도 넘치지
   않게 높이를 묶고 안에서 구르게 합니다. 폰 가로(915x412)처럼 아주 납작한 자리도
   이 한 규칙으로 함께 해결됩니다. */
.sheet.ask-sheet { align-items: center; padding: 16px; }
.sheet.ask-sheet .sheet-panel {
  width: min(420px, 100%);
  max-height: calc(100vh - 32px);
  max-height: calc(100dvh - 32px);   /* 주소창이 접히는 폰에서 더 정확합니다 */
  overflow-y: auto;
}

/* 인쇄물 글자 크기. 저학년은 글씨가 커서 «보통» 줄에는 답이 안 들어갑니다.
   줄을 키우면 문항이 적어도 A4 한 장이 그대로 찹니다. */
ol.wl.sz-big li { padding: 13px 0; }
ol.wl.sz-big .wl-q { font-size: 18px; }
ol.wl.sz-big .wl-a { font-size: 17px; min-height: 1.6em; }
ol.wl.sz-big li::before { font-size: 14px; width: 28px; }
ol.wl.sz-huge li { padding: 20px 0; }
ol.wl.sz-huge .wl-q { font-size: 23px; }
ol.wl.sz-huge .wl-a { font-size: 21px; min-height: 2.1em; }
ol.wl.sz-huge li::before { font-size: 17px; width: 34px; }

/* 학생 창이 열린 채로 «한 장으로 인쇄»를 누르면, 화면을 잠그려고 걸어 둔
   overflow:hidden 이 종이까지 잘라 버립니다. 인쇄할 때는 풀어 줍니다. */
@media print { body.sheet-open { overflow: visible !important; } }

/* 학생증 카드의 코드. 이제 20자까지 가능해서, 긴 코드는 글자를 줄여 한 줄에 앉힙니다. */
.qr-card-code { overflow-wrap: anywhere; }
.qr-card-code.long { font-size: 15px; letter-spacing: .02em; }
.qr-card-code.very-long { font-size: 12.5px; letter-spacing: 0; }

/* 첫 PIN 쪽지. 이 화면을 벗어나면 다시 볼 수 없어서, 오려 나눠 줄 수 있게 뽑습니다. */
.pin-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0; }
.pin-slip {
  border: 1px dashed #b9b2a9; padding: 12px 14px 14px;
  text-align: center; break-inside: avoid; margin: -0.5px;
}
.pin-logo { height: 16px; width: auto; opacity: .75; }
.pin-code { font-size: 15px; font-weight: 700; margin-top: 6px; overflow-wrap: anywhere; }
.pin-cls { font-size: 11.5px; color: var(--ink-soft); margin-top: 1px; }
.pin-num { font-size: 30px; font-weight: 700; letter-spacing: .18em; margin: 6px 0 2px; }
.pin-note { font-size: 10.5px; color: var(--ink-soft); }
@media print { .pin-slip { border-color: #999; } }

/* 의미 단위 끊어 읽기 -- 낱말 사이의 «틈»을 눌러 표시합니다.
   틈은 평소에는 옅은 세로줄로만 있다가, 누르면 «/» 가 들어옵니다. 태블릿에서
   손가락으로 눌러야 하므로 폭이 좁아도 높이는 낱말만큼 잡아 둡니다. */
.chunk-line {
  display: flex; flex-wrap: wrap; align-items: stretch;
  margin: 18px 0 4px; padding: 14px 10px;
  background: var(--tint); border: 1.5px dashed var(--line); border-radius: 12px;
  font-size: 19px; line-height: 1.9;
}
.chunk-w { padding: 4px 2px; font-weight: 600; color: var(--ink); align-self: center; }
.chunk-gap {
  width: 26px; min-height: 0; margin: 0 1px; padding: 4px 0;
  background: transparent; border: 0; box-shadow: none;
  color: var(--ink-soft); font-size: 18px; font-weight: 700; line-height: 1.4;
  border-left: 2px dotted var(--line);
  border-radius: 5px;
}
@media (hover: hover) { .chunk-gap:hover { background: var(--brand-soft); border-left-color: var(--brand-line); } }
/* 끊은 자리는 색으로 또렷하게 -- 어디를 끊었는지 한눈에 세어져야 합니다 */
.chunk-gap.on {
  color: var(--brand); background: var(--brand-soft);
  border-left: 2px solid var(--brand);
}

/* ---- 범위 고르기 -----------------------------------------------------------
   드롭다운 넷을 눌러서 고르는 칩과 숫자판으로 바꾼 자리입니다. 태블릿에서
   드롭다운은 «누르고 · 뜨고 · 굴리고 · 다시 누르는» 네 동작이라, 범위 하나
   고르는 데 여덟 번이 들었습니다. 여기서는 하나에 한 번입니다. */
.picker label { margin-top: 16px; }
.picker label:first-child { margin-top: 4px; }

/* Day 숫자판. 갤럭시탭 세로에서 여덟 칸이 한 줄에 들어오고, 한 칸이 44px 이라
   일곱 살 손가락으로도 옆 날을 잘못 누르지 않습니다. */
.daygrid {
  display: grid; grid-template-columns: repeat(8, 1fr);
  gap: 6px; margin-top: 8px;
}
.daygrid .day {
  min-height: 44px; padding: 0; font-size: 15px; font-weight: 700;
  background: #fff; color: var(--ink-soft);
  border: 1px solid var(--line); border-radius: 9px; box-shadow: none;
}
.daygrid .day:hover { border-color: var(--brand-line); }
/* 고른 사이는 옅게, 양 끝은 진하게 -- «어디부터 어디까지» 가 색의 모양으로 보입니다 */
/* 고른 «사이» 의 숫자는 옅은 바탕 위라 --brand-ink 로 씁니다. 대표색 그대로면
   노랑을 고른 학원에서 1.7:1 이라 숫자가 안 보였습니다. */
.daygrid .day.on { background: var(--brand-soft); border-color: var(--brand-line); color: var(--brand-ink); }
/* 양 끝은 흰 글자라, 흰 글자가 읽히는 바탕(--brand-btn)을 씁니다. */
.daygrid .day.edge {
  background: var(--brand-btn); border-color: var(--brand-btn); color: #fff;
}
.day-hint { font-weight: 600; }

/* 폰(2026-10): 380px 에서만 여섯 칸이었는데, 요즘 폰(390~430px)도 여덟 칸이면
   한 칸 폭이 33~38px 이라 옆 날을 잘못 누릅니다. 폰 세로는 모두 여섯 칸(약 46px)으로.
   한 줄 늘어도 시작 단추는 아래에 붙어 있어 굴릴 일이 없습니다. */
@media (max-width: 440px) {
  .daygrid { grid-template-columns: repeat(6, 1fr); }
  /* 문장 만들기의 «방식» 칩(«의미 단위로 끊어 읽기»)이 반쪽 칸에서 두 줄로 접혔습니다 -- 폰에서는 한 줄을 다 씁니다. */
  .row > .opt-wide { flex-basis: 100%; }
}

/* 홈 타일의 묶음 제목. 열한 개가 한 줄로 늘어서면 무엇부터 할지가 안 보여서
   «오늘 할 것 / 낱말 / 문장과 글 / 그밖에» 로 갈랐습니다. 제목은 조용해야
   합니다 -- 눈에 들어와야 하는 것은 타일이지 제목이 아닙니다. */
.tgroup {
  margin: 26px 0 10px; font-size: 13px; font-weight: 700;
  color: var(--ink-soft); letter-spacing: .04em;
}
.tgroup:first-of-type { margin-top: 6px; }

/* ---- 머리글 간판 (글자) ----------------------------------------------------
   예전에는 로고 그림 하나였습니다. 그런데 그 그림은 프랜차이즈 이름이 크고
   학원 이름이 그 아래 작게 깔린 모양이라, 정작 이 포털을 쓰는 학원 이름이
   가장 작았습니다. 그림을 글자로 바꾸면 크기를 원하는 대로 두는 것은 물론,
   선생님 화면에서 이름만 고쳐도 바로 반영됩니다 -- 간판이 코드 밖에 있다는
   이 포털의 약속이 머리글에서만 예외였던 것을 없앤 것입니다.

   «수지메이플영어학원» 을 한 덩어리로 쓰면 아홉 글자가 벽처럼 붙어 읽는 데
   시간이 걸립니다. 고유부와 종류부를 갈라 무게와 색으로 층을 주면, 글자 수는
   같은데 «이름» 으로 읽힙니다. */
header.bar .brand .wm {
  display: flex; align-items: baseline; gap: 5px;
  white-space: nowrap;
}
header.bar .brand .wm b {
  font-family: var(--font-brand);
  font-size: 20px; font-weight: 400; letter-spacing: -0.005em;
  color: var(--brand-mark);
  /* 한글은 글자마다 속공간이 넓어 -0.035em 쯤 조여야 로고처럼 뭉칩니다 */
}
header.bar .brand .wm i {
  font-style: normal;
  font-family: var(--font-brand);
  font-size: 12.5px; font-weight: 400; letter-spacing: 0.04em;
  color: var(--ink-soft);
  /* 종류부는 이름이 아니라 설명입니다. 한 칸 내려 앉히면 눈이 먼저 이름을
     읽고 그다음에 이것을 봅니다. */
  position: relative; top: -1px;
}
header.bar .brand { text-decoration: none; }
header.bar .brand:hover .wm b { color: var(--brand-dark); }

/* 좁은 화면에서는 종류부를 접습니다. 학원 이름이 먼저입니다. */
@media (max-width: 430px) {
  header.bar .brand .wm i { display: none; }
  header.bar .brand .wm b { font-size: 17px; }
}

/* 받아쓰기 «무엇을» 고르기 -- 출처를 줄 제목으로, 단추에는 단위만.
   다섯이 한 줄이던 때는 「교재 단어 / 낱말책 문장」처럼 이름 하나에 두 가지가
   들어 있어서, 낱말로 들어와도 문장이 보이는 이유를 알 수 없었습니다. */
#whatPick { margin-top: 8px; }
#whatPick .wg {
  display: flex; align-items: center; gap: 12px;
  padding: 7px 0;
}
#whatPick .wg + .wg { border-top: 1px solid var(--line-soft); }
#whatPick .wg-t {
  flex: none; width: 78px;
  font-size: 12.5px; font-weight: 700; color: var(--ink-soft);
}
#whatPick .chips { margin-top: 0; }

@media (max-width: 430px) {
  #whatPick .wg { flex-direction: column; align-items: flex-start; gap: 4px; }
  #whatPick .wg-t { width: auto; }
}

/* 로그인 화면의 간판. 학생이 제일 먼저 보는 자리라 학원 이름이 가장 커야 하는데,
   여기가 프랜차이즈 로고가 240px 로 가장 크던 자리였습니다. 머리글과 같은
   «고유부＋종류부» 구조를 쓰되, 여기서는 두 줄로 쌓아 이름에 자리를 줍니다. */
.login-brand .wm {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
}
.login-brand .wm b {
  font-family: var(--font-brand);
  font-size: 40px; font-weight: 400; letter-spacing: 0;
  color: var(--brand); line-height: 1.1;
}
.login-brand .wm i {
  font-style: normal;
  font-family: var(--font-brand);
  font-size: 15.5px; font-weight: 400; letter-spacing: 0.2em;
  color: var(--ink-soft);
  /* 자간을 넓히면 마지막 글자 뒤에도 빈칸이 붙어 가운데가 왼쪽으로 밀립니다 */
  text-indent: 0.22em;
}

@media (max-width: 430px) {
  .login-brand .wm b { font-size: 31px; }
  .login-brand .wm i { font-size: 12px; letter-spacing: 0.18em; text-indent: 0.18em; }
}

/* «이어서 하기» 안내. 범위가 저절로 골라져 있으면 아이는 «내가 안 골랐는데»
   합니다. 왜 그 범위인지 한 줄로 말해 주면 그때부터는 «맞아, 저기까지 했지»
   가 됩니다. 눈에 띄되 시작 단추보다 세면 안 되므로 색은 옅게. */
.msg.info.resume { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.msg.info.resume .resume-say { flex: 1; min-width: 200px; }
/* 이어가기 단추는 시작 단추와 같은 일을 하므로 같은 색을 씁니다. 다만 여기서는
   «안내» 안에 있는 것이라 한 단계 작게 두어, 화면의 주인공인 아래 시작 단추를
   가리지 않게 합니다. */
.msg.info.resume .resume-go {
  flex: none; min-height: 40px; padding: 9px 18px; font-size: 14px;
}
.msg.info.resume b {
  display: block; margin-bottom: 3px;
  font-size: 12.5px; letter-spacing: .02em; color: var(--brand);
}
.msg.info.resume span { font-size: 14px; }

/* 스스로 채점의 O/X -- 보기만 하는 표시가 아니라 누르는 단추입니다. 그래서
   손가락 크기(40px)를 주고, 누를 수 있다는 것이 보이게 테두리를 남깁니다.
   기본값은 O 이고 틀린 것만 눌러 X 로 바꿉니다(선생님 채점 화면과 같은 규칙). */
.mark.self {
  min-height: 40px; min-width: 40px; padding: 0;
  font-size: 16px; font-weight: 800; cursor: pointer;
  border-radius: 10px; box-shadow: none;
}
.mark.self.o { background: var(--ok-soft); color: var(--ok); border: 1.5px solid var(--ok); }
.mark.self.x { background: var(--bad-soft, #fdeef0); color: var(--bad); border: 1.5px solid var(--bad); }
#selfList li { align-items: center; }
#selfList .en { font-size: 17px; }

/* ---- 활동 화면(«play») -------------------------------------------------------
   시험·카드·받아쓰기 화면은 지금까지 «내용만큼» 크기의 카드였습니다. 태블릿을
   세로로 들면 화면 위쪽 셋 중 하나만 쓰고 나머지 둘은 빈 종이였고, 누를 것은
   전부 손가락에서 먼 위쪽에 있었습니다. 아이가 태블릿을 두 손으로 들면 엄지는
   아래에 있습니다.

   .play 는 세 가지를 합니다.
     1. 카드가 머리글 아래를 다 채웁니다(내용이 짧아도).
     2. 글자와 단추를 손가락 크기로 키웁니다.
     3. 마지막 단추 줄을 카드 바닥에 붙입니다 -- 보기가 둘이든 넷이든 «다음» 은
        늘 같은 자리, 엄지 아래에 있습니다.
   설정 화면(setup)과 결과 화면(done)은 그대로입니다. 하나는 고르는 표고 하나는
   읽는 목록이라 채울 이유가 없습니다. */
.card.play {
  display: flex; flex-direction: column;
  /* 머리글 72 + 위 여백 22 + 아래 여백 64 + 카드 간격 18. 세로 태블릿에서는
     화면이 안 굴러가고, 내용이 더 길면(리딩 지문) 그만큼 자랍니다.
     dvh 는 주소창이 접힐 때 같이 줄어듭니다. 못 읽는 브라우저는 윗줄을 씁니다.
     (머리글이 66 이던 때의 172 가 남아, 문제 화면이 늘 4px 굴러갔습니다 — 엄지로 «다음» 을
      누르다 화면이 살짝 밀리는 그 4px 입니다.) */
  min-height: calc(100vh - 176px);
  min-height: calc(100dvh - 176px);
  padding: 22px 24px 20px;
}
/* 마지막 단추 줄은 바닥으로.
   !important 를 쓴 이유: 여러 화면의 그 줄에 style="margin-top:18px" 가 인라인으로
   박혀 있어, 보통 규칙으로는 auto 가 지지 않습니다. 인라인 값을 다 지우는 것보다
   여기서 한 번에 이기는 편이 덜 흩어집니다 -- 나중에 누가 인라인을 또 붙여도 이깁니다. */
.card.play > .row:last-child { margin-top: auto !important; padding-top: 18px; }
.card.play > .row:last-child > button { min-height: 58px; font-size: 17px; }

/* 문제 덩어리(낱말 + 보기)는 남는 공간의 가운데에 둡니다. 위아래 auto 여백이
   빈 공간을 나눠 가져서, 보기가 둘이든 넷이든 화면 한가운데 옵니다.
   단추 줄이 있으면 그 줄은 그래도 바닥입니다(마지막 자식이라 뒤에 아무것도 없음). */
.card.play .prompt { margin-top: auto; }
.card.play .choices, .card.play #typingBox { margin-bottom: auto; }
/* 함께 풀기의 쓰는 칸(받아쓰기 · 생각 모으기 · 영작)도 보기와 같이. 빠져 있어서 남는 자리가 전부 질문
   위로 가 질문 · 칸 · «내기» 가 화면 바닥에 붙었고, 폰에서 자판이 올라오면 칸과 단추가 그 뒤로 숨었습니다. */
.card.play .rc-type, .card.play .rc-think, .card.play .rc-write { margin-bottom: auto; }
/* 문장 만들기의 세 상자(순서·빈칸·끊어읽기)는 낱말이 없고 조작만 있으니 통째로
   가운데에. 읽고 채우기와 리딩은 «글» 이라 위에서부터 읽는 게 맞아 그대로 둡니다. */
.card.play #orderBox, .card.play #blankBox, .card.play #chunkBox {
  margin-top: auto; margin-bottom: auto;
}

/* 진행 표시 -- 5px 줄과 14px 숫자는 아이 눈에 안 들어옵니다.
   !important: 화면마다 «1 / 10» 칸에 style="font-size:14px" 가 박혀 있어(단어 시험 · 받아쓰기 · 문장 만들기 ·
   말하기 · 함께 풀기) 이 규칙이 한 번도 이긴 적이 없었습니다 -- 모든 활동 화면이 같은 크기로 보이게.
   낮은 가로 태블릿(893×534)은 14px 로 재 둔 높이 그대로 둡니다(3px 만 커져도 카드가 넘칩니다). */
.card.play .progress { height: 9px; margin-bottom: 14px; }
.card.play #counter, .card.play #pcounter {
  font-size: 16px; font-weight: 700; color: var(--ink-soft); font-variant-numeric: tabular-nums;
}
@media not all and (min-width: 760px) and (max-height: 820px) {
  .card.play #counter, .card.play #pcounter { font-size: 16px !important; }
}

/* 문제 낱말 */
.card.play .prompt {
  font-size: clamp(36px, 8vw, 58px); padding: 34px 10px 30px; line-height: 1.15;
}
/* 보기 -- 손가락 하나가 넉넉히 들어가는 높이 */
.card.play .choices { gap: 12px; }
.card.play .choice {
  min-height: 66px; font-size: 19px; padding: 18px 22px;
  border-radius: var(--r-md); border-width: 1.5px;
}
.card.play .choice.picked { box-shadow: inset 0 0 0 1.5px var(--brand); }
/* 직접 입력 칸도 같은 키로 */
.card.play input#typed {
  font-size: 22px; padding: 16px 18px; min-height: 60px; text-align: center;
}

/* 단어 학습 카드 -- 카드가 화면을 채우니 낱말도 그만큼 큽니다 */
.card.play .flash { flex: 1; min-height: 0; padding: 20px 12px; }
.card.play .flash .word { font-size: clamp(44px, 9vw, 64px); }
.card.play .flash .mean { font-size: clamp(24px, 4.5vw, 32px); margin-top: 22px; min-height: 40px; }
/* 단어 학습의 단추 둘 -- 오른쪽이 주인공이지만 둘 다 손가락 크기 */
.card.play #controls { margin-top: auto; padding-top: 18px; }
.card.play #controls > button { min-height: 62px; font-size: 18px; }
.card.play #controls > #primary { flex: 2; }
/* 폰(400 아래): 1:2 로 나누면 «아직 몰라요» 칸이 95px 라 «아직 / 몰라요» 두 줄이었습니다 -- 1:1.4 로, 글자는 한 줄 (2026-11-01) */
@media (max-width: 400px) {
  .card.play #controls > button { white-space: nowrap; padding-left: 10px; padding-right: 10px; }
  .card.play #controls > #again { flex: 1 1 0; }
  .card.play #controls > #primary { flex: 1.4 1 0; }
}

/* 스피드 퀴즈 시계 -- 10초짜리 놀이에서 시계가 곧 화면입니다 */
.card.play .speed-clock {
  font-size: 44px; min-width: 88px; padding: 6px 18px;
  border-radius: 16px; border-width: 2px;
}

/* 받아쓰기 공책 화면 -- 번호와 말하기 단추 */
.card.play .paper-num { font-size: 52px; }
.card.play .speak-btn.speak-big { width: 128px; height: 128px; }
.card.play .speak-btn.speak-big svg { width: 54px; height: 54px; }

/* 읽고 채우기 -- 지문과 낱말 은행 */
.card.play .cloze-passage { font-size: 18px; line-height: 2.2; }
.card.play .cloze-slot { min-width: 84px; font-size: 17px; padding: 5px 12px; }
.card.play .cloze-word { min-height: 46px; font-size: 17px; padding: 11px 18px; }

/* 문장 만들기 -- 낱말 카드와 끊어 읽기 */
.card.play .sent-card { font-size: 18px; padding: 12px 18px; min-height: 48px; }
.card.play .chunk-line { font-size: 21px; }
.card.play .chunk-gap { width: 30px; font-size: 20px; }

/* 리딩 지문 */
.card.play .passage { font-size: 17.5px; line-height: 1.9; }

/* ---- 가로 태블릿 (폭 760 이상 · 높이 700 이하) -- 주된 사용 방향 ---------------
   갤럭시탭 A9 를 가로로 들면 CSS 기준 약 893×534 입니다. 폭은 넉넉하고 높이가
   귀합니다. 세로에서 하던 «위아래로 채우기» 는 여기서 오히려 스크롤을 만듭니다.
   그래서 가로에서는 «옆으로 펼쳐서 높이를 줄입니다».
     - 문제 화면(.two): 왼쪽에 낱말·진행·단추, 오른쪽에 보기.
       왼손은 넘기고 오른손은 고릅니다.
     - 리딩(.read): 왼쪽 지문, 오른쪽 문제. 문제를 푸는 동안 지문이 옆에 그대로.
     - 빈칸(.fill): 왼쪽 지문, 오른쪽 낱말 은행을 세로로.
     - 범위 고르기(#setup): 왼쪽 고르개, 오른쪽 나머지(개수·방향·시작).
   전부 grid 에 «열» 만 못 박고 «줄» 은 자동(dense)으로 둡니다. 화면마다 위쪽
   항목 수가 달라서 줄 번호를 세어 두면 한 화면만 바뀌어도 다른 화면이 깨집니다.
   «> *» 로 전부 왼쪽에 넣은 뒤 오른쪽으로 갈 것만 골라 빼는 순서라, 아래 규칙의
   차례를 바꾸면 안 됩니다(같은 특이도라 뒤에 오는 것이 이깁니다). */
@media (min-width: 760px) and (max-height: 820px) {
  /* 활동 카드는 «화면 높이 - 머리글·여백» 만큼 잡습니다. dvh 가 아니라 vh 입니다 --
     이 브라우저 pane 에서 dvh 는 실제 뷰포트(innerHeight)보다 크게 잡혀, 세로 flex
     로 채우면 화면이 18px 씩 넘쳤습니다. vh 는 innerHeight 와 일치합니다.
     머리글 54 + .wrap 위 8 + 아래 16 + 카드 아래 여백 12 = 90. */
  header.bar { padding: 7px 18px 6px; }
  .wrap, .wrap.narrow { max-width: 1080px; padding: 8px 18px 16px; }
  .card { padding: 16px 20px; margin-bottom: 12px; }
  h2 { font-size: 17px; margin-bottom: 8px; }

  /* ---- 활동 화면 공통 ---- */
  .card.play { min-height: calc(100vh - 90px); padding: 14px 20px 14px; }
  /* 공책(#paper)은 «화면 하나를 통째로 쓰는» 별도 규칙이라 margin-top: 18px 을
     따로 갖고 있습니다. 가로에서는 그 18px 이 카드를 아래로 밀어 화면을 넘겼습니다. */
  #paper.card.play { margin: 0 auto; }   /* 위아래 18px 만 지웁니다 -- «0» 으로 가운데 정렬까지 지워 왼쪽에 붙었습니다 */
  .card.play .progress { height: 7px; margin-bottom: 8px; }
  .card.play > .row:last-child { padding-top: 10px; }
  .card.play > .row:last-child > button { min-height: 52px; font-size: 16px; }

  /* ---- 문제 화면: 왼쪽 낱말·단추 | 오른쪽 보기 ---- */
  .card.play.two {
    display: grid; grid-template-columns: 1fr 1.15fr; column-gap: 26px;
    grid-auto-flow: row dense; align-content: center;
  }
  .card.play.two > * { grid-column: 1; }
  .card.play.two > .progress { grid-column: 1 / -1; grid-row: 1; margin-bottom: 4px; }
  .card.play.two > .choices, .card.play.two > #typingBox {
    grid-column: 2; grid-row: 2 / span 8; align-self: center; margin: 0;
  }
  .card.play.two .prompt {
    margin: 0; padding: 10px 6px 14px; font-size: clamp(34px, 5.2vw, 52px);
  }
  .card.play.two > .row:last-child { margin-top: 6px !important; padding-top: 0; }
  .card.play.two .choices { gap: 9px; }
  .card.play.two .choice { min-height: 54px; font-size: 18px; padding: 12px 18px; }
  .card.play.two .speed-clock { font-size: 36px; min-width: 76px; }

  /* ---- 리딩: 왼쪽 지문 | 오른쪽 문제 ---- */
  .card.play.read {
    display: grid; grid-template-columns: 1.05fr 1fr; column-gap: 26px;
    grid-auto-flow: row dense; align-content: start;
  }
  .card.play.read > * { grid-column: 1; }
  .card.play.read > h3, .card.play.read > p.hint, .card.play.read > #quizMsg,
  .card.play.read > #questions, .card.play.read > .row:last-child { grid-column: 2; }
  .card.play.read > h3 { margin-top: 0; }
  /* 리딩은 지문이 길면 grid 가 내용만큼 커집니다. 높이를 화면에 못 박고(min 이
     아니라 height) 넘치는 것은 지문·문제 각자의 상자 안에서만 굴러가게 합니다. */
  .card.play.read { height: calc(100vh - 90px); overflow: hidden; }
  /* 지문 상자는 줄 열 개에 걸칩니다. 한 줄에만 있으면 그 줄이 지문만큼 높아져
     오른쪽 문제가 지문 «아래» 에서 시작합니다. 걸치면 높이가 줄들에 나뉘어
     오른쪽 열은 맨 위부터 씁니다. */
  .card.play.read > .subcard { grid-row: span 10; }
  /* «지문은 위에 그대로 있어요» 안내는 접습니다 -- 가로에서는 지문이 «옆» 이라
     글이 틀리고, 두 줄로 접혀 45px 을 먹어 카드가 534 를 넘겼습니다. */
  .card.play.read > p.hint { display: none; }
  /* 지문과 문제는 각자 상자 안에서 굴러갑니다. 문제를 푸는 동안 지문이 옆에 있습니다.
     grid 의 «줄» 은 두 열이 같이 쓰므로 오른쪽 열도 왼쪽 첫 두 줄(출처 37 + 제목 37)
     아래에서 시작합니다. 534 기준으로 카드 442 - 안쪽 여백 28 - 위 두 줄 74 = 340 이
     지문 상자, 거기서 제출 줄 60 을 더 뺀 280 이 문제 상자입니다. */
  .card.play.read > .subcard { max-height: calc(100vh - 194px); overflow: auto; }
  .card.play.read > #questions { max-height: calc(100vh - 254px); overflow: auto; padding-right: 4px; }
  .card.play.read > .row:last-child { margin-top: 8px !important; padding-top: 0; }
  .card.play.read .passage { font-size: 16.5px; line-height: 1.8; }

  /* ---- 빈칸: 왼쪽 지문 | 오른쪽 낱말 은행(세로) ---- */
  .card.play.fill {
    display: grid; grid-template-columns: 1.4fr 1fr; column-gap: 26px;
    grid-auto-flow: row dense; align-content: start;
  }
  .card.play.fill > * { grid-column: 1; }
  /* 세로로 세울 때 «flex-wrap: wrap»(기본 규칙)을 그대로 두면, 숙제 띠로 상자가 낮아졌을 때
     5번째 낱말과 하는 법 줄이 «옆 둘째 단» 으로 넘어가 화면 밖에 숨었습니다(가로 스크롤은
     손가락으로 찾을 수 없습니다). 한 단으로 두고 넘치면 위아래로 굴러가게 합니다. */
  .card.play.fill > .cloze-bank {
    grid-column: 2; grid-row: 1 / span 6; align-self: start;
    flex-direction: column; flex-wrap: nowrap; margin-top: 0; padding-top: 0; border-top: 0;
    border-left: 1px dashed var(--line); padding-left: 18px;
  }
  .card.play.fill .cloze-word { width: 100%; text-align: left; }
  .card.play.fill > .row:last-child { grid-column: 1 / -1; }
  .card.play.fill .cloze-passage { font-size: 16.5px; line-height: 2; }
  /* 긴 지문(Blue 700자)·보기 8개(듣기)에서도 534 안에 들어가야 합니다. 예전에는
     카드가 내용만큼 자라서 화면을 넘겼습니다. 리딩처럼 카드를 높이에 고정하고,
     지문과 보기 은행은 그 안에서 스크롤합니다. 숫자는 534 기준으로 잰 것입니다:
     머리글 60 + 카드 여백 28 + 출처·제목 72 + (듣기 단추줄 60) + 아래 단추줄 60. */
  .card.play.fill { height: calc(100vh - 90px); overflow: hidden; }
  .card.play.fill > .cloze-passage { overflow: auto; max-height: calc(100vh - 260px); }
  .card.play.fill > .listen-bar:not(.hidden) ~ .cloze-passage { max-height: calc(100vh - 320px); }
  .card.play.fill > .cloze-bank { max-height: calc(100vh - 190px); overflow: auto; }
  /* 보기가 일곱 개를 넘으면(듣고 채우기은 8개) 한 줄로는 안 들어가서 두 줄로 */
  .card.play.fill > .cloze-bank:has(> :nth-child(7)) { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
  .card.play.fill .listen-bar { margin-bottom: 8px; }
  .card.play.fill .listen-bar .wide, .card.play.fill .listen-bar .say-btn { min-height: 44px; min-width: 160px; font-size: 15px; }

  /* ---- 단어 학습·받아쓰기 공책: 한 열이되 높이 안에 ---- */
  .card.play .flash { padding: 8px; }
  .card.play .flash .word { font-size: clamp(36px, 6vw, 52px); }
  .card.play .flash .mean { font-size: 24px; margin-top: 10px; min-height: 30px; }
  .card.play #controls { padding-top: 8px; }
  .card.play #controls > button { min-height: 52px; font-size: 16px; }
  .card.play .paper-num { font-size: 40px; margin-bottom: 6px; }
  .card.play .speak-btn.speak-big { width: 100px; height: 100px; }
  .card.play .speak-btn.speak-big svg { width: 44px; height: 44px; }

  /* ---- 범위 고르기: 왼쪽 고르개 | 오른쪽 나머지 ---- */
  section#setup.card {
    /* minmax(0, …) 가 없으면 오른쪽 열의 긴 칩(«공책에 쓰기 (선생님이 채점)»)이
       제 최소 폭만큼 오른쪽을 넓혀 왼쪽이 줄고, «10권» 이 둘째 줄로 내려갑니다. */
    /* 여기는 dense 를 쓰지 않습니다. 활동 화면은 오른쪽으로 뺄 것을 «고르는»
       구조라 dense 가 맞지만, 설정 화면은 «위에서 아래로 차례대로» 가 뜻이라
       dense 가 앞의 빈칸을 뒤 항목으로 채우면 «쓰는 곳» 이 맨 위로 튑니다. */
    display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); column-gap: 24px;
    grid-auto-flow: row; align-content: start; padding: 8px 20px 8px;
  }
  /* «범위 고르기» 제목은 접습니다 -- 머리글에 이미 화면 이름이 있고, 534px 에서
     35px 은 Day 숫자판 한 줄입니다. */
  section#setup.card > h2 { display: none; }
  section#setup.card > #msg, section#setup.card > #voiceWarn { grid-column: 1 / -1; }
  /* 이어서 하기는 오른쪽 열 맨 위로. 왼쪽(고르개)이 높이를 다 쓰는 열이라
     45px 배너를 오른쪽으로 옮기면 그만큼 고르개가 들어옵니다. */
  section#setup.card > .msg.info.resume { grid-column: 2; margin-bottom: 0; }
  .msg.info.resume .resume-say b { display: inline; margin-right: 8px; }
  /* 고르개 셋(교재·낱말책·사다리)은 왼쪽 열에서 줄 열두 개에 걸칩니다. 한 줄에만
     있으면 그 줄이 고르개만큼 높아져 오른쪽 옵션이 고르개 «아래» 에서 시작합니다. */
  section#setup.card > #picker, section#setup.card > #vocaPick,
  section#setup.card > #ladderPick { grid-column: 1; grid-row: span 12; align-self: start; }
  /* Day 숫자판은 8칸×3줄 대신 12칸×2줄 -- 한 줄(40px) 이 그대로 절약됩니다.
     칸 폭 33px 이 좁아 보여도 높이 36px 은 그대로라 손가락은 들어갑니다. */
  .daygrid { grid-template-columns: repeat(12, 1fr); }
  /* 받아쓰기의 «무엇을» 세 묶음(교재에서/낱말책에서/연습용)은 옆으로 눕혀 한 줄에.
     세로로 세 줄이면 그것만 120px 입니다. 묶음 제목은 옆에 붙이고, 설명 한 줄과
     «무엇을 받아쓸까요» 이름표는 접습니다(묶음 제목이 곧 설명입니다). */
  section#setup.card > #whatPick {
    grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 4px 18px; margin: 0 0 4px;
  }
  section#setup.card > #whatPick .wg { padding: 1px 0; }
  /* 칩 높이 36px(2026-10-21): 28px 은 아이 손가락에 작았습니다. 늘려도 시작 단추는 첫 화면 안에 남습니다(893×534). */
  section#setup.card > #whatPick .chip { min-height: 36px; padding: 3px 9px; font-size: 12.5px; }
  section#setup.card > #whatPick .wg + .wg {
    border-top: 0; border-left: 1px solid var(--line-soft); padding-left: 16px;
  }
  section#setup.card > #whatPick .wg-t { width: auto; margin-right: 2px; }
  section#setup.card > #voiceWarn + label, section#setup.card > #whatHint { display: none; }
  /* 오른쪽 열의 옵션들. .row 는 세 칸을 옆으로 놓는 줄인데 오른쪽 열(약 330px)
     에서는 칸마다 칩이 다시 접혀 두 줄씩 됩니다. 칸을 위아래로 쌓으면 칩이 한
     줄에 들어가 오히려 낮습니다. */
  section#setup.card .row { display: block; }
  section#setup.card .row > * { min-width: 0; }
  section#setup.card > div[style*="margin-top"] { margin-top: 8px !important; }
  section#setup.card #start { min-height: 48px; }
  section#setup.card #review { min-height: 38px; padding: 6px 14px; font-size: 14px; }
  section#setup.card #wayHint { display: none; }      /* «쓰는 곳» 칩이 이미 같은 말입니다 */
  .msg.info.resume .resume-say { font-size: 13px; }
  /* 소리 확인 상자: 글과 단추를 한 줄에. 두 줄이면 120px 을 먹습니다. */
  #voiceWarn .msg { display: flex; align-items: center; gap: 12px; padding: 5px 12px; margin: 0 0 4px; }
  #voiceWarn .msg > div { flex: 1; }
  #voiceWarn .msg > button { margin-top: 0 !important; min-height: 32px !important; padding: 5px 12px !important; flex: none; }
  /* 오른쪽 열의 옵션 묶음(개수·방향·방식·쓰는 곳·읽기 속도): 이름표와 칩을 한
     줄에 놓습니다. 위아래로 두면 묶음마다 54px, 옆으로 두면 34px 입니다 --
     다섯 묶음이면 100px 차이고, 그것이 534px 안에 들어가느냐를 가릅니다. */
  section#setup.card .row > div { display: flex; align-items: flex-start; gap: 8px; margin-top: 6px; }
  /* 이름표 폭 66px: «쓰는 곳» 의 두 칩(약 320px)이 330px 열에서 한 줄에 들어가는 한계입니다 */
  section#setup.card .row > div > label { flex: 0 0 66px; margin: 6px 0 0; font-size: 12px; line-height: 1.35; }
  /* 칩 받침은 칩만큼(남은 폭이 모자라면 줄어들며 접힘) -- flex: 1 이면 받침이 줄 끝까지 늘어나 덜 채운 막대처럼 보였습니다(2026-10-26 점검). */
  section#setup.card .row > div > .chips { flex: 0 1 auto; margin-top: 0; min-width: 0; }
  section#setup.card > label { margin: 6px 0 2px; }
  section#setup.card > .chips { margin-top: 2px; }
  /* 이어서 하기: 가로에서는 이름과 단추만. 어느 범위인지는 왼쪽 고르개에 이미
     칠해져 있고 «Day 17~20» 이라고 적혀 있습니다. */
  .msg.info.resume { flex-wrap: nowrap; }
  .msg.info.resume .resume-say span { display: none; }
  /* 고르개를 높이에 맞게 조입니다 -- 534px 안에 세 줄짜리 Day 숫자판까지 들어가야
     합니다. 날 단추는 36px 를 지킵니다(더 내리면 옆 날을 잘못 누릅니다). 대신
     설명 글과 여백에서 뺍니다. */
  .picker label { margin: 4px 0 2px; font-size: 12px; }
  .picker label:first-child { margin-top: 0; }
  .picker .chips { gap: 4px; margin-top: 2px; }
  /* 낱말책·사다리 고르개의 칩과 이름표도 교재 고르개와 같은 크기로 */
  #vocaPick .chips .chip, #ladderPick .chips .chip { min-height: 27px; padding: 2px 6px; font-size: 12px; }
  #vocaPick .chips, #ladderPick .chips { margin-top: 2px; gap: 3px; }
  #vocaPick label, #ladderPick label { margin: 4px 0 2px; font-size: 12px; }
  #vocaPick .daygrid, #ladderPick .daygrid { margin-top: 2px; }
  #vbHint, #ldHint { display: none; }   /* 책 이름은 칩에 이미 있고, 사다리 설명은 시작하면 읽어 줍니다 */
  /* 교재 칩 열 개(1권~10권)가 한 줄에 들어가도록. 893px 화면에서 왼쪽 열은
     약 460px 이고 칩 열 개는 40px 씩 + 틈 3px -> 437px 입니다. 여기서 한 칸이라도
     넓어지면 «10권» 이 둘째 줄로 내려가 35px 을 잃습니다. */
  .picker .chips { gap: 4px; }
  /* 여기는 **가로로 든 태블릿** 입니다 -- 아이가 제일 많이 쓰는 자세입니다.
     자리를 아끼려고 칩을 27px(글씨 12px)까지 줄여 두었는데, 재 보니 1024x600
     에서 40px 로 키워도 스크롤이 한 픽셀도 안 생겼습니다(시작 단추가 242px 에
     있고 화면은 600px). 아낄 자리가 없어서 줄인 것이 아니라, 아낄 필요가
     없는데 줄여 두었던 것입니다. 손가락 크기를 되돌립니다. */
  .picker .chips .chip { min-height: 40px; padding: 7px 11px; font-size: 14px; }
  .daygrid { gap: 4px; margin-top: 2px; }
  .daygrid .day { min-height: 44px; font-size: 15px; border-radius: 7px; }
  .picker > p.hint { margin-top: 3px; font-size: 12px; }
  /* «이대로 시작을 누르면…» 두 줄 설명은 가로에서는 접습니다. 40px 을 먹는데,
     오른쪽에 시작 단추가 바로 보여서 설명 없이도 압니다. */
  #picker .range-hint { display: none; }
  #picker button.ghost { min-height: 38px; padding: 6px 14px; font-size: 13.5px; }
  #picker > div > div { margin-top: 2px !important; }   /* 인라인 margin 두 개를 조입니다 */
  .msg.info.resume { padding: 8px 12px; gap: 10px; margin-bottom: 6px; }
  .msg.info.resume .resume-go { min-height: 36px; padding: 6px 14px; font-size: 13.5px; }
  section#setup.card label { margin: 8px 0 4px; }
  /* 옵션 칩(개수·방향·방식…)만. id 선택자라 «.picker .chips .chip» 을 이기므로
     고르개까지 잡으면 교재 칩이 커져 «10권» 이 둘째 줄로 내려갑니다. */
  section#setup.card .row .chips .chip,
  section#setup.card > .chips .chip { min-height: 36px; font-size: 12.5px; padding: 3px 8px; }
  section#setup.card p.hint { font-size: 13px; margin-top: 6px; }
  section#setup.card #start { min-height: 52px; }
}

/* 리딩: 넓고 키도 큰 가로 태블릿(1280×800 · 1180×820). 위의 «왼쪽 지문 | 오른쪽 문제» 는
   높이 700 이하에서만 켜져서, 이런 화면은 한 줄 860px 이었습니다 -- 지문 한 줄이 90자가 넘어
   초등학생에게 너무 길고, 2~4번 문제를 푸는 동안 지문이 화면 위로 사라졌습니다.
   여기서는 키를 못 박지 않습니다. 지문은 왼쪽에 붙어(sticky) 있고, 문제는 보통처럼
   화면이 굴러가며 내려갑니다. 열 나누는 방식은 위 규칙과 같습니다(전부 왼쪽 → 고른 것만 오른쪽). */
@media (min-width: 1000px) and (min-height: 701px) {
  .wrap:has(> .card.play.read:not(.hidden)) { max-width: 1120px; }
  .card.play.read {
    display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); column-gap: 28px;
    grid-auto-flow: row dense; align-content: start; align-items: start;
  }
  .card.play.read > * { grid-column: 1; }
  .card.play.read > h3, .card.play.read > .qdots, .card.play.read > p.hint, .card.play.read > #quizMsg,
  .card.play.read > #questions, .card.play.read > .row:last-child { grid-column: 2; }
  .card.play.read > h3 { margin-top: 0; }
  .card.play.read > p.hint { display: none; }   /* «글은 위에 그대로 있어요» -- 여기서는 «옆» 이라 틀린 말 */
  .card.play.read > .subcard { grid-row: span 10; position: sticky; top: 84px; max-height: calc(100vh - 110px); overflow: auto; }
  .card.play.read .passage { font-size: 19px; line-height: 1.8; }
}

/* ---- 문장 단위 읽어 주기 (리딩 · 듣고 채우기) ----
   지금 읽는 문장이 밝아지고, 문장을 누르면 그 문장만 다시 들립니다. */
.sent { cursor: pointer; border-radius: 6px; padding: 1px 2px; transition: background .15s; }
@media (hover: hover) { .sent:hover { background: var(--brand-soft); } }
.sent.now { background: #fff3c4; box-shadow: inset 0 -2px 0 #e8b400; }
.listen-bar { display: flex; align-items: center; gap: 12px; margin: 0 0 12px; flex-wrap: wrap; }
.listen-bar .wide, .listen-bar .say-btn { flex: 0 0 auto; width: auto; min-width: 190px; }
.tile.t-listen { --tone: #2f80c9; }


/* 이번 주 일곱 칸. 아이가 «빈 칸» 을 보고 채우고 싶어지는 것이 요점이라,
   한 것과 안 한 것의 차이를 색으로 뚜렷하게 둡니다. */
.weekdots { display: flex; gap: 5px; flex: none; }
.wd {
  width: 30px; height: 36px; border-radius: 9px;
  border: 1px solid var(--line); background: #fff;
  display: flex; align-items: center; justify-content: center;
}
.wd i { font-style: normal; font-size: 12px; font-weight: 700; color: var(--ink-soft); }
/* 한 날은 **꽉 채웁니다.** 처음에 옅은 분홍으로 두었더니 흰 종이 위에서
   «한 날» 과 «안 한 날» 이 구별되지 않았습니다 -- 채우려는 마음이 안 생깁니다. */
.wd.on { background: var(--brand-btn); border-color: var(--brand-btn); }
.wd.on i { color: #fff; }
.wd.today { border-color: var(--brand-btn); border-width: 2px; }
.wd.today:not(.on) i { color: var(--brand-ink); }

/* 화면에 들어올 때 살짝 인사합니다. 한 번만, 짧게 -- 매번 흔들리면 성가십니다. */
.hello .maple svg { animation: maple-in .45s cubic-bezier(.34, 1.56, .64, 1); }
@keyframes maple-in {
  from { transform: scale(.72) rotate(-8deg); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .hello .maple svg { animation: none; } }
/* 말하기는 듣기 옆자리라 같은 계열에서 한 칸 따뜻한 쪽으로 -- 두 타일이
   나란히 있어도 아이가 어느 쪽을 눌렀는지 알아볼 수 있어야 합니다. */
.tile.t-speak  { --tone: #0f9488; }

/* ---- 둘러보기 첫 카드: «이게 뭘 해 주는 물건인가» ----
   예전에는 이 안내가 로그인 화면에 붙어 있었습니다. 들어오기 전에 학생 활동
   목록이 보일 이유가 없어 안으로 들여왔고, 대신 소개와 흐름을 앞에 세웠습니다. */
.card.intro h2 { margin-bottom: 6px; }
.intro .lead { font-size: 15px; line-height: 1.75; margin: 0 0 4px; }
.intro h3 { margin: 20px 0 4px; font-size: 14px; color: var(--brand); letter-spacing: .02em; }
.flow { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin: 14px 0 4px; }
.flow .step { border: 1px solid var(--line); border-radius: 12px; padding: 11px 12px; background: var(--bg); }
.flow .step b {
  display: inline-flex; align-items: center; justify-content: center;
  width: 21px; height: 21px; border-radius: 999px;
  background: var(--brand); color: #fff; font-size: 12px; margin-bottom: 6px;
}
.flow .step span { display: block; font-weight: 700; font-size: 14px; }
.flow .step em {
  display: block; font-style: normal; color: var(--ink-soft);
  font-size: 12.5px; line-height: 1.55; margin-top: 3px;
}
.always { list-style: none; margin: 4px 0 0; padding: 0; }
.always li { padding: 6px 0; border-bottom: 1px dashed var(--line); font-size: 14px; line-height: 1.6; }
.always li:last-child { border-bottom: 0; }
@media (max-width: 900px) { .flow { grid-template-columns: 1fr 1fr; } }
@media (max-width: 540px) {
  .flow { grid-template-columns: 1fr; gap: 7px; }
  .flow .step { padding: 9px 11px; }
  .intro .lead { font-size: 14px; }
}

/* ---- 눌러 고르는 줄: «레벨  [버블][버블]…» ----
   드롭다운이 있던 자리입니다. 이름표는 왼쪽에 붙여 두고 버블만 접히게 합니다. */
.pick-row { display: flex; align-items: flex-start; gap: 10px; margin-top: 8px; }
.pick-row > .tb-label {
  flex: 0 0 auto; padding-top: 9px; min-width: 34px;
  font-size: 13px; font-weight: 600; color: var(--ink-soft);
}
.pick-row > .bubble-row { margin: 0; flex: 1 1 auto; min-width: 0; }
.pick-row .bubble { padding: 6px 12px; font-size: 13.5px; }
@media (max-width: 540px) {
  .pick-row { gap: 7px; }
  .pick-row > .tb-label { min-width: 30px; padding-top: 8px; }
  .pick-row .bubble { padding: 6px 10px; font-size: 13px; }
}

/* ---- 숙제 미리보기: 내기 전에 «이렇게 나갑니다» ---- */
.hw-preview {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 14px;
  border: 1px solid var(--line); border-radius: 10px; padding: 10px 13px;
  background: var(--bg); font-size: 14px;
}
.hw-preview:empty { display: none; }
.hw-preview b { color: var(--brand); font-size: 12.5px; margin-right: 4px; }
.hw-preview .sep { color: var(--ink-soft); }
.hw-preview.todo { border-style: dashed; }
.hw-preview.todo b { color: var(--ink-soft); }
.hw-yes {
  display: inline-block; margin-left: 5px; padding: 1px 7px; border-radius: 99px;
  background: var(--brand-soft); color: var(--brand); font-size: 11px; font-weight: 700;
  vertical-align: 1px;
}

/* ---- 좌측 메뉴의 한 줄 설명 ---- */
.tnav button { align-items: flex-start; }
.tnav button svg { margin-top: 1px; }
.tnav .nav-txt { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }
.tnav .nav-txt small { font-size: 11.5px; font-weight: 500; color: var(--ink-soft); line-height: 1.35; }
.tnav button.active .nav-txt small { color: var(--brand); opacity: .8; }
@media (max-width: 900px) {
  /* 좁은 화면에서는 메뉴가 가로 줄이 됩니다. 설명은 숨기고, 이름은 한 줄로 두어
     («실 시 간» 처럼 글자마다 줄이 바뀌던 것) 넘치면 옆으로 밀어 봅니다. */
  .tnav .nav-txt small { display: none; }
  .tnav .nav-txt { flex-direction: row; align-items: center; }
  .tnav .nav-txt > span { white-space: nowrap; }
  .tnav button { flex: 0 0 auto; }
}

/* ---- 낮은 가로 화면 (폰 가로 ≈ 915×412 · 교실 태블릿 가로 893×534) ----
   틈이 하나 있었습니다. 폭이 900 을 넘어 «좁은 화면» 규칙이 안 걸리고, 높이는
   폰만큼 낮습니다. 그대로 두면 메뉴 아홉 개가 **679px** 로 서서 412px 짜리 화면을
   한참 넘깁니다 — 원장이 폰을 눕히면 메뉴가 줄줄이 흘러내렸습니다.

   여기서 모자란 것은 폭이 아니라 **높이**입니다. 그러니 가로 배치는 그대로 두고
   (폭은 남습니다) 세로로 자리를 먹는 것만 줄입니다. 그래도 넘치면 메뉴 안에서만
   굴러갑니다 — 페이지가 통째로 밀려 내용이 따라 올라가는 것보다 낫습니다. */
@media (orientation: landscape) and (max-height: 560px) and (min-width: 700px) {
  /* 메뉴를 **두 칸**으로 세웁니다. 한 줄로 세우면 열 개가 300px 을 넘어 낮은
     화면에서 굴려야 하고, 가로 한 줄로 눕히면 내용이 그만큼 아래로 밀립니다.
     두 칸이면 다섯 줄, 170px 안쪽이라 굴릴 일이 없습니다. */
  .teacher-layout { grid-template-columns: 228px 1fr; gap: 14px; }
  .tnav {
    /* 위의 `max-width: 860` 규칙이 가로줄로 눕혀 놓는 폭대(700~860)가 있습니다.
       거기서 이 규칙이 사이드바 폭만 좁히면, 좁은 칸 안에 긴 가로줄이 갇혀
       옆으로 밀어야 메뉴가 보입니다 -- 실제로 그렇게 됐습니다. 그래서 여기서
       눕힌 것을 **되돌려 놓고** 시작합니다. */
    position: sticky; top: 62px;
    display: grid; grid-template-columns: 1fr 1fr; gap: 3px;
    padding: 6px; overflow: visible;
  }
  .tnav button {
    flex: none; width: auto; min-width: 0;
    justify-content: flex-start;
    padding: 7px 8px; gap: 7px; align-items: center;
  }
  .tnav button svg { width: 16px; height: 16px; margin-top: 0; }
  /* 한 줄 설명은 접습니다. 이름만으로 열 개가 한 화면에 들어옵니다. */
  .tnav .nav-txt { flex-direction: row; align-items: center; }
  .tnav .nav-txt small { display: none; }
  .tnav .nav-txt > span { font-size: 12.5px; white-space: nowrap; }
  .tnav button span { font-size: 12.5px; }
  /* 지금 있는 화면 표시는 세로 막대로 되돌립니다(가로줄일 때는 밑줄이었습니다) */
  .tnav button.active::before {
    left: 0; right: auto; top: 50%; bottom: auto; transform: translateY(-50%);
    width: 3px; height: 14px; border-radius: 0 99px 99px 0;
  }
  .tnav .badge { margin-left: auto; padding: 0 5px; font-size: 10.5px; }
  /* 두 칸 메뉴는 칸이 좁아 배지가 이름 끝 글자(«숙제·채점» 의 «점»)를 덮었습니다. 단추 오른쪽 위 구석으로 띄웁니다. */
  .tnav .badge { position: absolute; top: 1px; right: 2px; margin: 0; min-width: 16px; height: 16px; line-height: 16px; padding: 0 4px; }
  .wrap { padding-top: 14px; }
}

/* ---- 채점·성적의 고르개 줄 (학생·파트) ---- */
.filter-row {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 10px 0 14px; padding: 9px 12px;
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius);
}
.filter-row select { min-height: 34px; padding: 4px 10px; font-size: 13.5px; width: auto; margin: 0; }
.filter-row .tb-label { font-size: 12px; }
.pill.part { background: var(--bg); color: var(--ink-soft); border: 1px solid var(--line); font-weight: 600; }

/* ============================================================================
   폰에서 선생님 화면 (갤럭시 S23 U 기준 CSS 폭 ≈ 412)
   ----------------------------------------------------------------------------
   고치기 전 문제 (2026-09-09 에 실제로 재 본 값):
     · 머리글이 **152px** — «선생님 화면» 이 «선/생/님/화/면» 으로 세로로 쪼개져서
       화면 위 6분의 1을 이름표가 먹었습니다.
     · 좌측 메뉴 일곱 개가 가로 줄이 되면서 **한 개만 보였습니다.** 나머지는 옆으로
       숨어서, 옆으로 밀 수 있다는 걸 모르면 채점·성적에 갈 길이 없었습니다.
     · 반 고르개와 단추 두 개가 각각 줄을 차지해 본문이 더 밀렸습니다.
   ========================================================================== */
@media (max-width: 540px) {
  /* ---- 머리글: 한 줄 안에 ---- */
  header.bar { padding: 10px 12px 9px; gap: 8px; }
  /* 화면 이름은 브랜드 옆에 붙는 부제라, 좁으면 줄이는 대신 지웁니다.
     어느 화면인지는 바로 아래 메뉴에서 칠해진 칸이 말해 줍니다. */
  header.bar h1 { display: none; }
  /* 넓은 화면에서 학생 코드 · 홈 단추를 오른쪽 끝으로 미는 것은 제목(h1, flex: 1)이었습니다.
     제목을 지우면 둘이 로고 옆에 붙고 오른쪽이 비어서, 홈 단추가 엄지 자리를 떠났습니다.
     로고가 남는 자리를 맡습니다. */
  header.bar .brand { margin-right: auto; }
  /* 학생 코드는 아이가 선생님께 불러 줘야 하는 글자입니다. 좁다고 11.5px 로
     줄이고 있었는데, 바로 위에서 화면 이름(h1)을 감추므로 자리는 남습니다.
     줄일 까닭이 없어진 뒤에도 규칙만 남아 있었습니다. */
  header.bar .who { font-size: 12.5px; padding: 3px 9px; }
  header.bar .brand .wm b { font-size: 15px; }
  header.bar .brand .wm i { font-size: 12px; }   /* 10px 은 아이 화면 하한(12px) 아래였습니다 */
  header.bar #outBtn { min-height: 34px !important; padding: 6px 10px !important; font-size: 13px !important; }

  /* ---- 메뉴: 일곱 개가 한눈에. 네 칸씩 두 줄 ---- */
  .tnav {
    display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px;
    overflow: visible; padding: 6px;
  }
  .tnav button {
    flex: none; width: auto; min-width: 0;
    flex-direction: column; align-items: center; justify-content: center;
    gap: 3px; padding: 8px 2px; min-height: 54px;
  }
  .tnav button svg { margin: 0; }
  .tnav .nav-txt { flex-direction: column; align-items: center; flex: none; }
  .tnav .nav-txt > span { font-size: 11.5px; line-height: 1.2; white-space: nowrap; }
  /* 밑줄 표시는 칸 안에 */
  .tnav button.active::before {
    left: 8px; right: 8px; top: auto; bottom: 3px; transform: none;
    width: auto; height: 2px; border-radius: 99px;
  }
  /* 채점 대기 숫자는 아이콘 오른쪽 위에 작게 */
  .tnav .badge {
    position: absolute; top: 4px; right: 50%; margin-right: -20px;
    min-width: 16px; height: 16px; font-size: 10.5px; line-height: 16px; padding: 0 4px;
  }

  /* ---- 반 고르개와 단추를 한 줄로 ---- */
  .toolbar { gap: 6px; padding: 8px 10px; }
  .toolbar select { flex: 1; min-width: 0; }
  .toolbar .tb-right { margin-left: 0; width: auto; flex: none; gap: 6px; }
  .toolbar .tb-right button { flex: none; font-size: 12.5px; padding: 6px 9px; min-height: 34px; }

  /* ---- 숫자 카드는 두 칸, 조금 작게 ---- */
  .stat-row { grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 12px; }
  .stat { padding: 12px 12px 11px; }
  .stat .n { font-size: 26px; }

  /* ---- 카드 여백을 줄여 한 화면에 더 ---- */
  .tmain .card { padding: 14px 13px; margin-bottom: 12px; }
  .tmain .card h2 { font-size: 16px; }
  .tmain .card h3 { font-size: 14.5px; }
  .tmain .hint { font-size: 12.5px; }

  /* ---- 표: 여백을 조여 화면 안에 넣고, 그래도 넘치면 표 안에서만 밀립니다 ----
     칸을 억지로 넓혀 두면(min-width) 접을 칸을 접어도 소용이 없습니다. 실제 폭에
     맡기고 여백만 줄입니다. 화면 밖으로 나가는 표는 자기 상자 안에서 밀립니다. */
  .tbl { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .tmain th, .tmain td { padding: 9px 7px; font-size: 13px; }
  .tmain th { font-size: 11.5px; }

  /* ---- 채점·성적 고르개 줄 ---- */
  .filter-row { gap: 6px; padding: 8px 10px; }
  .filter-row select { flex: 1; min-width: 0; font-size: 13px; }
}

/* 폰에서 접는 칸. 표를 옆으로 밀지 않고도 보이게 하려는 것입니다.
   접는 것은 «없어도 아는 것»만 — 코드는 이름 옆에 이미 있고, 반은 위 고르개로 거릅니다. */
@media (max-width: 540px) {
  .wide-only { display: none !important; }
  /* 범위 이름이 길어 한 줄을 다 먹지 않게 */
  .tmain table td { word-break: keep-all; }
}

/* ---- 둘러보기: 활동마다 «진짜 예시» 한 개 ---- */
.tour-card {
  border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px; margin-bottom: 12px;
  background: var(--card);
}
.tour-head { display: flex; align-items: center; gap: 8px; }
.tour-head b { font-size: 15.5px; }
.tour-ex { background: var(--bg); border-radius: 10px; padding: 13px 14px; }
.tour-q { font-size: 22px; font-weight: 700; text-align: center; margin-bottom: 10px; }
.tour-q2 { font-weight: 600; margin: 10px 0 8px; }
.tour-a { font-size: 16px; font-weight: 600; margin: 4px 0; }
.tour-title { font-weight: 700; margin-bottom: 6px; }
.tour-passage {
  font-size: 14.5px; line-height: 1.85; color: var(--ink-soft);
  word-break: keep-all; margin-bottom: 4px;
}
.tour-opts { display: flex; flex-wrap: wrap; gap: 7px; }
.tour-opt {
  border: 1px solid var(--line); background: var(--card); border-radius: 8px;
  padding: 6px 11px; font-size: 14px;
}
.tour-opt.right { border-color: var(--ok); background: var(--ok-soft); color: var(--ok-ink); font-weight: 600; }
.tour-from { font-size: 12px; color: var(--ink-soft); margin-top: 9px; }
@media (max-width: 540px) {
  .tour-card { padding: 12px 12px; }
  .tour-q { font-size: 19px; }
  .tour-passage { font-size: 13.5px; line-height: 1.8; }
}

/* ---- 눌러서 고르는 버블 (숙제 대상·종류) ----
   드롭다운은 열기 전에는 «무엇이 있는지» 가 안 보입니다. 선생님이 학생 이름과
   낼 수 있는 것을 한눈에 보고 눌러 고르게 합니다. */
.bubble-row { display: flex; flex-wrap: wrap; gap: 7px; margin: 4px 0 0; }
.bubble {
  border: 1px solid var(--line); background: var(--card); color: var(--ink);
  border-radius: 999px; padding: 8px 14px; font-size: 14px; font-weight: 600;
  min-height: 0; box-shadow: none; cursor: pointer;
  transition: background .12s, border-color .12s, color .12s;
}
.bubble:hover { border-color: var(--brand); }
.bubble.on { background: var(--brand); border-color: var(--brand); color: #fff; }
.bubble .sub { font-weight: 500; opacity: .75; font-size: 12px; margin-left: 5px; }
/* 이 문구는 «누구에게» 칸에만 맞습니다. 버블 줄은 이제 여러 곳에 있습니다. */
#hwWho.bubble-row:empty::after { content: '학생을 먼저 등록해 주세요'; color: var(--ink-soft); font-size: 13px; }

/* ---- 수업: 오늘 오는 학생 줄 ---- */
.lesson-row {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 11px 13px; border: 1px solid var(--line); border-radius: 10px;
  margin-bottom: 8px; background: var(--card);
}
.lesson-row.done { background: var(--bg); }
.lesson-row .ls-time { font-variant-numeric: tabular-nums; min-width: 48px; font-size: 15px; }
.lesson-row .ls-who { font-weight: 600; }
.lesson-row .ls-sub {
  border: 1px solid var(--line); border-radius: 999px; padding: 2px 10px;
  font-size: 12.5px; color: var(--ink-soft);
}
.lesson-row > button:last-child { margin-left: auto; }
@media (max-width: 540px) {
  .lesson-row { padding: 10px; gap: 7px; }
  .lesson-row .ls-time { min-width: 42px; font-size: 14px; }
  /* 폰: «김 선생님 · 1교실» 뒤에 단추가 꺾여 줄마다 단추 하나가 한 줄을 차지했습니다(한 줄 90px).
     단추 · «적음» 은 윗줄 끝에, 선생님 · 교실은 아랫줄로 (2026-10-30) */
  .lesson-row > button:last-child, .lesson-row > .pill:last-child { order: 4; margin-left: auto; }
  .lesson-row .ls-meta { order: 5; flex-basis: 100%; padding-left: 49px; margin-top: -4px; }
}

/* 시간표에서 고치는 중인 줄 */
tr.picked > td { background: var(--brand-soft); }
/* 좁은 화면에서만 보이는 것 (과목 한 글자). wide-only 의 짝입니다. */
.narrow-only { display: none; }
@media (max-width: 540px) {
  .narrow-only { display: inline; }
  /* 시간표 버블은 수가 많아 폰에서 한 단계 작게 */
  #scHourPick .bubble { padding: 7px 11px; font-size: 13.5px; }
}

/* ---- 간판 미리보기 ----
   저장하기 전에 아이 화면이 어떻게 보이는지 보여 줍니다. 진짜 화면을 축소해
   놓은 것이라, 색이 얼마나 진한지·이름이 얼마나 긴지를 누르기 전에 압니다.
   색은 `--bp` 하나로 흐르고, 그 값은 화면이 색을 고를 때마다 넣어 줍니다. */
.brand-prev {
  --bp: var(--brand);
  border: 1px solid var(--line); border-radius: 14px; overflow: hidden;
  background: var(--card); margin-top: 14px;
}
.brand-prev .bp-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 13px; border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--bp) 7%, transparent);
}
.brand-prev .bp-mark b { color: var(--bp); font-size: 15px; letter-spacing: -.01em; }
.brand-prev .bp-mark i { font-style: normal; color: var(--ink-soft); font-size: 10.5px; margin-left: 4px; }
.brand-prev .bp-who {
  margin-left: auto; font-size: 11.5px; font-weight: 600;
  color: var(--bp); border: 1px solid color-mix(in srgb, var(--bp) 35%, transparent);
  border-radius: 99px; padding: 2px 9px;
}
.brand-prev .bp-body { display: flex; align-items: center; gap: 12px; padding: 13px; flex-wrap: wrap; }
.brand-prev .bp-tile {
  display: flex; flex-direction: column; gap: 3px; min-width: 96px;
  border: 1px solid var(--line); border-left: 3px solid var(--bp);
  border-radius: 10px; padding: 9px 12px; background: var(--bg);
}
.brand-prev .bp-tile b { color: var(--bp); font-size: 14px; }
.brand-prev .bp-tile span { font-size: 12px; color: var(--ink-soft); }
.brand-prev .bp-btn {
  background: var(--bp); color: #fff; border: 0; border-radius: 10px;
  padding: 9px 18px; font-size: 14px; font-weight: 700; min-height: 0;
  box-shadow: none; cursor: default;
}

/* ---- 골라 둔 색 동그라미 ----
   이름을 붙이지 않았습니다. «산호빛» 이라고 적어 두면 화면의 색과 머릿속 이름을
   맞춰 보느라 한 번 더 생각하게 됩니다. 동그라미가 곧 이름입니다. */
.swatch {
  width: 34px; height: 34px; padding: 0; min-height: 0; border-radius: 999px;
  background: var(--sw); border: 2px solid var(--card);
  box-shadow: 0 0 0 1px var(--line); cursor: pointer;
  transition: transform .12s, box-shadow .12s;
}
.swatch:hover { transform: scale(1.08); }
.swatch.on { box-shadow: 0 0 0 2px var(--card), 0 0 0 4px var(--sw); }

/* ---- 개발자: 내 학원들 ---- */
#dvSiteList table { font-variant-numeric: tabular-nums; }
#dvSiteList td a { color: var(--ink-soft); text-decoration: none; }
#dvSiteList td a:hover { color: var(--brand); text-decoration: underline; }

/* 처음 할 일: 줄마다 «거기로 가기» 단추. 글로 «아래 학원 설정에서» 라고만 적어
   두면 읽고 나서 그 자리를 다시 찾아 내려가야 합니다. */
ol.steps li button.mini { margin-top: 8px; }

/* ---- 도움말: 묻고 답하기 ----
   접어 두지 않습니다. 답이 한두 줄이라 다 펴 두어도 길지 않고, 접어 두면
   «내 것이 어느 줄인지» 를 찾느라 하나씩 눌러 보게 됩니다. */
.qa { padding: 11px 0; border-top: 1px solid var(--line); }
.qa:first-child { border-top: 0; padding-top: 2px; }
.qa > b { display: block; font-size: 15px; }
.qa p b { color: var(--ink); }
.qa p { margin: 4px 0 0; font-size: 13.5px; line-height: 1.7; color: var(--ink-soft); }

/* 처음 할 일: 줄 전체가 단추입니다. 끝난 줄도 눌러서 그 자리로 갑니다. */
ol.steps li.go { cursor: pointer; border-radius: 10px; transition: background .12s; }
ol.steps li.go:hover, ol.steps li.go:focus-visible { background: var(--bg); outline: none; }

/* ---- 선생님 화면의 표: 누를 수 있는 줄인지 PC 에서도 보이게 ----
   마우스를 올렸을 때 흰색(#ffffff)이 #faf8f5 로 바뀌는 것이 전부였습니다. 거의
   같은 색이라 PC 에서는 **눌러 볼 이유가 안 생깁니다** -- 폰은 손가락으로 눌러
   보면 되지만 마우스는 그렇지 않습니다.

   `.teacher-layout` 안으로 묶었습니다. 이 규칙이 학생 화면까지 가면 받아쓰기
   화면이 같이 바뀝니다 -- 표가 없어서 지금은 걸릴 것이 없지만, 공용 CSS 를
   고칠 때는 그쪽부터 생각해야 합니다. */
.teacher-layout tbody tr.tap { cursor: pointer; }
.teacher-layout tbody tr.tap:hover > td { background: var(--tint); box-shadow: inset 0 0 0 1px var(--line-soft); }
.teacher-layout tbody tr.tap:active > td { background: var(--brand-soft); }

/* ---- 내 기록: 활동별 평균과 한 판씩 ----------------------------------------
   표였습니다. 폰 412px 에서 다섯 칸이 눌려 «Orange 1권 Day 7-1 A Color Walk» 이
   다섯 줄로 깨지고, 똑같은 날짜가 열두 번 되풀이되고, 점수가 «25점» 과 «1/4» 두
   칸에 나뉘어 있었습니다. 게다가 표는 아이가 궁금한 것(«내가 어디가 약한가»)에
   답하지 않습니다 -- 숫자를 눈으로 견줘야 하니까요. 길이로 견주게 합니다. */
.bykind { margin: 2px 0 18px; }
.bk-row {
  display: grid; grid-template-columns: 4.6em minmax(0, 1fr) 3.4em 2.6em;
  align-items: center; gap: 9px; padding: 5px 0;
}
.bk-name { font-size: 13.5px; font-weight: 600; }
/* 막대 바탕은 --line-soft(#f2eeea) 보다 한 톤 진하게 -- 0 점에 가까운 막대가
   바탕에 묻히면 «아직 안 봤다» 와 «다 틀렸다» 가 같아 보입니다. */
.bk-track { height: 12px; border-radius: 99px; background: var(--line-soft); overflow: hidden; }
.bk-track i { display: block; height: 100%; background: var(--brand-btn); border-radius: 0 4px 4px 0; }
.bk-val { font-size: 14px; font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }
.bk-n { font-size: 12px; color: var(--ink-soft); text-align: right; font-variant-numeric: tabular-nums; }

.runs { margin-top: 2px; }
.run-day {
  margin: 16px 0 2px; font-size: 12px; font-weight: 700; color: var(--ink-soft);
  letter-spacing: .02em;
}
.run-day:first-child { margin-top: 2px; }
/* 한 판이 한 줄입니다. 첫 줄에 «무엇을 · 어디를 · 몇 점», 둘째 줄에 그 점수의
   길이. 이름이 길면 줄을 늘리지 않고 끝을 …으로 줄입니다 -- 한 판의 높이가
   들쭉날쭉하면 쉰 판을 훑을 수 없습니다. */
.run {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas: "kind range score" "bar bar of";
  align-items: center; gap: 6px 8px;
  padding: 9px 0; border-bottom: 1px solid var(--line-soft);
}
.run > .kind { grid-area: kind; }
.run-range {
  grid-area: range; min-width: 0; font-size: 14px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.run-score { grid-area: score; font-size: 15px; font-variant-numeric: tabular-nums; }
.run-bar { grid-area: bar; height: 8px; border-radius: 99px; background: var(--line-soft); overflow: hidden; }
.run-bar i { display: block; height: 100%; background: var(--brand-btn); border-radius: 0 4px 4px 0; }
.run-of {
  grid-area: of; font-size: 12px; color: var(--ink-soft);
  text-align: right; font-variant-numeric: tabular-nums;
}
/* 외우기 기록엔 점수가 없습니다 -- 막대 줄을 비워 두지 않고 한 줄로 둡니다. */
.run.slog { grid-template-areas: "kind range score"; }

/* 들어오면 막대가 자기 길이까지 자랍니다. 0.5초, 한 번. 숫자만 있던 자리가
   «움직이는 것» 이 되면 아이가 한 번 더 봅니다. */
@keyframes bar-grow { from { transform: scaleX(0); } }
.bk-track i, .run-bar i {
  transform-origin: left center;
  animation: bar-grow .5s cubic-bezier(.2, .8, .2, 1) both;
}
@media (prefers-reduced-motion: reduce) { .bk-track i, .run-bar i { animation: none; } }

/* ---- 자주 틀린 단어: 읽는 자리에서 바로 맞혀 보기 ----
   목록을 «다시 외우세요» 하고 보여 주기만 했습니다. 뜻을 덮어 두면 같은 목록이
   시험이 됩니다. 한 줄을 누르면 그 줄만 열립니다. */
.weaklist + button.wide { margin-top: 10px; }
button.mini + .weaklist { margin-top: 6px; }
.weaklist .ko { border-radius: 6px; transition: background .12s, color .12s; }
.weaklist.covered li { cursor: pointer; }
.weaklist.covered .ko { background: #ece7e1; color: transparent; padding: 0 22px; }
.weaklist.covered li.open .ko { background: none; color: inherit; padding: 0; }

/* ---- 이어서 할 때는 고르개를 접습니다 ----
   칩이 마흔두 개라(레벨 5 · 권 10 · Day 24 · 묶음 3) 폰에서 시험 하나를
   시작하려면 1437px 을 굴려 내려가야 했습니다. 이어서 할 곳을 이미 골라
   두었을 때만 접고, 접힌 자리에 고른 범위를 적어 둡니다. */
/* 접은 고르개. «바꾸기» 줄은 #picker 안에 있으므로 그것만 남깁니다 --
   밖에 두면 화면이 #picker 를 숨길 때(받아쓰기의 낱말책 갈래) 이 줄만 남습니다. */
#picker.folded > *:not(.picker-open) { display: none; }
.picker-open {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; margin: 10px 0 2px; padding: 13px 15px;
  background: #fff; border: 1px dashed var(--line); border-radius: 12px;
  font: inherit; font-size: 15px; color: var(--ink); text-align: left; cursor: pointer;
  min-height: 52px;
}
.picker-open:hover, .picker-open:focus-visible { border-color: var(--brand); outline: none; }
.po-range { font-weight: 700; }
.po-go { flex: none; font-size: 13px; color: var(--brand-ink); font-weight: 600; }
.po-go::after { content: ' ▾'; }


/* ---- 아래쪽 탭 (js/tabs.mjs) ----------------------------------------------
   엄지가 닿는 자리에 갈래 다섯. 고르는 화면(홈 · 숙제 · 내 기록)에만 붙습니다.
   글자를 아이콘 밑에 늘 적어 둡니다 -- 일곱 살은 아이콘만으로 «듣기» 를 모릅니다.
   켜진 탭은 색만이 아니라 알약 바탕으로도 보입니다(색을 못 가리는 아이도 압니다). */
.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  background: rgba(255, 255, 255, .95);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border-top: 1px solid var(--line);
  box-shadow: 0 -6px 20px rgba(51, 56, 63, .06);
  padding-bottom: env(safe-area-inset-bottom);
}
.tabbar-in { max-width: 560px; margin: 0 auto; display: grid; grid-template-columns: repeat(5, 1fr); }
.tabbar a {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  min-height: 60px; padding: 6px 0 7px;
  text-decoration: none; color: var(--ink-soft);
  font-size: 12px; font-weight: 700; letter-spacing: -.01em;
}
.tabbar i {
  width: 48px; height: 30px; border-radius: 99px;
  display: flex; align-items: center; justify-content: center;
  transition: background .15s, color .15s;
}
.tabbar svg { width: 22px; height: 22px; }
.tabbar a.on { color: var(--brand-ink); }
.tabbar a.on i { background: var(--brand-soft); color: var(--brand); }
.tabbar a:active i { transform: scale(.92); }
body.has-tabs .wrap { padding-bottom: calc(100px + env(safe-area-inset-bottom)); }
@media print { .tabbar { display: none; } }


/* ---- 방 (단어 · 듣기 · 읽기) ----
   홈에서는 옅은 색 판 하나에 친구 얼굴 + 작은 타일 셋. 타일 아홉 개가 세로로
   늘어서던 것(폰에서 1,900px)이 세 판으로 줄어 한 화면 남짓에 들어옵니다. */
.room {
  --room-bg: #fff6ec; --room-line: #f3dfc6; --room-ink: #8a4f14;
  background: var(--room-bg); border: 1px solid var(--room-line);
  border-radius: 22px; padding: 10px 12px 12px; margin-top: 14px;
}
.room[data-room="listen"] { --room-bg: #eef5fd; --room-line: #d3e3f6; --room-ink: #23609f; }
.room[data-room="read"]   { --room-bg: #eef8f1; --room-line: #cfe7d6; --room-ink: #2c6e42; }
.room-head {
  display: flex; align-items: center; gap: 10px;
  text-decoration: none; color: inherit; padding: 2px 2px 8px;
}
.room-pal { flex: none; line-height: 0; }
.room-t { flex: 1 1 auto; min-width: 0; }
.room-t b { display: block; font-family: var(--font-brand); font-weight: 400; font-size: 20px; color: var(--room-ink); }
.room-t small { display: block; font-size: 12.5px; color: var(--ink-soft); }
.room-go { flex: none; font-size: 13px; font-weight: 700; color: var(--room-ink); white-space: nowrap; }
.room-say { display: none; }
.room .tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.room .tile {
  align-items: center; text-align: center; padding: 12px 4px 11px;
  border-color: transparent; box-shadow: 0 1px 2px rgba(51, 56, 63, .06);
}
.room .tile b { margin: 8px 0 0; font-size: 13.5px; max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.room .tile span { display: none; }
.room .tile .big { width: 44px; height: 44px; border-radius: 14px; }

/* 방 하나를 펼친 화면(/home.html#words). 홈 위쪽 것은 숨기고 그 방만 크게. */
body[data-view="room"] .home-only { display: none !important; }
body[data-view="room"] .room:not(.on) { display: none; }
.room.on { margin-top: 4px; padding: 16px 14px 16px; }
.room.on .room-head { cursor: default; gap: 14px; padding-bottom: 4px; }
.room.on .room-t b { font-size: 28px; }
.room.on .room-t small { font-size: 14px; }
.room.on .room-go { display: none; }
.room.on .room-pal { cursor: pointer; }
.room.on .room-say {
  display: block; position: relative; margin: 6px 0 16px;
  background: var(--card); border: 1px solid var(--room-line); border-radius: 16px;
  padding: 11px 15px; font-size: 15px; font-weight: 600; color: var(--ink);
}
.room.on .room-say::before {
  content: ""; position: absolute; left: 38px; top: -7px;
  width: 12px; height: 12px; background: var(--card);
  border-left: 1px solid var(--room-line); border-top: 1px solid var(--room-line);
  transform: rotate(45deg);
}
/* 방 안에서는 타일이 한 줄에 하나(폰) -- 무엇을 하는지 설명까지 읽히게. */
.room.on .tiles { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 10px; }
.room.on .tile {
  display: grid; grid-template-columns: 52px 1fr; column-gap: 14px;
  align-items: center; text-align: left; padding: 14px 16px; box-shadow: var(--shadow);
}
.room.on .tile .big { grid-row: span 2; width: 52px; height: 52px; border-radius: 16px; }
.room.on .tile .big svg { width: 26px; height: 26px; }
.room.on .tile b { margin: 0; font-size: 17px; align-self: end; white-space: normal; }
.room.on .tile span { display: block; margin: 1px 0 0; font-size: 13.5px; align-self: start; }

/* 친구의 몸짓. 방 안에서는 천천히 숨 쉬듯 들썩이고, 누르면 폴짝 뜁니다.
   홈에서는 가만히 있습니다 -- 셋이 한꺼번에 움직이면 정신없습니다. */
@keyframes friend-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }
@keyframes friend-hop {
  0% { transform: none; } 35% { transform: translateY(-12px) rotate(-7deg); }
  70% { transform: translateY(0) rotate(4deg); } 100% { transform: none; }
}
.room.on .room-pal svg { animation: friend-bob 3.2s ease-in-out infinite; transform-origin: 50% 90%; }
.room-pal.hop svg, #helloMaple.hop svg { animation: friend-hop .5s ease; transform-origin: 50% 90%; }
@media (prefers-reduced-motion: reduce) {
  .room.on .room-pal svg, .room-pal.hop svg, #helloMaple.hop svg { animation: none; }
}
@media (max-width: 360px) {
  .room .tile b { font-size: 12.5px; }
  .room-go { display: none; }
}

/* ---- 결과의 친구 (js/cheer.mjs) ---- */
.cheer { text-align: center; margin-bottom: 4px; }
.cheer-pal { display: block; line-height: 0; }
.cheer-pal svg { animation: friend-hop .55s ease .05s both; transform-origin: 50% 90%; }
.cheer-say {
  display: inline-block; margin: 6px auto 10px; padding: 8px 14px;
  background: var(--brand-soft); color: var(--brand-ink);
  border-radius: 14px; font-size: 15px; font-weight: 700; line-height: 1.45;
}
.confetti { position: fixed; inset: 0; pointer-events: none; z-index: 60; overflow: hidden; }
.confetti i {
  position: absolute; top: -14px; width: 9px; height: 13px; border-radius: 2px;
  animation: confetti-fall 1.4s cubic-bezier(.25, .6, .5, 1) forwards;
}
@keyframes confetti-fall {
  to { transform: translate(var(--x), 105vh) rotate(var(--r)); opacity: .85; }
}
@media (prefers-reduced-motion: reduce) { .cheer-pal svg { animation: none; } .confetti { display: none; } }

/* ---- 스티커판 (내 기록 · js/stickers.mjs) ----
   못 받은 것은 흐리게 · 눈 감은 얼굴로. 자물쇠를 그리지 않습니다 -- «잠겨 있다»
   보다 «아직 자고 있다» 가 깨우고 싶어집니다. */
.stk-count { font-size: 13px; font-weight: 700; color: var(--ink-soft); margin-left: 6px; }
.stickers { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 10px; margin-top: 12px; }
.stk {
  position: relative; text-align: center; padding: 10px 4px 12px;
  border-radius: 16px; background: var(--tint); border: 1px solid var(--line-soft);
}
.stk-pic { display: block; line-height: 0; filter: grayscale(1); opacity: .42; }
.stk b { display: block; margin-top: 6px; font-size: 13px; line-height: 1.3; color: var(--ink-soft); }
.stk small { display: block; font-size: 12px; color: var(--ink-soft); margin-top: 1px; }
.stk.got { background: #fffaf0; border-color: #f3dfb8; }
.stk.got .stk-pic { filter: none; opacity: 1; }
.stk.got b { color: var(--ink); }
.stk.got small { color: #a26a10; font-weight: 700; }
.stk-bar {
  position: absolute; left: 14px; right: 14px; bottom: 6px; height: 4px;
  border-radius: 99px; background: var(--line);
}
.stk-bar::after {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: var(--p);
  border-radius: inherit; background: var(--brand);
}
.stk.new { border-color: var(--brand-line); box-shadow: 0 0 0 3px var(--brand-soft); }
.stk.new::before {
  content: "NEW"; position: absolute; top: -7px; right: -4px;
  padding: 1px 7px; border-radius: 99px; background: var(--brand-btn); color: #fff;
  font-size: 12px; font-weight: 800; letter-spacing: .04em;   /* «NEW» 10.5px → 아이 화면 하한 12px */
}
.stk.new .stk-pic svg { animation: friend-hop .6s ease .3s 2; transform-origin: 50% 90%; }
@media (prefers-reduced-motion: reduce) { .stk.new .stk-pic svg { animation: none; } }
/* 폰(360~559): 칸이 셋이라 열여섯째 «시험 100번» 하나만 맨 밑 줄에 외톨이로 남았습니다 (2026-11-05).
   넷씩 네 줄로 -- 그림(54px)은 그대로, 이름은 두 줄까지 낱말 단위로 꺾습니다. 320 폰은 셋 그대로(칸이 54px 보다 좁아집니다). */
@media (min-width: 360px) and (max-width: 559px) {
  .stickers { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
  .stk { padding: 8px 2px 14px; }
  .stk b { font-size: 12px; word-break: keep-all; }
  .stk-bar { left: 8px; right: 8px; }
}

/* ---- 로그인 화면의 친구 넷 ---- */
.login-cast { display: flex; justify-content: center; align-items: flex-end; gap: 6px; margin: -8px 0 10px; }
.login-cast span { line-height: 0; cursor: pointer; animation: cast-in .5s cubic-bezier(.34, 1.56, .64, 1) both; }
.login-cast span.hop svg { animation: friend-hop .5s ease; transform-origin: 50% 90%; }
@keyframes cast-in { from { transform: translateY(14px) scale(.8); opacity: 0; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .login-cast span, .login-cast span.hop svg { animation: none; } }

/* ---- 숙제 목록 맨 위의 «몇 개 중 몇 개» ---- */
.hw-top { display: flex; align-items: center; gap: 14px; }
.hw-top-pal { flex: none; line-height: 0; }
.hw-top-t { flex: 1; min-width: 0; }
.hw-top-t b { display: block; font-size: 17px; }
.hw-top-t span { display: block; font-size: 13.5px; color: var(--ink-soft); }
.hw-top .pbar { margin-top: 10px; }
.hw-top.all { background: #f3fbf6; border-color: #cfe9d9; }
.hw-top.all .pbar i { background: var(--ok); }

/* ---- 범위 고르기 칸의 친구 (js/cheer.mjs perch) ---- */
/* 제목은 한 줄로 두고(«범위 고르기» 가 두 줄로 쪼개지지 않게), 말풍선이 줄어들며 두 줄로 접힌다 */
h2.perched { display: flex; align-items: center; gap: 8px; white-space: nowrap; }
.perch { margin-left: auto; display: flex; align-items: center; gap: 6px; cursor: pointer; min-width: 0; white-space: normal; }
.perch-pal { line-height: 0; flex: none; }
.perch-pal.hop svg { animation: friend-hop .5s ease; transform-origin: 50% 90%; }
.perch-say {
  position: relative; font-style: normal; font-size: 12.5px; font-weight: 700;
  color: var(--brand-ink); background: var(--brand-soft);
  padding: 5px 10px; border-radius: 12px; white-space: normal; line-height: 1.35; text-align: center;
}
.perch-say::after {
  content: ""; position: absolute; right: -5px; top: 50%; margin-top: -5px;
  border: 5px solid transparent; border-right: 0; border-left-color: var(--brand-soft);
}
@media (max-width: 360px) { .perch-say { display: none; } }
@media (prefers-reduced-motion: reduce) { .perch-pal.hop svg { animation: none; } }

/* 진행 막대 끝의 친구 (js/cheer.mjs runner). 막대가 잘라 내지 않게 넘침을 풀고,
   친구 키만큼 위쪽에 자리를 둡니다. 0% 일 때도 친구가 왼쪽 끝에 서 있습니다. */
.progress.has-runner { overflow: visible; margin-top: 32px; position: relative; }
.progress.has-runner i { position: relative; border-radius: inherit; min-width: 1px; }
.progress.has-runner i::after {
  content: ""; position: absolute; right: -18px; bottom: 1px;
  width: 36px; height: 38px; background: var(--runner) center bottom / contain no-repeat;
  transition: right .2s;
}

/* ==== 학생 홈 (home.html) — 덩어리 카드(벤토) ================================
   홈이 위에서 아래로 얇은 줄을 **나열**한 모양이라 태블릿에서 «만들다 만 앱» 처럼
   보였습니다(2026-10). 공부 앱 첫 화면들(듀오링고 · 칸 아카데미 키즈 · 토스)처럼
   덩어리 몇 개로 다시 짰습니다.
     ┌────────────────────────┬──────────────┐
     │ 큰 카드: 메이플 · 인사   │ 이번 주       │
     │ «지금 할 것» 단추 하나   ├──────────────┤
     │                        │ 숙제 · 복습   │
     ├───────┬────────┬───────┴──────────────┤
     │ 단어 방 │ 듣기 방 │ 읽기 방  (진한 색 카드 + 친구)
   폰에서는 위아래로 서고, 넓은 화면(720px~)에서는 아래쪽 탭 대신 머리글에
   «홈 · 내 기록» 만 둡니다(방이 한 화면에 다 보이는데 탭이 같은 문을 또 들고
   있었습니다). */
.home-wrap { max-width: 1060px; padding-top: 18px; }
.bento { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }

/* ── 오늘의 공부 ── 흰 카드 · 고리 · 할 일 줄 · 단추 하나 */
.todaycard {
  position: relative; overflow: hidden; isolation: isolate;
  display: flex; flex-direction: column; gap: 12px;
  background: var(--card); border: 1px solid var(--line); border-radius: 26px;
  box-shadow: var(--shadow); padding: 18px 18px 18px;
}
/* 위쪽에 대표색을 아주 옅게 -- 흰 카드 셋 사이에서 이것이 «주인공» 으로 보이게 */
.todaycard::before {
  content: ""; position: absolute; z-index: -1; left: 0; right: 0; top: 0; height: 120px;
  background: linear-gradient(180deg, rgba(var(--brand-rgb), .09), rgba(var(--brand-rgb), 0));
}
.today-head { display: flex; align-items: center; gap: 14px; }
.today-t { flex: 1 1 auto; min-width: 0; }
.today-t small { display: block; font-size: 13px; font-weight: 700; color: var(--brand-ink); }
.today-t b {
  display: block; margin-top: 2px; font-family: var(--font-brand); font-weight: 400;
  font-size: 26px; line-height: 1.2; letter-spacing: -.01em; color: var(--ink);
}
/* 고리: --p(0~100)만큼 대표색으로 차오릅니다. 메이플이 가운데에 삽니다. */
.ring {
  --p: 0; flex: none; position: relative;
  width: 92px; height: 92px; border-radius: 50%;
  background: conic-gradient(var(--brand) calc(var(--p) * 1%), var(--line-soft) 0);
  display: flex; align-items: center; justify-content: center;
  transition: background .6s;
}
.ring::before {
  content: ""; position: absolute; inset: 8px; border-radius: 50%; background: var(--card);
}
.ring.full { background: conic-gradient(var(--ok) 100%, var(--ok) 0); }
#helloMaple { position: relative; line-height: 0; cursor: pointer; margin-top: -6px; }
#helloMaple svg { width: 58px; height: 58px; }
.ring em {
  position: absolute; left: 50%; bottom: -9px; transform: translateX(-50%);
  font-style: normal; font-size: 12px; font-weight: 800; white-space: nowrap;
  font-variant-numeric: tabular-nums;
  /* 12px 작은 글씨라 «굵은 큰 글씨 3:1» 기준이 아니라 4.5:1 이 필요합니다. 단추 색(--brand-btn)
     위 흰 글씨는 3.45:1 이라, 학원 색에서 4.5:1 로 계산된 진한 색(--brand-ink)을 씁니다. */
  background: var(--brand-ink); color: #fff; padding: 2px 9px; border-radius: 99px;
  box-shadow: 0 0 0 3px var(--card);
}
.ring.full em { background: var(--ok); }

/* 할 일 줄 */
.missions { list-style: none; margin: 2px 0 0; padding: 0; display: grid; gap: 7px; }
.ms {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 12px; border-radius: 15px; text-decoration: none; color: inherit;
  background: var(--tint); border: 1px solid transparent;
  transition: border-color .14s, transform .14s;
}
.ms:hover { border-color: var(--brand-line); transform: translateX(2px); }
.ms::after { content: "›"; margin-left: auto; font-size: 20px; line-height: 1; color: var(--ink-soft); opacity: .6; }
.ms-chk {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  border: 2px solid var(--line); background: var(--card);
  display: flex; align-items: center; justify-content: center;
}
.ms-t { min-width: 0; }
/* 아래 줄(«2개 남았어요» · «오늘 했어요»)이 아이에게 «무엇을 할지» 를 말하는 줄입니다.
   12.5px 은 카드에서 제일 작은 글씨라 팔 길이로 든 태블릿에서 가는 선으로만 보였습니다. */
.ms-t b { display: block; font-size: 16px; font-weight: 800; letter-spacing: -.01em; }
.ms-t span { display: block; font-size: 13.5px; color: var(--ink-soft); margin-top: 1px; }
/* 할 차례: 대표색 테두리 · 글자 */
.ms.todo { background: var(--card); border-color: var(--brand-line); box-shadow: 0 2px 0 rgba(var(--brand-rgb), .12); }
.ms.todo .ms-chk { border-color: var(--brand); }
.ms.todo .ms-t span { color: var(--brand-ink); font-weight: 700; }
.ms.todo::after { color: var(--brand); opacity: 1; }
/* 끝: 초록 체크 */
.ms.done .ms-chk { background: var(--ok); border-color: var(--ok); }
.ms.done .ms-chk::before {
  content: ""; width: 10px; height: 6px; margin-top: -3px;
  border-left: 2.5px solid #fff; border-bottom: 2.5px solid #fff; transform: rotate(-45deg);
}
.ms.done .ms-t span { color: var(--ok); font-weight: 700; }
/* 오늘은 없음: 흐리게(누를 수는 있습니다 -- 지난 숙제 보기 등) */
/* 줄 전체를 opacity .62 로 흐리게 했더니 «오늘은 숙제가 없어요» 가 2.6:1 로 읽히지
   않았습니다. 글자는 흐린 색(--ink-soft, 4.5:1 넘음)까지만 낮추고, 흐리게 하는 것은
   동그라미와 화살표에만 맡깁니다. */
.ms.rest .ms-t b { color: var(--ink-soft); font-weight: 700; }
.ms.rest .ms-chk { border-style: dashed; opacity: .7; }
.ms.rest::after { opacity: .35; }

/* 단추 하나 -- 눌리는 느낌이 나게 아랫단을 두껍게(눌리면 내려앉습니다) */
.go {
  display: flex; align-items: center; justify-content: center; gap: 10px; margin-top: 2px;
  min-height: 50px; padding: 9px 18px; border-radius: 17px;
  background: var(--brand-btn); color: #fff; text-decoration: none;
  box-shadow: 0 5px 0 var(--brand-ink);
  transition: transform .1s, box-shadow .1s;
}
.go b { font-size: 18px; font-weight: 800; letter-spacing: -.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.go i { font-style: normal; font-size: 24px; font-weight: 700; line-height: 1; }
@media (hover: hover) { .go:hover { transform: translateY(-1px); box-shadow: 0 6px 0 var(--brand-ink); } }
.go:active { transform: translateY(4px); box-shadow: 0 1px 0 var(--brand-ink); }

/* ── 오른쪽 칸: 이번 주 한 줄 · 내 교재 · 다음 스티커 · 다시 볼 단어 ── */
.side { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.statrow, .bookcard, .nextstk, .weakcard, .remarkcard {
  background: var(--card); border: 1px solid var(--line); border-radius: 22px;
  box-shadow: var(--shadow); padding: 13px 16px 14px;
}
/* 폰: 할 수 있는 것(단어 · 스티커)이 기록(이번 주)보다 먼저 */
.bookcard { order: 1; } .weakcard { order: 2; } .nextstk { order: 3; } .statrow { order: 4; }
.statrow { display: grid; gap: 8px; text-decoration: none; color: inherit; }
.statrow[hidden] { display: none; }
.statrow:hover { border-color: var(--brand-line); }
.wk-line { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.wk-t { font-size: 13px; font-weight: 800; color: var(--ink); white-space: nowrap; }
.stat-go { font-size: 13px; font-weight: 700; color: var(--brand-ink); white-space: nowrap; }
/* 요일 일곱 칸은 이제 한 줄 안의 작은 칸입니다 */
.statrow .weekdots { flex: 1 1 auto; display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; max-width: 230px; }
.statrow .weekdots .wd { width: auto; height: 26px; border-radius: 7px; }
.statrow .weekdots .wd i { font-size: 12px; }   /* 아이 화면 글씨는 12px 아래로 내리지 않습니다 */
.hstats { display: flex; gap: 14px; flex-wrap: wrap; font-size: 12.5px; color: var(--ink-soft); }
.hstat b { font-size: 15px; font-weight: 800; color: var(--brand-ink); font-variant-numeric: tabular-nums; margin-right: 1px; }

/* 다음 스티커: [자는 얼굴] 다음 스티커 · 3일 공부 ▓▓░ 1일 더 하면 받아요 */
.nextstk { display: flex; align-items: center; gap: 12px; text-decoration: none; color: inherit; }
.nextstk.hidden { display: none; }

/* 선생님 한마디 (2026-10) -- 홈 카드 · 내 기록 */
.remarkcard { display: grid; gap: 10px; order: 0; border-color: var(--brand-line); }
.remarkcard.hidden { display: none; }
.remarkcard .wk-line { align-items: center; }
.remarkcard .wk-line .mini { margin-left: auto; }
.rk-item { display: flex; gap: 10px; align-items: flex-start; }
.rk-stamp { font-size: 28px; line-height: 1; flex: none; }
.rk-t { display: grid; gap: 2px; min-width: 0; }
.rk-t b { font-size: 15px; word-break: keep-all; }
.rk-t small { font-size: 12px; color: var(--ink-soft); }
.run-remark { display: flex; gap: 8px; align-items: center; padding: 2px 10px 10px 14px; font-size: 13.5px; color: var(--brand-ink); font-weight: 600; }
.run-remark .rk-stamp { font-size: 18px; }
.remarks-top { display: grid; gap: 8px; margin-bottom: 12px; padding: 12px 14px; border-radius: 12px; background: var(--brand-soft); }
.remarks-top .rk-t b { font-size: 14.5px; }

/* 함께 풀기 (2026-10) -- 아이 화면 · 홈 띠 · 어느 화면에서든 뜨는 알림 */
.rc-wait { text-align: center; display: grid; gap: 8px; justify-items: center; padding: 26px 10px 10px; }
.rc-wait b { font-size: 20px; }
.rc-wait .rc-n { font-size: 17px; font-weight: 800; color: var(--brand-ink); }
.rc-state { text-align: center; margin-top: 14px; font-size: 15px; color: var(--ink-soft); min-height: 22px; }
.rc-passage { margin: 10px 0 4px; padding: 10px 14px; border-radius: 12px; background: var(--tint, #faf6f0); }
.rc-passage summary { cursor: pointer; font-size: 13px; font-weight: 700; color: var(--brand-ink); }
.rc-passage b, .rc-passage-wait b { display: block; margin: 8px 0 4px; font-size: 16px; }
.rc-passage p, .rc-passage-wait p { margin: 0; font-size: 15px; line-height: 1.7; white-space: pre-wrap; max-height: 34vh; overflow: auto; }
.rc-passage-wait { margin-top: 14px; padding: 14px 16px; border-radius: 12px; background: var(--tint, #faf6f0); text-align: left; }
.rc-tag { display: table; margin: 8px auto 0; padding: 2px 10px; border-radius: 12px; background: var(--brand-soft); color: var(--brand-ink); font-size: 12.5px; font-weight: 700;
  line-height: 1.6; text-align: center; }   /* 12px: 한 줄이면 알약 그대로, 영작 힌트처럼 두 줄이면 찌그러진 알약 대신 둥근 상자 */
/* 긴 문제(리딩 질문 · 18자 넘는 낱말)는 작게. «.card.play .prompt»(특이도 0,3,0)가 이 줄을
   이겨서 태블릿에서 58px 세 줄 · 폰에서 보기 C·D 가 접힌 아래로 밀렸습니다 -- 같은 이름을
   «.card.play» 붙여 한 번 더 적어 0,4,0 으로 이깁니다(가로 태블릿 .two 규칙도 이깁니다). */
.prompt.rc-q, .card.play .prompt.rc-q { font-size: clamp(20px, 4.6vw, 26px); padding: 10px 6px 14px; line-height: 1.4; }
.run-with { display: inline-block; padding: 1px 8px; border-radius: 99px; background: var(--ok-soft); color: var(--ok-ink); font-size: 12px; font-weight: 800; vertical-align: 1px; }   /* 11.5px · 3.4:1 이던 것을 아이 화면 하한 12px · 5.8:1 로 */
.rc-hand { display: block; margin: 10px auto 0; min-height: 40px; font-size: 14px; padding: 6px 16px; }
.rc-type { display: grid; gap: 10px; margin-top: 6px; }
.rc-type input { font-size: 22px; text-align: center; letter-spacing: .03em; }
.rc-spell { text-align: center; display: grid; gap: 4px; margin-top: 4px; }
.rc-spell-a { font-size: 30px; font-weight: 800; color: var(--ok); }
.rc-spell-a span.miss { color: #c0392b; text-decoration: underline; text-underline-offset: 5px; }
.rc-spell-g { font-size: 18px; color: var(--ink-soft); }
.rc-spell-g span { color: var(--ink); font-weight: 700; }
.rc-spell-g span.bad { color: #c0392b; text-decoration: underline; }
.rc-why { margin: 10px 0 0; padding: 10px 12px; border-radius: 10px; background: var(--ok-soft); color: var(--ok-ink); font-size: 14px; line-height: 1.6; }
.rc-state.sent { color: var(--brand-ink); font-weight: 600; }
.rc-state.ok { color: var(--ok); font-weight: 800; font-size: 18px; }
.rc-state.no, .rc-state.miss { color: #c0392b; font-weight: 700; }
.choices .choice.rc-right, .choices .choice.rc-right:hover { border-color: var(--ok); background: var(--ok-soft); font-weight: 700; opacity: 1; }
.choices .choice.rc-wrong, .choices .choice.rc-wrong:hover { border-color: #e2a0a0; background: #fdf0f0; opacity: 1; }
.choice.rc-dim { opacity: .5; }
/* 문법 설명 카드 (함께 풀기 «문법 설명», common.js grammarCard) -- 아이 태블릿 크기.
   교실 TV(board.html) · 선생님 판(teacher.css)은 같은 모양을 크게 덮어씁니다. */
.gc { display: grid; gap: 10px; text-align: left; }
.gc-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.gc-stage { padding: 2px 10px; border-radius: 99px; background: var(--brand-soft); color: var(--brand-ink); font-size: 12.5px; font-weight: 800; }
.gc-title { font-size: 20px; line-height: 1.3; word-break: keep-all; }
.gc-say { margin: 0; padding-left: 20px; display: grid; gap: 4px; font-size: 15.5px; line-height: 1.6; word-break: keep-all; }
.gc-rule { padding: 10px 14px; border-radius: 12px; background: #fff7e0; border: 2px solid #f2d27a; font-weight: 800; font-size: 16px; line-height: 1.5; word-break: keep-all; }
.gc-ex { margin: 0; padding-left: 24px; display: grid; gap: 8px; }
.gc-ex li { padding-left: 2px; }
.gc-en { display: block; font-size: 17px; font-weight: 700; line-height: 1.4; }
.gc-ko { display: block; font-size: 14px; color: var(--ink-soft); line-height: 1.5; }
/* 칠한 낱말: 형광펜처럼(노랑 바탕 + 아랫줄) -- 빨강 · 초록은 «틀림 · 맞음» 으로 읽혀서 피합니다. */
.gc mark { background: #ffe27a; color: inherit; padding: 0 .12em; border-radius: 4px; box-shadow: inset 0 -0.16em 0 #f0b400; }
/* 함께 풀기 아이 화면의 문법 설명 · 골든벨 · 생각 모으기 */
.rc-gram-wait { margin-top: 14px; padding: 14px 16px; border-radius: 12px; background: var(--tint, #faf6f0); }
.rc-gram summary { cursor: pointer; font-size: 13px; font-weight: 700; color: var(--brand-ink); }
.rc-gram[open] .gc { margin-top: 8px; }
.rc-bell { text-align: center; margin: 0 0 8px; padding: 6px 12px; border-radius: 99px; background: #fff7e0; border: 1.5px solid #f2d27a; font-size: 14px; font-weight: 800; color: #8a5a00; }
.rc-bell.out { background: #f1f2f4; border-color: #d9dce1; color: var(--ink-soft); font-size: 16px; padding: 10px 14px; border-radius: 14px; }
.rc-think { display: grid; gap: 8px; margin-top: 6px; }
.rc-think textarea { font-size: 19px; line-height: 1.5; font-family: inherit; resize: none; margin: 0; padding: 10px 14px; box-sizing: border-box; width: 100%; }
.rc-think-n { text-align: right; font-size: 13px; color: var(--ink-soft); }
.rc-think-n.over { color: #c0392b; font-weight: 700; }
.rc-mine { padding: 12px 14px; border-radius: 14px; background: var(--brand-soft); border: 2px solid var(--brand-line); font-size: 18px; font-weight: 700; word-break: break-word; }
.rc-mine.spot { border-color: var(--brand); box-shadow: 0 0 0 4px var(--brand-soft); }
.course-card.live { background: var(--ok); box-shadow: 0 6px 16px rgba(39, 122, 78, .25); }
.course-card.live .cc-go { color: var(--ok); }
.room-notice { position: fixed; top: 10px; left: 50%; transform: translateX(-50%); z-index: 60; display: flex; align-items: center; gap: 10px;
  padding: 10px 14px 10px 16px; border-radius: 99px; background: var(--ok); color: #fff; text-decoration: none; font-size: 14px;
  box-shadow: 0 8px 20px rgba(0, 0, 0, .18); max-width: calc(100% - 24px); }
.room-notice b { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.room-notice.now-notice { background: var(--brand-btn, #e75a6e); }
.room-notice.now-notice span { color: var(--brand-ink); }
.room-notice span { background: #fff; color: var(--ok); font-weight: 700; padding: 4px 10px; border-radius: 99px; white-space: nowrap; }

/* 내 책 길 (2026-10) -- 책 열 권을 한 줄(좁으면 두 줄)의 징검다리로 */
.bookpath { display: grid; grid-template-columns: repeat(auto-fill, minmax(52px, 1fr)); gap: 12px 4px; position: relative; }
.bp-step { display: grid; justify-items: center; gap: 4px; position: relative; }
.bp-step:not(:last-child)::after {           /* 다음 돌로 잇는 줄 */
  content: ''; position: absolute; top: 19px; left: calc(50% + 21px); width: calc(100% - 38px); height: 3px;
  border-radius: 2px; background: var(--line);
}
.bp-step.done:not(:last-child)::after { background: var(--lv); opacity: .55; }
.bp-dot {
  width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center;
  font-weight: 800; font-size: 15px; color: var(--ink-soft); background: #fff; border: 2px solid var(--line);
}
.bp-step.some .bp-dot { border-color: var(--lv); color: var(--ink); background: conic-gradient(color-mix(in srgb, var(--lv) 30%, transparent) var(--p), #fff 0); }
.bp-step.done .bp-dot { background: var(--lv); border-color: var(--lv); color: #fff; font-size: 18px; }
.bp-step.cur .bp-dot, .bp-step.here .bp-dot {
  border-color: var(--lv); color: var(--ink); width: 46px; height: 46px; margin-top: -3px;
  background: conic-gradient(color-mix(in srgb, var(--lv) 35%, transparent) var(--p), #fff 0);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--lv) 22%, transparent);
}
.bp-step.done.here .bp-dot { background: var(--lv); color: #fff; }
.bp-step small { font-size: 12px; color: var(--ink-soft); font-weight: 600; }
.bp-step.here small { color: var(--ink); font-weight: 800; }
.bp-step.next .bp-dot { border-style: dashed; border-color: var(--nx); color: var(--nx); }
/* 자리가 좁으면 줄이 접히는데, 폰에서는 다섯 개씩 접혀 «5» · «10» 뒤의 잇는 줄이 화면 밖으로
   뻗었고 목표 별이 셋째 줄에 혼자 남았습니다(두 단 태블릿에서도 «6» · «8» 뒤로 같은 줄이 뻗음).
   열한 개(책 열 권 + 별)가 한 줄에 안 들어가는 자리에서는 여섯 개씩 두 줄로, 줄 끝의 잇는 줄은 지웁니다.
   폭은 화면이 아니라 카드 폭으로 잽니다(내 기록은 넓은 화면에서 두 단). 옛 브라우저는 폰 규칙만. */
@media (max-width: 430px) {
  .bookpath { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .bp-step:nth-child(6n)::after { display: none; }
}
:has(> .bookpath) { container-type: inline-size; }
@container (max-width: 620px) {
  .bookpath { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .bp-step:nth-child(6n)::after { display: none; }
}
/* 아직 못 본 새 스티커 -- 대표색 테두리로 «눌러 보세요» */
.nextstk.fresh { border-color: var(--brand-line); background: linear-gradient(0deg, rgba(var(--brand-rgb), .06), rgba(var(--brand-rgb), .06)), var(--card, #fff); }
.nextstk.fresh .ns-left { color: var(--brand-ink); font-weight: 700; }
.nextstk:hover { border-color: var(--brand-line); }
.ns-pic { flex: none; line-height: 0; width: 56px; height: 56px; border-radius: 50%; background: var(--tint);
  display: flex; align-items: center; justify-content: center; }
.ns-pic svg { width: 46px; height: 46px; }
.ns-t { flex: 1 1 auto; min-width: 0; }
.ns-t small { display: block; font-size: 12px; font-weight: 800; color: var(--brand-ink); }
.ns-t b { display: block; font-size: 16px; font-weight: 800; margin-top: 1px; }
.nextstk .pbar, .bookcard .pbar { display: block; }
.nextstk .pbar { height: 8px; margin: 6px 0 3px; }
.ns-left { display: block; font-size: 12.5px; color: var(--ink-soft); }

/* 다시 볼 단어: 뜻은 가려 두고, 누르면 열리며 소리 */
.weakcard { display: grid; gap: 10px; }
.weakcard.hidden { display: none; }
.wc-hint { font-size: 12px; color: var(--ink-soft); }
.wc-words { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.wc-w {
  display: grid; place-items: center; gap: 1px; min-height: 54px; padding: 7px 6px;
  background: var(--tint); border: 1px solid var(--line); border-radius: 14px; color: var(--ink);
  cursor: pointer; text-align: center; box-shadow: 0 2px 0 rgba(51, 56, 63, .06);
}
.wc-w b { font-size: 15.5px; font-weight: 800; overflow-wrap: anywhere; line-height: 1.2; }
.wc-w span { font-size: 12.5px; font-weight: 700; color: var(--brand-ink); visibility: hidden; line-height: 1.25; }
.wc-w.open { background: var(--brand-soft); border-color: var(--brand-line); }
.wc-w.open span { visibility: visible; }
/* 가린 뜻은 자리만 차지해서 낱말이 상자 위쪽에 붙어 «뒤집는 카드» 가 아니라 삐뚤어진
   상자로 보였고, 유일한 안내(«눌러서 뜻 보기» 12px 회색)는 아이들이 안 읽습니다.
   닫힌 카드는 뜻 대신 «뜻은?» 을 같은 크기 한 줄로 보여 줍니다 -- 카드마다 스스로 묻습니다.
   (읽어 주는 기능은 단추의 aria-label «… 뜻 보기» 를 읽으므로 이 글자와 상관없습니다.) */
.wc-w:not(.open) > span { display: none; }
.wc-w:not(.open)::after { content: "뜻은?"; font-size: 12.5px; line-height: 1.25; font-weight: 600; color: var(--ink-soft); }
/* 글자는 작아도 누르는 자리는 40px -- 위아래 여백을 넓히고 같은 만큼 바깥 여백으로 되돌려 줄 높이는 그대로 */
.wc-go { justify-self: end; font-size: 13px; font-weight: 700; color: var(--brand-ink); text-decoration: none;
  padding: 10px 0 10px 12px; margin: -10px 0; }

/* 내 교재: [Orange] 1권 · 평균 85점 / 막대 / Day 3 / 24 */
.bookcard { display: grid; gap: 7px; align-content: center; }
.bookcard.hidden { display: none; }
.bc-row { display: flex; align-items: center; gap: 8px; }
.bc-row b { font-size: 18px; font-weight: 800; }
.bc-avg { margin-left: auto; font-size: 13px; font-weight: 700; color: var(--ink-soft); }
.bookcard .pbar { margin: 0; height: 10px; }
.bc-days { display: flex; justify-content: space-between; gap: 8px; font-size: 12.5px; color: var(--ink-soft); }
.mb-sub { font-size: 12.5px; font-weight: 800; color: var(--brand-ink); }
.mb-sub:empty, .bc-avg:empty { display: none; }

/* 제목이 «민준의 오늘 공 / 부» 처럼 글자 단위로 꺾이지 않게 낱말 단위로만 꺾고,
   좁은 폰(360px)에서는 고리와 글자를 한 단계 줄입니다. */
.today-t b { word-break: keep-all; overflow-wrap: anywhere; }
@media (max-width: 400px) {
  .today-t b { font-size: 22px; }
  .ring { width: 76px; height: 76px; }
  .ring::before { inset: 7px; }
  #helloMaple svg { width: 48px; height: 48px; }
}

/* 선생님이 정해 준 것: 가로로 누운 칸이 줄을 꽉 채웁니다 */
.tiles-row { grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 10px; }
.tiles-row .tile {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; column-gap: 12px;
  align-items: center; padding: 12px 12px 12px 14px;
}
.tiles-row .tile .big { grid-column: 1; grid-row: 1 / span 2; }
.tiles-row .tile b { grid-column: 2; margin: 0; align-self: end; font-size: 15.5px; }
.tiles-row .tile span { grid-column: 2; margin: 1px 0 0; align-self: start; font-size: 12.5px; }
.tiles-row .tile::after {
  content: "›"; grid-column: 3; grid-row: 1 / span 2;
  font-size: 22px; line-height: 1; color: var(--tone);
}
@media (max-width: 430px) {
  .tiles-row .tile { grid-template-columns: auto minmax(0, 1fr); column-gap: 10px; padding: 11px 10px 11px 12px; }
  .tiles-row .tile::after { display: none; }
  .tiles-row .tile span { display: none; }
  .tiles-row .tile b { align-self: center; }
  .tiles-row .tile .big { grid-row: auto; }
}
#restToggleBox { margin-top: 14px; text-align: center; }
#restToggleBox .wide { width: auto; min-width: 220px; }

/* ── 방 셋 ── 진한 색 카드 + 친구 얼굴 + 흰 단추 */
.sec-t {
  margin: 26px 2px 12px; font-family: var(--font-brand); font-weight: 400;
  font-size: 22px; color: var(--ink); letter-spacing: -.01em;
}
.home-wrap .tgroup#pickHead { margin-top: 24px; }
body[data-view="room"] .sec-t { display: none; }
body[data-view="home"] #restMenu:not(.hidden) { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
.room { --c1: #f4a04a; --c2: #dc6f1a; }
.room[data-room="listen"] { --c1: #56a3ec; --c2: #2b6cc2; }
.room[data-room="read"]   { --c1: #4cb877; --c2: #24834c; }
body[data-view="home"] .room {
  position: relative; overflow: hidden; isolation: isolate;
  margin: 0; padding: 14px 14px 14px; border: 0; border-radius: 24px;
  background: linear-gradient(155deg, var(--c1), var(--c2));
  box-shadow: 0 10px 22px rgba(51, 56, 63, .12);
}
body[data-view="home"] .room::before {
  content: ""; position: absolute; z-index: -1; right: -50px; top: -60px;
  width: 180px; height: 180px; border-radius: 50%; background: rgba(255, 255, 255, .13);
}
body[data-view="home"] .room-head { gap: 12px; padding: 0 0 10px; }
body[data-view="home"] .room-pal {
  width: 58px; height: 58px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, .92); box-shadow: 0 4px 10px rgba(0, 0, 0, .12);
}
body[data-view="home"] .room-pal svg { width: 46px; height: 46px; }
body[data-view="home"] .room-t b { color: #fff; font-size: 26px; text-shadow: 0 1px 2px rgba(0, 0, 0, .12); }
body[data-view="home"] .room-t small { color: rgba(255, 255, 255, .93); font-weight: 600; }
body[data-view="home"] .room-go {
  color: #fff; background: rgba(255, 255, 255, .2); padding: 6px 11px; border-radius: 99px;
}
body[data-view="home"] .room .tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
/* 방에 활동이 넷이면(짝 맞추기 · 듣고 고르기를 더한 단어 · 듣기 방, 2026-10-24) 세 칸 격자에서 넷째가 혼자
   둘째 줄로 떨어졌습니다. 좁은 화면(홈이 접힌 방 타일을 쓰는 719px 까지)에서는 네 칸, 폰은 두 칸 두 줄로. */
@media (max-width: 719px) {
  body[data-view="home"] .room .tiles:has(> .tile:nth-child(4)) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (max-width: 559px) {
  body[data-view="home"] .room .tiles:has(> .tile:nth-child(4)) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
body[data-view="home"] .room .tile {
  background: #fff; border: 0; border-radius: 16px; padding: 11px 4px 10px;
  box-shadow: 0 3px 0 rgba(0, 0, 0, .12);
}
@media (hover: hover) { body[data-view="home"] .room .tile:hover { transform: translateY(-2px); box-shadow: 0 5px 0 rgba(0, 0, 0, .12); } }
body[data-view="home"] .room .tile:active { transform: translateY(2px); box-shadow: 0 1px 0 rgba(0, 0, 0, .12); }

/* ── 넓은 화면 ── */
@media (min-width: 720px) {
  .home-wrap { padding-top: 22px; }
  .bento { grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr); gap: 14px; }
  /* 오른쪽 칸이 더 길면 왼쪽 카드도 같이 늘어나고, 단추는 맨 아래에 붙습니다 */
  .todaycard .go { margin-top: auto; }
  .todaycard { padding: 18px 20px 20px; gap: 12px; }
  /* 태블릿에서는 할 일 줄 하나가 746px 너비에 63px 높이라, 글씨가 큰 빈 막대 속 가는 선이었습니다 */
  .ms { padding: 11px 16px; }
  .ms-t b { font-size: 17px; }
  .ms-t span { font-size: 14px; }
  /* 넓은 화면: 오른쪽 칸은 위에서부터 이번 주(한 줄) → 내 교재 → 다음 스티커 → 다시 볼 단어 */
  .statrow { order: 1; } .bookcard { order: 2; } .nextstk { order: 3; } .weakcard { order: 4; }
  .today-t b { font-size: 30px; }
  .ring { width: 88px; height: 88px; }
  #helloMaple svg { width: 56px; height: 56px; }

  body[data-view="home"] #restMenu:not(.hidden) { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
  body[data-view="home"] .room { padding: 14px 14px 14px; }
  .sec-t { margin: 22px 2px 10px; }
  body[data-view="home"] .room-go { display: none; }
  body[data-view="home"] .room .tiles { grid-template-columns: minmax(0, 1fr); gap: 8px; }
  body[data-view="home"] .room .tile {
    display: grid; grid-template-columns: 38px minmax(0, 1fr) auto; column-gap: 10px;
    align-items: center; text-align: left; padding: 7px 12px 7px 7px;
  }
  body[data-view="home"] .room .tile::after { content: "›"; font-size: 20px; line-height: 1; color: var(--tone); }
  body[data-view="home"] .room .tile .big { width: 38px; height: 38px; border-radius: 11px; }
  body[data-view="home"] .room .tile .big svg { width: 20px; height: 20px; }
  body[data-view="home"] .room .tile b { margin: 0; font-size: 15px; }

  /* 아래쪽 탭 → 머리글의 «홈 · 내 기록» */
  .tabbar { display: none; }
  body.has-tabs .wrap { padding-bottom: 40px; }
}
/* 세로로 선 태블릿(720~999px): 큰 카드를 맨 위 한 줄로, 작은 카드 둘을 그 밑에 나란히.
   큰 카드를 왼쪽 칸에 두면 단추 글자가 «단어 시험 보러 ...» 로 잘렸습니다. */
@media (min-width: 720px) and (max-width: 999px) {
  .bento { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .todaycard { grid-column: 1 / -1; }
  .side { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  body[data-view="home"] .room-t small { display: none; }
}
/* 세로 태블릿에서 오른쪽 칸 카드들은 키도 개수도 저마다 달라서, 두 칸 격자에 넣으면
   «다시 볼 단어» 옆이 텅 비는 구멍이 생겼습니다(«덜 만든 앱» 처럼 보임). 내 기록(my.html)과
   같은 신문 단 방식으로 위에서 아래로 채워 두 단 길이를 저절로 맞춥니다.
   단에서는 order 가 안 먹지만, 카드는 HTML 에 이미 같은 차례(코스 · 이번 주 · 내 교재 ·
   스티커 · 단어)로 있습니다. 가로로 누운 화면은 아래 규칙(한 줄 세로 쌓기)이 그대로입니다. */
@media (min-width: 720px) and (max-width: 999px) and (orientation: portrait) {
  .side { display: block; columns: 2; column-gap: 14px; margin-bottom: -14px; }
  /* .bento 를 앞에 붙인 것은 home.html 의 «.side > .course-card { margin-bottom: 0 }»
     (flex gap 용)을 이기기 위해서입니다 -- 단에는 gap 이 없어 아래 여백이 그 몫을 합니다. */
  .bento > .side > *, .bento > .side > .course-card { break-inside: avoid; margin: 0 0 14px; }
}
/* 키 큰 세로 태블릿(갤럭시 탭 A8 · A9+ 세로 800×1280 · 브라우저 800×1200, 2026-10): 방 단추가 54px 짜리
   가는 줄이고 화면 아래 ≈290px 가 비었습니다. 남는 높이를 손가락 자리로 씁니다 -- 단추 ≈70px · 글자 17px. */
@media (min-width: 720px) and (max-width: 999px) and (orientation: portrait) and (min-height: 1100px) {
  .todaycard .go { min-height: 58px; font-size: 18px; }
  .ms { padding: 14px 18px; }
  .ms-t b { font-size: 18px; }
  .ms-t span { font-size: 15px; }
  body[data-view="home"] .room { padding: 16px; }
  body[data-view="home"] .room .tiles { gap: 10px; }
  body[data-view="home"] .room .tile { grid-template-columns: 46px minmax(0, 1fr) auto; padding: 12px 14px 12px 10px; }
  body[data-view="home"] .room .tile .big { width: 46px; height: 46px; border-radius: 13px; }
  body[data-view="home"] .room .tile .big svg { width: 24px; height: 24px; }
  body[data-view="home"] .room .tile b { font-size: 17px; }
}
.topnav { display: none; }
@media (min-width: 720px) {
  .topnav { display: flex; gap: 2px; flex: none; }
  .topnav a {
    display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 7px 13px;   /* 손가락 기준 44px */
    border-radius: 99px; text-decoration: none; color: var(--ink-soft);
    font-size: 14px; font-weight: 700;
  }
  .topnav a:hover { color: var(--ink); background: var(--line-soft); }
  .topnav a.on { background: var(--brand-soft); color: var(--brand-ink); }
  .topnav svg { width: 18px; height: 18px; }
  /* 숙제 · 내 기록 머리글의 «홈» 단추는 머리글 탭의 «홈» 과 같은 문입니다 */
  body.has-tabs .bar-home { display: none; }
}
@media print { .topnav { display: none !important; } }

/* 방 하나를 펼친 화면(#words 등)도 홈의 방 카드와 같은 색으로 -- 누르고 들어갔는데
   색이 옅은 딴 판으로 바뀌면 «같은 방» 으로 안 읽힙니다. */
.room.on {
  border: 0; background: linear-gradient(160deg, var(--c1), var(--c2) 70%);
  box-shadow: 0 12px 26px rgba(51, 56, 63, .14);
}
.room.on .room-t b { color: #fff; text-shadow: 0 1px 2px rgba(0, 0, 0, .12); }
.room.on .room-t small { color: rgba(255, 255, 255, .93); font-weight: 600; }
.room.on .room-say { border-color: transparent; box-shadow: 0 4px 12px rgba(0, 0, 0, .10); }
.room.on .room-say::before { border-color: transparent; }
.room.on .tile { border: 0; box-shadow: 0 3px 0 rgba(0, 0, 0, .12); }
.room.on .room-pal {
  width: 108px; height: 108px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, .92); box-shadow: 0 6px 14px rgba(0, 0, 0, .14);
}

/* ==== 2026-10 디자인 손질 — «상용 제품» 의 옷 =================================
   «애들 장난처럼 보인다» 는 말을 듣고 기능은 그대로 두고 옷만 바꿨습니다.
   장난감처럼 보이게 한 것으로 짚은 것:
     · 간판 · 제목이 둥근 손글씨체(Jua) -- 첫인상이 장난감 상자였습니다
     · 머리글 맨 위 무지개 띠, 바탕의 색 번짐, 단추의 그라데이션과 색 그림자
     · 제목마다 붙은 빨간 눈금 · 점, 곳곳의 대표색 -- 강조가 많으면 강조가 없습니다
     · 둥글기가 제각각(8 · 9 · 12 · 15 · 16 · 22 · 26px)
   그래서: 서체는 Pretendard(없으면 기기 기본 고딕), 바탕은 차분한 회색, 대표색은
   «누를 것» 과 «고른 것» 에만, 둥글기는 10 / 14 / 18 세 가지.
   학원이 고른 대표색(--brand…)은 js/common.js 가 그대로 덮고, 레벨 다섯 색은
   교재 표지 색이라 손대지 않습니다. 이 층은 **덮어쓰기**라 위의 규칙을 지우면
   예전 옷으로 돌아갑니다. 서체 파일은 각 화면 <head> 가 막지 않게 받아 옵니다. */
:root {
  --font-ui: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont,
             "Apple SD Gothic Neo", "Noto Sans KR", "Malgun Gothic", "맑은 고딕", system-ui, sans-serif;
  --font-brand: var(--font-ui);
  --ink: #191f28;
  /* 흐린 글씨: 회색 바탕(#f4f5f7)에서 5.0:1, 흰 카드에서 5.6:1 */
  --ink-soft: #5b6573;
  --line: #e2e5ea;
  --line-soft: #eef0f3;
  --line-strong: #d3d8de;      /* 입력칸 · 보조 단추의 테두리 */
  --bg: #f4f5f7;
  --tint: #f8f9fa;
  --radius: 14px;
  --r-sm: 10px;
  --r-lg: 18px;
  --shadow: 0 1px 2px rgba(16, 24, 40, .04), 0 1px 3px rgba(16, 24, 40, .05);
  --shadow-lift: 0 4px 8px -2px rgba(16, 24, 40, .08), 0 12px 24px -4px rgba(16, 24, 40, .10);
  --focus: 0 0 0 3px rgba(var(--brand-rgb), .20);
}
body {
  font-family: var(--font-ui);
  background: var(--bg);
  letter-spacing: -0.006em;
}

/* ---- 머리글: 흰 띠 하나. 무지개 띠와 유리 효과를 걷어 냅니다 ---- */
header.bar {
  background: rgba(255, 255, 255, .96);
  -webkit-backdrop-filter: none; backdrop-filter: none;
  border-bottom: 1px solid var(--line);
  /* 높이(padding)는 건드리지 않습니다 -- 가로 태블릿 · 폰 규칙이 머리글을 줄여서
     534px 안에 화면을 넣고 있습니다. 여기서 덮으면 시험 화면이 스크롤됩니다. */
}
header.bar h1 { font-size: 15px; font-weight: 600; color: var(--ink); white-space: nowrap; }   /* «선생님 / 화면» 으로 쪼개지지 않게 */
header.bar .brand .wm b { font-weight: 800; font-size: 19px; letter-spacing: -0.035em; }
header.bar .brand .wm i { font-weight: 600; font-size: 12px; letter-spacing: -0.01em; top: 0; }
header.bar .who {
  background: var(--tint); border-color: var(--line); color: var(--ink-soft);
  font-weight: 600; padding: 4px 10px;
}
header.bar .who:empty { display: none; }
.login-brand .wm b { font-weight: 800; font-size: 36px; letter-spacing: -0.04em; }
.login-brand .wm i { font-weight: 600; font-size: 14px; letter-spacing: 0.12em; text-indent: 0.12em; }
.login-brand p { letter-spacing: .12em; font-weight: 600; font-size: 12px; }
@media (max-width: 430px) {
  .login-brand .wm b { font-size: 30px; }
  .login-brand .wm i { font-size: 12px; }
}

/* ---- 카드와 제목 ---- */
.card { border-radius: var(--radius); box-shadow: var(--shadow); padding: 24px; }
h2 { font-size: 18px; font-weight: 700; letter-spacing: -0.025em; gap: 8px; }
h2::before, h3::before { display: none; }
h3 { font-size: 15px; font-weight: 700; letter-spacing: -0.02em; margin: 26px 0 10px; }
p.hint { font-size: 13.5px; line-height: 1.6; }
.subcard {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 18px 20px;
}

/* ---- 입력 ---- */
label { color: var(--ink); font-weight: 600; font-size: 13.5px; letter-spacing: -0.01em; }
input, select, textarea {
  border-color: var(--line-strong); border-radius: var(--r-sm);
  transition: border-color .12s, box-shadow .12s;
}
input:hover, select:hover { border-color: var(--line-hover); }
input:focus, select:focus, textarea:focus { border-color: var(--brand); box-shadow: var(--focus); }
/* 빈 칸 안내 글(«답을 쓰세요»)이 2.5:1 로 흐려 아이가 못 읽었습니다. 4.5:1 을 넘기되
   쓴 글자(--ink)보다는 확실히 옅은 값입니다. */
input::placeholder, textarea::placeholder { color: #776d64; }

/* ---- 단추: 평평한 대표색 하나 · 흰 보조 · 조용한 작은 단추 ---- */
button {
  background: var(--brand-btn); box-shadow: none;
  border-radius: var(--r-sm); font-weight: 600; letter-spacing: -0.015em;
}
@media (hover: hover) { button:hover { background: var(--brand-dark); } }
/* 글쇠판(Tab)으로 옮겨 다닐 때 «지금 여기» 표시. 예전에는 대표색 20% 그림자라 흰 바탕에서
   1.2:1 -- 거의 안 보였습니다. 손가락 · 마우스로 누를 때는 :focus-visible 이 켜지지 않아
   평소 모습은 그대로입니다. 링크 · 누르는 줄도 아래 «접근성 점검» 묶음에서 같은 테두리를 씁니다. */
button:focus-visible { outline: 3px solid var(--brand-ink); outline-offset: 2px; box-shadow: none; }
button.ghost { background: #fff; border-color: var(--line-strong); color: var(--ink); }
@media (hover: hover) { button.ghost:hover { background: var(--tint); border-color: var(--line-hover); } }
button.mini {
  border-radius: 8px; background: #fff; color: var(--ink);
  border: 1px solid var(--line); font-weight: 600;
}
@media (hover: hover) { button.mini:hover { background: var(--tint); color: var(--ink); border-color: var(--line-strong); } }
button.mini.solid { background: var(--brand-btn); color: #fff; border-color: transparent; }
@media (hover: hover) { button.mini.solid:hover { background: var(--brand-dark); color: #fff; } }
button.linky { background: none; }

/* ---- 고르는 것들: 테두리만 있는 버블, 고르면 옅은 대표색 ---- */
.chips .chip, .bubble { border-color: var(--line-strong); }
.chips .chip:hover, .bubble:hover { border-color: var(--line-hover); }
.bubble.on { background: var(--brand-soft); border-color: var(--brand); color: var(--brand-ink); }
.daygrid .day { border-radius: 9px; }
.choice { border-radius: 12px; }

/* ---- 알림 줄 · 표 ---- */
.msg { border-radius: var(--r-sm); }
.msg.info { color: var(--brand-ink); }
th { font-size: 12.5px; font-weight: 600; color: var(--ink-soft); background: var(--tint); letter-spacing: -0.01em; }
tbody tr:hover > td { background: var(--tint); }
.tbl { border-radius: var(--r-sm); }
.pill { font-weight: 600; }

/* ---- 타일 · 숫자 칸 ---- */
.tile { border-radius: var(--radius); }
.tile:hover { transform: translateY(-1px); }
.stat { border-radius: 12px; box-shadow: none; }
.stat::before { display: none; }
.stat b { letter-spacing: -0.03em; }

/* ---- 학생 홈: 간판 서체가 빠진 자리를 굵기로 ---- */
.todaycard { border-radius: var(--r-lg); }
.todaycard::before { opacity: .55; }
.today-t b { font-weight: 800; font-size: 24px; letter-spacing: -0.035em; }
.sec-t { font-weight: 800; font-size: 20px; letter-spacing: -0.03em; }
.room { border-radius: var(--r-lg); }
.room-t b { font-weight: 800; letter-spacing: -0.03em; }
.room .tile { border-radius: 12px; }
.ms { border-radius: 12px; }
.sheet { background: rgba(17, 24, 39, .38); -webkit-backdrop-filter: none; backdrop-filter: none; }
.sheet-panel { border-radius: var(--r-lg); }
.sheet-head { border-radius: var(--r-lg) var(--r-lg) 0 0; }

/* 시작 단추: 아랫단이 두꺼운 «장난감 단추» 대신 평평한 단추 */
.go { box-shadow: none; border-radius: 14px; }
@media (hover: hover) { .go:hover { transform: none; box-shadow: none; background: var(--brand-dark); } }
.go:active { transform: translateY(1px); box-shadow: none; }

/* 홈의 방 셋: 진한 그라데이션 판 → 흰 카드. 방의 색은 친구 얼굴 바탕과 아이콘에만 */
body[data-view="home"] .room {
  background: var(--card); border: 1px solid var(--line);
  box-shadow: var(--shadow); border-radius: var(--r-lg);
}
body[data-view="home"] .room::before { display: none; }
body[data-view="home"] .room-pal { background: color-mix(in srgb, var(--c1) 16%, #fff); box-shadow: none; }
body[data-view="home"] .room-t b { color: var(--ink); text-shadow: none; font-size: 21px; }
body[data-view="home"] .room-t small { color: var(--ink-soft); font-weight: 500; }
body[data-view="home"] .room-go { color: var(--ink-soft); background: var(--tint); border: 1px solid var(--line); }
body[data-view="home"] .room .tile { background: var(--tint); border: 1px solid var(--line-soft); box-shadow: none; }
body[data-view="home"] .room .tile:hover { background: #fff; border-color: var(--line); box-shadow: var(--shadow); transform: translateY(-1px); }
body[data-view="home"] .room .tile:active { transform: none; box-shadow: none; }

/* 방 하나를 펼친 화면: 같은 방이라는 것은 친구 얼굴 바탕색으로 알립니다 */
.room.on {
  background: var(--card); border: 1px solid var(--line); box-shadow: var(--shadow);
}
.room.on .room-t b { color: var(--ink); text-shadow: none; }
.room.on .room-t small { color: var(--ink-soft); font-weight: 500; }
.room.on .room-pal { background: color-mix(in srgb, var(--c1) 16%, #fff); box-shadow: none; }
.room.on .room-say { background: var(--tint); border-color: var(--line); box-shadow: none; }
.room.on .room-say::before { background: var(--tint); border-color: var(--line); }
.room.on .tile { border: 1px solid var(--line); box-shadow: none; }

/* 로그인: 가로 태블릿(높이 534px)에서 세로로 쌓으면 720px 이라 아이가 밀어 올려야
   «들어가기» 가 보였습니다. 간판 덩어리는 왼쪽, 들어가는 칸은 오른쪽으로. */
.login-side { display: contents; }
@media (min-width: 760px) and (max-height: 820px) {
  body:has(#loginCard) > .wrap {
    max-width: 900px !important; padding: 12px 28px !important; min-height: 100vh;
    display: grid; grid-template-columns: minmax(0, 1fr) 400px; column-gap: 56px;
    align-content: center;
  }
  body:has(#loginCard) > .wrap > * { grid-column: 2; }
  body:has(#loginCard) .login-side {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    grid-column: 1; grid-row: 1 / span 6; align-self: center;
  }
  body:has(#loginCard) .login-brand { margin-bottom: 18px; }
  body:has(#loginCard) #loginCard, body:has(#loginCard) #pinCard { padding: 20px 22px; margin-bottom: 10px; }
  body:has(#loginCard) #loginCard label { margin-top: 10px; }
  body:has(#loginCard) #loginCard .hint { margin-top: 6px; }
  body:has(#loginCard) .wrap > p.center { margin: 6px 0 0 !important; }
}

/* «처음 할 일» 줄(ol.steps li.go) 이 학생 홈의 시작 단추(.go)와 이름이 겹쳐서 줄마다
   대표색 판이 되어 있었습니다(선생님 화면 · 설정). 줄 모양으로 되돌립니다. */
ol.steps li.go {
  display: block; margin: 0; min-height: 0; gap: 0;
  padding: 12px 10px 12px 52px; border-radius: 10px;
  background: none; color: inherit; box-shadow: none; text-decoration: none;
}
ol.steps li.go::before { left: 12px; }
ol.steps li.go:hover, ol.steps li.go:focus-visible { background: var(--tint); transform: none; }
ol.steps li.go:active { transform: none; }
ol.steps li.go b, ol.steps li.go span { white-space: normal; overflow: visible; }

/* «오늘 할 범위» 카드 (js/common.js foldPicker). 접힌 고르개 대신 이 한 장과 «시작» 만. */
#picker.folded > .today-pick { display: block; }
.opt-folded { display: none !important; }
.today-pick {
  border: 1px solid var(--line); background: var(--tint); border-radius: var(--radius);
  padding: 14px 16px; margin: 2px 0 4px;
}
.today-pick small { display: block; font-size: 12.5px; font-weight: 700; color: var(--brand-ink); }
.tp-range { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 6px; }
.tp-range .level-chip { font-size: 13px; padding: 3px 11px; }
.tp-range b { font-size: 24px; font-weight: 800; letter-spacing: -0.03em; color: var(--ink); }
.tp-opts { margin-top: 4px; font-size: 14px; color: var(--ink-soft); }
.tp-acts { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.tp-acts button { flex: 1 1 140px; min-height: 42px; padding: 8px 12px; font-size: 14px; }

/* 가로 태블릿 문제 화면: 진행 막대는 카드 맨 위에 붙이고, 낱말 · 보기만 가운데로.
   격자 전체를 가운데로 모았더니 진행 막대도 함께 내려와, 카드 위쪽 110px 이
   비고 막대가 화면 한가운데를 가로질렀습니다. */
@media (min-width: 760px) and (max-height: 820px) {
  .card.play.two { position: relative; padding-top: 58px; }
  .card.play.two > .progress {
    position: absolute; top: 38px; left: 20px; right: 20px; margin: 0;
    grid-area: auto;   /* 격자 칸을 정해 두면 그 칸이 기준이 되어 엉뚱한 데 붙습니다 */
  }
}

/* 가로 태블릿(갤럭시탭 893×534)은 폭이 720~999 라 «세로 태블릿» 규칙에 걸려, 큰 카드가
   한 줄을 다 쓰고 작은 카드들이 그 밑에 짝이 안 맞게 쌓였습니다. 가로로 누운 화면에서는
   처음 뜻대로 «왼쪽 오늘의 공부 | 오른쪽 이번 주 · 스티커 · 다시 볼 단어» 로 둡니다. */
@media (min-width: 720px) and (max-width: 999px) and (orientation: landscape) {
  .bento { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); }
  .todaycard { grid-column: auto; }
  .side { grid-column: auto; display: flex; flex-direction: column; }
  .todaycard .go b { font-size: 16px; }
}

/* 결과 화면 (js/common.js arrangeResults): 점수 · 단추가 먼저, 목록은 틀린 것부터 */
.res-side > .row, .res-side > div[style*="margin-top"] { margin-top: 10px !important; }
.res-main > h3:first-child { margin-top: 18px; }
li.ok-fold { display: block; padding: 10px 0 0; border-bottom: 0; }
li.ok-fold summary {
  cursor: pointer; font-size: 14px; font-weight: 600; color: var(--ok);
  padding: 8px 12px; border-radius: var(--r-sm); background: var(--ok-soft); display: inline-block;
}
li.ok-fold summary::-webkit-details-marker { display: none; }
li.ok-fold ul.answers { margin-top: 6px; }
@media (min-width: 760px) {
  section#done.res-grid {
    display: grid; grid-template-columns: minmax(260px, 320px) minmax(0, 1fr);
    column-gap: 32px; align-items: start;
  }
  section#done.res-grid > .res-side { position: sticky; top: 76px; }
  section#done.res-grid > .res-main > h3:first-child { margin-top: 4px; }
  section#done.res-grid .res-side .row { flex-direction: column; }
  section#done.res-grid .res-side .row > * { min-width: 0; }
}

/* 내 기록(my.html): 넓은 화면에서 두 단. 카드 높이가 저마다 달라(스티커판 · 기록 표) 줄을
   맞추면 빈 칸이 생기므로, 신문 단처럼 위에서 아래로 채우고 두 단 길이를 저절로 맞춥니다.
   위의 숫자 셋은 두 단을 가로지릅니다. 태블릿 가로에서 1,857 → 약 1,000px. */
@media (min-width: 860px) {
  .wrap:has(> section#summary) { max-width: 1100px; columns: 2; column-gap: 16px; }
  .wrap:has(> section#summary) > #msg,
  .wrap:has(> section#summary) > section#summary { column-span: all; }
  .wrap:has(> section#summary) > section.card { break-inside: avoid; display: block; }
}

/* ==== 고르는 단추 묶음 = «받침» 하나 (2026-10) ===============================
   단추마다 동그란 테두리가 있어 한 화면에 버블이 수십 개 떠 보였습니다(레벨 5 · 권 10 ·
   문제 수 · 방향 · 방식 · 학생 …). 같은 묶음은 옅은 받침 하나에 테두리 없이 담고,
   고른 것만 흰 바탕으로 도드라지게 합니다 -- 화면 위 칸 고르개(.sectabs)와 같은 말투.
   누르는 면적(높이)은 그대로입니다. */
.chips, .bubble-row {
  width: fit-content; max-width: 100%;
  gap: 3px; padding: 4px;
  background: var(--tint); border: 1px solid var(--line); border-radius: 12px;
}
.chips:empty, .bubble-row:empty { display: none; }
.chips .chip, .bubble {
  background: transparent; border-color: transparent; color: var(--ink-soft);
  border-radius: 9px; box-shadow: none;
}
.chips .chip:hover, .bubble:hover { background: rgba(16, 24, 40, .05); border-color: transparent; color: var(--ink); }
.chips .chip.on, .bubble.on {
  background: #fff; color: var(--brand-ink); border-color: transparent;
  box-shadow: 0 1px 2px rgba(16, 24, 40, .08), 0 0 0 1px var(--line);
}
/* 받침 안에 받침이 겹치지 않게 (받아쓰기 «무엇을» 묶음 · 접힌 줄) */
#whatPick .chips { background: none; border: 0; padding: 0; }
/* 가로 태블릿(534px)에서는 받침을 얇게 -- 줄마다 6px 이 쌓여 범위 화면이 다시 넘쳤습니다.
   교재 1~10권이 한 줄에 들도록 칩 옆 여백도 줄입니다. */
@media (min-width: 760px) and (max-height: 820px) {
  .chips, .bubble-row { padding: 2px; gap: 2px; border-color: transparent; }
  .picker .chips .chip { padding-left: 9px; padding-right: 9px; }
}
@media (min-width: 760px) and (max-height: 820px) {
  section#setup.card { margin-bottom: 4px; }
}

/* 숙제 목록: 줄마다 눌리고, 다음에 할 것 하나만 꽉 찬 단추 (homework.html) */
.card.hw-list { padding: 6px; }
.hw-row { display: flex; align-items: center; gap: 12px; padding: 12px 12px; border-radius: 12px;
  color: inherit; text-decoration: none; min-height: 64px; }
a.hw-row:hover, a.hw-row:active { background: var(--tint); }
.hw-row + .hw-row { border-top: 1px solid var(--line-soft); border-radius: 0 0 12px 12px; }
.hw-row.next { background: var(--brand-soft, #fdf0f2); }
.hw-row-t { flex: 1 1 7em; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
/* 큰 글씨(기기 글자 크기 · 확대 150%)에서는 «시작 ›» · «했어요» 가 자리를 지키느라 숙제 이름이 한 글자씩 세로로
   섰습니다(2026-11-01). 이름 칸이 7em 아래로 줄면 오른쪽 단추가 다음 줄 오른쪽으로 내려갑니다. */
.hw-row { flex-wrap: wrap; }
.hw-row-go, .hw-row-done { margin-left: auto; }
.hw-row-t b { font-size: 16px; }
.hw-row-s { font-size: 13.5px; color: var(--ink-soft); display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.hw-row-note { font-size: 13px; color: var(--ink); background: var(--card); border: 1px solid var(--line);
  border-radius: 8px; padding: 4px 8px; margin-top: 4px; align-self: flex-start; }
.hw-row-go { flex: none; min-width: 64px; text-align: center; padding: 9px 14px; border-radius: 99px;
  font-weight: 700; font-size: 14.5px; color: var(--brand-ink); border: 1.5px solid var(--brand); background: var(--card); }
.hw-row-go.next { background: var(--brand); color: #fff; border-color: var(--brand); padding: 10px 18px; }
.hw-row-go::after { content: ' ›'; }
.hw-row.done { opacity: .75; }
.hw-row.done .hw-row-t b { color: var(--ink-soft); }
.hw-row-done { flex: none; display: inline-flex; align-items: center; gap: 6px; font-weight: 700;
  font-size: 14px; color: var(--ok-ink); font-variant-numeric: tabular-nums; }
.hw-row-done i { font-style: normal; width: 22px; height: 22px; border-radius: 50%; background: var(--ok-soft);
  display: inline-grid; place-items: center; font-size: 12px; }

/* 가로 태블릿: 숙제로 들어온 시험은 위에 «선생님이 낸 숙제» 띠가 붙어, 카드의 최소 높이
   (화면 − 90px)와 합쳐 615px 로 화면을 넘었습니다. 띠는 얇게, 카드는 그만큼 낮게. */
@media (min-width: 760px) and (max-height: 820px) {
  .wrap > .msg { margin: 2px 0 8px; padding: 6px 10px 6px 14px; min-height: 0; font-size: 14px; }
  .wrap > .msg button { min-height: 30px; padding: 4px 10px; font-size: 13px; }
  .wrap > .msg ~ .card.play { min-height: calc(100vh - 150px); }
  /* 리딩 · 빈칸은 카드 키를 min 이 아니라 height 로 못 박아 두어(위 «리딩» · «빈칸» 규칙)
     위 줄의 min-height 가 안 먹었습니다. 숙제 · 오늘의 코스로 들어오면 띠만큼 화면을 넘어
     «다 풀었어요» 가 잘렸습니다(534 화면에 589). 높이마다 띠 몫 60px 을 똑같이 뺍니다. */
  .wrap > .msg ~ .card.play.read, .wrap > .msg ~ .card.play.fill { height: calc(100vh - 150px); }
  .wrap > .msg ~ .card.play.read > .subcard { max-height: calc(100vh - 254px); }
  .wrap > .msg ~ .card.play.read > #questions { max-height: calc(100vh - 314px); }
  .wrap > .msg ~ .card.play.fill > .cloze-passage { max-height: calc(100vh - 320px); }
  .wrap > .msg ~ .card.play.fill > .listen-bar:not(.hidden) ~ .cloze-passage { max-height: calc(100vh - 380px); }
  .wrap > .msg ~ .card.play.fill > .cloze-bank { max-height: calc(100vh - 250px); }
}
/* 고르개(교재·낱말책·사다리)가 없는 화면(말하기)은 두 칸으로 나누면 이름표는 왼쪽,
   그 단추는 오른쪽으로 갈라져 «책 · 단원» 글자만 덩그러니 남았습니다. 한 칸으로. */
@media (min-width: 760px) and (max-height: 820px) {
  section#setup.card:not(:has(> #picker, > #vocaPick, > #ladderPick)) {
    display: block; max-width: 640px; margin-left: auto; margin-right: auto; padding: 14px 24px 16px;
  }
}

/* 레벨 차례 안내 (common.js rangePicker) */
.lv-guide { margin-left: 8px; font-size: 12px; font-weight: 500; color: var(--ink-soft); }

/* 숙제를 끝냈을 때의 띠 (common.js watchHomeworkDone) */
.msg.hw-finished { display: flex; align-items: center; gap: 10px; background: var(--ok-soft); color: var(--ok-ink);
  border-color: var(--ok-line); }
.hw-fin-t { flex: 1; display: inline-flex; align-items: center; gap: 8px; font-weight: 700; }
.hw-fin-t i { font-style: normal; width: 22px; height: 22px; border-radius: 50%; background: var(--ok); color: #fff;
  display: inline-grid; place-items: center; font-size: 12px; }
.hw-fin-go { flex: none; padding: 7px 14px; border-radius: 99px; background: var(--ok); color: #fff;
  font-weight: 700; font-size: 14px; text-decoration: none; }

/* 결과 목록: O/X 글자 대신 동그란 ✓ ✗, 줄 간격은 조금 좁게 (2026-10).
   스무 줄이 한 줄 73px 이라 틀린 것 열두 개가 화면 두 장이었습니다. */
.res-grid ul.answers > li { padding: 8px 0; align-items: flex-start; }
.res-grid ul.answers > li > .mark.o:not(.self), .res-grid ul.answers > li > .mark.x:not(.self) {
  min-width: 0; width: 22px; height: 22px; border-radius: 50%; font-size: 0;
  display: inline-grid; place-items: center; margin-top: 1px;
}
.res-grid ul.answers > li > .mark.o:not(.self) { background: var(--ok-soft); }
.res-grid ul.answers > li > .mark.x:not(.self) { background: #fdeef0; }
.res-grid ul.answers > li > .mark.o:not(.self)::after { content: '✓'; font-size: 12px; color: var(--ok); }
.res-grid ul.answers > li > .mark.x:not(.self)::after { content: '✗'; font-size: 12px; color: var(--bad); }
.res-grid .answers .wrong { margin-left: 0; font-size: 14px; }
/* 점수에 안 넣은 문제(차례가 안 온 버저 · 구경한 골든벨 · 들어오기 전 · 하나도 안 낸 판): 빨간 ✗ 가 아니라 옅은 – (2026-11-01).
   예전에는 class 가 'x' 라 위 규칙이 글자를 지우고 ✗ 를 그렸습니다. */
.mark.skip { color: var(--ink-soft); }
.res-grid ul.answers > li > .mark.skip { min-width: 0; width: 22px; height: 22px; border-radius: 50%; display: inline-grid; place-items: center;
  margin-top: 1px; background: var(--tint, #f7f1e8); font-size: 13px; }

/* 스피드 퀴즈 결과: 가로 태블릿에서 점수 | 순위 두 단 (한 칸이면 635px 로 화면을 넘음).
   격자로 나누면 왼쪽 마스코트 높이만큼 순위표가 밀려 내려가서, 신문처럼 단으로 나눕니다. */
@media (min-width: 760px) and (max-height: 820px) {
  section#done.card:has(> #board) { columns: 2; column-gap: 32px; }
  section#done.card:has(> #board) > * { break-inside: avoid; }
  section#done.card:has(> #board) > h3 { break-before: column; margin-top: 0; }
  section#done.card:has(> #board) > .row { margin-top: 12px !important; }
}

/* 폰 · 세로 태블릿도 같은 일: «선생님이 낸 숙제» 띠가 붙으면 카드의 최소 높이
   (화면 − 172px)와 합쳐 화면을 넘어, 맨 아래 «다음» 단추가 굴려야 보였습니다(917px). */
@media (max-width: 759px), (min-height: 701px) {
  .wrap > .msg.hw-banner { margin: 0 0 10px; padding: 8px 10px 8px 14px; font-size: 14px; }
  .wrap > .msg.hw-banner button { min-height: 32px; padding: 4px 10px; font-size: 13px; }
  .wrap > .msg.hw-banner ~ .card.play {
    min-height: calc(100vh - 230px);
    min-height: calc(100dvh - 230px);
  }
}

/* «＋ 이 범위도 더하기» 는 가끔 쓰는 것 -- 작은 글씨 단추 (common.js multiRangePicker) */
button.add-range { background: none; border: 0; box-shadow: none; min-height: 32px; width: auto;
  padding: 4px 2px; font-size: 13.5px; font-weight: 600; color: var(--brand-ink); }
button.add-range:hover { text-decoration: underline; background: none; }

/* ── 오늘의 코스 (course.html · 홈 카드) ───────────────────────────────── */
.course-card { display: flex; align-items: center; gap: 12px; padding: 14px 16px; margin-bottom: 12px;
  border-radius: var(--r-lg, 18px); background: var(--brand); color: #fff; text-decoration: none;
  box-shadow: 0 6px 16px rgba(231, 90, 110, .22); }
.course-card[hidden] { display: none; }
.course-card .cc-ic { flex: none; width: 36px; height: 36px; border-radius: 50%; background: rgba(255,255,255,.22);
  display: grid; place-items: center; font-size: 22px; font-weight: 700; line-height: 1; }
.course-card .cc-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.course-card .cc-t b { font-size: 16.5px; }
.course-card .cc-t span { font-size: 13px; opacity: .92; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.course-card .cc-go { flex: none; background: #fff; color: var(--brand-ink); font-weight: 700; font-size: 14px;
  padding: 7px 14px; border-radius: 99px; }
.course-card:active { transform: translateY(1px); }

.card.course { max-width: 640px; margin-left: auto; margin-right: auto; }
.course-head { display: flex; align-items: center; gap: 14px; margin-bottom: 14px; }
.course-pal { flex: none; line-height: 0; }
.course-t { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.course-t small { color: var(--brand-ink); font-weight: 700; font-size: 13px; }
.course-t b { font-size: 21px; letter-spacing: -0.01em; }
.course-t .muted { font-size: 13.5px; }
.course-steps { list-style: none; margin: 0 0 14px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.course-step { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-radius: var(--r-md);
  border: 1px solid var(--line); background: var(--card); }
.course-step .cs-n { flex: none; width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center;
  font-weight: 700; background: var(--tint); color: var(--ink-soft); border: 1px solid var(--line); }
.course-step .cs-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.course-step .cs-t b { font-size: 16px; }
.course-step .cs-t span { font-size: 13px; color: var(--ink-soft); }
.course-step .cs-s { flex: none; font-size: 13px; font-weight: 700; }
/* 큰 글씨(기기 글자 크기 · 확대 150%)에서 «지금 할 차례» 가 자리를 버티느라 단계 이름이 «단/어/시/험» 으로
   한 글자씩 섰습니다(2026-11-01, 260px 폭). 이름 칸이 7em 아래로 줄면 오른쪽 말은 다음 줄로 내려갑니다. */
.course-step { flex-wrap: wrap; }
.course-step .cs-t { flex: 1 1 6em; }
.course-step .cs-s { margin-left: auto; }
.course-step.now { border-color: var(--brand); background: var(--brand-soft, #fdf0f2); }
.course-step.now .cs-n { background: var(--brand); color: #fff; border-color: transparent; }
.course-step.now .cs-s { color: var(--brand-ink); }
.course-step.done { opacity: .8; }
.course-step.done .cs-n { background: var(--ok); color: #fff; border-color: transparent; }
.course-step.done .cs-s { color: var(--ok-ink); }
.go.done { background: var(--ok); }   /* 흰 글자 3.5:1 → 5.3:1 (초록 한 집안) */
@media (min-width: 760px) and (max-height: 820px) {
  .card.course { padding: 14px 20px; }
  .course-head { margin-bottom: 10px; }
  .course-step { padding: 9px 14px; }
  .course-steps { gap: 6px; margin-bottom: 10px; }
}

/* ── 도장판 (common.js stampBoard) ───────────────────────────────────── */
.stamps { display: grid; grid-template-columns: repeat(8, minmax(0, 1fr)); gap: 8px; }
.stamps .stp { position: relative; aspect-ratio: 1; border-radius: 50%; display: grid; place-items: center;
  border: 2px dashed var(--line-strong); color: var(--ink-soft); text-decoration: none; background: var(--card); }
.stamps .stp b { font-size: 14px; font-weight: 700; line-height: 1; }
/* 점수(«85점»)는 12px -- 아이 화면 글씨는 12px 아래로 내리지 않습니다. 인쇄지(.sheet-page)는 아래에서 따로 9px */
.stamps .stp small { position: absolute; bottom: 13%; font-size: 12px; font-weight: 700; line-height: 1; letter-spacing: -.03em; white-space: nowrap; }
.stamps .stp.on { border: 0; color: #fff; background: var(--lv); }
.stamps .stp.on::before { content: ''; position: absolute; inset: 14%; background: rgba(255, 255, 255, .22);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 1.5l1.7 3.9 3.2-1.4-.7 3.7 3.7-.5-2 3.2 3.6 1.6-3.9 2 1.1 3.1-3.7-.9-1.1 3.3-2.2-2.6v5.6h-1.8v-5.6l-2.2 2.6-1.1-3.3-3.7.9 1.1-3.1-3.9-2 3.6-1.6-2-3.2 3.7.5-.7-3.7 3.2 1.4z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 1.5l1.7 3.9 3.2-1.4-.7 3.7 3.7-.5-2 3.2 3.6 1.6-3.9 2 1.1 3.1-3.7-.9-1.1 3.3-2.2-2.6v5.6h-1.8v-5.6l-2.2 2.6-1.1-3.3-3.7.9 1.1-3.1-3.9-2 3.6-1.6-2-3.2 3.7.5-.7-3.7 3.2 1.4z'/%3E%3C/svg%3E") center / contain no-repeat; }
.stamps .stp.on b { position: relative; margin-top: -6px; }
.stamps .stp.on small { color: rgba(255, 255, 255, .92); }
/* 점수가 낮다고 도장을 흐리게 하지 않습니다 -- 해 본 것은 해 본 것. 90점 넘으면 금테만 */
.stamps .stp.on.s3 { box-shadow: 0 0 0 3px #f6c445; }
.stamps .stp.next { border: 2px solid var(--brand); color: var(--brand-ink); background: rgba(var(--brand-rgb), .07);
  animation: stp-pulse 1.8s ease-in-out infinite; }
.stamps .stp.next small { color: var(--brand-ink); }
/* 다음 칸에도 밑에 «다음» 이 붙으므로 Day 숫자를 도장 칸처럼 올립니다. 안 올리면 42px 동그라미에서
   «12» 와 «다음» 이 겹칩니다(도장 칸만 올려 두었던 때). */
.stamps .stp.next b { position: relative; margin-top: -6px; }
a.stp.next:active { transform: scale(.96); }
@keyframes stp-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(var(--brand-rgb), .35); } 50% { box-shadow: 0 0 0 6px rgba(var(--brand-rgb), 0); } }
@media (prefers-reduced-motion: reduce) { .stamps .stp.next { animation: none; } }
@media (max-width: 430px) { .stamps { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 7px; } }
/* 몇 칸으로 나눌지는 화면 폭이 아니라 «판이 놓인 자리의 폭» 으로 정합니다. 내 기록은 860 넘으면
   두 단이라 같은 태블릿이어도 판 폭이 740 · 380 으로 갈립니다.
     넓은 자리(세로 태블릿 820, 한 단): 여덟 칸이면 85px 동그라미 세 줄(300px) -> 열두 칸 두 줄
     좁은 자리(900 · 1000 의 두 단, 폰): 여덟 칸이면 39px 이라 «85점» 이 Day 숫자와 겹침 -> 여섯 칸
   열두 칸은 판 폭 640 부터입니다. 560 부터로 두었더니 판 폭 560~640(화면 640~720)에서 동그라미가
   39~46px 이 되어 «100점» 이 Day 숫자에 붙었습니다. 640 이면 열두 칸이 46px 이상입니다.
   컨테이너 쿼리를 모르는 옛 브라우저는 위의 화면 폭 규칙(폰 여섯 칸 · 그 밖 여덟 칸)을 씁니다.
   인쇄지(.sheet-page)는 아래 규칙이 뒤에 있어 열두 칸 그대로입니다. */
:has(> .stamps:not(.mini)) { container-type: inline-size; }
@container (min-width: 640px) { .stamps:not(.mini) { grid-template-columns: repeat(12, minmax(0, 1fr)); } }
@container (max-width: 440px) { .stamps:not(.mini) { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 7px; } }
/* 폰(360 · 판 폭 278)의 여섯 칸은 동그라미가 40px 남짓이라 Day 숫자와 점수가 맞닿습니다. 점수 글씨는
   12px 아래로 줄이지 않고(아이 화면 글씨 하한), 숫자만 조금 더 올립니다. 점수를 내리면 동그라미
   아래쪽 둥근 테두리 밖으로 «100점» 이 삐져나옵니다. */
@container (max-width: 320px) { .stamps:not(.mini) .stp:is(.on, .next) b { margin-top: -10px; } }
/* 홈 «내 교재» 카드의 작은 판: 점 24개 한 줄 */
.stamps.mini { grid-template-columns: repeat(24, minmax(0, 1fr)); gap: 3px; margin: 8px 0 6px; }
.stamps.mini i { aspect-ratio: 1; border-radius: 50%; background: var(--line); max-width: 12px; }
.stamps.mini i.on { background: var(--lv); }
.stamps.mini i.on.s3 { box-shadow: 0 0 0 2px #f6c445; }
.stamps.mini i.next { background: transparent; box-shadow: inset 0 0 0 2px var(--brand); }

/* 내 기록 칸 셋 (my.html) */
.my-tabs { margin: 0 0 12px; width: fit-content; max-width: 100%; }
.wrap > section.tab-off { display: none !important; }
@media (min-width: 860px) {
  .wrap:has(> section#summary) > .my-tabs { column-span: all; }
}
.my-tabs .chip { padding: 9px 18px; font-size: 15px; font-weight: 700; }

/* 결과 화면 «새 도장» (common.js watchNewStamps) */
.stamp-new { display: flex; align-items: center; gap: 10px; margin: 10px 0; padding: 10px 14px; border-radius: var(--r-md);
  background: #fff8e8; border: 1px solid #f6dfa6; color: var(--ink); text-decoration: none;
  animation: sn-pop .45s cubic-bezier(.2, 1.4, .4, 1) both; }
.stamp-new .sn-leaf { flex: none; width: 34px; height: 34px; background: var(--lv);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 1.5l1.7 3.9 3.2-1.4-.7 3.7 3.7-.5-2 3.2 3.6 1.6-3.9 2 1.1 3.1-3.7-.9-1.1 3.3-2.2-2.6v5.6h-1.8v-5.6l-2.2 2.6-1.1-3.3-3.7.9 1.1-3.1-3.9-2 3.6-1.6-2-3.2 3.7.5-.7-3.7 3.2 1.4z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 1.5l1.7 3.9 3.2-1.4-.7 3.7 3.7-.5-2 3.2 3.6 1.6-3.9 2 1.1 3.1-3.7-.9-1.1 3.3-2.2-2.6v5.6h-1.8v-5.6l-2.2 2.6-1.1-3.3-3.7.9 1.1-3.1-3.9-2 3.6-1.6-2-3.2 3.7.5-.7-3.7 3.2 1.4z'/%3E%3C/svg%3E") center / contain no-repeat; }
.stamp-new .sn-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.stamp-new .sn-t b { font-size: 15.5px; color: #8a5a12; }
.stamp-new .sn-t small { font-size: 12.5px; color: var(--ink-soft); }
.stamp-new i { font-style: normal; font-weight: 700; color: #8a5a12; }
@keyframes sn-pop { from { transform: scale(.85); opacity: 0; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .stamp-new { animation: none; } }
@media (min-width: 760px) and (max-height: 820px) { .stamp-new { margin: 6px 0; padding: 7px 12px; } .stamp-new .sn-leaf { width: 26px; height: 26px; } }

/* 내 기록 · 지난 시험 펼치기 */
.run.tap { cursor: pointer; border-radius: 10px; }
.run.tap.on { background: var(--tint); }
/* 손가락으로 누른 뒤에도 :hover 가 남아(터치 화면), 접은 줄이 펼친 줄처럼 칠해져 있었습니다.
   마우스가 있는 화면에서만 올리면 칠합니다. */
@media (hover: hover) { .run.tap:hover { background: var(--tint); } }
/* 줄을 누르면 그 시험의 맞은 답 · 틀린 답이 펼쳐지는데(이 화면에서 제일 쓸모 있는 것),
   알려 주는 것은 마우스를 올려야 뜨는 title 뿐이라 태블릿에서는 점수 목록으로만 보였습니다.
   «8/10» 옆에 한 마디를 붙입니다. 학습 기록 줄(.tap 없음)은 그대로입니다. */
.run.tap .run-of::after { content: " · 답 보기 ›"; color: var(--brand-ink); font-weight: 700; }
.run.tap.on .run-of::after { content: " · 접기"; }
.run-open { margin: 2px 0 10px; padding: 10px 14px; border-radius: 12px; background: var(--card); border: 1px solid var(--line); }
.run-open-t { display: block; font-size: 14px; color: var(--bad); margin-bottom: 4px; }
.run-open-t.ok { color: var(--ok); }
.run-open ul.answers > li { padding: 7px 0; font-size: 14.5px; }
.run-open .answers .wrong { display: block; margin: 2px 0 0; }

/* 비어 있음 (teacher.html · my.html 의 empty()) */
.empty-state { display: flex; align-items: center; gap: 12px; padding: 14px 16px; margin: 4px 0;
  border-radius: 12px; background: var(--tint); border: 1px dashed var(--line-strong, var(--line)); }
.empty-state p { margin: 0; font-size: 14px; color: var(--ink-soft); line-height: 1.55; }
.empty-state .es-ic { flex: none; width: 22px; height: 22px; background: var(--line-strong, #cfc6ba); opacity: .9;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 1.5l1.7 3.9 3.2-1.4-.7 3.7 3.7-.5-2 3.2 3.6 1.6-3.9 2 1.1 3.1-3.7-.9-1.1 3.3-2.2-2.6v5.6h-1.8v-5.6l-2.2 2.6-1.1-3.3-3.7.9 1.1-3.1-3.9-2 3.6-1.6-2-3.2 3.7.5-.7-3.7 3.2 1.4z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 1.5l1.7 3.9 3.2-1.4-.7 3.7 3.7-.5-2 3.2 3.6 1.6-3.9 2 1.1 3.1-3.7-.9-1.1 3.3-2.2-2.6v5.6h-1.8v-5.6l-2.2 2.6-1.1-3.3-3.7.9 1.1-3.1-3.9-2 3.6-1.6-2-3.2 3.7.5-.7-3.7 3.2 1.4z'/%3E%3C/svg%3E") center / contain no-repeat; }
td > .empty-state, .tbl > .empty-state { margin: 0; border: 0; }

/* 창 머리가 바깥 여백(40px)만큼 아래에 붙어서, 굴리면 머리 «위» 로 내용이 비쳐 보였습니다.
   여백만큼 위로 올려 붙여 화면 맨 위에 딱 붙게 합니다(작은 화면은 여백이 12px). */
.sheet > .sheet-panel > .sheet-head { top: -40px; }
@media (max-height: 700px) { .sheet > .sheet-panel > .sheet-head { top: -12px; } }
.sheet.ask-sheet > .sheet-panel > .sheet-head { top: -16px; }

/* 인쇄: 도장판 색이 종이에도 나오게, 반짝임은 없이 */
.sheet-page .stamps { gap: 6px; }
.sheet-page .stamps .stp { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
.sheet-page .stamps .stp.next { animation: none; }
@media print { .stamps .stp { -webkit-print-color-adjust: exact; print-color-adjust: exact; } .stamps .stp.next { animation: none; box-shadow: none; } }
.sheet-page .stamps { grid-template-columns: repeat(12, minmax(0, 1fr)); max-width: 640px; gap: 6px; }
.sheet-page .stamps .stp b { font-size: 12px; }
.sheet-page .stamps .stp small { font-size: 9px; }

/* 인터넷 끊김 띠 (common.js netBanner) */
.net-bar { position: fixed; left: 50%; top: 10px; transform: translate(-50%, -140%); z-index: 90;
  padding: 9px 16px; border-radius: 999px; background: #3a2f28; color: #fff; font-size: 14px; font-weight: 600;
  box-shadow: 0 8px 24px -8px rgba(0, 0, 0, .4); transition: transform .25s ease; pointer-events: none; max-width: calc(100vw - 32px); }
.net-bar.on { transform: translate(-50%, 0); }
.net-bar.back { background: var(--ok); }
@media (prefers-reduced-motion: reduce) { .net-bar { transition: none; } }

/* ==== 접근성 점검 (2026-10): 글쇠판 · 손가락 ==============================================
   모습은 거의 그대로 두고, 보이지 않던 것 · 누르기 어려운 것만 고칩니다. */

/* 글쇠판(Tab)으로 옮겨 다닐 때 링크 · 누르는 줄(내 기록의 시험 줄 등)도 단추와 같은 테두리.
   :where() 라 특이도가 0 이어서, 화면마다 따로 정해 둔 초점 모양이 있으면 그것이 이깁니다.
   글 칸 · 고르는 칸(input · select)은 제 테두리 표시가 있어 넣지 않았습니다. */
:where(a[href], [role="button"], [role="tab"], [tabindex]:not([tabindex="-1"]), summary):focus-visible {
  outline: 3px solid var(--brand-ink); outline-offset: 2px;
}

/* 머리글의 누르는 것(간판 · 화면 이름 · 홈 · 나가기)은 26~40px 이라 손가락 기준 44px 에 모자랐습니다.
   보이는 크기를 키우면 머리글이 높아져, 가로 태블릿에서 «화면 - 90px» 로 재 둔 활동 카드가
   화면을 넘칩니다. 그래서 모습은 그대로 두고 **누르는 자리만** 투명한 덧판으로 44px 까지 넓힙니다.
   «+ 다른 Day 더하기» 같은 작은 글씨 단추도 같은 방법입니다. */
header.bar .brand, header.bar h1 a, header.bar button.ghost, button.add-range { position: relative; }
header.bar .brand::after, header.bar h1 a::after, header.bar button.ghost::after, button.add-range::after {
  content: ''; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: max(100%, 44px); height: max(100%, 44px);
}
/* 고르는 칩은 40px 입니다(가로 태블릿 534px 화면에 고르개를 다 넣으려고 맞춘 값). 칩 사이 틈 안에서
   위아래 2px 씩만 누르는 자리를 넓혀 44px 이 되게 합니다 -- 줄 높이 · 모습은 그대로입니다. */
.chips .chip { position: relative; }
.chips .chip::after { content: ''; position: absolute; inset: -2px 0; }

/* 다 채운 고리의 «3 / 3» 도 12px 작은 글씨라 4.5:1 이 필요합니다(--ok 위 흰 글씨는 4.0:1). */
.ring.full em { background: var(--ok); }   /* --ok 가 이제 그 4.5:1 넘는 값입니다 */

/* ==== 아이 화면 부품 한 벌 (2026-10-22 디자인 개편) ========================================
   교실 공용 태블릿(가로 1180×820 이 주, 세로 820×1180)과 폰(390×844)으로 화면마다 써 보며
   맞춘 것들입니다. 화면마다 따로 생겼던 부품을 한 모양으로 묶습니다 -- 소리 단추 · 빈 화면 ·
   방 타일 · 고르는 칩의 폭 · 체크 칸. 색 · 서체 변수는 위 :root 그대로이고, 메이플 테마
   (theme-maple.css)가 덮는 둥글기 · 바탕도 그대로 받습니다(이 블록은 그 변수만 씁니다). */

/* ---- 소리 단추 (.say-btn) ----
   «소리 듣기»(단어 학습) · «읽어 주기»(리딩) · «글 들려주기»(빈칸 리스닝) · «다시 듣기»(함께 풀기 ·
   받아쓰기)가 화면마다 생김새가 달랐습니다 -- 34px 작은 회색 단추, 흰 테두리 단추, 대표색 통 단추.
   아이는 «소리가 나는 단추» 를 모양으로 알아봅니다. 모두 같은 옷: 옅은 대표색 알약 + 스피커 그림 +
   44px 넘는 키. 소리가 나는 동안(.on)은 그림이 «멈춤» 네모로 바뀝니다(글자도 «멈추기»).
   .wide 를 쓰지 않습니다 -- 메이플 테마가 .wide 단추를 대표색 통으로 칠합니다. 폭을 다 쓰려면 .full. */
.say-btn {
  --say-ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M11 5 6 9H2v6h4l5 4z' fill='%23000'/%3E%3Cpath d='M15.5 8.5a5 5 0 0 1 0 7'/%3E%3Cpath d='M18.5 5.5a9.5 9.5 0 0 1 0 13'/%3E%3C/svg%3E");
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 46px; padding: 8px 18px 8px 14px; border-radius: 999px;
  background: var(--brand-soft); color: var(--brand-ink); border: 1.5px solid var(--brand-line);
  font-size: 15px; font-weight: 800; letter-spacing: -0.01em; box-shadow: none; flex: none;
}
.say-btn::before {
  content: ''; flex: none; width: 22px; height: 22px; background: currentColor;
  -webkit-mask: var(--say-ic) center / contain no-repeat; mask: var(--say-ic) center / contain no-repeat;
}
.say-btn.on {
  --say-ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Crect x='5' y='5' width='14' height='14' rx='3' fill='%23000'/%3E%3C/svg%3E");
  background: #fff; border-color: var(--brand);
}
.say-btn.full { display: flex; width: 100%; }
@media (hover: hover) { .say-btn:hover { background: var(--brand-soft); border-color: var(--brand); color: var(--brand-ink); } }
.say-btn:active { transform: translateY(1px); }
/* 가로 태블릿(높이 820 이하 -- 가로 배치 묶음과 같은 기준)은 카드 키를 화면에 못 박아 두어(리딩 · 단어 학습), 단추가 12px 커지면 그만큼
   지문 상자 · 카드 바닥이 잘립니다. 보이는 키는 38px 로 두고 누르는 자리만 위아래 4px 씩 넓혀 46px 로. */
@media (min-width: 760px) and (max-height: 820px) {
  .say-btn { position: relative; min-height: 38px; padding: 4px 14px 4px 10px; font-size: 14px; }
  .say-btn::after { content: ''; position: absolute; inset: -4px 0; }
  .say-btn::before { width: 19px; height: 19px; }
}

/* ---- 빈 화면 (.kid-empty) ----
   숙제가 없을 때 · 오늘의 코스를 못 만들 때 · 함께 풀기가 없을 때. 예전에는 하나는 카드 속 글 두 줄,
   하나는 분홍 알림 상자 한 줄, 하나는 친구 그림 + 큰 단추라 «비어 있다» 가 화면마다 달랐고, 두 화면은
   다음에 누를 곳이 없었습니다. 친구(또는 메이플) 얼굴 · 굵은 한 줄 · 흐린 한 줄 · 큰 단추 하나로. */
.kid-empty { display: grid; justify-items: center; gap: 6px; text-align: center; padding: 30px 18px 24px; }
.kid-empty .ke-pal { line-height: 0; margin-bottom: 6px; }
.kid-empty > b { font-size: 20px; font-weight: 800; letter-spacing: -0.02em; word-break: keep-all; }
.kid-empty > p { margin: 0; max-width: 420px; font-size: 15px; line-height: 1.6; color: var(--ink-soft); }
.kid-empty .ke-go { margin-top: 14px; width: min(320px, 100%); text-decoration: none; }
.kid-empty .ke-go button { width: 100%; min-height: 54px; font-size: 17px; }

/* ---- «오늘 할 범위» 카드의 «책 · Day 바꾸기 · 몇 문제 · 어떻게» ---- 42 → 46px (가로 태블릿은 그대로) */
@media not all and (min-width: 760px) and (max-height: 820px) {
  .tp-acts button { min-height: 46px; font-size: 14.5px; }
}

/* ---- 체크 칸 한 줄(단어 학습 «영어 단어를 소리로도 듣기») ----
   네모가 13px 이라 저학년 손가락이 못 맞혔습니다. 줄 전체가 44px 누르는 자리이고 네모도 22px. */
#voiceWrap {
  min-height: 46px; width: fit-content; max-width: 100%; padding: 6px 16px 6px 12px; border-radius: 999px;
  background: var(--tint); border: 1px solid var(--line); color: var(--ink); font-size: 15px; cursor: pointer;
}
#voiceWrap input[type="checkbox"] { width: 22px !important; height: 22px; accent-color: var(--brand-btn); flex: none; }
/* 짝 맞추기 · 문장 만들기의 체크 칸도 같은 모양(2026-10-26 점검 -- #voiceWrap 만 고쳐져 13px 기본 네모가 남아 있었음) */
/* 낮은 가로(높이 640 아래, 교실 태블릿 1024×600 · 폰 가로)는 고르기 화면 높이를 재 두어 빼 둡니다. */
@media not all and (min-width: 760px) and (max-height: 639px) {
  #setup label:has(> input[type="checkbox"]):not(#voiceWrap) {
    min-height: 46px; width: fit-content; max-width: 100%; padding: 6px 16px 6px 12px; border-radius: 999px;
    background: var(--tint); border: 1px solid var(--line); color: var(--ink); font-size: 15px; cursor: pointer;
  }
}
#setup label:has(> input[type="checkbox"]) input[type="checkbox"] { width: 22px !important; height: 22px; accent-color: var(--brand-btn); flex: none; }

/* ---- 방 하나를 펼친 화면(/home.html#words) ----
   타일이 «240px 넘는 칸을 되는 만큼» 이라 가로 태블릿(1180)에서 빈 칸이 생겼습니다. 있는 타일만큼 칸을
   나누고, 누르는 판도 아이 손에 맞게 키웁니다. 그림(.big)이 56px 이니 그 칸도 56px 로(52px 칸에서 4px 삐져나옴). */
.room.on .tiles { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }
.room.on .tile { min-height: 92px; padding: 16px 18px; grid-template-columns: 56px 1fr; }
.room.on .tile .big { width: 56px; height: 56px; }
.room.on .tile b { font-size: 18.5px; }

/* ---- 화면마다 하나뿐인 «시작» 단추는 크게 ----
   범위 고르기 화면의 «시험 시작 · 학습 시작 · 시작하기» 가 보통 단추(48px · 15px)라, 바로 위 «책 · Day 바꾸기»
   (46px)와 키가 거의 같았습니다. 다음에 누를 곳이 한눈에 보이게 활동 화면 바닥 단추와 같은 56px · 17px 로.
   가로 태블릿은 위 «범위 고르기» 규칙이 #start 를 따로 재 두어 그대로입니다.
   홈 «오늘의 공부» · 오늘의 코스의 큰 단추(.go)도 같은 키로 맞춥니다(50 → 56px). */
/* 아이 범위 고르기 화면(#setup)만 -- 선생님 화면도 style.css 를 읽어 «교실 열기»(.start-dock 안)까지 커졌고, 가로 태블릿은
   위 «범위 고르기» 규칙이 키를 따로 재 두어 글자만 커졌습니다. */
@media not all and (min-width: 760px) and (max-height: 820px) {
  #setup .start-dock > button { min-height: 56px; font-size: 17px; font-weight: 800; }
}
@media not all and (min-width: 760px) and (max-height: 820px) { .go { min-height: 56px; } }
/* 결과 화면의 단추들(«틀린 N문제만 다시 풀기» · «같은 Day로 새 문제» · «홈으로»)은 보통 단추(48px)였습니다.
   끝난 뒤 아이가 고르는 다음 걸음이라 52px 로 한 단계 키웁니다(가로 태블릿은 그대로). 결과 목록 줄의 🔊(.say-mini)는 빼고. */
@media not all and (min-width: 760px) and (max-height: 820px) {
  section#done button:not(.mark):not(.mini):not(.linky):not(.say-mini) { min-height: 52px; font-size: 16px; }
}

/* 세로 태블릿 · 폰: (가로 태블릿 1180×820 · 1280×800 은 높이 820 까지의 가로 배치 묶음이 맡습니다) 활동 카드의 키는 «화면 - 172px»(머리글 · 위 22 · 아래 64 · 카드 여백)로 재 두었는데
   실제 머리글이 몇 px 더 커서, 문제 화면이 늘 4~7px 넘쳐 화면이 살짝 밀렸습니다(820×1180 에서 1184).
   카드가 떠 있는 동안 아래 여백만 52px 로 -- 손가락 닿는 단추는 그대로 바닥 근처입니다. */
@media not all and (min-width: 760px) and (max-height: 820px) {
  .wrap:has(> .card.play:not(.hidden)) { padding-bottom: 52px; }
}

/* ---- 넉넉한 가로 태블릿 (갤럭시 탭 A8 · A9+ · 레노버 M10 을 눕혀 크롬으로 연 1280×720~800) ----
   가로 배치(위 «min-width: 760px and max-height: 820px» 묶음)는 폰 가로 · 교실 태블릿(534~600px)
   높이에 맞춰 글자와 보기를 줄여 둡니다. 그 묶음을 820 까지 넓혔더니(탭 A8 가로가 세로 화면 배치로
   떨어져 문제 화면이 94px 씩 굴러갔습니다), 높이가 넉넉한 화면에서는 낱말이 작고 빈 곳이 많았습니다.
   높이 640 이 넘으면 손가락 · 눈 크기로 다시 키웁니다. */
@media (min-width: 760px) and (min-height: 640px) and (max-height: 820px) {
  .card.play { padding: 18px 24px; }
  .card.play .progress { height: 8px; margin-bottom: 12px; }
  .card.play.two { column-gap: 34px; }
  /* 낱말 하나일 때만 -- 함께 풀기의 긴 질문(.rc-q) · 문장(.rc-sent)까지 72px 로 키우면 화면 두 배를 먹었습니다 */
  .card.play.two .prompt:not(.rc-q):not(.rc-sent) { font-size: clamp(44px, 5.6vw, 72px); padding: 14px 6px 22px; }
  .card.play.two .choices { gap: 12px; }
  .card.play.two .choice { min-height: 68px; font-size: 21px; padding: 16px 22px; }
  .card.play > .row:last-child > button { min-height: 58px; font-size: 17px; }
  .card.play.read .passage { font-size: 18px; }
  .card.play.fill .cloze-passage { font-size: 18px; }
  .card.play.read .choice, .card.play.fill .cloze-word { min-height: 56px; font-size: 18px; }
}

/* ---- 세로 태블릿 리딩: 지문을 위에 붙여 둡니다 (탭 A8 세로 800×1280 · 탭 A9 세로 600×960) ----
   세로에서는 지문 아래로 문제 넷이 이어져, 3 · 4번을 풀 때면 지문이 화면 위로 사라졌습니다 — 아이는 근거를
   찾으려고 올렸다 내렸다를 되풀이했습니다. 지문 상자를 머리글 밑에 붙이고(화면의 36%까지, 넘치면 상자 안에서
   굴림) 문제만 아래로 지나가게 합니다. 폰(높이 860 아래)은 지문 상자가 화면을 다 먹으므로 그대로 둡니다. */
@media (orientation: portrait) and (min-width: 560px) and (min-height: 860px) {
  .card.play.read > .subcard {
    position: sticky; top: 72px; z-index: 2; max-height: 36vh; overflow: auto;
    box-shadow: 0 8px 14px -10px rgba(40, 30, 20, .28);
  }
  .card.play.read > p.hint { display: none; }   /* «올려서 다시 읽어도 돼요» -- 이제 늘 위에 있으니 틀린 말 */
}

/* 손가락 기기에서 작던 단추들: «+ 다른 Day 더하기» 32px(소리 단추는 위 .say-btn 이 46px).
   아이 손가락은 44px 언저리가 편합니다. 마우스 화면은 그대로 둡니다. */
@media (pointer: coarse) {
  button.add-range { min-height: 42px; }
  /* «5 · 10 · 15» 처럼 한두 글자 칩이 가로 태블릿에서 폭 26px 이었습니다 */
  .chips .chip { min-width: 46px; min-height: 40px; text-align: center; }
}

/* 함께 풀기 리딩 판(class.html)을 가로로: 지문 상자 · 질문 · 손들기 줄이 왼쪽 한 칸에 쌓여, 탭 A9 가로(1024×552)에서
   120px · 정답 공개 뒤 50px 넘쳤습니다. 지문 글 칸을 «남는 높이» 만큼으로 묶고 넘치는 글은 상자 안에서 굴립니다. */
@media (min-width: 760px) and (max-height: 820px) {
  .rc-passage p { max-height: min(34vh, max(72px, calc(100vh - 494px))); }
  /* 따라 말하기 · 영작 문장(.rc-sent)이 낱말용 큰 글씨(52px)를 받아 두 줄이면 탭 A9 가로에서 86px 넘쳤습니다 */
  .card.play .prompt.rc-sent { font-size: clamp(26px, 3.4vw, 40px); padding: 8px 6px 12px; }
}

/* ---- 넉넉한 가로 태블릿의 고르기 화면 ----
   고르기 카드는 높이 600px 용 크기라, 탭 A8 · A9+ 가로(1280×720~800)에서는 화면 위쪽 200px 에 작게 몰리고
   아래 600px 이 비었습니다. 카드를 화면 가운데 높이로 내리고, 아이 손가락 · 눈 크기로 키웁니다. */
@media (min-width: 760px) and (min-height: 640px) and (max-height: 820px) {
  .wrap:has(> #setup:not(.hidden)) {
    min-height: calc(100vh - 54px); display: flex; flex-direction: column; justify-content: center;
    padding-top: 12px; padding-bottom: 48px;
  }
  #setup.card { padding: 26px 30px; }
  #setup .today-pick { padding: 18px 22px; }
  #setup .today-pick small { font-size: 14px; }
  #setup .tp-range b { font-size: 34px; }
  #setup .tp-range .level-chip { font-size: 15px; padding: 4px 13px; }
  #setup .tp-acts button { min-height: 50px; font-size: 16px; }
  #setup #start { min-height: 64px; font-size: 20px; }
  /* 옵션 칩(개수 · 방향 · 방식)과 받아쓰기 «무엇을» 칩: 534 · 600px 높이용으로 줄인 36px · 12.5px 가 여기(800 · 820)에도
     걸려 아이 손가락 · 눈에 작았습니다(2026-10-26 점검). 넉넉한 가로에서는 다시 키웁니다. */
  section#setup.card .row .chips .chip,
  section#setup.card > .chips .chip,
  section#setup.card > #whatPick .chip { min-height: 44px; font-size: 15px; padding: 6px 14px; }
  section#setup.card label { font-size: 14px; }
}

/* 홈 맨 아래 «앱으로 깔기» 안내(home.html) -- 할 일보다 눈에 덜 띄게, 한 줄짜리 */
.install-card {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 18px 0 0; padding: 12px 16px; border: 1px dashed var(--line-strong, var(--line)); border-radius: var(--radius);
  background: var(--card);
}
.install-card .ic { font-size: 24px; }
.install-card .t { flex: 1 1 220px; display: flex; flex-direction: column; gap: 2px; }
.install-card .t b { font-size: 15px; }
.install-card .t small { font-size: 13px; color: var(--ink-soft); }
.install-card button { min-height: 44px; padding: 8px 16px; font-size: 14px; flex: none; }

/* 키 큰 세로 태블릿(갤럭시 탭 A8 · A9+ 세로 800×1280, 2026-10). 빈칸 리딩 글이 17.5px 로 위쪽 440px 에
   끝나고 «다 풀었어요» 까지 ≈550px 가 비었습니다. 남는 높이를 글자 크기로 씁니다 -- 책상에 세워 두고
   읽는 거리에서도 보이게. 문장 만들기 낱말 카드도 같은 까닭으로 크게. */
@media (orientation: portrait) and (min-width: 700px) and (min-height: 1000px) {
  .card.play #passage.cloze-passage { font-size: 21px; line-height: 2.45; }
  .card.play .cloze-slot { min-width: 96px; min-height: 44px; font-size: 20px; line-height: 1.5; padding: 4px 14px; }
  .card.play .cloze-word { min-height: 54px; font-size: 20px; padding: 12px 20px; }
  .card.play .sent-card { font-size: 21px; padding: 14px 20px; min-height: 56px; }
  .card.play .chunk-line { font-size: 24px; }
}

/* 단어 방을 펼쳤을 때만 보이는 «교재 단어 찾기» 한 줄(home.html). 홈의 접힌 방 · 넓은 화면의 세 단 방에서는 숨깁니다. */
.room-extra { display: none; }
.room.on .room-extra {
  display: flex; align-items: center; gap: 10px; margin-top: 12px; min-height: 52px; padding: 10px 16px;
  border-radius: 16px; background: rgba(255, 255, 255, .92); color: var(--ink); text-decoration: none; font-weight: 700; font-size: 16px;
  box-shadow: 0 3px 0 rgba(0, 0, 0, .10);
}
.room.on .room-extra span { margin-left: auto; font-size: 13px; font-weight: 500; color: var(--ink-soft); }
@media (max-width: 420px) { .room.on .room-extra span { display: none; } }

/* 새로 생긴 활동 타일의 «NEW» 표(home.html NEW_ACTS). 스티커판의 NEW 와 같은 모양. */
.tile.is-new { position: relative; }
.tile.is-new::before {
  content: "NEW"; position: absolute; top: -7px; right: -4px; z-index: 1;
  padding: 1px 7px; border-radius: 99px; background: var(--brand-btn); color: #fff;
  font-size: 12px; font-weight: 800; letter-spacing: .04em; line-height: 1.5;
}

/* 할로윈 파티 띠(home.html · 11월 8일까지) */
.hw-band {
  display: flex; align-items: center; gap: 14px; margin: 18px 0 4px; padding: 14px 18px; border-radius: 22px; text-decoration: none;
  background: linear-gradient(120deg, #2b1840, #5b2a86 60%, #c2560c); color: #fff4e3; box-shadow: 0 8px 22px rgba(43, 24, 64, .3);
}
.hw-band-ic { font-size: 42px; line-height: 1; }
.hw-band-t { flex: 1; min-width: 0; }
.hw-band-t b { display: block; font-size: 19px; }
.hw-band-t small { display: block; margin-top: 2px; font-size: 13.5px; opacity: .88; }
.hw-band-go { font-size: 22px; font-weight: 800; white-space: nowrap; }
/* 할로윈 팀전 참가 (로그인 화면 · 11월 8일까지) */
.hw-join { display: block; margin-top: 16px; padding: 12px 16px; border-radius: 16px; text-align: center; text-decoration: none; font-weight: 800; font-size: 17px;
  background: linear-gradient(120deg, #2b1840, #5b2a86 60%, #c2560c); color: #fff4e3; }
.hw-join small { display: block; font-weight: 500; font-size: 13px; opacity: .88; margin-top: 2px; }
.hw-band-team { margin-top: 8px; background: linear-gradient(120deg, #1d2b4a, #3a2a86 60%, #8b3fbf); }

/* 머리줄: 코드가 길면(20자까지 됩니다 -- «minjun2019abcdefghij») 이름표만 «…» 로 줄고, 단추는 꺾이지 않습니다 (2026-11-01).
   320px 폰에서 «나가기» 가 «나/가/기» 세로로 섰습니다. */
header.bar .who { min-width: 0; flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
header.bar button, header.bar a > button { white-space: nowrap; flex: none; }
header.bar > a:has(> button) { flex: none; }
/* 가로로 든 폰(높이 480 아래, 844×390 등): 가로 태블릿용 «카드를 화면 높이에 고정, 지문은 상자 안에서 굴림» 이
   여기서는 지문 상자를 100px(세 줄)로 만들었습니다(2026-11-03). 이 높이에서는 고정을 풀고 화면째 굴립니다
   (낱말 은행을 붙여 따라오게 하면 카드 아래 «다 풀었어요» 줄을 덮어서 그냥 둡니다 -- 굴릴 거리가 150px 남짓). */
@media (min-width: 760px) and (max-height: 480px) {
  .card.play.fill, .card.play.read { height: auto; overflow: visible; }
  .card.play.fill > .cloze-passage,
  .card.play.fill > .listen-bar:not(.hidden) ~ .cloze-passage { max-height: none; overflow: visible; }
  .card.play.fill > .cloze-bank { max-height: none; overflow: visible; }
  .card.play.read > .subcard, .card.play.read > #questions { max-height: none; overflow: visible; }
}
