/* ═══════════════════════════════════════════════════════════════
   tokens.css
   색 토큰 — 기본 팔레트, 포인트 컬러 8종 프리셋, 다크 모드 오버라이드.

   포인트 컬러를 손볼 일은 거의 전부 이 파일 안에서 끝난다.
   ⚠️ theme.js의 ACCENTS HEX와 --md-primary-rgb는 1:1로 대응한다. 한쪽만 바꾸지 말 것.

   ⚠️ 이 파일들은 index.html의 <style> 하나를 순서 그대로 자른 것이다.
      선택자가 파일을 넘나들며 겹치므로 <link> 순서를 바꾸면 화면이 깨진다.
      순서: tokens → base → app → landing → overrides
   ═══════════════════════════════════════════════════════════════ */
/* ===== 테마 토큰: 기본(라벤더/라이트) ===== */
:root {
  --md-background-rgb: 250 248 255;
  --md-surface-rgb: 250 248 255;
  --md-surface-variant-rgb: 225 226 236;
  --md-surface-container-low-rgb: 245 243 250;
  --md-surface-container-rgb: 239 237 244;
  --md-surface-container-high-rgb: 233 231 238;
  --md-primary-rgb: 73 93 146;
  --md-on-primary-rgb: 255 255 255;
  --md-secondary-container-rgb: 220 226 249;
  --md-on-secondary-container-rgb: 21 27 43;
  --md-tertiary-rgb: 115 85 114;
  --md-error-rgb: 179 38 30;
  --md-on-error-rgb: 255 255 255;
  --md-outline-rgb: 117 118 127;
  --md-on-surface-rgb: 26 27 32;
  --md-on-surface-variant-rgb: 68 70 78;
}
/* ===== 포인트 색상 프리셋 (파스텔톤) =====
   배경/표면(surface) 계열도 각 포인트 색상의 색조(hue)로 살짝 물들여서(M3 톤 팔레트 방식),
   포인트 컬러를 바꾸면 버튼뿐 아니라 사이트 전체 배경 톤도 자연스럽게 같이 바뀌도록 한다.
   (라벤더 기본값과의 hue 차이만큼 :root 중립 톤을 회전시켜 라이트/다크 각각 계산함) */
