/*
 * People — site-bookshelf 의 결을 그대로 따른다.
 *
 * 규칙 셋이 전부다.
 *   1. 선을 쓰지 않는다. 계층은 표면 밝기와 여백으로만 만든다.
 *   2. 만지는 것에만 표면을 준다. 읽기만 하는 것은 바닥 위에 놓인다.
 *      (이름 카드는 누르는 것이라 표면을 갖는다.)
 *   3. 떠 있는 버튼을 누르면 아래에서 시트가 올라온다. 예외 없다.
 */

:root {
  /*
   * 밝은 화면이다. bookshelf 는 어둡지만 여기는 종이 위에 적는 쪽이 맞다 —
   * 사람에 대한 메모는 밤에 읽는 서가보다 낮에 잠깐 들춰 보는 수첩에 가깝다.
   *
   * 브라우저에게도 밝음을 알린다. 이걸 빼면 기기가 다크 모드일 때 브라우저가
   * 그리는 기본 UI — date 입력의 달력 아이콘, 스크롤바 — 가 어두운 배경용으로
   * 나와서 혼자 튄다.
   */
  color-scheme: light;

  /*
   * 표면 셋. 어두운 화면에서는 위로 올라올수록 밝았지만, 종이 위에서는
   * 만지는 것이 한 겹 눌려(더 짙게) 보이고 떠 있는 것(시트)이 가장 희다.
   */
  --bg: #faf8f4;        /* 종이. 순백이 아니라 시트가 그 위에 뜰 자리를 남긴다 */
  --surface: #eeeae3;   /* 만지는 것: 입력·버튼·떠 있는 버튼·카드 */
  --raised: #ffffff;    /* 떠 있는 것: 시트. 입력에 포커스가 가면 이 색이 된다 */
  --hover: #e4dfd6;     /* 만지는 것 위에 손이 올라간 때. 밝은 화면에서는 짙어지는 쪽이 눌림이다 */

  --text: #23201b;
  --text-dim: #6c6458;  /* 카드(surface) 위에서도 4.5:1 을 넘기는 가장 흐린 값 */

  /*
   * 주 버튼은 잉크색이다. 종이 위에 만년필로 적는 색 — 금색은 어두운 서가에서
   * 빛나는 색이었고 밝은 종이 위에서는 바래 보인다. 흰 글자와 9:1.
   */
  --accent: #2e4a6e;    /* 주 버튼에만. 장식으로 쓰지 않는다 */
  --accent-hover: #233b59;
  --on-accent: #ffffff; /* 잉크 위의 글자 */
  --warn: #96591f;      /* 흰 바탕에서 읽히려면 어두운 쪽 호박색이어야 한다 */
  --danger: #b0503f;    /* 되돌릴 수 없는 것에만. 채도를 낮춰 경고음이 되지 않게 한다 */
  --shift: #dde4ea;     /* 날짜 바꾸기. 잉크와 같은 결의 옅은 쪽 — 같은 계열이라 겨루지 않는다 */
  --shift-hover: #cad5dc;
  --scrim: rgba(35, 30, 22, 0.28);   /* 시트 뒤를 가리는 막. 짙으면 종이가 꺼진 것처럼 보인다 */

  --radius: 12px;
  --pill: 999px;
  /*
   * 폭이 둘이다.
   *   --app   읽고 쓰는 것: 사람 화면·시트. 기준은 줄당 자 수다 — 본문 0.94rem
   *           에서 560px 이 약 35자다. 넓히더라도 갈 수 있는 데가 정해져 있다.
   *           취향이 아니라 구조다: 45자면 713px 인데, 그것은 첫 화면이 760px 구간에서 갖는
   *           700px 과 사실상 같은 수다. 거기까지 가면 폭이 둘이 아니게 된다.
   *   --shelf 훑는 것: 첫 화면. 넓은 기기에서는 한 줄에 더 담는 편이 낫다
   */
  --app: 560px;
  --shelf: 480px;
  --tap: 46px;
  --ease: 170ms cubic-bezier(0.2, 0.7, 0.3, 1);
}

