
:root {
  /* ── 브랜드 색 (DESIGN_SYSTEM.md 승계) ── */
  --bg:          #f4ece0;
  --bg-soft:     #efe6d8;
  --bg-warm:     #e8dcc8;
  --surface:     #faf5ec;
  --surface-2:   #f6efe3;
  --ink:         #40342a;
  --ink-strong:  #33291f;
  --taupe:       #8a7a67;
  --taupe-soft:  #a3927d;
  --line:        #d9cbb6;
  --line-soft:   #e2d6c3;
  --accent:      #6b5844;
  --band:        #24190e;
  --on-band:     #f1e8d8;
  --on-band-soft: rgba(241,232,216,0.66);
  --on-band-faint: rgba(241,232,216,0.42);
  --on-band-line: rgba(241,232,216,0.2);
  --gold:        #d9bd8b;
  /* 저채도 인주색 — 브랜드가 이미 쓰는 유일한 경고색. 밝은 액센트는 금지다 */
  --seal:        #7d3f36;
  --seal-soft:   rgba(125,63,54,0.10);
  --seal-line:   rgba(125,63,54,0.28);

  /* ── 간격: 4px 그리드 ── */
  --s-0: 2px;  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px;
  --s-5: 20px; --s-6: 24px; --s-8: 32px; --s-10: 40px;
  --s-14: 56px; --s-18: 72px;

  /* ── 서체 ── */
  --sans:  "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont,
           "Apple SD Gothic Neo", system-ui, sans-serif;
  --serif: "Cormorant Garamond", Georgia, "Times New Roman", serif;

  --fs-overline: 11px;  --ls-overline: 0.28em;
  --fs-xs: 12px; --fs-sm: 13px; --fs-md: 15px;
  --fs-lg: 18px; --fs-xl: 24px; --fs-2xl: 34px;
  --lh-body: 1.7; --lh-tight: 1.35;

  /* ── 반경 ── */
  --r-sm: 4px; --r: 10px; --r-lg: 18px; --r-pill: 999px;

  /* ── 그림자: 낮은 채도, 큰 blur, 절제 ── */
  --shadow-sm: 0 1px 2px rgba(64,52,42,0.04);
  --shadow:    0 2px 10px rgba(64,52,42,0.055), 0 1px 2px rgba(64,52,42,0.03);
  --shadow-lift: 0 6px 22px rgba(64,52,42,0.09), 0 2px 6px rgba(64,52,42,0.04);

  /* ── 모션 ── */
  --t-fast: 160ms;
  --t:      260ms;
  --ease:   cubic-bezier(0.22, 0.61, 0.36, 1);
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--fs-md);
  line-height: var(--lh-body);
  letter-spacing: -0.01em;
  -webkit-font-smoothing: antialiased;
  /* 한글은 기본값(break-all에 준하는 동작)으로 두면 단어 한가운데서 잘린다.
     폰 폭에서 "메시지가 만들어/지지 않습니다"처럼 읽기가 끊긴다.
     띄어쓰기에서만 넘기고, 띄어쓰기 없는 아주 긴 토큰(코드·주소)만 예외로 자른다. */
  word-break: keep-all;
  overflow-wrap: break-word;
}

::selection { background: rgba(217,189,139,0.42); }

/* ═══ 여백의 단일 관리 지점 ═══════════════════════════
   컨테이너 직계 자식 사이에 항상 24px(모바일 20px).
   개별 컴포넌트는 자기 바깥 여백을 들지 않는다.            */
.stack > * + * { margin-top: var(--s-6); }
.stack-sm > * + * { margin-top: var(--s-4); }
.stack-xs > * + * { margin-top: var(--s-2); }

.wrap {
  max-width: 720px;
  margin-inline: auto;
  padding: var(--s-8) var(--s-6) var(--s-18);
}
/* 단일 폼 화면(로그인·제출)은 좁게 둔다. 입력이 가로로 늘어지면 읽기 나쁘다. */
.wrap-narrow { max-width: 480px; }
/* 목록 화면은 넓은 화면에서 넉넉하게. 모바일에서는 어차피 화면 폭이 한계다. */
.wrap-list { max-width: 680px; }