[data-accent="m3"] {
  --md-primary-rgb: 103 80 164;  --md-secondary-container-rgb: 232 222 248; --md-on-secondary-container-rgb: 29 25 43;  --md-tertiary-rgb: 125 82 96;
  --md-background-rgb: 254 247 255; --md-surface-rgb: 254 247 255; --md-surface-variant-rgb: 231 224 236;
  --md-surface-container-low-rgb: 247 242 250; --md-surface-container-rgb: 243 237 247; --md-surface-container-high-rgb: 236 230 240;
  --md-outline-rgb: 121 116 126; --md-on-surface-rgb: 29 27 32; --md-on-surface-variant-rgb: 73 69 79;
}
[data-accent="teal"] {
  --md-primary-rgb: 0 105 106;  --md-secondary-container-rgb: 205 232 231; --md-on-secondary-container-rgb: 5 31 31;  --md-tertiary-rgb: 76 96 124;
  --md-background-rgb: 244 250 250; --md-surface-rgb: 244 250 250; --md-surface-variant-rgb: 218 228 228;
  --md-surface-container-low-rgb: 239 245 245; --md-surface-container-rgb: 233 239 239; --md-surface-container-high-rgb: 227 233 233;
  --md-outline-rgb: 111 121 121; --md-on-surface-rgb: 23 29 28; --md-on-surface-variant-rgb: 63 72 72;
}
[data-accent="green"] {
  --md-primary-rgb: 55 105 61;  --md-secondary-container-rgb: 212 232 209; --md-on-secondary-container-rgb: 15 31 17;  --md-tertiary-rgb: 57 101 108;
  --md-background-rgb: 247 251 243; --md-surface-rgb: 247 251 243; --md-surface-variant-rgb: 222 229 218;
  --md-surface-container-low-rgb: 241 245 237; --md-surface-container-rgb: 235 239 231; --md-surface-container-high-rgb: 229 233 225;
  --md-outline-rgb: 114 121 112; --md-on-surface-rgb: 25 29 24; --md-on-surface-variant-rgb: 66 73 65;
}
[data-accent="yellow"] {
  --md-primary-rgb: 126 87 15;  --md-secondary-container-rgb: 249 222 188; --md-on-secondary-container-rgb: 38 25 5;  --md-tertiary-rgb: 79 100 65;
  --md-background-rgb: 255 248 244; --md-surface-rgb: 255 248 244; --md-surface-variant-rgb: 239 224 208;
  --md-surface-container-low-rgb: 254 242 229; --md-surface-container-rgb: 248 236 224; --md-surface-container-high-rgb: 242 230 218;
  --md-outline-rgb: 128 117 103; --md-on-surface-rgb: 32 27 20; --md-on-surface-variant-rgb: 78 69 57;
}
[data-accent="orange"] {
  --md-primary-rgb: 139 79 38;  --md-secondary-container-rgb: 255 219 200; --md-on-secondary-container-rgb: 43 23 9;  --md-tertiary-rgb: 97 96 51;
  --md-background-rgb: 255 248 245; --md-surface-rgb: 255 248 245; --md-surface-variant-rgb: 243 222 211;
  --md-surface-container-low-rgb: 255 241 235; --md-surface-container-rgb: 252 235 227; --md-surface-container-high-rgb: 246 229 221;
  --md-outline-rgb: 132 116 107; --md-on-surface-rgb: 34 26 21; --md-on-surface-variant-rgb: 82 68 60;
}
[data-accent="pink"] {
  --md-primary-rgb: 137 74 102;  --md-secondary-container-rgb: 254 217 230; --md-on-secondary-container-rgb: 42 21 29;  --md-tertiary-rgb: 126 85 56;
  --md-background-rgb: 255 248 248; --md-surface-rgb: 255 248 248; --md-surface-variant-rgb: 242 222 227;
  --md-surface-container-low-rgb: 255 240 244; --md-surface-container-rgb: 249 234 238; --md-surface-container-high-rgb: 244 228 231;
  --md-outline-rgb: 131 115 119; --md-on-surface-rgb: 33 25 27; --md-on-surface-variant-rgb: 80 67 71;
}
/* ⚠️ 레드는 사용자가 직접 고른 팔레트다(2026-08-21). 포인트 #C82820 / 파스텔 면 #FFDAD4 /
   배경 #FFF8F6 / 위젯 면 #FFEDE9 / 보조 강조 #715B2E 를 씨앗으로 palette.js의
   buildScheme()이 나머지 토큰과 다크 모드를 계산했다. 12개 대비 항목 전부 AA 통과 확인.
   ⚠️ 예전의 베이지 톤(#FFEBD6)은 더 이상 쓰지 않는다 — 이 값들로 대체됐다. */