* { box-sizing: border-box; }

/* hidden 속성은 UA 스타일인데 작성자가 선언한 display 가 그것을 이긴다.
   개별 규칙마다 막지 말고 여기서 한 번에 이긴다. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Apple SD Gothic Neo',
               'Noto Sans KR', 'Malgun Gothic', sans-serif;
  font-size: 16px;
  line-height: 1.6;
  -webkit-text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; border: none; background: none; cursor: pointer; }

/* 키보드로 옮겨 다닐 때만 윤곽이 나온다 */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* 넓은 화면에서도 레이아웃을 가르지 않는다. 폰에서 만든 것을 가운데 세운다. */
.wrap { width: 100%; margin: 0 auto; padding: 0 18px; }

.screen { display: none; }
.screen.is-active { display: block; }

/* ── 글자 ─────────────────────────────────────────────────── */

.t-title { font-size: 1.05rem; font-weight: 600; line-height: 1.35; }
.t-body  { font-size: 0.94rem; }
.t-sub   { font-size: 0.78rem; color: var(--text-dim); }

/* ── 폼 ───────────────────────────────────────────────────── */

.input, .textarea, select {
  width: 100%;
  min-height: var(--tap);
  padding: 11px 13px;
  background: var(--surface);
  border: none;
  border-radius: var(--radius);
  color: var(--text);
  font-size: 1rem;
  font-family: inherit;
  transition: background var(--ease);
}

.input::placeholder, .textarea::placeholder { color: var(--text-dim); opacity: 1; }

/* 브라우저가 그리는 지우기 버튼은 밝은 배경을 가정해 파랗게 나온다 — 직접 그린다 */
input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
  width: 20px;
  height: 20px;
  cursor: pointer;
  background-color: var(--text-dim);
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M6 6l12 12M18 6L6 18' stroke='black' stroke-width='2.4' stroke-linecap='round' fill='none'/></svg>") center / 13px no-repeat;
  mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M6 6l12 12M18 6L6 18' stroke='black' stroke-width='2.4' stroke-linecap='round' fill='none'/></svg>") center / 13px no-repeat;
}

/* 한 줄에 입력과 버튼이 나란히 서는 곳. input 의 width:100% 가 버튼을 눌러
   글자를 세로로 접어버리므로 여기서 몫을 다시 나눈다. */
.row { display: flex; gap: 8px; align-items: center; }
.row .input { flex: 1; min-width: 0; }
.row .btn { flex: none; }

/* 포커스도 선이 아니라 표면이 희어지는 것으로 알린다 — 쓰는 칸이 종이에서 떠오른다 */
.input:focus, .textarea:focus, select:focus { outline: none; background: var(--raised); }

.textarea { min-height: 110px; resize: vertical; line-height: 1.6; }

.btn {
  min-height: var(--tap);
  padding: 11px 18px;
  border-radius: var(--radius);
  background: var(--surface);
  font-size: 0.95rem;
  white-space: nowrap;
  transition: background var(--ease), transform var(--ease);
}

.btn:hover { background: var(--hover); }
.btn:active { transform: scale(0.985); }
.btn-primary { background: var(--accent); color: var(--on-accent); font-weight: 600; }
.btn-primary:hover { background: var(--accent-hover); }
.btn-quiet { background: none; color: var(--text-dim); }
.btn-quiet:hover { background: var(--surface); }
/* 되돌릴 수 없는 것. 표면은 그대로 두고 글자만 물러선 붉은색이다 —
   잉크색을 주면 "이걸 누르면 된다" 가 되고, 채운 붉은색은 경고음이 된다 */
.btn-danger { color: var(--danger); }
.btn:disabled { opacity: 0.45; cursor: default; transform: none; }

.chip {
  min-height: 40px;
  padding: 7px 16px;
  border-radius: var(--pill);
  background: var(--surface);
  color: var(--text-dim);
  font-size: 0.85rem;
  transition: background var(--ease), color var(--ease);
}