/* ═══ 상단 밴드 — 페이지의 무게중심 ═══════════════════ */
.band {
  background: linear-gradient(180deg, #2c2015 0%, var(--band) 55%, #1c1308 100%);
  color: var(--on-band);
}
.band-in {
  max-width: 720px;
  margin-inline: auto;
  /* 폰 상태바 아래에 바짝 붙지 않도록 safe-area를 더한다 */
  padding: calc(var(--s-8) + env(safe-area-inset-top, 0px)) var(--s-6) var(--s-8);
}
.band-in.narrow { max-width: 480px; }
.band-in.list { max-width: 680px; }

/* ═══ 관리자 미리보기 띠 ═══════════════════════════════
   학생 화면 위에 얹히는 시스템 띠다. 학생에게는 렌더 자체가 되지 않는다.
   밴드와 같은 헤더 안에 살지만 색을 완전히 달리해 "지금 남의 화면을 보는 중"이
   한눈에 읽히게 한다. 브랜드가 쓰는 유일한 경고색(인주)을 쓴다. */
.preview {
  background: var(--seal);
  color: rgba(255, 248, 242, 0.94);
}
.preview-in {
  max-width: 720px;
  margin-inline: auto;
  /* 폰 상태바를 여기서 피한다. 아래 .band-in은 그만큼 덜 준다 */
  padding: calc(var(--s-3) + env(safe-area-inset-top, 0px)) var(--s-6) var(--s-3);
  display: flex;
  align-items: center;
  gap: var(--s-4);
  flex-wrap: wrap;
}
.preview-in.narrow { max-width: 480px; }
.preview-in.list { max-width: 680px; }
/* 띠가 위에 붙으면 밴드는 safe-area를 두 번 계산하지 않는다.
   띠 텍스트와 밴드 첫 줄 사이가 12 + 32 = 44px로 벌어진다. */
.preview + .band-in { padding-top: var(--s-8); }
.preview-tag {
  flex: none;
  padding: var(--s-1) var(--s-2);
  border-radius: var(--r-sm);
  background: rgba(255, 255, 255, 0.18);
  font-size: var(--fs-xs);
  font-weight: 600;
  line-height: 1.5;
}
.preview-who {
  flex: 1 1 12ch;
  min-width: 12ch;
  font-size: var(--fs-xs);
  line-height: 1.5;
  color: rgba(255, 248, 242, 0.82);
}
.preview form { flex: none; }
.preview .btn {
  border-color: rgba(255, 248, 242, 0.5);
  color: rgba(255, 248, 242, 0.96);
}
.preview .btn:hover {
  background: rgba(255, 255, 255, 0.16);
  border-color: rgba(255, 248, 242, 0.9);
  color: #fff;
}
.band-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  padding-bottom: var(--s-5);
  border-bottom: 1px solid var(--on-band-line);
}
.wordmark {
  font-family: var(--serif);
  font-size: var(--fs-lg);
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--on-band);
}
.band nav { display: flex; gap: var(--s-5); }
.band nav a {
  position: relative;
  color: var(--on-band-soft);
  text-decoration: none;
  font-size: var(--fs-sm);
  transition: color var(--t-fast) var(--ease);
}
/* 글자 높이는 22px뿐이라 폰에서 손가락으로 정확히 누르기 어려웠다.
   보이는 크기·밴드 높이는 그대로 두고 **누를 수 있는 면적만** 44px로 넓힌다.
   탭 사이 간격이 20px이라 좌우 8px씩 넓혀도 옆 탭과 겹치지 않는다. */
.band nav a::after {
  content: "";
  position: absolute;
  inset: -11px -8px;
}
.band nav a:hover { color: var(--on-band); }
.band nav a[aria-current="page"] { color: var(--gold); }

/* 히어로 높이를 페이지마다 고정한다.
   슬롯이 비어도 자리를 지켜야 탭을 옮길 때 제목·설명이 움찔거리지 않는다. */
/* 라벨 22 + 여백 12 + 제목 42.5 + 여백 12 + 설명 22 + 위 여백 24.
   설명이 없는 화면(학생·로그인)은 그만큼 낮아진다. 탭이 하나뿐이라 움찔할 일이 없다. */
.band-body {
  padding-top: var(--s-6);
  min-height: 135px;
}
.band-body:not(:has(.band-note)) { min-height: 101px; }
/* 영문 라벨 전용. 넓은 자간은 라틴 글자에서만 성립한다 — 한글에 쓰면 낱자가 흩어진다.
   line-height를 22px로 고정해 한글 라벨(.band-date)과 같은 높이를 차지하게 한다.
   서체가 다르면 높이가 달라지고, 그만큼 아래 제목이 밀린다. */