[data-accent="red"] {
  --md-primary-rgb: 200 40 32;  --md-secondary-container-rgb: 255 218 212; --md-on-secondary-container-rgb: 42 23 19;  --md-tertiary-rgb: 113 91 46;
  --md-background-rgb: 255 248 246; --md-surface-rgb: 255 248 246; --md-surface-variant-rgb: 247 225 216;
  --md-surface-container-low-rgb: 255 244 240; --md-surface-container-rgb: 255 237 233; --md-surface-container-high-rgb: 249 232 224;
  --md-outline-rgb: 133 116 108; --md-on-surface-rgb: 34 26 22; --md-on-surface-variant-rgb: 83 68 62;
}
/* ===== 다크 모드 (포인트 색상별로 중립 톤을 다시 계산, 포인트 강조색 자체는 유지) ===== */
[data-theme="dark"] {
  /* M3 다크 팔레트의 error 역할은 라이트(#B3261E)를 그대로 쓰지 않고 밝은 톤(#F2B8B5)으로
     뒤집는다 — 어두운 표면 위에서 진한 빨강은 대비가 확보되지 않기 때문이다. on-error도
     같이 뒤집어(어두운 적갈색) 채워진 error 버튼의 글자가 읽히게 한다.
     (포인트 색상 프리셋들은 error를 건드리지 않는다 — 위험/에러는 테마와 무관하게 항상
     같은 의미의 색이어야 하므로 6종 프리셋 공통으로 이 값을 쓴다.) */
  --md-error-rgb: 242 184 181;
  --md-on-error-rgb: 96 20 16;
  /* M3 다크 팔레트: primary는 밝은 톤으로, on-primary는 어두운 톤으로 뒤집는다.
     예전엔 이 둘을 라이트와 똑같이 두는 바람에 다크에서 `text-md-primary`(더보기 링크·D-day 등)가
     대비 2.9:1로 거의 안 읽혔다. secondary-container도 뒤집지 않으면 톤 버튼·칩이 어두운 배경 위에
     "밝은 덩어리"로 튄다. 6종 포인트 프리셋 각각에 대해 아래에서 같은 방식으로 덮어쓴다. */
  --md-primary-rgb: 178 197 255;
  --md-on-primary-rgb: 24 46 96;
  --md-secondary-container-rgb: 64 71 89;
  --md-on-secondary-container-rgb: 220 226 249;
  --md-tertiary-rgb: 225 187 220;
  --md-background-rgb: 18 19 24;
  --md-surface-rgb: 18 19 24;
  --md-surface-variant-rgb: 68 70 78;
  --md-surface-container-low-rgb: 26 27 32;
  --md-surface-container-rgb: 30 32 36;
  --md-surface-container-high-rgb: 40 42 47;
  --md-outline-rgb: 143 144 153;
  --md-on-surface-rgb: 227 226 233;
  --md-on-surface-variant-rgb: 197 198 207;
}
[data-accent="m3"][data-theme="dark"] {
  --md-primary-rgb: 208 188 255; --md-on-primary-rgb: 56 30 114;
  --md-secondary-container-rgb: 74 68 88; --md-on-secondary-container-rgb: 232 222 248;
  --md-tertiary-rgb: 239 184 200;
  --md-background-rgb: 20 18 24; --md-surface-rgb: 20 18 24; --md-surface-variant-rgb: 73 69 79;
  --md-surface-container-low-rgb: 29 27 32; --md-surface-container-rgb: 33 31 38; --md-surface-container-high-rgb: 43 41 48;
  --md-outline-rgb: 147 143 153; --md-on-surface-rgb: 230 224 233; --md-on-surface-variant-rgb: 202 196 208;
}
[data-accent="teal"][data-theme="dark"] {
  --md-primary-rgb: 128 212 212; --md-on-primary-rgb: 0 55 54;
  --md-secondary-container-rgb: 50 75 75; --md-on-secondary-container-rgb: 205 232 231;
  --md-tertiary-rgb: 179 200 232;
  --md-background-rgb: 14 20 20; --md-surface-rgb: 14 20 20; --md-surface-variant-rgb: 63 72 72;
  --md-surface-container-low-rgb: 23 29 28; --md-surface-container-rgb: 27 33 32; --md-surface-container-high-rgb: 37 43 43;
  --md-outline-rgb: 137 147 146; --md-on-surface-rgb: 222 228 228; --md-on-surface-variant-rgb: 190 200 200;
}
[data-accent="green"][data-theme="dark"] {
  --md-primary-rgb: 157 212 159; --md-on-primary-rgb: 1 57 19;
  --md-secondary-container-rgb: 58 75 58; --md-on-secondary-container-rgb: 212 232 209;
  --md-tertiary-rgb: 161 206 214;
  --md-background-rgb: 16 20 15; --md-surface-rgb: 16 20 15; --md-surface-variant-rgb: 66 73 65;
  --md-surface-container-low-rgb: 25 29 24; --md-surface-container-rgb: 29 33 28; --md-surface-container-high-rgb: 39 43 38;
  --md-outline-rgb: 140 147 137; --md-on-surface-rgb: 224 228 220; --md-on-surface-variant-rgb: 194 201 190;
}
[data-accent="yellow"][data-theme="dark"] {
  --md-primary-rgb: 242 190 110; --md-on-primary-rgb: 68 44 0;
  --md-secondary-container-rgb: 86 68 43; --md-on-secondary-container-rgb: 249 222 188;
  --md-tertiary-rgb: 183 206 163;
  --md-background-rgb: 24 18 12; --md-surface-rgb: 24 18 12; --md-surface-variant-rgb: 78 69 57;
  --md-surface-container-low-rgb: 32 27 20; --md-surface-container-rgb: 36 31 23; --md-surface-container-high-rgb: 47 41 33;
  --md-outline-rgb: 155 143 129; --md-on-surface-rgb: 236 225 213; --md-on-surface-variant-rgb: 210 196 180;
}
[data-accent="orange"][data-theme="dark"] {
  --md-primary-rgb: 255 182 138; --md-on-primary-rgb: 82 35 0;
  --md-secondary-container-rgb: 91 65 49; --md-on-secondary-container-rgb: 255 219 200;
  --md-tertiary-rgb: 204 201 146;
  --md-background-rgb: 26 18 14; --md-surface-rgb: 26 18 14; --md-surface-variant-rgb: 82 68 60;
  --md-surface-container-low-rgb: 34 26 21; --md-surface-container-rgb: 38 30 25; --md-surface-container-high-rgb: 49 40 35;
  --md-outline-rgb: 159 141 132; --md-on-surface-rgb: 240 223 215; --md-on-surface-variant-rgb: 215 195 184;
}
[data-accent="pink"][data-theme="dark"] {
  --md-primary-rgb: 255 176 208; --md-on-primary-rgb: 83 29 55;
  --md-secondary-container-rgb: 89 64 73; --md-on-secondary-container-rgb: 254 217 230;
  --md-tertiary-rgb: 241 188 151;
  --md-background-rgb: 24 17 19; --md-surface-rgb: 24 17 19; --md-surface-variant-rgb: 80 67 71;
  --md-surface-container-low-rgb: 33 25 27; --md-surface-container-rgb: 37 30 33; --md-surface-container-high-rgb: 48 40 43;
  --md-outline-rgb: 157 141 145; --md-on-surface-rgb: 239 223 226; --md-on-surface-variant-rgb: 212 194 199;
}
[data-accent="red"][data-theme="dark"] {
  --md-primary-rgb: 255 180 170; --md-on-primary-rgb: 105 0 2;
  --md-secondary-container-rgb: 90 65 61; --md-on-secondary-container-rgb: 255 218 212; --md-tertiary-rgb: 225 195 141;
  --md-background-rgb: 26 18 14; --md-surface-rgb: 26 18 14; --md-surface-variant-rgb: 83 68 62;
  --md-surface-container-low-rgb: 34 26 22; --md-surface-container-rgb: 39 30 26; --md-surface-container-high-rgb: 49 40 36;
  --md-outline-rgb: 160 141 134; --md-on-surface-rgb: 240 223 216; --md-on-surface-variant-rgb: 215 194 185;
}
/* 다크/라이트 모드·포인트 컬러 전환 시 색상이 뚝 끊기지 않고 부드럽게 바뀌도록(눈부심 방지).
   transform 계열(스케일 애니메이션 등)은 건드리지 않고 색상 관련 속성에만 한정한다.
   페이지 최초 로드 시에는 깜빡임을 막기 위해 body에 .theme-ready가 붙기 전까지 전환을 끈다. */