.chip:hover { background: var(--hover); }
.chip.is-active { background: var(--accent); color: var(--on-accent); }

/* ── 첫 화면: 제목 ────────────────────────────────────────── */

/*
 * 여백이 첫인상이다. flex:1 로 화면을 차지하되 스크롤하면 그냥 위로 사라진다
 * — 고정하지 않는다. musings 와 같은 자리에 있다.
 */
#screen-home.is-active { display: flex; flex-direction: column; min-height: 100vh; }

.intro {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 58vh;
  padding: max(2rem, env(safe-area-inset-top)) 18px 2.5rem;
  width: 100%;
  max-width: var(--shelf);
  margin: 0 auto;
}

.intro h1 {
  margin: 0 0 0.6rem;
  font-size: 2rem;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.intro-links { display: flex; gap: 16px; }
.intro-links button { padding: 0; font-size: 0.82rem; color: var(--text-dim); }
.intro-links button:hover { color: var(--text); }

/* ── 구역 · 이름 카드 ─────────────────────────────────────── */

.group, .bdays { margin-bottom: 34px; }

.group-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 12px;
}

.group-name { font-size: 0.86rem; font-weight: 600; }
.group-count { font-size: 0.78rem; color: var(--text-dim); }

/*
 * 이름 카드. 얼굴도 동그라미도 없이 이름만 선다 — 사진을 쓰지 않기로 했고,
 * 색 동그라미는 이름을 한 번 더 말할 뿐이다.
 *
 * 균등 격자다. 책장은 칸막이와 표지를 한 줄에 섞어야 해서 흐름 배치였지만
 * 여기에는 섞을 것이 없다. auto-fill 이라 칸 크기는 그대로고 열만 늘어난다.
 */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(136px, 1fr));
  gap: 10px;
}

.card {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  min-height: 62px;
  padding: 10px 13px;
  border-radius: var(--radius);
  background: var(--surface);
  transition: background var(--ease);
  /* 꾹 누를 때 텍스트 선택이나 기본 메뉴가 끼어들지 않게 */
  -webkit-touch-callout: none;
  user-select: none;
  -webkit-user-select: none;
}

.card:hover { background: var(--hover); }