.overline {
  display: block;
  min-height: 22px;
  font-family: var(--serif);
  font-size: var(--fs-overline);
  line-height: 22px;
  letter-spacing: var(--ls-overline);
  text-transform: uppercase;
  color: var(--on-band-faint);
}
.band-date {
  display: block;
  min-height: 22px;
  font-size: var(--fs-sm);
  line-height: 22px;
  letter-spacing: -0.01em;
  color: var(--on-band-faint);
}
.band-headline {
  margin: var(--s-3) 0 0;
  font-size: var(--fs-2xl);
  font-weight: 600;
  /* line box를 글자 크기에 고정한다.
     비율(1.25)로 두면 <em>(1.22배 숫자)이 line box를 키우고,
     그만큼 baseline이 내려가 한글이 5px 아래에 그려진다.
     px로 고정하면 em이 그 안에서만 커진다. */
  line-height: calc(var(--fs-2xl) * 1.25);
  min-height: calc(var(--fs-2xl) * 1.25);
  letter-spacing: -0.025em;
  color: var(--on-band);
}
.band-headline em {
  font-style: normal;
  font-family: var(--serif);
  /* line box에 전혀 기여하지 않게 한다.
     line-height를 부모와 같게 맞춰도 Cormorant와 Pretendard의
     ascent/descent가 달라 한글 baseline이 1px 어긋난다. */
  line-height: 0;
  font-variant-numeric: lining-nums;
  color: var(--gold);
  font-size: 1.22em;
  font-weight: 500;
  letter-spacing: 0;
  margin-inline: 3px;
}
.band-note {
  margin: var(--s-3) 0 0;
  min-height: 22px;
  color: var(--on-band-soft);
  font-size: var(--fs-sm);
  line-height: 22px;
}

/* ═══ 제목 ═══════════════════════════════════════════ */
h1, h2, h3 { margin: 0; letter-spacing: -0.02em; color: var(--ink-strong); }
h1 { font-size: var(--fs-xl); font-weight: 600; }
h2 { font-size: var(--fs-lg); font-weight: 600; }
h3 { font-size: var(--fs-md); font-weight: 600; letter-spacing: -0.01em; }
/* 제목과 바로 아래 설명은 붙여야 하는 쌍 — 예외로 좁힌다 */
h1 + .sub, h2 + .sub, h3 + .sub { margin-top: var(--s-2); }
.sub { margin: 0; color: var(--taupe); font-size: var(--fs-sm); }
.eyebrow {
  font-family: var(--serif);
  font-size: var(--fs-overline);
  letter-spacing: var(--ls-overline);
  text-transform: uppercase;
  color: var(--taupe-soft);
  display: block;
}
/* eyebrow와 바로 아래 제목은 붙여야 하는 쌍 — 컨테이너 기본 간격을 좁힌다 */
.card > .eyebrow + * { margin-top: var(--s-2); }

/* ═══ 카드 ═══════════════════════════════════════════ */
.card {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-lg);
  padding: var(--s-6);
  box-shadow: var(--shadow-sm);
}
.card > * + * { margin-top: var(--s-5); }
/* .row·.msg-item은 자체 padding과 구분선으로 이미 간격을 만든다.
   컨테이너 마진까지 더하면 44px가 되어 목록이 흩어진다. */
.card > .row + .row,
.card > .msg-item + .msg-item { margin-top: 0; }
.card-quiet { background: transparent; box-shadow: none; border-color: var(--line-soft); }

/* ═══ 판단 카드 — 이 앱의 시그니처 ═════════════════════ */
.judge {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--s-5) var(--s-6) var(--s-6);
  box-shadow: var(--shadow);
}
/* 처음 열 때만 솟아오른다. 탭을 옮길 때마다 재생되면 산만하다. */
body:not([data-swapped]) .judge { animation: rise var(--t) var(--ease) both; }
.judge + .judge { margin-top: var(--s-6); }
.judge-head { display: flex; align-items: baseline; gap: var(--s-3); flex-wrap: wrap; }
.judge-name {
  font-size: var(--fs-lg);
  font-weight: 600;
  color: var(--ink-strong);
  letter-spacing: -0.02em;
}
.judge-meta { margin-top: var(--s-2); color: var(--taupe); font-size: var(--fs-sm); }
.judge-flag {
  margin-top: var(--s-3);
  padding: var(--s-2) var(--s-3);
  background: var(--seal-soft);
  box-shadow: inset 2px 0 0 var(--seal-line);
  border-radius: var(--r-sm);
  color: var(--seal);
  font-size: var(--fs-sm);
}
/* 실제로 자주 누르는 두 행동만 나란히 둔다.
   '사정 있음'은 드물어서 같은 크기로 놓으면 판단을 흐린다. */