body:not(.theme-ready) * { transition: none !important; }
*, *::before, *::after {
  transition: background-color 0.35s cubic-bezier(0.2, 0, 0, 1), color 0.35s cubic-bezier(0.2, 0, 0, 1), border-color 0.35s cubic-bezier(0.2, 0, 0, 1), fill 0.35s cubic-bezier(0.2, 0, 0, 1);
}
/* 사이드바/섹션 제목용 단색 M3 아이콘. 색상은 currentColor를 따르므로 텍스트 색이 바뀌면(활성 탭, 다크모드 등) 자동으로 함께 바뀐다. */
.material-symbols-outlined.m3-icon { font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24; font-size: 22px; line-height: 1; vertical-align: middle; flex-shrink: 0; }
/* ⚠️ 명시도 주의: 위 `.material-symbols-outlined.m3-icon`은 클래스 2개(0,2,0)라
   `h1 .m3-icon`(0,1,1)보다 강하다 — 예전엔 이 규칙이 그대로 밀려서 섹션 제목 아이콘이
   22px에 머물러 있었다(제목 글자 30px 옆에서 작아 보이던 원인). 같은 두 클래스를 명시해
   이긴 뒤 크기를 준다. 사이드바 규칙은 #sidebar(id)가 있어 애초에 문제없다. */