.card-name {
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 소개는 한 줄만. 카드 높이가 사람마다 달라지면 격자가 출렁인다 */
.card-intro {
  font-size: 0.74rem;
  line-height: 1.35;
  color: var(--text-dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/*
 * 이번 주 생일. 알림이 아니라 지나가며 보는 줄이라 색을 쓰지 않는다 —
 * 잉크색은 주 버튼의 것이고, 붉은 기는 경고로 읽힌다.
 */
.bday-list { display: flex; flex-wrap: wrap; gap: 8px; }

.bday {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  min-height: 40px;
  padding: 8px 16px;
  border-radius: var(--pill);
  background: var(--surface);
  transition: background var(--ease);
}

.bday:hover { background: var(--hover); }
.bday-name { font-size: 0.88rem; font-weight: 600; }
.bday-when { font-size: 0.76rem; color: var(--text-dim); }

.groups { max-width: var(--shelf); padding-bottom: 150px; }

.empty { padding: 40px 0; color: var(--text-dim); font-size: 0.9rem; text-align: center; }

/* ── 떠 있는 버튼 ─────────────────────────────────────────── */

/*
 * 늘 우하단 세로 스택. 색을 쓰지 않는다 — 이것들은 진입점이지
 * 확정 행동이 아니다. 진짜 주 버튼은 시트 안에 있다.
 */
.fabs {
  position: fixed;
  bottom: calc(20px + env(safe-area-inset-bottom));
  z-index: 30;
  display: flex;
  flex-direction: column;
  gap: 12px;
  /*
   * 첫 화면 폭에 맞춰 세운다. 사람 화면에서도 같은 자리에 둔다 —
   * 화면을 옮길 때마다 버튼이 가로로 튀면 손이 자리를 다시 찾아야 한다.
   * 떠 있는 것이라 콘텐츠 경계에 꼭 붙을 이유도 없다.
   */
  right: max(18px, calc(50vw - var(--shelf) / 2 + 18px));
}

.fab {
  position: relative;
  width: 52px;
  height: 52px;
  display: grid;
  place-items: center;
  border-radius: var(--pill);
  background: var(--surface);
  transition: background var(--ease), transform var(--ease);
}

.fab:hover { background: var(--hover); }
.fab:active { transform: scale(0.94); }
.fab svg { width: 22px; height: 22px; stroke: var(--text); fill: none; stroke-width: 1.7;
           stroke-linecap: round; stroke-linejoin: round; }

/* 필터가 걸린 동안에만 찍히는 점 */
.fab .dot {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 7px;
  height: 7px;
  border-radius: var(--pill);
  background: var(--accent);
}

/* ── 사람 화면 ────────────────────────────────────────────── */

/* 지금 누구인지 알려주는 이름표. 작을수록 좋다. */
.person-head {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: calc(10px + env(safe-area-inset-top)) 18px 10px;
  background: var(--bg);
  width: 100%;
  max-width: var(--app);
  margin: 0 auto;
}

.person-head .back { width: 34px; height: 34px; display: grid; place-items: center; flex: none; }
.person-head .back svg { width: 20px; height: 20px; stroke: var(--text-dim); fill: none;
                         stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.person-head .meta { min-width: 0; flex: 1; }

.head-edit {
  flex: none;
  padding: 6px 10px;
  border-radius: var(--radius);
  font-size: 0.78rem;
  color: var(--text-dim);
  transition: background var(--ease), color var(--ease);
}

.head-edit:hover { background: var(--surface); color: var(--text); }

/* 태그 — 읽기 전용. 고치는 것은 머리의 편집 버튼이다. */
.tag {
  padding: 2px 9px;
  border-radius: var(--pill);
  background: var(--surface);
  font-size: 0.7rem;
  line-height: 1.6;
  color: var(--text-dim);
  white-space: nowrap;
}

.person-name {
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 소개·생일 뒤에 태그가 붙는다. 자리가 모자라면 앞 텍스트가 먼저 줄어든다. */
.person-sub {
  display: flex;
  align-items: center;
  gap: 5px;
  overflow: hidden;
  font-size: 0.76rem;
  color: var(--text-dim);
}

.sub-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.person-sub .tag { flex: none; }

/* ── 타임라인 ─────────────────────────────────────────────── */

.timeline {
  display: flex;
  flex-direction: column;
  gap: 22px;
  /*
   * 아래 여백은 쓰는 자리의 높이를 따라간다 — 입력창이 자라면 그만큼
   * 늘어야 마지막 줄이 바 뒤로 숨지 않는다. --bar-h 는 ResizeObserver 가
   * 채우고, 그것이 오기 전 한 프레임을 위해 기본값을 둔다.
   */
  padding: 14px 18px calc(var(--bar-h, 120px) + 24px);
  width: 100%;
  max-width: var(--app);
  margin: 0 auto;
}

.tl-note { display: flex; flex-direction: column; gap: 5px; }
.tl-text { margin: 0; font-size: 0.94rem; white-space: pre-wrap; word-break: break-word; }

/* 시각과 지우기가 한 줄에 선다. 시각 바로 옆이지 오른쪽 끝이 아니다 —
   끝으로 밀면 화면 가장자리에 아이콘이 스무 개 늘어선 열이 생긴다. */
.tl-meta { display: flex; align-items: center; gap: 4px; }
.tl-when { font-size: 0.74rem; color: var(--text-dim); }

/*
 * 소급해 넣은 날짜. 구분자가 말하는 날(적은 날)과 다를 때만 나타난다.
 *
 * --danger 를 쓰지 않는다. 그 색은 지우기가 눌린 순간에만 켜지기로 되어
 * 있어서, 같은 줄에서 늘 붉게 떠 있으면 옆의 휴지통이 이미 눌린 것처럼
 * 읽힌다. --warn 은 붉은기가 도는 주황이라 흐린 줄에서 혼자 앞으로 나오되
 * 무엇을 경고하지는 않는다.
 */
.tl-when-back { color: var(--warn); }

/*
 * 날짜 구분자.
 *
 * 상태 변경(.tl-status)보다 한 겹 더 뒤에 둔다 — 저쪽은 읽다가 걸려야 하는
 * 사건이고 이쪽은 찾을 때만 보이면 되는 눈금이다. 그래서 더 작고 더 흐리다.
 *
 * 위는 넓고 아래는 좁다. 등거리로 두면 어느 그룹에도 속하지 않은 한 줄로
 * 떠 버리는데, 이것은 아래에 오는 것들의 머리말이다. 선을 긋는 대신 거리로
 * 소속을 적는다.
 */
.tl-daysep {
  margin: 10px 0 -10px;
  text-align: center;
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  color: var(--text-dim);
  opacity: 0.55;
}

/*
 * 지우기.
 *
 * 흐린 줄에 얹히므로 색은 그 줄을 따라가고, 누를 때만 붉어진다. 늘 붉으면
 * 읽는 내내 스무 개의 경고가 켜져 있는 꼴이다.
 *
 * 세로 여백을 음수 마진으로 되돌리는 것은 손가락과 눈이 다른 크기를 원하기
 * 때문이다 — 실제로 누르는 넓이는 32px 이고 줄 높이는 글자만큼만 차지한다.
 */
.tl-del {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  margin: -9px 0 -9px 2px;
  flex: none;
  opacity: 0.5;
  transition: opacity var(--ease);
}

.tl-del svg {
  width: 15px;
  height: 15px;
  stroke: var(--text-dim);
  fill: none;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* 표면을 깔지 않는다. 누르는 넓이(32px)가 글줄(19px)보다 크므로 배경을 주면
   그 조각이 위 본문까지 올라온다 — 흐리기만 걷어도 만질 것으로 읽힌다. */
.tl-del:hover, .tl-del:active { opacity: 1; }
.tl-del:active svg { stroke: var(--danger); }

/* 상태 변경. 가운데로 보내면 선을 하나도 쓰지 않고 구획이 생긴다 */
.tl-status { padding: 2px 0; text-align: center; font-size: 0.76rem; color: var(--text-dim); }

/* ── 쓰는 자리 ────────────────────────────────────────────── */

/*
 * 사람 화면에만 선다. 최신이 아래이므로 쓰는 손과 결과가 나타나는 자리가
 * 같다 — 최신이 위였다면 아래에서 쓰고 위에서 튀어나오는 꼴이었다.
 *
 * 바닥 근처가 아니면 사라진다. fixed 라 사라지는 순간 그 아래에 있던
 * 타임라인이 그대로 드러나고, 문서 높이는 그대로여서 "사라짐 → 짧아짐 →
 * 다시 바닥 → 나타남" 으로 떠는 되먹임이 생기지 않는다.
 *
 * 화면이 꺼진 것처럼 보이면 안 되므로 배경을 깐다 — 글이 바 뒤로 흘러
 * 비쳐 보이면 둘 다 못 읽는다.
 */
.composer {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 30;
  width: 100%;
  max-width: var(--app);
  margin: 0 auto;
  padding: 10px 14px calc(10px + env(safe-area-inset-bottom));
  background: var(--bg);
  transition: opacity var(--ease);
}

/* 위로 올라가 읽는 동안. 보이지 않는 것이 탭을 삼키면 안 된다 */
.composer.is-away { opacity: 0; pointer-events: none; }

/*
 * 입력할수록 아래로 자란다. 상한을 두는 이유는 여덟 줄이면 이미 화면
 * 대부분이고, 그 위의 맥락이 한 줄도 안 남으면 쓰던 것이 무엇에 대한
 * 이야기였는지 사라지기 때문이다.
 */
.composer-text {
  display: block;
  width: 100%;
  min-height: var(--tap);
  max-height: min(40vh, 12em);
  padding: 11px 13px;
  background: var(--surface);
  border: none;
  border-radius: var(--radius);
  color: var(--text);
  font-size: 1rem;
  font-family: inherit;
  line-height: 1.6;
  resize: none;
  overflow-y: auto;
  transition: background var(--ease);
}

.composer-text::placeholder { color: var(--text-dim); opacity: 1; }
.composer-text:focus { outline: none; background: var(--raised); }

/*
 * 왼쪽은 정하는 것, 오른쪽 끝은 되돌릴 수 없는 것 하나. 엄지가 가장 자주
 * 닿는 자리에 실수의 여지를 두지 않는다.
 */
.composer-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
}

/*
 * 위아래는 직선, 좌우 끝은 반원. 떠 있는 버튼(.fab)이 원이라 그것과
 * 겹쳐 읽히지 않고, 바 안에 나란히 누워 가로 흐름을 따라간다.
 */
.composer-btn {
  position: relative;
  width: 52px;
  height: 36px;
  display: grid;
  place-items: center;
  border-radius: var(--pill);
  background: var(--surface);
  transition: background var(--ease), transform var(--ease);
}

/*
 * 보이는 것은 36px 이지만 손이 닿는 곳은 44px 그대로다. 남기기는 되돌릴
 * 수 없으므로 빗나간 탭이 곧 "안 눌렸다" 가 되어야 하고, 그러려면 눈에
 * 보이는 크기를 줄인 값을 히트 영역이 같이 치르면 안 된다.
 */
.composer-btn::after { content: ''; position: absolute; inset: -4px; }

.composer-btn:hover { background: var(--hover); }
.composer-btn:active { transform: scale(0.94); }
.composer-btn svg { width: 19px; height: 19px; stroke: var(--text); fill: none;
                    stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }

/*
 * 둘 다 색을 쓰되 같은 짙기는 아니다. 짙은 잉크는 되돌릴 수 없는 것 하나에만
 * 준다 — 둘 다 짙으면 "오른쪽 끝에만 위험이 있다" 는 배치가 무너져
 * 손이 어느 쪽을 조심해야 하는지 알 수 없게 된다.
 */
.composer-send { background: var(--accent); }
.composer-send:hover { background: var(--accent-hover); }
.composer-send svg { stroke: var(--on-accent); stroke-width: 2; }

.composer-date { background: var(--shift); }
.composer-date:hover { background: var(--shift-hover); }

/* 커밋이 가는 동안. 무슨 일이 벌어지는지 계속 보이게 두고 손만 막는다 */
.composer.is-busy .composer-text,
.composer.is-busy .composer-send { opacity: 0.45; }
.composer.is-busy .composer-send { transform: none; }

/* ── 시트 ─────────────────────────────────────────────────── */

.sheet-back {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: var(--scrim);
  animation: fade-in 170ms ease-out;
}

.sheet {
  width: 100%;
  max-width: var(--app);
  max-height: 88vh;
  overflow-y: auto;
  padding: 10px 18px calc(20px + env(safe-area-inset-bottom));
  background: var(--raised);
  border-radius: 22px 22px 0 0;
  animation: sheet-up 230ms cubic-bezier(0.2, 0.7, 0.3, 1);
}

/* 아래에서 올라온 것임을 형태로 말한다 */
.sheet::before {
  content: '';
  display: block;
  width: 36px;
  height: 4px;
  margin: 0 auto 16px;
  background: var(--surface);
  border-radius: var(--pill);
}

.sheet-title { margin: 0 0 14px; font-size: 1rem; font-weight: 600; }

/* 브라우저 기본 체크박스는 파란 테두리라 이 화면의 결에서 혼자 튄다 */
.check { display: flex; align-items: center; gap: 9px; min-height: 42px;
         font-size: 0.78rem; color: var(--text-dim); cursor: pointer; }

.check input {
  appearance: none;
  -webkit-appearance: none;
  width: 20px;
  height: 20px;
  flex: none;
  border-radius: 6px;
  background: var(--surface);
  display: grid;
  place-items: center;
  transition: background var(--ease);
}

.check input:checked { background: var(--accent); }
.check input:checked::after { content: '✓'; font-size: 13px; color: var(--on-accent); line-height: 1; }
.field { display: flex; flex-direction: column; gap: 7px; margin-bottom: 14px; }
.field-label { font-size: 0.78rem; color: var(--text-dim); }
.chips { display: flex; gap: 8px; flex-wrap: wrap; }

/*
 * 지울 것을 그대로 보여주는 자리. 시트보다 어두운 표면에 얹어 "여기부터
 * 저기까지가 그 글" 이 보이게 한다 — 확인이 성립하려면 그 경계가 필요하다.
 * 긴 글은 안에서 구른다. 시트가 화면을 넘기면 버튼이 밖으로 밀린다.
 */
.quote {
  margin: 0;
  padding: 12px 14px;
  max-height: 40vh;
  overflow-y: auto;
  background: var(--surface);
  border-radius: var(--radius);
  font-size: 0.9rem;
  color: var(--text-dim);
  white-space: pre-wrap;
  word-break: break-word;
}

/* 세로로 쌓이는 선택지 — 무엇을 할지 고르는 자리 */
.stack { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; }
.stack .btn { min-height: 50px; }

.sheet-actions { display: flex; gap: 10px; margin-top: 18px; }
.sheet-actions .btn { flex: 1; min-height: 50px; }

/* 시트 안의 입력은 시트(raised)보다 짙어야 눌려 보인다. 포커스는 종이색으로 */
.sheet .input, .sheet .textarea { background: var(--surface); }
.sheet .input:focus, .sheet .textarea:focus { background: var(--bg); }

/* 생일 칸: 월·일은 좁고 연도는 남는 자리 */
.sheet .row select.input { flex: none; width: 5.2em; }

/* 넓은 기기에서는 첫 화면만 넓어진다 — 카드가 커지는 게 아니라 더 담긴다 */
@media (max-width: 400px) {
  .wrap, .groups { padding-left: 12px; padding-right: 12px; }
  .cards { grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 8px; }
}

@media (min-width: 760px)  { :root { --shelf: 700px; } }
@media (min-width: 1020px) { :root { --shelf: 920px; } }

@keyframes fade-in { from { opacity: 0; } }
@keyframes sheet-up { from { transform: translateY(26px); opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .sheet-back, .sheet { animation: none; }
  * { transition: none !important; }
  /* 페이드가 없으면 그냥 사라진다 — 투명한 채 남아 탭을 삼키면 안 된다 */
  .composer.is-away { visibility: hidden; }
}

/* ── 잠금 · 설정 ──────────────────────────────────────────── */

/* 여기도 손이 닿는 곳에서 끝난다 */
.center { min-height: 100vh; align-content: end; justify-items: center;
          padding: 24px 24px max(24px, 12vh); }
.center.is-active { display: grid; }

.gate { width: 100%; max-width: 320px; display: flex; flex-direction: column; gap: 12px; }
.gate h1 { margin: 0 0 6px; font-size: 1.6rem; font-weight: 600; text-align: center; }
.gate .hint { margin: 0; font-size: 0.78rem; line-height: 1.55; color: var(--text-dim); }
.gate .link { text-align: center; font-size: 0.78rem; color: var(--text-dim); }

/* ── 알림 ─────────────────────────────────────────────────── */

.msg { margin: 0; font-size: 0.83rem; color: var(--warn); }
.msg.is-info { color: var(--text-dim); }

.banner {
  width: 100%;
  max-width: var(--shelf);
  margin: 0 auto 20px;
  padding: 0 18px;
  color: var(--warn);
  font-size: 0.82rem;
  line-height: 1.5;
}

.toast {
  position: fixed;
  left: 50%;
  bottom: calc(24px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 90;
  padding: 11px 20px;
  background: var(--text);
  color: var(--bg);
  border-radius: var(--pill);
  font-size: 0.85rem;
}

.spinner { padding: 24px 0; text-align: center; color: var(--text-dim); font-size: 0.85rem; }