.judge-acts {
  margin-top: var(--s-5);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-3);
}
.judge-acts form { display: contents; }
.judge-aside {
  margin-top: var(--s-3);
  display: flex;
  justify-content: center;
}

@keyframes rise {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
.judge:nth-child(1) { animation-delay: 0ms; }
.judge:nth-child(2) { animation-delay: 45ms; }
.judge:nth-child(3) { animation-delay: 90ms; }
.judge:nth-child(4) { animation-delay: 135ms; }
.judge:nth-child(n+5) { animation-delay: 180ms; }

/* ═══ 학생 화면 ══════════════════════════════════════
   항목이 가진 정보는 제목·마감·행동 셋뿐이다. 카드로 감싸면
   폰에서 높이의 3분의 2가 여백이 된다(측정값 33%).
   그룹 하나를 면 하나로 두고, 항목은 행으로 놓는다. */

/* 그룹 라벨 — 사이클 경계를 알린다. 선 없이 라벨만으로 나눈다.
   margin을 직접 두지 않는다. 컨테이너 규칙(.stack > * + *)과 명시도가 같아
   나중에 선언된 쪽이 이기고, 그러면 앞 면과 붙어 버린다. */
.group-label {
  margin-bottom: 0;
  color: var(--taupe-soft);
  font-size: var(--fs-xs);
  font-weight: 550;
  letter-spacing: -0.01em;
}
.stack > .group-label { margin-top: var(--s-8); }
.stack > .group-label:first-child { margin-top: 0; }
.stack > .group-label + * { margin-top: var(--s-4); }

/* 그룹 면 — 안쪽 여백을 항목마다 물지 않고 여기서 한 번만 낸다 */
.tasks {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 0 var(--s-5);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.tasks-quiet { background: transparent; box-shadow: none; border-color: var(--line-soft); }

/* 항목 행 — 행 전체가 탭 영역이다.
   행동이 하나뿐이면 버튼을 따로 둘 이유가 없다. 48px이 통째로 절약된다.
   높이 56px은 터치 타겟 권장치(44px)를 넘는다. */
.task {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-4) 0;
  min-height: 56px;
  border-bottom: 1px solid var(--line-soft);
  color: inherit;
  text-decoration: none;
  transition: background var(--t-fast) var(--ease);
}
.task:last-child { border-bottom: 0; }
a.task { margin-inline: calc(var(--s-5) * -1); padding-inline: var(--s-5); }
a.task:hover { background: var(--surface-2); }
a.task:active { background: var(--bg-warm); }

.task-title {
  flex: 1;
  min-width: 0;
  font-size: var(--fs-md);
  font-weight: 550;
  letter-spacing: -0.01em;
  color: var(--ink-strong);
}
.task-when {
  flex-shrink: 0;
  color: var(--taupe);
  font-size: var(--fs-sm);
}
.task-retake .task-when { color: var(--seal); }
.task-done .task-title { color: var(--taupe); font-weight: 400; }

/* 눌러서 들어갈 수 있다는 유일한 신호 */
a.task::after {
  content: "";
  flex-shrink: 0;
  width: 6px; height: 6px;
  border-right: 1.5px solid var(--taupe-soft);
  border-top: 1.5px solid var(--taupe-soft);
  transform: rotate(45deg);
  transition: transform var(--t-fast) var(--ease),
              border-color var(--t-fast) var(--ease);
}
a.task:hover::after { border-color: var(--accent); transform: rotate(45deg) translate(2px, -2px); }

/* 접기 — 자바스크립트 없이 <details>로 */
.fold {
  border: 1px solid var(--line-soft);
  border-radius: var(--r-lg);
  background: transparent;
}
.fold > summary {
  padding: var(--s-4) var(--s-5);
  color: var(--taupe);
  font-size: var(--fs-sm);
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-radius: var(--r-lg);
  transition: color var(--t-fast) var(--ease);
}
.fold > summary::-webkit-details-marker { display: none; }
.fold > summary::after {
  content: "";
  width: 7px; height: 7px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--t-fast) var(--ease);
}
.fold[open] > summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.fold > summary:hover { color: var(--ink); }
.fold-body { padding: 0 var(--s-5) var(--s-2); }