h1 .material-symbols-outlined.m3-icon { font-size: 28px; }
/* 모바일에서는 사이드바가 항상 풀 폭으로 열려서(레일 없음) 아이콘 옆에 공간이 넉넉한데,
   기본 22px는 상대적으로 작아 보였다 — 모바일 사이드바 안의 아이콘만 살짝 키운다. */
@media (max-width: 767.98px) {
  #sidebar .nav-link .m3-icon { font-size: 26px; }
}
.m3-input { background-color: rgb(var(--md-surface-container-low-rgb)); color: rgb(var(--md-on-surface-rgb)); border-bottom: 2px solid rgb(var(--md-outline-rgb)); border-top-left-radius: 12px; border-top-right-radius: 12px; padding: 14px 16px; outline: none; transition: 0.2s; width: 100%; }
.m3-input:focus { border-bottom-color: rgb(var(--md-primary-rgb)); background-color: rgb(var(--md-surface-container-high-rgb)); }
.nav-link { color: rgb(var(--md-on-surface-variant-rgb)); transition: all 0.3s cubic-bezier(0.2, 0, 0, 1); }
.nav-link:hover { background-color: rgb(var(--md-surface-container-high-rgb)); }
.content-section.hidden, .hidden { display: none !important; }
.admin-only { }
/* 모달/다이얼로그 등장 애니메이션. @starting-style(최신 브라우저 전용) 대신, main.js의
   MutationObserver가 .hidden이 제거되는 순간을 감지해 아주 짧게 .modal-fade-init(시작 상태:
   투명+살짝 작게)를 붙였다가 한 프레임 뒤 떼어내는 방식으로 구현한다 — 구형 브라우저 포함
   모든 데스크톱 브라우저에서 항상 재생된다. 기본값(클래스가 안 붙는 상황)은 항상 "완전히
   보임" 상태라서, 혹시 JS가 실패해도 모달/섹션이 안 보이게 되는 일은 없다(애니메이션은
   어디까지나 곁들이는 연출일 뿐, 그것에 콘텐츠 표시 여부가 걸려있지 않음). */
/* customAlert/Confirm/Prompt는 메시지를 .textContent로 넣는다. 그대로 두면 문구 안의
   \n이 HTML 공백으로 뭉개져 두 문장이 한 줄로 붙는다(기존 호출 몇 곳이 이미 그랬다). */
.sys-dialog-msg { white-space: pre-line; }
.modal-overlay:not(.hidden), .sys-dialog:not(.hidden) { opacity: 1; backdrop-filter: blur(3px); transition: opacity 0.22s cubic-bezier(0.2,0,0,1), backdrop-filter 0.25s ease-out; }
.modal-overlay:not(.hidden) > div, .sys-dialog:not(.hidden) > div { transform: scale(1) translateY(0); opacity: 1; transition: transform 0.32s cubic-bezier(0.34,1.56,0.64,1), opacity 0.22s cubic-bezier(0.2,0,0,1); }
.modal-overlay.modal-fade-init:not(.hidden), .sys-dialog.modal-fade-init:not(.hidden) { opacity: 0; backdrop-filter: blur(0px); }
.modal-overlay.modal-fade-init:not(.hidden) > div, .sys-dialog.modal-fade-init:not(.hidden) > div { transform: scale(0.9) translateY(14px); opacity: 0; }
/* 섹션(사이드바 메뉴) 전환 시에도 같은 방식으로 살짝 페이드인 */
/* 각 섹션을 둥근 패널 위에 올린다(2026-08-20). 예전엔 본문이 배경 위에 그냥 떠 있어서
   좌우 여백이 허전했다. M3 elevation 단계를 그대로 따른다:
     사이트 배경(N98) → 섹션 패널(surface-container-low, N96) → 위젯 카드(surface-container, N94)
   라이트에서는 배경보다 한 톤 낮고 다크에서는 한 톤 높아, 두 모드 모두 "면이 하나 떠 있는" 느낌이 된다.
   ⚠️ padding을 넣어도 #section-board의 min-height 계산은 고치지 않아도 된다 —
      box-sizing:border-box라 min-height에 padding이 포함되어 바깥 높이가 그대로다. */