/* ═══ 목록 행 ════════════════════════════════════════ */
.row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-4);
  padding: var(--s-3) 0;          /* 행 상하 12px 이상 */
  border-bottom: 1px solid var(--line-soft);
}
.row:last-child { border-bottom: 0; padding-bottom: 0; }
.row:first-child { padding-top: 0; }
.row-main { min-width: 0; }
.row-main > * + * { margin-top: var(--s-1); }
.row-side { flex-shrink: 0; display: flex; gap: var(--s-2); align-items: center; }
.row-title { font-weight: 550; color: var(--ink-strong); }
.row a.row-title { color: inherit; text-decoration: none; }
.row a.row-title:hover { color: var(--accent); }

/* ═══ 폼 ═════════════════════════════════════════════ */
label { display: block; font-size: var(--fs-sm); font-weight: 550; color: var(--ink); }
label + input, label + select, label + textarea { margin-top: var(--s-2); }
input, select, textarea, button { font: inherit; color: inherit; }
input[type=text], input[type=password], input[type=number],
input[type=date], input[type=datetime-local], input[type=file], select, textarea {
  width: 100%;
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  transition: border-color var(--t-fast) var(--ease),
              box-shadow var(--t-fast) var(--ease);
}
input:hover, select:hover { border-color: var(--taupe-soft); }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(107,88,68,0.12);
}
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
fieldset { border: 0; padding: 0; margin: 0; }
fieldset > * + * { margin-top: var(--s-5); }
.field-note { margin: var(--s-2) 0 0; color: var(--taupe-soft); font-size: var(--fs-xs); }

/* 태그. 기본과 다른 학생에게만 붙는다 — 전부 붙이면 아무것도 구별되지 않는다 */
.chip {
  display: inline-block;
  margin-left: var(--s-2);
  padding: 2px var(--s-2);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--bg-soft);
  color: var(--taupe);
  font-size: var(--fs-xs);
  line-height: 1.6;
  vertical-align: 2px;
}

/* 라디오·체크 묶음의 제목. 대상이 여럿이라 label을 못 쓴다 */
.field-label { display: block; font-size: var(--fs-sm); font-weight: 550; color: var(--ink); }
.field-label + .picks, .field-label + .check-grid { margin-top: var(--s-2); }
.picks + .check-grid { margin-top: var(--s-3); }

/* 설명이 딸린 선택지. .check과 같은 상자를 쓰되 위를 맞춘다 */
.picks { display: grid; gap: var(--s-2); }
/* 짧은 선택지 셋은 가로로. 세로로 쌓으면 화면만 길어진다 */
.picks-row { grid-template-columns: repeat(3, 1fr); }
.picks-row .pick { align-items: center; }
.picks-row .pick input { margin-top: 0; }
@media (max-width: 480px) { .picks-row { grid-template-columns: 1fr; } }
/* 학원 이름 칸은 선택지 바로 아래 붙는다 */
.picks + [data-org] { margin-top: var(--s-4); }
.pick { align-items: flex-start; }
.pick input { margin-top: 3px; }
.pick-title { display: block; font-weight: 550; }
.pick .tiny { display: block; margin-top: var(--s-0); }
.pick-off { opacity: 0.4; cursor: not-allowed; }

.check {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--line-soft);
  border-radius: var(--r);
  background: var(--surface);
  font-weight: 400;
  cursor: pointer;
  transition: border-color var(--t-fast) var(--ease),
              background var(--t-fast) var(--ease);
}
.check:hover { border-color: var(--taupe-soft); }
.check:has(input:checked) { border-color: var(--accent); background: var(--surface-2); }
.check input { width: auto; margin: 0; accent-color: var(--accent); }
.check-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-2); }

/* 요일 선택 — 7칸이 항상 같은 폭이라 눈이 자리를 기억한다 */
.days { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--s-2); margin-top: var(--s-2); }
.day {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s-3) 0;
  border: 1px solid var(--line-soft);
  border-radius: var(--r);
  background: var(--surface);
  font-size: var(--fs-sm);
  color: var(--taupe);
  cursor: pointer;
  transition: border-color var(--t-fast) var(--ease),
              background var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease);
}
.day input { position: absolute; opacity: 0; width: 0; height: 0; }
.day:hover { border-color: var(--taupe-soft); }
.day:has(input:checked) {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--surface);
  font-weight: 550;
}
.day:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }

.move-form input[type=date] { width: 100%; }

/* ═══ 버튼 ═══════════════════════════════════════════ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-5);
  border: 1px solid var(--accent);
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--accent);
  font-size: var(--fs-sm);
  font-weight: 550;
  letter-spacing: -0.01em;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease),
              border-color var(--t-fast) var(--ease),
              transform var(--t-fast) var(--ease);
}
.btn:hover { background: var(--accent); color: var(--surface); }
.btn:active { transform: translateY(1px); }
.btn-solid { background: var(--accent); color: var(--surface); }
.btn-solid:hover { background: var(--ink-strong); border-color: var(--ink-strong); }
.btn-quiet { border-color: var(--line); color: var(--taupe); }
.btn-quiet:hover { border-color: var(--accent); background: transparent; color: var(--accent); }
.btn-faint { border-color: transparent; color: var(--taupe-soft); }
.btn-faint:hover { border-color: var(--line); background: transparent; color: var(--taupe); }
.btn-seal { border-color: var(--seal-line); color: var(--seal); }
.btn-seal:hover { background: var(--seal); border-color: var(--seal); color: var(--surface); }
.btn-sm { padding: var(--s-2) var(--s-4); font-size: var(--fs-xs); }
.btn-block { width: 100%; }
.btn[disabled] {
  background: transparent;
  border-color: var(--line);
  color: var(--taupe-soft);
  pointer-events: none;
}

/* ═══ 배지 ═══════════════════════════════════════════ */
.badge {
  display: inline-flex;
  align-items: center;
  padding: var(--s-0) var(--s-2);
  border-radius: var(--r-sm);
  font-size: var(--fs-xs);
  font-weight: 550;
  letter-spacing: -0.01em;
  background: var(--bg-warm);
  color: var(--taupe);
}
.badge-done { background: rgba(107,88,68,0.10); color: var(--accent); }
.badge-seal { background: var(--seal-soft); color: var(--seal); }
.badge-gold { background: rgba(217,189,139,0.28); color: #8a6a2c; }

/* ═══ 알림 ═══════════════════════════════════════════ */
/* 배경(--bg)과 표면(--surface-2)의 차가 작아 면이 사라지고 강조선만 떠 보였다.
   표면을 올리고 테두리를 줘서 하나의 박스로 읽히게 한다.
   강조선은 border-left 대신 inset 그림자 — 둥근 모서리를 따라 잘린다. */
.note {
  padding: var(--s-4) var(--s-5);
  border: 1px solid var(--line-soft);
  border-radius: var(--r);
  font-size: var(--fs-sm);
  background: var(--surface);
  box-shadow: inset 3px 0 0 var(--accent);
  color: var(--ink);
}
.note-seal {
  background: var(--surface);
  border-color: var(--seal-line);
  box-shadow: inset 3px 0 0 var(--seal);
  color: var(--seal);
}
.note strong { color: var(--ink-strong); }
.note-seal strong { color: var(--seal); }

/* ═══ 보조 ═══════════════════════════════════════════ */
.muted { color: var(--taupe); font-size: var(--fs-sm); }
.tiny  { color: var(--taupe-soft); font-size: var(--fs-xs); }
.num   { font-family: var(--serif); font-variant-numeric: lining-nums;
         font-size: 1.15em; font-weight: 500; letter-spacing: 0; }

/* 카드 안에서는 조밀하게. 페이지 전체가 비었을 때만 .empty-page로 키운다. */
.empty {
  padding: var(--s-6) var(--s-4);
  text-align: center;
  color: var(--taupe-soft);
  font-size: var(--fs-sm);
}
.empty-page { padding: var(--s-14) var(--s-4); }
.empty strong {
  display: block;
  margin-bottom: var(--s-2);
  font-size: var(--fs-md);
  font-weight: 550;
  color: var(--taupe);
}

/* 메시지 항목: 읽는 것이 먼저, 누르는 것이 나중.
   가로로 나누면 본문 폭이 눌려 읽기 어려워진다. */
.msg-item { padding: var(--s-5) 0; border-bottom: 1px solid var(--line-soft); }
.msg-item:last-child { border-bottom: 0; padding-bottom: 0; }
.msg-item:first-child { padding-top: 0; }
.msg-head { display: flex; align-items: baseline; gap: var(--s-2); flex-wrap: wrap; }
.msg {
  margin-top: var(--s-3);
  padding: var(--s-4);
  background: var(--bg-soft);
  border-radius: var(--r);
  color: var(--ink);
  font-size: var(--fs-sm);
  line-height: 1.65;
  white-space: pre-wrap;
}
.msg-acts { margin-top: var(--s-3); display: flex; gap: var(--s-2); justify-content: flex-end; }

.split { display: flex; gap: var(--s-4); align-items: flex-start; justify-content: space-between; }
.split > :first-child { min-width: 0; }

/* 본문 안의 평범한 링크.
   규칙이 없어 브라우저 기본값(파란 밑줄)이 그대로 나왔다. 브랜드색과 어긋나
   "덜 만든 화면"으로 읽힌다. 버튼·항목·행 제목은 각자 규칙이 있으므로 제외한다. */
main a:not(.btn):not(.task):not(.row-title):not(.chip) {
  color: var(--accent);
  font-weight: 550;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: var(--line);
  transition: color var(--t-fast) var(--ease),
              text-decoration-color var(--t-fast) var(--ease);
}
main a:not(.btn):not(.task):not(.row-title):not(.chip):hover {
  color: var(--ink-strong);
  text-decoration-color: var(--accent);
}
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-4); }