/* ⚠️ #main-content의 space-y-4는 형제 사이 간격이라 섹션마다 위 여백 16px을 준다.
   그런데 섹션은 한 번에 하나만 보이므로 그 여백은 쓸모가 없고, 오픈채팅방처럼 높이를
   화면에 딱 맞춘 섹션에서는 딱 그만큼 페이지가 넘쳐 입력줄이 밀려난다(실측으로 확인).
   Tailwind가 쓰는 `:not([hidden])`는 우리의 .hidden **클래스**를 걸러내지 못하므로
   숨은 섹션에도 여백이 붙는다 — 여기서 명시도로 눌러 0으로 만든다. */
#main-content > .content-section:not(.hidden) { margin-top: 0; }
.content-section:not(.hidden) {
  opacity: 1; transition: opacity 0.25s ease-out;
  background-color: rgb(var(--md-surface-container-low-rgb));
  border-radius: 28px;
  padding: 1rem;
}
@media (min-width: 768px) {
  .content-section:not(.hidden) { border-radius: 32px; padding: 1.5rem; }
}
.content-section.section-fade-init:not(.hidden) { opacity: 0; }
/* 플로팅 패널(알림·프로필·검색 패널 공용): 각 모듈(notifications.js/auth.js/search.js)이 자기
   버튼 위치 기준으로 열 때마다 .hidden을 벗기 "직전"에 .modal-fade-init(시작 상태: 투명+살짝
   작게)을 동기적으로 붙였다가 다음 프레임에 떼어내는 방식으로 직접 등장 애니메이션을 재생한다
   (main.js의 공용 옵저버에 맡기면 hidden 해제와 시작 상태 추가 사이 틈에 애니메이션이 씹히는
   경우가 있어서 각자 자체 처리함). 퇴장도 반대로, 닫을 때 JS가 .floating-panel-closing을 먼저
   붙여서(같은 트랜지션을 거꾸로 재생) 부드럽게 사라지게 한 뒤, 트랜지션 시간이 지나고 나서야
   실제로 .hidden을 붙인다. left/top도 트랜지션에 포함시켜서, 패널이 뜬 채로 사이드바를 펼치거나
   접으면 패널이 순간이동하지 않고 부드럽게 따라 움직인다. */
#notif-panel:not(.hidden), #modal-my-info:not(.hidden), #search-panel:not(.hidden), #modal-cal-day:not(.hidden) {
  opacity: 1; transform: scale(1) translateY(0); transform-origin: top right;
  transition: transform 0.25s cubic-bezier(0.34,1.56,0.64,1), opacity 0.2s ease-out, left 0.2s ease-out, top 0.2s ease-out;
}
#notif-panel { transform-origin: top left; }
#search-panel { transform-origin: top center; }
#modal-cal-day { transform-origin: top left; }
#notif-panel.modal-fade-init:not(.hidden), #modal-my-info.modal-fade-init:not(.hidden), #search-panel.modal-fade-init:not(.hidden), #modal-cal-day.modal-fade-init:not(.hidden) { opacity: 0; transform: scale(0.95) translateY(-6px); }
#notif-panel.floating-panel-closing:not(.hidden), #modal-my-info.floating-panel-closing:not(.hidden), #search-panel.floating-panel-closing:not(.hidden), #modal-cal-day.floating-panel-closing:not(.hidden) {
  opacity: 0; transform: scale(0.95) translateY(-6px); transition: transform 0.2s cubic-bezier(0.2,0,0,1), opacity 0.18s ease-in;
}
/* 검색줄 — 열고 닫을 때 높이가 부드럽게 늘고 준다(팔레트 편집기와 같은 0fr→1fr 방식이라
   내용 높이를 몰라도 매직넘버 없이 동작한다). .hidden은 display:none이라 트랜지션이 안 걸리므로,
   search.js가 hidden을 먼저 벗기고 다음 프레임에 .open을 붙인다. */