.foot {
  margin-top: var(--s-10);
  padding-top: var(--s-5);
  border-top: 1px solid var(--line-soft);
  color: var(--taupe-soft);
  font-size: var(--fs-xs);
}

/* ═══ 반응형 ═════════════════════════════════════════ */
@media (max-width: 560px) {
  .stack > * + * { margin-top: var(--s-5); }   /* 모바일 최소 20px */
  .wrap { padding: var(--s-6) var(--s-5) var(--s-14); }
  .band-in {
    padding: calc(var(--s-6) + env(safe-area-inset-top, 0px)) var(--s-5) var(--s-6);
  }
  .card, .judge { padding: var(--s-5); }
  .grid-2, .check-grid { grid-template-columns: 1fr; }
  .judge-acts { grid-template-columns: 1fr; gap: var(--s-2); }
  .row { flex-direction: column; align-items: stretch; gap: var(--s-3); }
  .row-side { flex-wrap: wrap; }
  :root { --fs-2xl: 27px; --fs-xl: 21px; }
  .band-body { min-height: 126px; }
  .band-body:not(:has(.band-note)) { min-height: 92px; }

  /* 제목·설명과 버튼을 가로로 두면 폰에서 글이 버튼에 밀려 좁은 기둥이 된다.
     세로로 쌓아 글은 폭을 다 쓰고 버튼은 아래에 둔다. */
  .split { flex-direction: column; align-items: stretch; }
  .split .btn { align-self: flex-start; }

  /* 미리보기 띠 — 한 줄에 셋을 욱여넣으면 가운데 설명이 뭉개진다.
     1행 [표시][돌아가기] · 2행 설명 으로 나눈다. */
  .preview-in {
    padding: calc(var(--s-3) + env(safe-area-inset-top, 0px)) var(--s-5) var(--s-3);
    gap: var(--s-3);
  }
  .preview-tag { order: 1; }
  .preview form { order: 2; margin-left: auto; }
  .preview-who { order: 3; flex: 1 0 100%; }
}

/* 화면을 불러오는 동안의 진행 표시.
   0.2초 안에 끝나면 나타나지 않는다 — 순간적인 깜빡임이 더 산만하다.
   느린 회선에서 "눌렸는지 모르겠는" 상태를 없애는 것이 목적이다. */
.loading-bar {
  position: fixed;
  inset: 0 auto auto 0;
  height: 2px;
  width: 0;
  background: var(--gold);
  opacity: 0;
  z-index: 90;
  pointer-events: none;
  transition: width 0.4s var(--ease), opacity 0.2s var(--ease);
}
.loading-bar.on { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .loading-bar { transition: none; }
}

/* 부분 교체 시 부드러운 페이드. 미지원 브라우저는 그냥 즉시 바뀐다. */
::view-transition-old(root), ::view-transition-new(root) {
  animation-duration: 170ms;
  animation-timing-function: var(--ease);
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