.search-bar { display: grid; grid-template-rows: 0fr; opacity: 0;
  transition: grid-template-rows 0.28s cubic-bezier(0.2,0,0,1), opacity 0.2s ease-out; }
.search-bar.open { grid-template-rows: 1fr; opacity: 1; }
.search-bar > div { overflow: hidden; min-height: 0; }

/* 움직임을 줄이도록 설정한 사용자에게는 전환을 거의 없앤다(완전히 0으로 두면 상태 변화를
   인지하기 어려워, 아주 짧게만 남긴다). 부드러운 스크롤도 즉시 이동으로 바꾼다. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important; animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important; scroll-behavior: auto !important;
  }
}

/* 작은 글자 링크("더보기", 관리자 "수정" 등)는 글자만 보면 높이가 16~20px이라 M3의 최소
   터치 타겟 48dp에 한참 못 미친다. 보이는 크기는 그대로 두고 **누를 수 있는 영역만** 넓힌다 —
   가상 요소를 겹쳐 두는 방식이라 주변 레이아웃이 전혀 밀리지 않는다. */
/* M3 최소 터치 타겟 48dp — 모바일에서는 **실제로 키운다**(가상 요소로 덮기만 하면 인접한
   작은 버튼끼리 영역이 겹쳐 서로 클릭을 뺏는다. 손가락으로 쓰는 화면이라 실제 크기가 맞다).
   ⚠️ .m3-tap이 붙은 인라인 링크("더보기" 등)는 제외 — 그쪽은 글자 크기를 유지해야 해서
      가상 요소 방식으로 이미 처리했고, 여기서 또 키우면 줄 간격이 벌어진다.
   ⚠️ Nav Bar 항목은 자체 규격(80dp)이 있으므로 제외. */
@media (max-width: 767.98px) {
  #main-content :is(button, a[href]):not(.m3-tap):not(.navbar-item):not(.accent-swatch),
  #onboarding-view :is(button, a[href]):not(.m3-tap),
  #login-view :is(button, a[href]):not(.m3-tap),
  #mobile-topbar :is(button, a[href]):not(.topbar-avatar) {
    min-height: 48px;
  }
  /* 아이콘만 있는 버튼은 가로도 48이어야 손가락이 빗나가지 않는다. */
  #main-content button[aria-label]:not(.m3-tap):not(.accent-swatch):empty,
  #main-content button[aria-label]:not(.m3-tap):not(.accent-swatch) > .m3-icon:only-child {
    min-width: 48px;
  }
  #main-content button[aria-label]:not(.m3-tap):not(.accent-swatch):has(> .m3-icon:only-child) { min-width: 48px; }
  /* 세그먼트 토글(월간/주간, 라이트/다크)과 채팅 + 버튼은 높이는 맞았지만 폭이 42~44라
     손가락이 빗나가기 쉽다. 폭도 48로 못 박는다. */
  #cal-view-month, #cal-view-week, #cal-week-today, #cal-today,
  #meal-week-today, #timetable-week-today,
  #pv-mode-light, #pv-mode-dark, #btn-chat-menu, #onb-logout { min-width: 48px; }
  /* ⚠️ 포인트 색 스와치(.accent-swatch)는 예외다 — 40px 원이 12px 간격으로 늘어선 격자라
     실제 손가락 간격은 52px이고, 48로 키우면 한 줄에 들어가던 개수가 줄어 줄바꿈이 생긴다. */
}

.m3-tap { position: relative; }
.m3-tap::after {
  content: ''; position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 100%; min-width: 48px; height: 48px;
}

/* ══ M3 사양 기본기 (Material 3 Design Kit V1.25 / M3 Expressive 기준) ══
   키트가 정의하는 세 가지 스케일을 여기 한 곳에 모아 둔다.
   ⚠️ 새 UI를 만들 때 임의의 px 값을 쓰지 말고 아래 클래스/변수를 쓸 것. */

