/* ============================================================
 * withplan.css — withplan 프로젝트 전용 색상 테마
 *
 * 화면 구성과 컴포넌트 스타일은 공통 엔진(vendor/moca)을 그대로 쓰고,
 * CSS 변수(--c-*)와 로고만 프로젝트 전용으로 덮어쓴다.
 * 기본 테마 = 다크(딥 틸 그래파이트 + 프레시 민트). 라이트는 .theme-light 로 전환.
 * ============================================================ */

/* ★ hidden 속성은 클래스보다 약하다 — `display` 를 주는 클래스가 붙어 있으면 hidden 이 무시돼
   **"숨겼는데 보이는"** 사고가 난다. 이 프로젝트에서만 네 번을 클래스별로 개별 패치했고
   (.wsv_choice / .wsc_when / .wps_withdraw / #div_repeatPick), 그래도 또 새어 나갔다
   (챌린지 팝업 .wcg_form — 폼이 늘 열려 있어 "새 챌린지 만들기"가 두 번 보였다, 2026-08-30).
   개별 패치를 늘리는 대신 여기서 한 번에 못박는다. 숨김은 `hidden` 하나로 통일한다. */
[hidden] { display: none !important; }

/* ── 다크(기본) — 딥 틸 그래파이트 + 프레시 민트 ── */
:root {
  --c-primary:        #35C8A8;
  --c-primary-dark:   #23A386;
  --c-primary-deeper: #187C66;
  --c-primary-light:  rgba(53,200,168,0.14);
  --c-primary-mid:    #6ADCC2;
  --c-primary-pale:   rgba(53,200,168,0.07);
  --wp-accent:        #35C8A8;
  --wp-accent-pale:   rgba(53,200,168,0.10);

  --c-bg:           #1C2321;
  --c-surface:      #262E2B;
  --c-border:       #3D4844;
  --c-border-dark:  #5E6D67;
  --c-border-color: #3D4844;
  --c-text:         #E9F0ED;
  --c-text-sub:     #A3B2AC;
  --c-text-muted:   #7E8E87;

  --c-header-bg:      #151B19;
  --c-header-text:    #E9F0ED;
  --c-sidebar-bg:     #202826;
  --c-sidebar-border: #333E3A;
  --c-sidebar-text:   #A9B8B2;
  --c-sidebar-hover:  #2E3835;
  --c-footer-bg:      #151B19;
  --c-footer-text:    #7E8E87;

  --c-bg-input:          #222A27;
  --c-bg-input-focus:    #2A332F;
  --c-bg-input-readonly: #212926;
  --c-bg-elevated:       #2D3733;
  --c-bg-hover:          #323D39;

  --c-text-body:     #D6E0DC;
  --c-text-selected: #8FE8D1;

  --c-success: #2FBF71;
  --c-warning: #FFC145;
  --c-danger:  #FF7A7A;
  --c-info:    #4FB3FF;
  /* 하루기록 — 팝업 안 --wpp-orange 와 같은 값. 달력 격자는 팝업 밖이라 루트에도 필요하다(2026-09-14) */
  --wp-diary:  #FF8A4C;
  --c-req-border: var(--c-danger);

  --c-grid-toolbar:  #222A27;
  --c-grid-th:       #2E3834;
  --c-grid-row-alt:  #212926;
  --c-grid-hover:    #303B37;
  --c-grid-selected: rgba(53,200,168,0.14);
  --c-grid-agg-bg:         #14342B;
  --c-grid-agg-text:       #7FE0BE;
  --c-grid-agg-total-bg:   #2FBF71;
  --c-grid-agg-total-text: #0B1A12;

  --wp-shell-bg:     #181F1D;
  --wp-panel-bg:     #222A27;
  --wp-panel-strong: #2B3430;
  --wp-side-heading-bg:   #111614;
  --wp-side-heading-text: #8FE8D1;
  --wp-shell-shadow: 0 14px 34px rgba(6,10,9,0.24);
  --wp-control-h:    calc(30px * var(--wp-font-ratio, 1));
  --wp-ica-btn-w:    calc(24px * var(--wp-font-ratio, 1));
  --wp-ica-icon-inset: calc(5px * var(--wp-font-ratio, 1));
  --wp-pop-radius:   10px;
  --wp-pop-card-bg:  var(--c-bg);
  --wp-pop-border:   var(--c-border);
  --wp-danger-bg:    rgba(255,160,64,0.14);   /* 위험 동작 버튼의 옅은 바탕(다크 danger 주황 기준) — 2026-09-06 */
  --wp-badge-bg:     #F0C060;   /* 대기 수 배지 — 다크: 밝은 앰버 위 진한 글자(대비 10:1) */
  --wp-badge-fg:     #2A1D00;
}

/* ── 라이트 — 클린 페일 민트 + 딥 틸 ── */
:root.theme-light {
  --c-primary:        #0E8E7E;
  --c-primary-dark:   #0B7264;
  --c-primary-deeper: #085A4F;
  --c-primary-light:  rgba(14,142,126,0.10);
  --c-primary-mid:    #3AAF9E;
  --c-primary-pale:   rgba(14,142,126,0.05);
  --wp-accent:        #0E8E7E;
  --wp-danger-bg:     rgba(180,57,46,0.10);   /* 라이트 danger 빨강 기준 */
  --wp-badge-bg:      #7C4A00;   /* 라이트: 진한 앰버 위 흰 글자(대비 8:1) — 갈색 바탕+검정 글자(2.5:1)가 안 읽혔다(2026-09-06 지적) */
  --wp-badge-fg:      #FFFFFF;
  --wp-accent-pale:   rgba(14,142,126,0.09);

  --c-bg:           #FFFFFF;
  --c-surface:      #F5F8F7;
  --c-border:       #C7D4D0;
  --c-border-dark:  #7E918B;
  --c-border-color: #C7D4D0;
  --c-text:         #24312D;
  --c-text-sub:     #56685F;
  --c-text-muted:   #74857E;

  --c-header-bg:      #1E2A27;
  --c-header-text:    #F0F5F3;
  --c-sidebar-bg:     #D6E3DF;
  --c-sidebar-border: #AFC4BE;
  --c-sidebar-text:   #3F5650;
  --c-sidebar-hover:  #C6D7D2;
  --c-footer-bg:      #DCE5E2;
  --c-footer-text:    #6C7D77;

  --c-bg-input:          #F7FAF9;
  --c-bg-input-focus:    #FFFFFF;
  --c-bg-input-readonly: #E9EFED;
  --c-bg-elevated:       #EEF3F1;
  --c-bg-hover:          #DCE5E2;

  --c-text-body:     #3B4A45;
  --c-text-selected: #0B7264;

  --c-success: #1F9459;
  --c-warning: #B07C00;
  --c-danger:  #D84C4C;
  --c-info:    #1E88D8;
  --wp-diary:  #F26B1D;
  --c-req-border: var(--c-danger);

  --c-grid-toolbar:  #E7EEEC;
  --c-grid-th:       #DBE5E2;
  --c-grid-row-alt:  #EDF2F0;
  --c-grid-hover:    #DCE5E2;
  --c-grid-selected: rgba(14,142,126,0.18);
  --c-grid-agg-bg:         #E1F2EA;
  --c-grid-agg-text:       #14663F;
  --c-grid-agg-total-bg:   #1F9459;
  --c-grid-agg-total-text: #FFFFFF;

  --wp-shell-bg:     #DAE3E0;
  --wp-panel-bg:     #EEF3F1;
  --wp-panel-strong: #E5EBE9;
  --wp-side-heading-bg:   #FFFFFF;
  --wp-side-heading-text: #085A4F;
  --wp-shell-shadow: 0 12px 30px rgba(38,54,49,0.09);
}

/* WithPlanPlus 달력 입력 공통 — 화면별 wsc/wss 규칙으로 복제하지 않는다.
   단일·기간 달력 모두 프로젝트 글자 배율에 맞춰 높이·버튼·SVG 아이콘이 함께 커진다. */
div[data-m-type="inputCalendar"].moca_ica, div[data-m-type="inputMultiCalendar"].moca_ica { height: var(--wp-control-h); box-sizing: border-box; }
div[data-m-type="inputCalendar"].moca_ica > input.moca_input, div[data-m-type="inputMultiCalendar"].moca_ica > div > input.moca_input { height: calc(var(--wp-control-h) - 2px); box-sizing: border-box; }
div[data-m-type="inputMultiCalendar"].moca_ica > div { height: 100%; }
div[data-m-type="inputCalendar"].moca_ica > .moca_ica_btn, div[data-m-type="inputMultiCalendar"].moca_ica > div > .moca_ica_btn { width: var(--wp-ica-btn-w); height: calc(var(--wp-control-h) - 4px); }
div[data-m-type="inputCalendar"].moca_ica > .moca_ica_btn::after, div[data-m-type="inputMultiCalendar"].moca_ica > div > .moca_ica_btn::after { inset: var(--wp-ica-icon-inset); }

/* 엔진 기본 폭에 커진 아이콘 버튼의 증가분을 더해 날짜 텍스트 영역을 보존한다.
   좁은 화면에서는 컴포넌트 내부를 찌그러뜨리지 않고 부모의 flex-wrap/grid가 컴포넌트 전체를 재배치한다. */
div[data-m-type="inputCalendar"].moca_ica { --wp-ica-w: max(calc(116px + var(--wp-ica-btn-w)), calc(var(--m-ica-chars, 10) * 1ch + 22px + var(--wp-ica-btn-w))); width: var(--wp-ica-w); min-width: var(--wp-ica-w); flex-shrink: 0; }

/* ── 좌메뉴를 접으면 상단 헤더도 함께 접는다 (2026-09-01 지시) ────────────────────
   좌메뉴만 접으면 가로만 넓어지고 세로는 그대로다. 관리 화면은 그리드가 세로로 쌓여 있어
   실제로 아쉬운 건 높이다 — 헤더(54px)까지 걷어야 접는 값을 한다.

   JS 를 건드리지 않는다. 접기 버튼이 이미 #left 에 .folded 를 토글하므로, 그 상태를
   :has() 로 읽어 헤더를 감춘다. 상태를 두 곳에서 관리하면 어긋난다.
   .wrap 은 flex 세로 배치라 헤더가 빠지면 .container(flex:1)가 그만큼 자동으로 늘어난다.

   ★ 이 규칙은 프로젝트 CSS 에 둔다 — .left.folded 자체는 엔진(moca.css) 것이지만,
     "헤더까지 접는다" 는 withplan 의 선택이라 demo·erp 셸까지 바꾸지 않는다.
   ★ 모바일은 해당 없음 — mobile.css 가 .menufold 를 display:none 으로 감춰
     .folded 상태가 만들어지지 않는다(좌메뉴는 mob_open 방식). */
.wrap:has(.left.folded) > .header { display: none; }
/* 헤더가 사라졌으니 펼치기 손잡이도 화면 맨 위로 올린다(종전 top:59px 은 헤더 아래 기준). */
.wrap:has(.left.folded) .left.folded .menufold { top: 4px; }

/* 검색영역 접기 시 여백·정렬 보정은 엔진(moca.css)으로 승격했다 — MOCA 표준이 됐으므로
   프로젝트마다 다시 쓰지 않는다(SKILL PART A). */


/* base.css의 기본 헤더 마크 대신 withplan 로고를 표시한다. */
.header h1.wp_logo { width: auto; height: auto; background: none; }
.header h1.wp_logo span { width: auto; height: auto; display: inline-block; }
.wp_logo { display: flex; align-items: center; gap: 9px; }
.wp_logo img { width: 26px; height: 26px; display: block; }
.wp_logo_txt { font-size: 17px; font-weight: 800; letter-spacing: 0.04em; color: var(--c-header-text); }
.wp_logo_txt span { color: var(--c-primary); margin-left: 4px; }
:root.theme-light .wp_logo_txt { color: #F1F5F4; }

/* 라이트 테마 셸 보정 — 공통 라이트의 웜 페이퍼 고정색을 withplan 쿨 민트 팔레트로 교정한다. */
:root.theme-light .widget_card,
:root.theme-light .widget_edit_bar {
  --c-surface:        #F5F8F7;
  --c-bg:             #FFFFFF;
  --c-bg-input:       #F7FAF9;
  --c-bg-input-focus: #FFFFFF;
  --c-bg-elevated:    #EEF3F1;
  --c-bg-hover:       #DCE5E2;
  --c-grid-toolbar:   #E7EEEC;
  --c-grid-hover:     #DCE5E2;
  --c-border:         #C7D4D0;
  --c-border-dark:    #7E918B;
  --c-text-sub:       #56685F;
  --c-text-muted:     #74857E;
}
:root.theme-light .widget_card { box-shadow: 0 2px 7px rgba(38,54,49,0.11); }

:root.theme-light .mdi_tabbar { background: #DCE6E3; }
:root.theme-light .mdi_tab { background: #E9F0EE; }
:root.theme-light .mdi_tab:hover { background: #DCE7E4; }
:root.theme-light .mdi_tab.active { background: var(--c-surface); }
:root.theme-light .left {
  border-right: 1px solid var(--c-sidebar-border);
  box-shadow: 4px 0 14px rgba(43,66,60,0.10);
}
:root.theme-light .moca_treeview .tree-leaf.active { background: #C2E4DC; }
:root.theme-light ::-webkit-scrollbar-thumb { background: #B4C5C0; }
:root.theme-light ::-webkit-scrollbar-thumb:hover { background: #8EA39D; }

/* 라이트 테마에서도 withplan 헤더는 다크 틸 슬레이트를 유지한다. */
:root.theme-light .header_username { color: rgba(255,255,255,0.88); }
:root.theme-light .header_user_icon {
  background: rgba(14,142,126,0.22);
  border-color: rgba(103,196,181,0.72);
  color: #FFFFFF;
}
:root.theme-light .header_logout_btn {
  border-color: rgba(255,255,255,0.24);
  background: rgba(255,255,255,0.05);
  color: rgba(255,255,255,0.78);
}

/* ── WithPlanPlus 로그인 (COM_LOGIN) — 앱 일러스트를 확장한 PC 분할형 화면 ── */
.wp_login_page { display: grid; grid-template-columns: minmax(480px, 1.18fr) minmax(430px, 0.82fr); align-items: stretch; justify-content: stretch; background: radial-gradient(ellipse at 18% 14%, rgba(255,255,255,0.24) 0%, rgba(255,255,255,0.10) 32%, rgba(255,255,255,0) 62%), radial-gradient(ellipse at 88% 82%, rgba(255,226,174,0.24) 0%, rgba(255,226,174,0.08) 34%, rgba(255,226,174,0) 66%), linear-gradient(105deg, #B9EFD9 0%, #C7EED4 18%, #D8F1CB 36%, #E7F0C3 55%, #F3EDBC 73%, #F9EAB9 86%, #FFF0B4 100%); color: #4E4968; overflow: auto; }
.wp_login_hero { position: relative; min-width: 0; min-height: 680px; overflow: hidden; background-color: transparent; background-image: url('/system/withplan/images/main_bg.png'); background-repeat: no-repeat; background-position: center top; background-size: auto 150%; }
.wp_login_hero::after { position: absolute; inset: 0 0 0 auto; width: 34%; background: linear-gradient(90deg, rgba(255,240,180,0) 0%, rgba(255,243,200,0.10) 34%, rgba(255,244,214,0.30) 70%, rgba(255,246,226,0.46) 100%); content: ''; pointer-events: none; }
.wp_login_panel { position: relative; display: flex; min-width: 0; padding: 48px clamp(36px, 5vw, 86px) 28px; align-items: center; justify-content: center; flex-direction: column; box-sizing: border-box; background: linear-gradient(90deg, rgba(255,255,255,0.04) 0%, rgba(255,255,255,0.14) 38%, rgba(255,255,255,0.22) 100%); backdrop-filter: blur(6px); box-shadow: -24px 0 70px rgba(107,92,72,0.045); }
.wp_login_card { width: min(440px, 100%); padding: 34px 38px 30px; border: 1px solid rgba(168,144,198,0.34); border-radius: 30px; background: rgba(255,252,250,0.92); box-shadow: 0 28px 70px rgba(101,82,120,0.17), inset 0 1px 0 rgba(255,255,255,0.90); backdrop-filter: blur(18px); box-sizing: border-box; }
.wp_login_brand { display: flex; margin-bottom: 25px; align-items: center; justify-content: center; gap: 12px; text-align: left; }
.wp_login_logo { display: block; width: 48px; height: 48px; flex: 0 0 auto; object-fit: contain; box-sizing: border-box; }
.wp_login_brand_text { display: grid; gap: 2px; }
.wp_login_brand_text strong { color: #514A72; font-size: 20px; font-weight: 900; letter-spacing: -0.04em; }
.wp_login_brand_text span { color: #8A80A1; font-size: 12px; font-weight: 700; }
.wp_login_content { text-align: center; }
.wp_login_intro { margin-bottom: 20px; }
.wp_login_intro strong { display: block; margin-bottom: 6px; color: #514D70; font-size: 18px; font-weight: 800; }
.wp_login_intro span { color: #9188A1; font-size: 13px; }
.wp_login_card .wp_auth_form { gap: 11px; }
.wp_login_card .wp_auth_field { gap: 0; }
.wp_login_card .wp_auth_field input { height: 48px; padding: 0 15px; border-color: #D9CDE6; border-radius: 13px; background: rgba(255,255,255,0.92); color: #514D70; font-size: 14px; box-shadow: inset 0 1px 2px rgba(107,82,125,0.03); }
.wp_login_card .wp_auth_field input::placeholder { color: #91899E; opacity: 1; }
.wp_login_card .wp_auth_field input:focus { border-color: #0E8E7E; box-shadow: 0 0 0 3px rgba(14,142,126,0.13); }
.wp_login_card .wp_auth_remember { min-height: 26px; color: #6F6982; font-size: 12px; }
.wp_login_card .wp_auth_remember input { width: 18px; height: 18px; accent-color: #0E8E7E; }
.wp_login_card .wp_auth_primary { display: flex; min-height: 50px; margin-top: 1px; align-items: center; justify-content: center; gap: 9px; border-color: #0E8E7E; border-radius: 14px; background: #0E8E7E; color: #FFFFFF; box-shadow: 0 12px 24px rgba(14,142,126,0.24); }
.wp_login_card .wp_auth_primary:hover { background: #0B7669; transform: translateY(-1px); }
.wp_login_card .wp_auth_primary:active { transform: translateY(0); }
.wp_login_card .wp_auth_primary:focus-visible, .wp_login_card .wp_auth_links a:focus-visible, .wp_login_card .login_notice a:focus-visible { outline: 3px solid rgba(14,142,126,0.26); outline-offset: 3px; }
.wp_auth_login_icon { display: inline-grid; width: 22px; height: 22px; place-items: center; border: 1px solid rgba(255,255,255,0.50); border-radius: 7px; font-size: 15px; line-height: 1; }
.wp_login_card .wp_auth_links { margin: 16px 0 17px; }
.wp_login_card .wp_auth_links a { padding: 0 11px; border-color: #DAD3E1; color: #5C576D; font-size: 12px; }
.wp_login_card .wp_auth_links a:hover { color: #0E8E7E; }
.wp_login_content .login_loading { min-height: 44px; padding: 0 0 14px; color: #777085; }
.wp_login_content .login_spinner { border-color: #E4DDEC; border-top-color: #0E8E7E; }
.wp_login_content .login_error { margin: 0 0 16px; border-color: #EDA8B9; border-radius: 10px; background: #F9E1E7; color: #C54D68; }
.wp_login_content .login_notice { display: flex; margin-top: 2px; align-items: center; justify-content: center; gap: 9px; color: #8A8296; font-size: 12px; }
.wp_login_content .login_notice a { color: #0E8E7E; font-weight: 700; text-decoration: none; }
.wp_login_content .login_notice a:hover { color: #0B665C; text-decoration: underline; text-underline-offset: 3px; }
.wp_login_about { width: min(440px, 100%); margin-top: 20px; padding: 18px 20px; border: 1px solid rgba(168,144,198,0.28); border-radius: 18px; background: rgba(255,252,250,0.72); color: #686078; box-sizing: border-box; box-shadow: 0 12px 30px rgba(101,82,120,0.08); backdrop-filter: blur(12px); }
.wp_login_about h2 { margin: 0 0 8px; color: #514A72; font-size: 16px; font-weight: 850; line-height: 1.45; text-align: center; }
.wp_login_about p { margin: 0; font-size: 12px; line-height: 1.7; text-align: center; word-break: keep-all; }
.wp_login_about ul { display: flex; margin: 12px 0 0; padding: 0; justify-content: center; flex-wrap: wrap; gap: 6px; list-style: none; }
.wp_login_about li { padding: 5px 9px; border-radius: 999px; background: rgba(14,142,126,0.09); color: #0B665C; font-size: 12px; font-weight: 700; }
.wp_login_tagline { margin: 23px 0 0; color: #726B78; font-size: 14px; font-weight: 600; text-align: center; text-shadow: 0 1px 0 rgba(255,255,255,0.65); }
.wp_login_tagline span { margin-left: 4px; color: #E0A75C; font-size: 18px; }
.wp_login_copyright { margin: 10px 0 0; color: rgba(91,83,94,0.62); font-size: 12px; text-align: center; }
.wp_login_visually_hidden { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

/* ── WithPlanPlus 자체 로그인·회원가입 ── */
.wp_auth_form { display: grid; gap: 11px; text-align: left; }
.wp_auth_field { display: grid; gap: 5px; color: #A3B2AC; font-size: 12px; font-weight: 700; }
.wp_auth_field input { width: 100%; height: 42px; padding: 0 12px; border: 1px solid #4A5752; border-radius: 10px; outline: 0; background: #18201D; color: #E9F0ED; font: inherit; font-size: 14px; box-sizing: border-box; }
.wp_auth_field input:focus { border-color: #35C8A8; box-shadow: 0 0 0 3px rgba(53,200,168,0.13); }
.wp_auth_field input:disabled { opacity: 0.55; }
.wp_auth_field small { color: #7E8E87; font-size: 12px; font-weight: 500; }
.wp_auth_remember, .wp_auth_agree { display: flex; align-items: center; gap: 7px; min-height: 28px; color: #A3B2AC; font-size: 12px; }
.wp_auth_remember input, .wp_auth_agree input { width: 17px; height: 17px; accent-color: #35C8A8; }
.wp_auth_agree a { color: #6ADCC2; font-weight: 700; text-decoration: underline; text-underline-offset: 2px; }
.wp_auth_primary { width: 100%; min-height: 44px; padding: 0 16px; border: 1px solid #35C8A8; border-radius: 11px; background: #35C8A8; color: #06130F; font-family: inherit; font-size: 14px; font-weight: 800; cursor: pointer; }
.wp_auth_primary:hover { background: #6ADCC2; }
.wp_auth_primary:disabled { opacity: 0.55; cursor: wait; }
.wp_auth_links { display: flex; justify-content: center; gap: 0; margin: 13px 0 14px; }
.wp_auth_links a { padding: 0 8px; border-right: 1px solid #3D4844; color: #A3B2AC; font-size: 12px; text-decoration: none; }
.wp_auth_links a:last-child { border-right: 0; }
.wp_auth_links a:hover { color: #6ADCC2; }
.wp_auth_social_toggle { border: 0; background: transparent; color: #7E8E87; font-family: inherit; font-size: 12px; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.wp_auth_social { margin-top: 10px; }
.wp_auth_code_row { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: 8px; }
.wp_auth_code_row > button { min-height: 42px; padding: 0 12px; border: 1px solid #35C8A8; border-radius: 10px; background: transparent; color: #6ADCC2; font-family: inherit; font-size: 12px; font-weight: 700; cursor: pointer; }
/* 계정관리 페이지는 로그인 페이지의 2열 grid(히어로+패널)를 쓰지 않는다 — flex 로 카드를 화면 정중앙에 (2026-08-24) */
.wp_account_page { display: flex; flex-direction: column; overflow: auto; padding: 34px 16px; box-sizing: border-box; }
.wp_account_card { position: relative; width: min(420px, calc(100% - 24px)); margin: auto; padding-top: 32px; }
.wp_account_back { position: absolute; top: 18px; left: 22px; color: #A3B2AC; font-size: 12px; font-weight: 700; text-decoration: none; }
/* 브랜드는 세로 스택(로고 위·제목·부제목 아래) — 가로 나열이면 제목이 꺾이고 부제목이 옆에 낀다 */
.wp_account_card .wp_login_brand { flex-direction: column; gap: 0; margin-bottom: 20px; text-align: center; }
.wp_account_card .wp_login_logo { width: 58px; height: 58px; margin-bottom: 12px; padding: 11px; }
.wp_account_card .wp_login_title { margin: 0; color: #3F3A5C; font-size: 24px; font-weight: 800; letter-spacing: -0.3px; }
.wp_account_card .wp_login_subtitle { margin: 6px 0 0; color: #8A8296; font-size: 13px; }
.wp_auth_panel { text-align: left; }
.wp_auth_message { margin-top: 14px; padding: 10px 12px; border: 1px solid; border-radius: 9px; font-size: 12px; line-height: 1.5; text-align: center; }
.wp_auth_message_ok { border-color: rgba(53,200,168,0.35); background: rgba(53,200,168,0.10); color: #9AEAD7; }
.wp_auth_message_error { border-color: rgba(255,122,122,0.35); background: rgba(255,122,122,0.10); color: #FFA3A3; }
.wp_account_card .wp_auth_message { padding: 13px 15px; border-width: 2px; border-radius: 11px; font-size: 13px; font-weight: 800; line-height: 1.55; box-shadow: 0 8px 20px rgba(72,64,92,0.12); }
.wp_account_card .wp_auth_message_ok { border-color: #4BAF8F; background: #DCF5EA; color: #17604E; }
.wp_account_card .wp_auth_message_error { border-color: #C87591; background: #FBE8EE; color: #87304D; }

/* ── 회원탈퇴(AUTH_ACCOUNT?mode=withdraw) — 안내 박스·위험 버튼 (2026-08-24) ── */
.wp_auth_notice { margin: 0 0 3px; padding: 12px 14px; border: 1px solid #C87591; border-radius: 11px; background: #FBE8EE; color: #87304D; font-size: 12px; line-height: 1.65; }
.wp_auth_notice b { display: block; margin-bottom: 5px; font-size: 13px; }
.wp_auth_notice ul { margin: 0; padding-left: 17px; }
.wp_auth_notice li { list-style: disc; }
.wp_login_card .wp_auth_primary.wp_auth_danger { border-color: #C2455F; background: #C2455F; box-shadow: 0 12px 24px rgba(194,69,95,0.22); }
.wp_login_card .wp_auth_primary.wp_auth_danger:hover { background: #A93850; }

/* ── WithPlanPlus 개인정보 처리방침·이용 약관 ── */
.wp_policy_page .policy_brand { gap: 10px; color: #FFFFFF; }
.wp_policy_page .policy_brand img { width: 38px; height: 38px; }
.wp_policy_page .policy_brand strong { color: #FFFFFF; font-size: 18px; font-weight: 800; letter-spacing: 0.04em; }
.wp_policy_page .policy_brand strong span { color: #6ADCC2; }
.wp_policy_page.terms_page { color: #243841; background: #EDF3F5; }
.wp_policy_page.terms_page .policy_hero { background: linear-gradient(135deg, #082A35 0%, #0A4653 58%, #0C6D70 100%); }
.wp_policy_page.terms_page .policy_hero::before { border-color: rgba(132, 232, 219, 0.14); box-shadow: 0 0 0 80px rgba(132, 232, 219, 0.035), 0 0 0 170px rgba(132, 232, 219, 0.022); }
.wp_policy_page.terms_page .policy_hero::after { background: #74E2CF; box-shadow: 0 0 26px 7px rgba(116, 226, 207, 0.56); }
.wp_policy_page.terms_page .policy_kicker, .wp_policy_page.terms_page .policy_toc a span, .wp_policy_page.terms_page .policy_document_head > span { color: #159A91; }
.wp_policy_page.terms_page .policy_toc { border-color: #D7E3E6; box-shadow: 0 14px 38px rgba(24, 64, 74, 0.09); }
.wp_policy_page.terms_page .policy_toc_title { color: #173A45; border-color: #E4ECEE; }
.wp_policy_page.terms_page .policy_toc a { color: #60757D; }
.wp_policy_page.terms_page .policy_toc a:hover { color: #153E49; background: #EAF7F5; }
.wp_policy_page.terms_page .policy_toc a:focus-visible, .wp_policy_page.terms_page .policy_footer a:focus-visible, .wp_policy_page.terms_page .policy_brand:focus-visible { outline-color: rgba(62, 190, 172, 0.34); }
.wp_policy_page.terms_page .policy_document { border-color: #DCE6E9; box-shadow: 0 20px 55px rgba(22, 62, 72, 0.11); }
.wp_policy_page.terms_page .policy_document_head h2, .wp_policy_page.terms_page .policy_section h2 { color: #173945; }
.wp_policy_page.terms_page .policy_document_head p { border-left-color: #45BFAE; color: #536A73; background: #F3F8F8; }
.wp_policy_page.terms_page .policy_section { border-color: #E4ECEE; }
.wp_policy_page.terms_page .policy_section p, .wp_policy_page.terms_page .policy_section ul, .wp_policy_page.terms_page .policy_section ol { color: #52666E; }
.wp_policy_page.terms_page .policy_section strong { color: #174E5D; }
.wp_policy_page.terms_page .policy_section li::marker { color: #1DAA9E; }
.wp_policy_page.terms_page .terms_inline_link { color: #0E8E85; text-decoration-color: rgba(14, 142, 133, 0.35); }
.wp_policy_page.terms_page .policy_contact { background: linear-gradient(125deg, #0C4C58, #0B746E); }
.wp_policy_page.terms_page .policy_contact > span { color: #7DE3D0; }
.wp_policy_page.terms_page .policy_contact p, .wp_policy_page.terms_page .policy_contact strong { color: #D4EDEB; }
.wp_policy_page.terms_page .policy_footer { border-color: #E4ECEE; }
.wp_policy_page.terms_page .policy_footer a:hover { color: #0E8E85; }
.wp_login_content .login_footer { margin-top: 18px; border-color: #3D4844; }
.wp_login_content .login_footer p { color: #7E8E87; font-size: 12px; }

/* 헤더 테마 콤보 — 두 테마 모두 기본 다크 콤보와 동일하게 표시한다. */
:root .header .header_theme_select select {
  border-color: #5E6D67;
  background-color: #222A27;
  color: #E9F0ED;
  box-shadow: none;
  background-image:
    url("/vendor/moca/images/icon_cmb_arrow.svg"),
    linear-gradient(#3D4844,#3D4844),
    linear-gradient(#2A332F,#2A332F);
}
:root .header .header_theme_select select:hover:not(:disabled) {
  background-image:
    url("/vendor/moca/images/icon_cmb_arrow_hover.svg"),
    linear-gradient(#3D4844,#3D4844),
    linear-gradient(#2A332F,#2A332F);
}
:root .header .header_theme_select select:focus {
  border-color: #35C8A8;
  box-shadow: 0 0 0 2px rgba(53,200,168,0.07);
}


/* ============================================================
 * CAL001 — 월간 캘린더 화면 (달력 본체는 엔진 scheduleCalendar 컴포넌트 — moca.css msc_*)
 * ============================================================ */

/* calendar.html 셸(전용 호스트) — 기본은 뷰포트를 채우고, 일정이 많으면 달력이 자라 문서 전체가 스크롤된다.
   base.css 가 html/body 를 height:100%·overflow:hidden 으로 잠그므로 둘 다 풀어야 초과분이 잘리지 않는다.
   ★ 중간 단계에 % 최소높이를 두지 않는다 — auto 조상에서 해소되지 않아 무의미하다(§10-3-4).
      "뷰포트를 채우는 최소높이" 앵커는 달력 자신에게 dvh(조상 무관 확정값)로 한 번만 준다. */
html:has(.wp_cal_shell),
body:has(.wp_cal_shell) { height: auto; min-height: 100%; overflow-x: hidden; overflow-y: auto; }

/* 모달 딤이 떠 있는 동안 긴 달력 문서의 배경 스크롤을 잠근다. 팝업 내부 스크롤은 별도 컨테이너라 유지된다.
   비모달은 뒤 화면을 함께 조작하는 계약이므로 제외하며, 중첩 모달도 하나라도 남아 있으면 잠금이 유지된다. */
html:has(body > .bd_overlay.on:not(.bd_overlay_nomodal)), body:has(> .bd_overlay.on:not(.bd_overlay_nomodal)) { overflow: hidden; }
.wp_cal_shell { --wp-cal-page-gutter: 30px; height: auto; overflow: visible; background: var(--c-bg); }
.wp_cal_main { height: auto; overflow: visible; }
.wp_cal_main.moca-frame > div { height: auto; overflow: visible; }
.wp_cal_main .moca_schcal { min-height: calc(100vh - var(--wp-cal-page-gutter)); min-height: calc(100dvh - var(--wp-cal-page-gutter)); }

/* 일정 바·날짜영역 메타 스타일은 엔진(moca.css .msc_bar/.msc_meta — scheduleCalendar setData)으로 이관됨 (2026-07-26) */

/* ── CAL001 좌측 옵션·메뉴 드로어 (AS-IS FRM_SIDE 이식 — 달력 헤더의 햄버거로 열린다) ──
   팝업(.bd_overlay z-index:3000) 보다 낮게 둔다 — 드로어에서 뭘 열면 그게 위로 와야 한다. */
.wp_side_dim    { position: fixed; inset: 0; z-index: 2000; background: rgba(0,0,0,0.45);
                  opacity: 0; visibility: hidden; transition: opacity 0.18s; }
.wp_side_dim.on { opacity: 1; visibility: visible; }
/* 폭은 콘텐츠 실측으로 정했다(2026-07-26) — 열1은 고정 메뉴·옵션, 열2는 긴 공유달력명을 기준으로 했다.
  352px 압축 폭은 모바일 뷰포트에서만 적용한다. */
.wp_side        { position: fixed; top: 0; left: 0; z-index: 2010; display: flex; flex-direction: column;
                  max-width: 98vw; height: 100vh; height: 100dvh;
                  background: var(--c-sidebar-bg); border-right: 1px solid var(--c-sidebar-border);
                  box-shadow: var(--wp-shell-shadow); transform: translateX(-100%);
                  transition: transform 0.2s ease; }
.wp_side.on     { transform: none; }










































/* 묶음별 색 — 기본옵션(민트) · 기본공유(파랑) · 공유달력(초록) · 챌린지(노랑) */
#div_secCal     { --wp-sec-accent: var(--c-success); }
#div_secClg     { --wp-sec-accent: var(--c-warning); }





   








/* ============================================================
 * WithPlanPlus 팝업 공통 디자인 — 전체 POP_* 화면의 단일 골격
 * ============================================================ */
/* ★ 한글은 어절 단위로 끊는다 — 기본값(normal)은 CJK 를 음절 아무 데서나 잘라
   "찾았습/니다", "위드플/랜 내 일정"처럼 읽기 나쁜 줄바꿈이 된다(2026-08-30 지적).
   (word-break:break-all 은 반대로 **모든** 글자를 아무 데서나 끊으므로 한글 본문에 쓰지 않는다)

   ⚠ overflow-wrap:anywhere 를 여기(공통)에 함께 두지 않는다 — **상속되어** "81건"·"가져오기" 같은
   짧은 토막까지 아무 데서나 쪼갠다(2026-08-30 실사고: "81/건", "가져오/기").
   anywhere 는 **긴 이메일·URL 을 실제로 담는 자리에만** 좁게 준다(아래 .wp_pop_break_any). */
.wp_pop_layout,
.wp_pop_layout p, .wp_pop_layout li, .wp_pop_layout span, .wp_pop_layout b,
.wp_pop_layout em, .wp_pop_layout h3, .wp_pop_layout label
                { word-break: keep-all; }
/* 띄어쓰기 없는 긴 문자열(이메일·URL)이 들어오는 자리 전용 */
.wp_pop_break_any { overflow-wrap: anywhere; }

/* ── 가져오기 팝업 공용(.wp_imp_*) — POP_IMPORT 가 쓴다(POP_GIMPORT 는 2026-09-07 삭제).
   ★ 화면 <style> 에 두면 그 화면을 먼저 연 경우에만 적용된다 — 실제로 구글 팝업만 열면
   스타일이 통째로 빠졌다(2026-08-30). 두 화면이 공유하는 순간 공용 CSS 가 제자리다. ── */
.wp_imp_src    { padding:12px 14px; }
.wp_imp_src b  { display:block; font-size:14px; }
/* 이메일이 들어오는 자리라 여기만 아무 데서나 끊기를 허용한다(위 ⚠ 주석) */
.wp_imp_src span { display:block; color:var(--c-text-sub); font-size:12.5px; margin-top:2px; overflow-wrap: anywhere; }
.wp_imp_src em { display:block; margin-top:6px; color:var(--c-primary); font-style:normal; font-size:12.5px; }
.wp_imp_sum    { list-style:none; margin:0; padding:0; overflow:hidden; }
.wp_imp_sum li { display:flex; justify-content:space-between; align-items:center; gap:10px;
                 padding:10px 14px; border-bottom:1px solid var(--wp-pop-border); font-size:13px; }
.wp_imp_sum li:last-child { border-bottom:0; }
/* 라벨은 줄어들고(2줄이 돼도 읽힌다), 값은 절대 쪼개지지 않는다 —
   "81건"이 "81 / 건"으로 갈리면 숫자로 안 읽힌다(2026-08-30 지적) */
.wp_imp_sum span { color:var(--c-text-sub); min-width:0; }
.wp_imp_sum b  { font-size:14px; flex:0 0 auto; white-space:nowrap; }
.wp_imp_sum .wp_imp_skip b { color:var(--c-text-muted); }
.wp_imp_note   { margin:0; padding:10px 12px; border-left:3px solid var(--c-primary);
                 border-radius:0 var(--wp-pop-radius) var(--wp-pop-radius) 0;
                 background:color-mix(in srgb, var(--c-primary) 10%, transparent); color:var(--c-text-sub);
                 font-size:12.5px; line-height:1.7; }
.wp_imp_empty  { padding:26px 10px; text-align:center; color:var(--c-text-sub); font-size:13px; }
.wp_imp_h3     { margin:6px 0 0; font-size:13px; color:var(--c-text-sub); }
.wp_imp_hist   { list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:8px; }
.wp_imp_hist li{ display:flex; justify-content:space-between; align-items:center; gap:10px;
                 padding:10px 12px; font-size:13px; }
.wp_imp_hist li.is_rollback { opacity:.55; }
.wp_imp_hist b { display:block; }
.wp_imp_hist span { display:block; color:var(--c-text-sub); font-size:12px; margin-top:2px; }
.wp_imp_wrap   { display:flex; flex-direction:column; gap:12px; }
/* ★ 세로 flex + overflow:auto 컨테이너의 자식은 반드시 flex:0 0 auto.
   기본값이 flex-shrink:1 이라, 내용이 넘치면 스크롤이 생기는 게 아니라 **자식이 찌그러진다**.
   실제로 요약 카드가 347px 내용을 가진 채 높이 2px 로 눌려 화면에서 사라졌다(2026-08-30 실측). */
.wp_imp_wrap > * { flex:0 0 auto; }
/* ★ 팝업 골격 공통 — 「헤더·푸터 고정, 가운데만 스크롤」(§1-1 ④-2).
   호출측이 준 모달 높이를 팝업 몸통 → page_wrap → layout 으로 **flex 사슬로 전달**한다.
   사슬이 한 곳이라도 끊기면 레이아웃이 자기 내용만큼 뻗어 푸터가 화면 밖으로 밀린다.
   ★ 팝업마다 따로 선언하지 않는다 — 실제로 팝업 3개를 하나씩 고치다 같은 문제를 세 번 만났다
   (2026-08-30). 모든 withplan 팝업이 .wp_pop_layout 을 달고 있으므로 여기서 한 번에 준다. */
.moca_popup_body:has(> .page_wrap > .wp_pop_layout)              { display: flex; flex-direction: column; overflow: hidden; }
.moca_popup_body:has(> .page_wrap > .wp_pop_layout) > .page_wrap { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; overflow: visible; }
.wp_pop_layout  { color: var(--c-text); flex: 1 1 auto; min-height: 0; }
.wp_pop_toolbar { padding: 12px; border: 1px solid var(--wp-pop-border); border-radius: var(--wp-pop-radius); background: var(--wp-pop-card-bg); }
.wp_pop_scroll  { min-height: 0; overflow: auto; overscroll-behavior: contain; }
/* ★ auto 칸(data-m-token=auto)의 basis 를 내용으로 되돌린다 — 「height 를 안 준 팝업이 주저앉는」 사고 (2026-09-14)
   엔진 CSS 는 auto 칸을 flex:1 1 0(basis **0**)로 준다. 고정높이 팝업에서는 "남은 공간 전부"라 맞지만,
   height 를 주지 않은 팝업(=내용맞춤, §1-1 ④)에서는 그 칸이 **내용 높이에 한 톨도 기여하지 못한다** —
   팝업 몸통이 엔진 하한 .moca_popup_body{min-height:120px} 까지 주저앉아 본문이 20px 만 보인다.
   에러가 안 나고 조용히 찌그러지므로 호출측이 height 를 빠뜨린 것을 아무도 못 알아챈다(실사고: 일자목록 [등록] → 일정 등록).
   실측(1440x900, 내용 6카드): 수정 전 팝업 160px·본문 20px → 수정 후 725px(=90vh 상한)·본문 585px,
   내용이 짧으면 내용만큼(194px), height 를 준 팝업은 이전과 완전히 동일(725px — grow 1 이 그대로 채운다).
   fit/px 칸과 비율(숫자) 칸은 건드리지 않는다 — 토큰이 정확히 auto 인 칸만 고른다. */
.wp_pop_layout > .moca_layout_pane[data-m-token="auto"] { flex-basis: auto; }
.wp_pop_card    { border: 1px solid var(--wp-pop-border); border-radius: var(--wp-pop-radius); background: var(--wp-pop-card-bg); }
/* ★ 팝업 안의 실행 버튼은 **자리와 무관하게** 같은 규격이다 — 푸터든 인라인/* ============================================================
 * ★ 팝업 공통 개편 (wpp_*) — 2026-09-02, 상세팝업(POP_SCHVIEW A안)의 문법을 위드플랜 팝업 전부에
 *   ① 팝업 안의 테마 토큰을 블루 계열로 재정의한다 — 엔진·화면이 var(--c-primary) 로 칠하는 곳
 *      (머리 아이콘·체크박스·포커스 링·안내 상자 선·조회 버튼…)이 한 번에 파랑이 된다. 초록은 팝업 밖(달력)에만 남는다.
 *      역할색은 드로어와 같다: 파랑=주 행동/완료, 오렌지=등록·찾기, 퍼플=공유·음성, 붉은 글자=삭제.
 *   ② 머리: 순백(다크는 팝업 바탕) + 1px 회색 밑줄, 파랑 아이콘, ✕ 는 드로어 .wpm_x 와 같은 테두리 버튼.
 *      오른쪽 「동작 자리」(.wpp_acts — js/com.js 의 wpPop.acts 가 팝업 페이지 onpageload 에서 만든다):
 *      돋보기(오렌지)·마이크(퍼플), 44px 터치. 어떤 팝업에 무엇을 넣는지는 페이지가 정한다.
 *   ③ 푸터: 보이는 버튼 수만큼 등분(grid auto-fit — display:none 버튼은 칸을 안 먹는다).
 *      주 행동(bd_btn_save)=파랑 채움+아이콘, 닫기/취소=회색 보조, 삭제·되돌리기(bd_btn_del)=붉은 글자, 신규(bd_btn_new)=오렌지.
 *      아이콘은 클래스가 정한다 — 기본 ✓, 바꾸려면 wpp_i_plus / wpp_i_link / wpp_i_import / wpp_i_undo / wpp_i_copy / wpp_i_none 을 덧붙인다.
 *   엔진 CSS 는 손대지 않는다 — 전부 특이도로 덮는다. 버튼·체크박스는 :root 접두(0,3,x) — 엔진 theme-light-fix.css 가
 *   :root.theme-light .bd_btn_close 처럼 (0,2,0) 으로 덮고 있어 같은 특이도면 뒤에 오는 엔진 쪽이 이긴다(실측 — 닫기가 surface 색이었다).
 *   ★ 머리 날짜: 상세 팝업 제목에 붙이던 날짜(.wsv_pop_date)는 본문 시작일시와 겹쳐 뺐다. 일정 목록은 날짜가 곧 제목이라 그대로.
 * ============================================================ */
.bd_overlay > .bd_modal
                { --wpp-blue: #6E97FF; --wpp-blue-soft: #20304A; --wpp-orange: #FF8A4C; --wpp-purple: #A78BFF; --wpp-red: #FF627D;
                  --wpp-bg: #262E2B; --wpp-card: #1C2321; --wpp-line: #3D4844; --wpp-ink: var(--c-text); --wpp-mute: var(--c-text-sub);
                  --c-primary: var(--wpp-blue); --c-primary-dark: #5C88FF; --c-primary-light: rgba(110,151,255,0.16); --c-primary-pale: rgba(110,151,255,0.10);
                  --wp-pop-card-bg: var(--wpp-card); --wp-pop-border: var(--wpp-line);
                  background: var(--wpp-bg); border-color: var(--wpp-line); }
:root.theme-light .bd_overlay > .bd_modal
                { --wpp-blue: #1F5EFF; --wpp-blue-soft: #EAF0FF; --wpp-orange: #F26B1D; --wpp-purple: #7C4DFF; --wpp-red: #D84C64;
                  --wpp-bg: #FFFFFF; --wpp-card: #F4F6F8; --wpp-line: #E9ECF0;
                  --c-primary: var(--wpp-blue); --c-primary-dark: #1749CC; --c-primary-light: rgba(31,94,255,0.10); --c-primary-pale: rgba(31,94,255,0.06); }
.bd_overlay .bd_modal_body { background: var(--wpp-bg); }
/* 머리 */
.bd_overlay .bd_modal_header { gap: 8px; padding: 8px 10px 8px 16px; background: var(--wpp-bg); border-bottom: 1px solid var(--wpp-line); }
.bd_overlay .bd_modal_title  { flex: 1 1 auto; min-width: 0; font-size: 16px; color: var(--wpp-ink); }
.bd_overlay .bd_modal_title::before { background-color: var(--wpp-blue); }
/* 팝업 성격별 제목 아이콘(js/com.js wpPop.icon → .bd_modal.wpp_ico_<kind>) — 엔진 기본(문서 아이콘) 대신 (2026-09-03 지시) */
/* 일정 상세 제목은 메모 문서 아이콘 — 달력 아이콘은 본문 달력명 앞(.wp_ico_cal)에 쓰므로 둘이 겹쳐 보였다(2026-09-06 지적) */
.bd_modal.wpp_ico_view    .bd_modal_title::before { -webkit-mask-image: url('../images/icon_note.svg'); mask-image: url('../images/icon_note.svg'); background-color: var(--wpp-blue); }
.bd_modal.wpp_ico_edit    .bd_modal_title::before { -webkit-mask-image: url('../images/icon_edit.svg');   mask-image: url('../images/icon_edit.svg');   background-color: var(--wpp-orange); }
.bd_modal.wpp_ico_list    .bd_modal_title::before { -webkit-mask-image: url('/vendor/moca/images/icon_menu.svg');     mask-image: url('/vendor/moca/images/icon_menu.svg');     background-color: var(--wpp-blue); }
.bd_modal.wpp_ico_search  .bd_modal_title::before { -webkit-mask-image: url('/vendor/moca/images/icon_search.svg');   mask-image: url('/vendor/moca/images/icon_search.svg');   background-color: var(--wpp-orange); }
.bd_modal.wpp_ico_share   .bd_modal_title::before { -webkit-mask-image: url('../images/icon_share.svg');  mask-image: url('../images/icon_share.svg');  background-color: var(--wpp-purple); }
.bd_modal.wpp_ico_setting .bd_modal_title::before { -webkit-mask-image: url('../images/menu_setting.svg'); mask-image: url('../images/menu_setting.svg'); background-color: var(--wpp-ink); }
.bd_modal.wpp_ico_import  .bd_modal_title::before { -webkit-mask-image: url('../images/menu_import.svg');  mask-image: url('../images/menu_import.svg');  background-color: var(--wpp-blue); }
.bd_modal.wpp_ico_clg     .bd_modal_title::before,
.bd_modal.wpp_ico_clghist .bd_modal_title::before { -webkit-mask-image: url('../images/menu_challenge.svg'); mask-image: url('../images/menu_challenge.svg'); background-color: var(--wpp-orange); }
.bd_modal.wpp_ico_mycal   .bd_modal_title::before { -webkit-mask-image: url('../images/menu_mycal.svg');   mask-image: url('../images/menu_mycal.svg');   background-color: var(--wpp-blue); }
.bd_modal.wpp_ico_subcal  .bd_modal_title::before { -webkit-mask-image: url('../images/menu_subcal.svg');  mask-image: url('../images/menu_subcal.svg');  background-color: var(--wpp-purple); }
.bd_modal.wpp_ico_color   .bd_modal_title::before { -webkit-mask-image: url('../images/icon_palette.svg'); mask-image: url('../images/icon_palette.svg'); background-color: var(--wpp-purple); }
.bd_modal.wpp_ico_appinfo .bd_modal_title::before { -webkit-mask-image: url('../images/menu_info.svg');   mask-image: url('../images/menu_info.svg');   background-color: var(--wpp-blue); }
.bd_modal[class*="wpp_ico_"] .bd_modal_title::before { width: 1.05em; height: 1.05em; }
/* 일자 목록 제목(날짜)은 조금 작게 한 줄로 — 큰 글자에서 두 줄로 꺾였다(예약 2026-09-03) */
.bd_modal.wpp_ico_list .bd_modal_title { font-size: 14.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bd_overlay .bd_modal_close  { width: 44px; height: 44px; border: 1px solid var(--wpp-line); border-radius: 12px; background: var(--wpp-bg); color: var(--wpp-ink); font-size: 17px; }
.bd_overlay .bd_modal_close:hover { border-color: var(--wpp-blue); color: var(--wpp-blue); background: var(--wpp-bg); }
.bd_overlay .bd_modal_close:focus-visible, .wpp_act:focus-visible { outline: 2px solid var(--wpp-blue); outline-offset: 2px; }
.wpp_acts       { display: flex; gap: 6px; flex: 0 0 auto; }
.wpp_act        { position: relative; width: 44px; height: 44px; padding: 0; border: 0; border-radius: 12px; background: var(--wpp-card); cursor: pointer; }
.wpp_act::before { content: ''; position: absolute; inset: 0; margin: auto; width: 22px; height: 22px; background-color: currentColor; -webkit-mask: no-repeat center / contain; mask: no-repeat center / contain; }
.wpp_act:hover  { filter: brightness(0.96); }
.wpp_act_search { color: var(--wpp-orange); }
.wpp_act_search::before { -webkit-mask-image: url('/vendor/moca/images/icon_search.svg'); mask-image: url('/vendor/moca/images/icon_search.svg'); }
.wpp_act_mic    { color: var(--wpp-purple); }
.wpp_act_mic::before { -webkit-mask-image: url('../images/icon_mic.svg'); mask-image: url('../images/icon_mic.svg'); }
/* 채팅 모드에서 마이크 자리를 대신하는 채팅 아이콘(com.js wpPop KIND.chat) — 팝업 위 FAB 가 「닫기」를 가리던 것을 머리로 옮겼다(2026-09-04) */
.wpp_act_chat   { color: #7B8AFF; }
.wpp_act_chat::before { -webkit-mask-image: url('../images/icon_chat.svg'); mask-image: url('../images/icon_chat.svg'); }
/* 체크박스 — 켜진 칸은 파랑 채움(엔진 기본은 surface 바탕에 흰 체크라 켜졌는지 흐리다) */
:root .bd_overlay .checkboxGroup .moca_checkbox_input { border-color: var(--c-border-dark); }
:root .bd_overlay .checkboxGroup .moca_checkbox_input:checked { background-color: var(--wpp-blue); border-color: var(--wpp-blue); }
/* 푸터 — 보이는 버튼 수만큼 등분. 엔진 .pop_btn_area 의 margin-top:10px 도 여기서 접는다 */
:root .moca_popup_body .bd_modal_btns.wp_pop_footer { display: grid; grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); gap: 8px; margin: 0; padding: 8px 2px 2px; border-top: 1px solid var(--wpp-line); }
/* ★ 팝업 안의 실행 버튼은 **자리와 무관하게** 같은 규격이다 — 푸터든 인라인 폼이든.
   자리마다 따로 스타일을 주면 반드시 한 곳이 빠진다(2026-08-30 챌린지 폼 지적). 여백은 em 이라 배율을 따라 넉넉해진다(§15-3-4). */
/* 푸터 자식은 > * 로 잡는다 — button 요소를 붙이면 (0,3,1) 이 되어 아래 색 규칙(0,3,0)의 border-color 를 이긴다(실측 — 닫기 테두리가 투명이었다) */
:root .moca_popup_body .wp_pop_footer > *,
:root .moca_popup_body .bd_btn_save,  .moca_popup_body .bd_btn_close, :root .moca_popup_body .bd_btn_del,
:root .moca_popup_body .bd_btn_new,   .moca_popup_body .bd_btn_edit,  .moca_popup_body .bd_btn_cancel
                { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-width: 0; min-height: max(44px, var(--wp-control-h)); height: auto;
                  padding: 0.3em 0.9em; border: 1px solid transparent; border-radius: 12px; font-family: inherit; font-size: 14px; font-weight: 700; line-height: 1.2; white-space: nowrap; cursor: pointer; }
:root .moca_popup_body .bd_btn_save::before, :root .moca_popup_body .bd_btn_new::before, :root .moca_popup_body .bd_btn_edit::before, :root .moca_popup_body .bd_btn_del::before,
:root .moca_popup_body .bd_btn_close::before, :root .moca_popup_body .bd_btn_cancel::before
                { content: ''; flex: 0 0 auto; width: 18px; height: 18px; background-color: currentColor; -webkit-mask: no-repeat center / contain; mask: no-repeat center / contain; }
:root .moca_popup_body .bd_btn_save   { background: var(--wpp-blue); border-color: var(--wpp-blue); color: #FFFFFF; }
:root .moca_popup_body .bd_btn_save::before { -webkit-mask-image: url('../images/icon_check.svg'); mask-image: url('../images/icon_check.svg'); }
:root .moca_popup_body .bd_btn_edit   { background: var(--wpp-blue-soft); border-color: transparent; color: var(--wpp-blue); }
:root .moca_popup_body .bd_btn_edit::before { -webkit-mask-image: url('../images/icon_edit.svg'); mask-image: url('../images/icon_edit.svg'); }
:root .moca_popup_body .bd_btn_new    { background: var(--wpp-orange); border-color: var(--wpp-orange); color: #FFFFFF; }
:root .moca_popup_body .bd_btn_new::before { -webkit-mask-image: url('../images/icon_plus.svg'); mask-image: url('../images/icon_plus.svg'); }
:root .moca_popup_body .bd_btn_del    { background: transparent; border-color: var(--wpp-line); color: var(--wpp-red); }
:root .moca_popup_body .bd_btn_del::before { -webkit-mask-image: url('/vendor/moca/images/icon_trash.svg'); mask-image: url('/vendor/moca/images/icon_trash.svg'); }
/* ★ 버튼 색 규칙(2026-09-03 지시): 버튼에 회색을 쓰지 않는다 — 회색은 비활성(:disabled) 전용. 보조 버튼(닫기·취소)은 연파랑 바탕 + 파란 글자 */
:root .moca_popup_body .bd_btn_close, :root .moca_popup_body .bd_btn_cancel { background: var(--wpp-blue-soft); border-color: var(--wpp-blue-soft); color: var(--wpp-blue); }
/* ★ 닫기·취소도 글자 앞에 아이콘(✕) — 팝업마다 「■ 닫기」/「닫기」 로 달랐던 것을 통일(2026-09-04 지시). 일정 상세(.wsv_b_x)와 같은 SVG 를 쓴다 */
:root .moca_popup_body .bd_btn_close::before, :root .moca_popup_body .bd_btn_cancel::before { -webkit-mask-image: url('../images/icon_close.svg'); mask-image: url('../images/icon_close.svg'); }
:root .moca_popup_body .bd_btn_save:hover, :root .moca_popup_body .bd_btn_new:hover, :root .moca_popup_body .bd_btn_edit:hover { filter: brightness(1.05); }
:root .moca_popup_body .bd_btn_close:hover, :root .moca_popup_body .bd_btn_cancel:hover { filter: brightness(0.97); }
:root .moca_popup_body .bd_btn_del:hover { color: var(--wpp-red); border-color: var(--wpp-red); background: transparent; }
:root .moca_popup_body .wp_pop_footer button:focus-visible { outline: 2px solid var(--wpp-blue); outline-offset: 2px; }
/* 아이콘 교체 — 같은 특이도라 기본(✓)보다 뒤에 둔다 */
:root .moca_popup_body .wpp_i_plus::before   { -webkit-mask-image: url('../images/icon_plus.svg');   mask-image: url('../images/icon_plus.svg'); }
:root .moca_popup_body .wpp_i_link::before   { -webkit-mask-image: url('../images/icon_link.svg');   mask-image: url('../images/icon_link.svg'); }
:root .moca_popup_body .wpp_i_import::before { -webkit-mask-image: url('../images/menu_import.svg'); mask-image: url('../images/menu_import.svg'); }
:root .moca_popup_body .wpp_i_undo::before   { -webkit-mask-image: url('../images/icon_undo.svg');   mask-image: url('../images/icon_undo.svg'); }
:root .moca_popup_body .wpp_i_copy::before   { -webkit-mask-image: url('../images/icon_copy.svg');   mask-image: url('../images/icon_copy.svg'); }
:root .moca_popup_body .wpp_i_none::before   { display: none; }
/* ★ 못 누르는 버튼은 못 누르게 보여야 한다. 버튼명으로 상태를 설명하지 않기로 했으므로(§1-1 ④-4)
   disabled 의 시각 표현이 유일한 신호다 — 없으면 "왜 안 눌리지"가 되고, 실제로 다 가져온 뒤에도
   활성처럼 보여 "또 가져오려는 거냐"는 지적을 받았다(2026-08-30). */
:root .moca_popup_body .wp_pop_footer > [hidden] { display: none !important; }
.wp_pop_footer button:disabled,
.bd_modal_btns button:disabled { opacity: .4; cursor: not-allowed; box-shadow: none; filter: grayscale(.4); }
/* ★ 저장소 분리(62a7ab1) 때 이 줄의 앞부분이 잘려 나가 규칙 전체가 죽어 있었다 — 아이콘 버튼(수정·삭제)이
   테두리도 크기도 없이 보이지 않는 채로 남았고, 카드의 빈 곳을 누르면 눌리는 것처럼 보였다(2026-09-05 지적).
   원문은 moca2026ai c1cfb44^ 에서 복구. */
.wp_pop_icon_btn { display: flex; align-items: center; justify-content: center; width: var(--wp-control-h); height: var(--wp-control-h); padding: 0; border: 1px solid var(--c-border-dark); border-radius: 6px; background: transparent; color: var(--c-text-sub); cursor: pointer; }
.wp_pop_icon_btn::before { content: ''; display: block; width: 52%; height: 52%; background-color: currentColor; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-position: center; mask-position: center; -webkit-mask-size: contain; mask-size: contain; }
.wp_pop_icon_edit::before { -webkit-mask-image: url('../images/icon_edit.svg'); mask-image: url('../images/icon_edit.svg'); }
.wp_pop_icon_del::before { -webkit-mask-image: url('/vendor/moca/images/icon_trash.svg'); mask-image: url('/vendor/moca/images/icon_trash.svg'); }
.wp_pop_icon_btn:hover { border-color: var(--c-primary); color: var(--c-primary); }
.wp_pop_icon_del:hover { border-color: var(--c-danger); color: var(--c-danger); }
.wp_pop_icon_btn:focus-visible { outline: 2px solid var(--c-primary); outline-offset: 2px; }

/* ============================================================
 * POP_DAYLIST — 일자 일정 목록 팝업
 * ============================================================ */
/* 일정 목록도 챌린지 트레이와 짝인 테두리 카드 — 영역 경계가 테두리로 읽힌다(2026-08-10 지적) */
.wpl_list       { min-height: 0; overflow: auto; border: 1px solid var(--c-border-dark); border-radius: var(--wp-pop-radius); padding: 0 8px 4px; background: var(--wp-pop-card-bg); }
.wpl_schedule_head { position: sticky; top: 0; z-index: 2; display: flex; align-items: center; gap: 5px; padding: 8px 6px 7px; border-bottom: 1px solid var(--c-border); background: var(--c-surface); font-size: 13px; font-weight: 700; color: var(--c-text); }
.wpl_schedule_head b { color: var(--c-primary); }
.wpl_empty      { padding: 40px 0; text-align: center; color: var(--c-text-muted); font-size: 13px; }
.wpl_dayinfo    { display: flex; align-items: center; gap: 6px; padding: 6px 6px 8px; border-bottom: 1px solid var(--c-border); }
.wpl_holi       { color: var(--c-danger); font-size: 13px; font-weight: 600; }
.wpl_anniv      { color: var(--c-text-muted); font-size: 13px; font-weight: 500; }   /* 기념일 — 달력 칸의 회색 한 줄과 같은 톤 */
.wpl_dayinfo    { flex-wrap: wrap; }
.wpl_dayname    { display: inline-flex; align-items: center; gap: 4px; margin-right: 8px; }
/* 「설명」 버튼(2026-09-07 시안 B 채택) — 파란 바탕 흰 글자의 작은 사각 버튼. 글꼴은 font 축약형을 쓰지 않는다(inherit 가 들어가면 선언 전체가 무효 — 직전 배포 사고) */
.wpl_info       { display: inline-flex; align-items: center; height: 24px; padding: 0 10px; border: 0; border-radius: 7px; background: var(--c-primary); color: #fff; font-family: inherit; font-size: 12px; font-weight: 700; line-height: 1; white-space: nowrap; cursor: pointer; box-shadow: 0 1px 2px rgba(0,0,0,.12); }
.wpl_info:hover { filter: brightness(1.08); }
.wpl_info:active { transform: translateY(1px); }
.wpl_info:disabled { opacity: .5; cursor: default; }
/* 설명 팝업 — 높이를 화면의 40% 로 고정하고 본문만 스크롤(2026-09-07 지시). 긴 설명이 팝업을 화면 밖까지 늘리지 않게 */
.wpl_desc       { text-align: left; }
.wpl_desc p     { max-height: 40vh; overflow-y: auto; -webkit-overflow-scrolling: touch; padding-right: 6px; }
.wpl_desc b     { display: block; font-size: 15px; margin-bottom: 6px; }
.wpl_desc p     { margin: 0; font-size: 14px; line-height: 1.7; color: var(--c-text-body); word-break: keep-all; max-height: 40vh; overflow-y: auto; -webkit-overflow-scrolling: touch; padding-right: 6px; }
/* ── 일자 목록 줄 = 시안 C 「두 줄 미니멀」(2026-09-07 채택) ──
   1줄 [점][이모지] 제목 …… 시간 / 2줄(11px 흐림) [n/총일 칩] 달력명 · 작성자 이름. 장식 없이 글자 크기 차이로 위계.
   종전 「유형 칩 + 본문 두 줄(제목·시간 / 작성자·달력 칩)」 은 세 글자가 같은 강도로 읽혔고 칩 유무로 제목 시작점이 흔들렸다 */
.wpl_item       { display: block; padding: 8px 8px; border-bottom: 1px solid var(--c-border); cursor: pointer; }
.wpl_focus      { background: var(--c-primary-pale); box-shadow: inset 3px 0 0 var(--c-primary); }
.wpl_item:hover { background: var(--c-bg-hover); }
.wpl_item:last-child { border-bottom: none; }
.wpl_l1         { display: flex; align-items: center; gap: 8px; min-width: 0; }
.wpl_dot        { flex: 0 0 auto; width: 10px; height: 10px; border-radius: 50%; }
.wpl_ico        { flex: 0 0 auto; font-size: 13px; line-height: 1; }
.wpl_title_text { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; font-weight: 600; color: var(--c-text); }
.wpl_time       { flex: 0 0 auto; color: var(--c-text-sub); font-size: 12px; white-space: nowrap; }
.wpl_l2         { display: flex; align-items: center; gap: 5px; min-width: 0; margin: 1px 0 0 18px; font-size: 11px; color: var(--c-text-muted); }
.wpl_l2_txt     { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wpl_l2 b       { font-weight: 600; color: var(--c-text-sub); }
/* 연속일정 「n/총일」 칩 — 2줄 맨 앞, 보라 톤(달력 칸 연속 기본색과 같은 계열) */
.wpl_kind       { flex: 0 0 auto; display: inline-flex; align-items: center; padding: 0 6px; border-radius: 5px; font-size: 11px; font-weight: 700; line-height: 1.5;
                  background: rgba(124,77,255,0.12); color: #6A3DE8; white-space: nowrap; }
:root:not(.theme-light) .wpl_kind { background: rgba(167,139,255,0.18); color: #B9A4FF; }
.wpl_done .wpl_title_text { text-decoration: line-through; opacity: 0.6; }

/* 챌린지 고정 트레이 — 일정 스크롤 밖에서 요약 헤더는 항상 보이고, 본문은 위로 펼쳐진다.
   ★ 배경을 일정 목록(팝업 surface)과 같게 두면 접었다 펼칠 때 어디까지가 챌린지인지 안 읽힌다
   (2026-08-10 지적) — 한 단계 다른 배경(--c-bg) 카드 + primary 강조 헤더 바로 영역을 분리한다. */
.wpl_clg_slot   { min-height: 0; }
/* 트레이 본문 — 민트 색조 면(#14342B)은 "온통 초록"이 돼서 반려(2026-08-10 4차 지적).
   초록기를 뺀 블루그레이 중립 면으로: 색조(그린 vs 블루그레이) + 명도 둘 다 목록과 다르면서
   테마가 초록 일색이 되지 않는다. 좌측 primary 강조선도 같은 이유로 제거(헤더 색면이면 충분) */
.wpl_clg        { padding: 0; border: 1px solid var(--c-border-dark); border-radius: 10px; background: #171D24; overflow: hidden; }
:root.theme-light .wpl_clg { background: #E7EBF1; }

/* 헤더는 primary 채움(solid) — 틴트(반투명)로는 색약 사용자가 영역을 못 느낀다(2026-08-10 지적).
   색조가 아니라 명도 대비로 구분한다. 본문 배경도 --c-bg 로는 목록과 차이가 안 읽혀
   한 단계 더 어두운 --wp-shell-bg 를 쓴다. 다크 헤더는 --c-primary(형광 민트)가 아니라
   --c-primary-dark — 너무 밝으면 🏆 이모지가 배경에 묻힌다(같은 날 추가 지적). */
.wpl_clg_head   { display: flex; align-items: center; gap: 5px; width: 100%; min-height: 38px; padding: 5px 12px; border: 0; background: var(--c-primary-dark); font-family: inherit; text-align: left; font-size: 13px; font-weight: 700; color: #06130F; cursor: pointer; user-select: none; }
:root.theme-light .wpl_clg_head { color: #FFFFFF; }   /* 라이트 --c-primary-dark(#0B7264)는 흰 글자 AA 통과 */
.wpl_clg_head:hover { filter: brightness(1.08); }
.wpl_clg_head:focus-visible { outline: 2px solid currentColor; outline-offset: -3px; }
.wpl_clg_head b { color: inherit; }
.wpl_clg_body   { max-height: 260px; max-height: min(260px, 40dvh); margin: 0; padding: 5px 8px 7px; border-top: 1px solid var(--c-border); overflow-y: auto; overscroll-behavior: contain; }
.wpl_clg_arrow  { color: inherit; opacity: 0.75; font-size: 12px; }

/* 헤더 아이콘 — 사용자 제공 엠블럼(icon_challenge.png, 산+깃발). 원본이 다크 네이비 불투명 배경이라
   원형으로 잘라 배지처럼 얹는다 — 네이비 원판이 틸 색면 위에서 명도 대비로 뚜렷하다.
   (이모지 3종은 자체 색 때문에 전부 묻혀 반려된 이력 — SKILL 6-8) */
/* .wpl_clg_hico   { display: inline-block; flex: 0 0 auto; width: 30px; height: 30px; border-radius: 6px; background: url('../images/icon_challenge.png') no-repeat center / cover; } */
.wpl_clg_item   { display: flex; align-items: center; gap: 8px; padding: 8px 4px; cursor: pointer; }
.wpl_clg_item + .wpl_clg_item { border-top: 1px solid rgba(255,255,255,0.09); }   /* 행 구분선 — 중립(초록기 없음) */
:root.theme-light .wpl_clg_item + .wpl_clg_item { border-top-color: rgba(20,35,50,0.14); }
.wpl_clg_item:hover { background: var(--c-bg-hover); }
/* 모양은 엔진 .moca_checkbox_input 이 담당 — 여기선 배치만(토글은 행 클릭이 처리하므로 클릭 통과).
   크기는 글자 배율을 따라간다 — fontScale.js 는 font-size 만 스케일하고 width/height 는 안 건드리므로,
   드로어 체크박스와 같은 방식으로 em 을 써 글자를 따라 커진다(체크만 작게 남던 사고 2026-08-10).
   구 --wp-side-check-* 변수(JS 가 14px×비율로 계산)를 쓰다가 CSS 만으로 같은 결과가 나오는
   1.12em/0.8em 으로 옮겼다(2026-08-30) — 크기 규칙이 JS 와 CSS 두 곳에 나뉘어 있을 이유가 없다. */
.wpl_clg_chk    { margin: 0; pointer-events: none; width: 1.12em; height: 1.12em; }
.wpl_clg_chk:checked { background-size: 0.8em 0.8em; }

/* 라이트 테마 보정 — 이 체크박스는 checkboxGroup 컴포넌트가 아니라 클래스만 빌려 쓴 직접 input 이라
   엔진 theme-light-fix(.checkboxGroup 스코프)가 안 걸린다. 같은 규칙을 화면 스코프로 준다(2026-08-10 실사고 —
   라이트에서 흰 테두리+밝은 배경+흰 체크라 체크해도 안 보였다).
   ⚠ background 축약형 금지 — :checked 의 체크 아이콘(icon_check.svg)까지 리셋된다(엔진 light-fix 와 같은 주의) */
:root.theme-light .wpl_clg_chk { border-color: var(--c-border-dark); background-color: #ffffff; }
:root.theme-light .wpl_clg_chk:checked { background-color: var(--c-primary); border-color: var(--c-primary); }
.wpl_clg_ico    { flex: 0 0 auto; width: 20px; text-align: center; font-size: 14px; }
.wpl_clg_main   { min-width: 0; flex: 1; }
.wpl_clg_name   { font-size: 13px; color: var(--c-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wpl_clg_grp    { font-size: 12px; color: var(--c-text-muted); }
/* 달력명 앞 작은 달력 아이콘(일자 팝업 챌린지 줄·챌린지 목록 카드, 2026-09-06 지시) — 글자색을 따르는 mask 아이콘 */
.wp_ico_cal     { display: inline-block; width: 0.95em; height: 0.95em; margin-right: 0.3em; vertical-align: -0.12em; background-color: currentColor;
                  -webkit-mask: url('/vendor/moca/images/icon_calendar.svg') center / contain no-repeat; mask: url('/vendor/moca/images/icon_calendar.svg') center / contain no-repeat; }
.wpl_clg_done .wpl_clg_name { color: var(--c-text-sub); }

/* ============================================================
 * CAL001 일정찾기 FAB + POP_SCHSEARCH — 통합 일정검색 (wss_*)
 * ============================================================ */

/* 우측하단 돋보기 (AS-IS btn_magnific — 80px 반투명 원 → 테마 primary FAB 로).
   실체는 floatingButton 컴포넌트(CAL001, data-m-iconmode="mask") — 원형·fixed·primary 배경은
   엔진 .moca_fab 기본이 담당하고, 여기서는 위치(22px)·크기(52px)·그림자·z-index 만 오버라이드한다.
   z-index 900 필수: 엔진 기본 6900 은 드로어(2000)·팝업(3000) 위로 떠오른다.
   아이콘색은 mask+currentColor 라 color 로 준다 — 헤더와 같은 명도 규칙:
   다크=밝은 민트 위 어두운 아이콘, 라이트=진한 틸 위 흰 아이콘 */
.wp_cal_fab     { right: 22px; bottom: 22px; z-index: 900; width: 52px; height: 52px; color: #06130F; box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35); }
.wp_cal_fab .moca_fab_icon_mask { width: 24px; height: 24px; }
.wp_cal_fab:hover { filter: brightness(1.08); }
.wp_cal_fab:focus-visible { outline: 2px solid var(--c-text); outline-offset: 2px; }
:root.theme-light .wp_cal_fab { background: var(--c-primary-dark); color: #FFFFFF; }
/* 찾기 FAB 는 오렌지 — 초록이 너무 많다는 판단(2026-09-02). 역할별 색 규칙: 오렌지 = 행동/찾기. 두 테마 모두 흰 아이콘. */
#btn_schSearch.wp_cal_fab { background: #F26B1D; color: #FFFFFF; }
:root.theme-light #btn_schSearch.wp_cal_fab { background: #F26B1D; color: #FFFFFF; }
#btn_schSearch.wp_cal_fab:hover { filter: brightness(1.06); }
/* 앱 음성 FAB 는 일정찾기 버튼 위에 12px 간격으로 쌓는다.
   ★ 색은 원래대로 보라(음성)·민트 채움(검색) — 2026-09-02 에 "한 세트"(음성만 채움·검색 테두리형)로 바꿨다가
     실기기에서 원래 색이 더 낫다는 판단으로 되돌렸다. 다시 통일하려 들지 말 것. */
.wp_cal_voice_fab { bottom: 86px; background: #765CE8; color: #FFFFFF; }
:root.theme-light .wp_cal_voice_fab { background: #765CE8; color: #FFFFFF; }
/* 요일 줄의 회색 띠 제거 — 밑줄 하나면 충분하다(위젯과 같은 규칙) */
.wp_cal_shell .msc_week { background: transparent; }
/* 라이트 테마 — 달력 안쪽도 흰색으로(2026-09-05 지시).
   엔진 기본은 `.moca_schcal { background: var(--c-surface) }` 인데 withplan 라이트 팔레트에서
   --c-surface 는 #F5F8F7(살짝 회색)이라, 바깥 여백(흰색)과 달력 속이 다른 색으로 보였다.
   엔진을 고치지 않고 이 프로젝트에서만 덮는다 — 다른 프로젝트는 회색 면을 의도해 쓸 수 있다. */
:root.theme-light .wp_cal_shell .moca_schcal { background: var(--c-bg); }
/* 음성 FAB만 캘린더 셸 직속 전역 액션이다. 모든 팝업 최대 z-index(3900) 위,
   메시지박스·드롭다운(6200+) 아래에 두며 전환·진행 중 표시는 calendar.html JS가 제한한다. */
.wp_cal_voice_global { z-index: 4000; }
/* ★ 채팅 모드(앱 설정 「에이전트 방식 = 채팅」, calendar.html appToWeb_agentMode) — 마이크를 전부 숨긴다: 달력 음성 FAB + 팝업 머리 마이크(일정찾기·일정상세 등). 2026-09-04 지시 */
html.wp_agent_chat .wp_cal_voice_fab, html.wp_agent_chat .wpp_act_mic { display: none !important; }
/* 채팅 FAB — 검색 FAB 와 같은 엔진 floatingButton(드래그 손맛 동일 — 네이티브 버튼과 달라 2026-09-04 지적). 음성 FAB 자리(bottom 86px)를 쓴다.
   채팅 모드에서만 보인다(음성 모드 = 음성 FAB, 채팅 모드 = 채팅 FAB — 상호 배타). */
.wp_cal_chat_fab { bottom: 86px; background: #5B6EF0; color: #FFFFFF; }
:root.theme-light .wp_cal_chat_fab { background: #5B6EF0; color: #FFFFFF; }
html:not(.wp_agent_chat) .wp_cal_chat_fab { display: none !important; }
/* 그 자리 녹음(호출어로 부른 경우) — 마이크가 깜박이면 듣는 중, 은은히 숨 쉬면 정리 중 (calendar.html appToWeb_voiceState) */
@keyframes wpVoiceBlink { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .35; transform: scale(.92); } }
@keyframes wpVoiceBreath { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
body.wp_voice_rec .wp_cal_voice_fab, :root body.wp_voice_rec .wp_cal_voice_fab { background: #D8466E; animation: wpVoiceBlink .9s ease-in-out infinite; }
body.wp_voice_rec .wpp_act_mic { color: #D8466E; animation: wpVoiceBlink .9s ease-in-out infinite; }
body.wp_voice_proc .wp_cal_voice_fab, body.wp_voice_proc .wpp_act_mic { animation: wpVoiceBreath 1.4s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { body.wp_voice_rec .wp_cal_voice_fab, body.wp_voice_rec .wpp_act_mic, body.wp_voice_proc .wp_cal_voice_fab, body.wp_voice_proc .wpp_act_mic { animation: none; } }

/* 검색 조건 바 — ★ 한 행의 컨트롤(inputCalendar·input·버튼) 높이는 변수 하나로 통일한다
   (moca SKILL §0-3 대원칙 — 컴포넌트 기본 높이가 제각각(28/39/32px)이라 그냥 나열하면 들쭉날쭉).
   높이는 글자 배율 비례(30px×ratio) — ica 표준 28px 고정으로 줄였더니 이번엔 배율을 따라 커진
   팝업 푸터 [닫기]와 어긋났다(2026-08-10 왕복 사고). 통일 범위는 "그 행"이 아니라
   **같은 화면에서 함께 보이는 컨트롤 전부**다 — 배율을 쓰는 화면이면 행 컨트롤도 배율을 따라야 한다 */
.wss_bar        { display: flex; flex-direction: column; gap: 8px; }
.wss_row        { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* .wss_bar 접두로 특이도(0,3,1) — 큰 배율 공통규칙 `.wp_font_lg .moca_input input`(height:auto·min-height:34px)에 지지 않게 */
.wss_bar .wss_row .moca_input input { height: var(--wp-control-h); box-sizing: border-box; }
.wss_bar .wss_row .moca_input input { min-height: 0; }

/* 달력 두 개가 행 폭을 나눠 갖는다 — 1행(from~to)의 우측 끝이 2행(검색어+버튼)의 우측 끝과
   정렬돼야 안정감이 생긴다(2026-08-10 지적). ica 기본 내용폭(ch 계산)을 flex 로 덮는다 */
.wss_bar .wss_row .moca_ica { flex-grow: 1; }
.wss_bar .wss_row .moca_ica input { flex: 1 1 0; width: auto; min-width: 0; }
/* 기간 칸 이름 — 두 줄로 나뉘어도 어느 쪽이 시작인지 읽히게 한다(구 「~」 대체).
   min-width 를 em 으로 둬 배율이 커져도 두 칸의 입력 시작점이 나란히 유지된다. */
.wss_lbl        { flex: 0 0 auto; min-width: 2.4em; color: var(--c-text-sub);
                  font-size: 13px; font-weight: 700; }
.wss_kw         { flex: 1; min-width: 0; }
.wss_kw input   { width: 100%; }

/* 조회 — 정사각 돋보기 아이콘 버튼(글씨 반려 — FAB 와 같은 mask + 명도 규칙).
   bd_btn_save 는 팝업 푸터(.bd_modal_btns) 안에서만 크기를 받는 색상 클래스라 밖에서 쓰지 않는다 */
.wss_btn        { display: flex; align-items: center; justify-content: center; flex: 0 0 auto; width: var(--wp-control-h); height: var(--wp-control-h); padding: 0; border: 0; border-radius: var(--radius-sm); background: var(--c-primary-dark); cursor: pointer; }
.wss_btn::before { content: ''; display: block; width: 55%; height: 55%; background-color: #06130F; -webkit-mask: url('/vendor/moca/images/icon_search.svg') no-repeat center / contain; mask: url('/vendor/moca/images/icon_search.svg') no-repeat center / contain; }
.wss_btn:hover  { filter: brightness(1.08); }
.wss_btn:focus-visible { outline: 2px solid var(--c-text); outline-offset: 2px; }
:root.theme-light .wss_btn::before { background-color: #FFFFFF; }

/* 결과 목록 — 일정 목록 카드(wpl_list)와 같은 카드 골격 */
.wss_list       { min-height: 0; overflow: auto; border: 1px solid var(--c-border-dark); border-radius: var(--wp-pop-radius); padding: 0 8px 4px; background: var(--wp-pop-card-bg); }
.wss_head       { position: sticky; top: 0; z-index: 2; padding: 8px 6px 7px; border-bottom: 1px solid var(--c-border); background: var(--c-surface); font-size: 13px; font-weight: 700; color: var(--c-text); }
.wss_head b     { color: var(--c-primary); }
.wss_more       { color: var(--c-text-muted); font-weight: 400; font-size: 12px; }
.wss_empty      { padding: 40px 0; text-align: center; color: var(--c-text-muted); font-size: 13px; }
.wss_item       { padding: 9px 6px; border-bottom: 1px solid var(--c-border); cursor: pointer; }
.wss_item:hover { background: var(--c-bg-hover); }
.wss_item:last-child { border-bottom: none; }
.wss_date       { display: flex; align-items: center; gap: 8px; color: var(--c-text-sub); font-size: 12px; }
.wss_time       { color: var(--c-text-muted); }
.wss_title      { display: flex; align-items: center; gap: 4px; margin-top: 2px; font-size: 13px; color: var(--c-text); }
.wss_title_text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wss_cru        { color: var(--c-danger); font-weight: 400; }
.wss_sub        { margin-top: 2px; font-size: 12px; color: var(--c-text-muted); }
.wss_ocr        { display: flex; gap: 6px; align-items: baseline; margin-top: 4px; min-width: 0; color: var(--c-text-sub); font-size: 12px; }
.wss_ocr_badge  { flex: 0 0 auto; padding: 1px 5px; border-radius: 999px; background: var(--c-primary-light); color: var(--c-primary); font-size: 11px; font-weight: 700; }
.wss_ocr_snip   { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wss_done .wss_title_text { text-decoration: line-through; opacity: 0.6; }

/* 마지막으로 연 항목 — 상세를 닫아도 남아 "다음 볼 항목"의 기준점이 된다. 좌측 강조선 + 톤 배경 */
.wss_item.wss_active { background: var(--c-primary-light); box-shadow: inset 3px 0 0 var(--c-primary); }
.wss_item.wss_active:hover { background: var(--c-primary-light); }

/* ============================================================
 * POP_SCHVIEW — 일정 상세 (wsv_*) — 2026-09-02 개편(A안, 시안 https://claude.ai/code/artifact/457e761e-fbf7-48ed-93ab-345d77dc2504)
 *   드로어와 같은 문법: 순백·회색 카드·역할별 색(파랑=완료/주 행동, 오렌지=등록, 퍼플=공유, 붉은 글자=삭제).
 *   초록 제목 상자 대신 큰 제목 + 메타 줄, 첨부는 둥근 카드 안에 「이미지 문자 보기」 링크, 정보는 회색 표.
 *   버튼은 「완료·수정」 둘만 크게, 나머지 넷은 아이콘 줄. 「수정」은 연파랑 채움 + 연필(흰 바탕 글자만은 허전 — 사용자 지적).
 *   팝업 머리(제목 바)·푸터 버튼 규격은 위 「팝업 공통 개편(wpp_*)」 절이 모든 팝업에 준다.
 * ============================================================ */
.wsv_layout     { --wsv-ink: var(--c-text); --wsv-mute: var(--c-text-muted); --wsv-line: var(--c-border); --wsv-card: var(--c-bg);
                  --wsv-blue: #6E97FF; --wsv-blue-soft: #20304A; --wsv-orange: #FF8A4C; --wsv-purple: #A78BFF; --wsv-red: #FF627D; }
:root.theme-light .wsv_layout { --wsv-card: #F4F6F8; --wsv-line: #E9ECF0;
                  --wsv-blue: #1F5EFF; --wsv-blue-soft: #EAF0FF; --wsv-orange: #F26B1D; --wsv-purple: #7C4DFF; --wsv-red: #D84C64; }
.wsv_body       { min-height: 0; overflow: auto; display: flex; flex-direction: column; gap: 12px; padding: 2px 2px 6px; }
/* 제목 + 메타 줄 — 제목은 큰 글자 그대로(상자 없음). 메타 = 달력 색 점 + 달력명 · 시간 · 반복 칩 */
.wsv_head       { padding: 4px 2px 0; }
/* .wsv_title 은 폐기(2026-09-06) — 등록에 제목이 없어 본문(메모지)만 보인다. 완료 취소선은 .wsv_cont.wsv_done */
.wsv_meta_line  { display: flex; flex-wrap: wrap; align-items: center; gap: 5px 12px; margin-top: 6px; font-size: 13.5px; color: var(--wsv-mute); }   /* 12.5→13.5px — 달력 배지(1.3em)가 카드 제목 배지와 비슷한 크기로(2026-09-07) */
/* 달력명과 일시를 분리(2026-09-07 지적 "섞여 버렸다") — 달력명은 진한 글씨, 일시는 흐린 글씨 + 왼쪽 세로 구분선 */
.wsv_calnm      { font-weight: 700; color: var(--wsv-ink); }
.wsv_when       { padding-left: 12px; border-left: 1px solid var(--wsv-line); color: var(--wsv-mute); font-size: 11.5px; }   /* 일시는 더 작게(2026-09-07 지시) */
/* .wsv_dot 은 폐기(2026-09-06) — 달력명 앞은 공통 달력 아이콘 .wp_ico_cal. 상세에선 조금 크게, 기본색은 달력 파랑 */
.wsv_calico     { width: 1.05em; height: 1.05em; vertical-align: -0.15em; color: var(--wsv-blue); }
.wsv_chip       { display: inline-block; padding: 1px 8px; border-radius: 999px; background: var(--wsv-card); color: var(--wsv-mute); font-size: 11.5px; }
/* 연속일정 「보고 있는 날」 띠 — 시안 A(2026-09-07 채택): [큰 날짜 · n/총일째 | 기간 · 며칠간]. 하루짜리는 안 그린다(POP_SCHVIEW _strip) */
.wsv_strip      { display: flex; align-items: stretch; gap: 12px; margin-top: 8px; border: 1px solid var(--wsv-line); border-radius: 12px; overflow: hidden; }
.wsv_strip_day  { flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 8px 14px; background: var(--c-primary); color: #fff; line-height: 1.05; }
.wsv_strip_day b { font-size: 24px; font-weight: 800; }
.wsv_strip_day small { font-size: 11px; opacity: .92; margin-top: 3px; white-space: nowrap; }
.wsv_strip_rng  { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; justify-content: center; gap: 1px; padding: 6px 10px 6px 0; font-size: 13px; color: var(--wsv-ink); }
.wsv_strip_rng .k { font-size: 11px; color: var(--wsv-mute); }
.wsv_strip_rng .n { font-weight: 700; word-break: keep-all; } 
.wsv_link       { color: var(--wsv-blue); font-weight: 800; }
/* 「이 기기에만 저장」 배지 — 서버에 없는 일정이라는 표시(2026-09-04).
   ★ 색을 직접 갖는다. --wsv-* 는 상세 화면(.wsv_layout) 안에서만 정의돼 있어, 그 변수를 쓰면
     일자목록·검색에서는 배경이 통째로 비어 **흰 글씨만 남는다**(실기기에서 그렇게 보였다).
   자물쇠(잠금·암호 연상)도, 폰 그림(태블릿과 안 맞는다)도 쓰지 않고 장소를 말하는 글자만 쓴다. */
.wp_chip_local  { display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: 999px;
                  background: #1F5EFF; color: #fff; font-size: 11px; font-weight: 700;
                  line-height: 1.6; vertical-align: 1px; white-space: nowrap; }
:root:not(.theme-light) .wp_chip_local { background: #3E6BFF; }
.wsv_share      { color: var(--wsv-purple); font-weight: 800; }
/* 내용(SCH_CONT) — 제목과 같으면 그리지 않는다(JS). 2026-09-06 개편(시안 A + C 의 본문): 본문은 **메모지** — 왼쪽 4px 색 띠 + 연한 메모지 색면 +
   큰 글자로 「적어 둔 내용」임이 한눈에 읽히게. 종전엔 본문·정보 표가 같은 회색(--wsv-card)이라 경계가 없어 정신없다는 지적. */
.wsv_layout     { --wsv-note: #FFF8DF; --wsv-note-line: #E8D48A; }
:root:not(.theme-light) .wsv_layout { --wsv-note: #2E2A18; --wsv-note-line: #6A5A22; }
.wsv_cont       { padding: 12px 14px 13px; border-left: 4px solid var(--wsv-blue); border-radius: 0 12px 12px 0; background: var(--wsv-note);
                  color: var(--wsv-ink); font-size: 16px; font-weight: 600; line-height: 1.7; word-break: keep-all; overflow-wrap: anywhere; }
.wsv_cont a     { color: var(--wsv-blue); text-decoration: underline; }
.wsv_cont.wsv_done { text-decoration: line-through; color: var(--c-text-sub); }
/* 제목≠내용인 옛 일정 — 메모지 첫 줄에 제목(굵게), 그 아래 내용 */
.wsv_cont_title { display: block; margin-bottom: 4px; padding-bottom: 4px; border-bottom: 1px dashed var(--wsv-note-line); font-weight: 800; }
/* 내용 없는 일정 — 메모지 자리는 지키되 연한 안내문(2026-09-06) */
.wsv_cont.wsv_cont_empty { color: var(--wsv-mute); font-size: 13.5px; }
/* 첨부 이미지 카드 — 둥근 카드 안에 이미지, 아래 캡션 줄에 「이미지 문자 보기」 링크 */
/* 본문 칸(#div_cont) — 메모지·소제목·이미지·AI 설명을 세로로 띄운다(붙어 있으면 메모지와 사진의 경계가 없다) */
#div_cont       { display: flex; flex-direction: column; gap: 12px; }
#div_cont[hidden] { display: none; }
.wsv_imgs       { display: flex; flex-direction: column; gap: 8px; }
.wsv_img_wrap   { border: 1px solid var(--wsv-line); border-radius: 14px; overflow: hidden; background: var(--wsv-card); }
.wsv_img        { position: relative; display: block; width: 100%; background: var(--c-surface); cursor: zoom-in; }
.wsv_img img    { display: block; width: 100%; height: auto; }
.wsv_img_cap    { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 7px 12px; font-size: 12.5px; color: var(--wsv-mute); }
.wsv_ocr_btn    { padding: 0; border: 0; background: none; color: var(--wsv-blue); font-family: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; }
.wsv_ocr_btn::after { content: ' \203A'; }
.wsv_lightbox   { position: fixed; inset: 0; z-index: 5000; display: flex; align-items: center; justify-content: center; padding: 16px; background: rgba(0, 0, 0, 0.82); cursor: zoom-out; }
.wsv_lightbox img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 4px; }
.wsv_img img    { display: block; width: 100%; height: auto; }
.wsv_img_err    { min-height: 80px; }
.wsv_img_err img { display: none; }
.wsv_img_err::after { content: '이미지를 불러올 수 없습니다'; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; padding: 6px; color: var(--c-text-muted); font-size: 12px; text-align: center; word-break: keep-all; }
.wsv_ocrbox     { position: fixed; inset: 0; z-index: 5100; display: flex; align-items: center; justify-content: center; padding: 16px; background: rgba(0, 0, 0, 0.68); }
.wsv_ocrpanel   { display: flex; flex-direction: column; width: min(620px, 100%); max-height: min(78dvh, 720px); border-radius: 12px; background: var(--c-surface); color: var(--c-text); box-shadow: 0 16px 44px rgba(0, 0, 0, 0.35); overflow: hidden; }
.wsv_ocrhead    { display: flex; align-items: center; justify-content: space-between; padding: 11px 14px; border-bottom: 1px solid var(--c-border); font-weight: 700; }
.wsv_ocrclose   { width: 30px; height: 30px; padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--c-text); font-size: 24px; line-height: 1; cursor: pointer; }
.wsv_ocrtext    { flex: 1 1 auto; min-height: 0; margin: 0; padding: 14px; overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere; font-family: inherit; font-size: 13px; line-height: 1.6; }
/* 정보 표 — 회색 카드 안 key/value */
/* 부가정보(시안 A) — 색면 카드가 아니라 「정보」 소제목 + 얇은 두 칸 표(라벨 회색·값 진하게). 본문 메모지와 형태가 달라 섞이지 않는다 */
.wsv_sec        { margin: 4px 2px -6px; font-size: 11.5px; font-weight: 700; letter-spacing: .08em; color: var(--wsv-mute); display: flex; align-items: center; gap: 5px; }
/* 소제목 앞 아이콘(2026-09-06 지시 — 「정보」·「첨부 이미지」) — 글자색을 따르는 mask */
.wsv_sec::before { content: ''; display: inline-block; width: 13px; height: 13px; background-color: currentColor; -webkit-mask: center / contain no-repeat; mask: center / contain no-repeat; }
.wsv_sec_info::before { -webkit-mask-image: url('/vendor/moca/images/icon_page_info.svg'); mask-image: url('/vendor/moca/images/icon_page_info.svg'); }
.wsv_sec_img::before  { -webkit-mask-image: url('../images/icon_image.svg'); mask-image: url('../images/icon_image.svg'); }
.wsv_meta       { padding: 0 2px; border: 0; border-top: 1px solid var(--wsv-line); border-radius: 0; background: transparent; }
.wsv_info       { padding: 0; }
.wsv_row        { display: flex; gap: 14px; align-items: baseline; padding: 8px 0; border-top: 1px solid var(--wsv-line); }
.wsv_row:first-child { border-top: 0; }
.wsv_th         { flex: 0 0 auto; min-width: 4.6em; white-space: nowrap; color: var(--wsv-mute); font-size: 12.5px; }
.wsv_td         { min-width: 0; flex: 1; color: var(--wsv-ink); font-size: 12px; word-break: keep-all; overflow-wrap: anywhere; }   /* 값 글자 13→12px(2026-09-07 지시 — 라벨과 같은 크기라 표가 무거웠다) */
.wsv_sub        { display: block; margin-top: 1px; color: var(--wsv-mute); font-size: 12px; }
.wsv_ai         { padding: 9px 12px; border-left: 3px solid var(--wsv-purple); border-radius: 4px; background: var(--wsv-card); color: var(--c-text-sub); font-size: 13px; line-height: 1.6; }
/* 푸터 — 주 행동 둘(완료·수정) + 아이콘 줄(공유·등록·목록·삭제). 엔진 .bd_modal_btns 규격(28px 알약)을 쓰지 않는다 */
.wsv_foot       { display: flex; flex-direction: column; gap: 8px; padding: 8px 2px 2px; border-top: 1px solid var(--wsv-line); }
.wsv_main       { display: grid; grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); gap: 8px; }   /* 보이는 버튼 수만큼 등분(완료|수정 · 완료|닫기 · 닫기) */
.wsv_main button[hidden] { display: none; }
.wsv_b_x        { background: var(--wsv-blue-soft); color: var(--wsv-blue); }   /* 닫기 — 수정과 같은 보조 버튼 색(회색 금지) */
.wsv_b          { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: max(44px, var(--wp-control-h));
                  padding: 0 14px; border-radius: 12px; border: 1px solid transparent; font-family: inherit; font-size: 14px; font-weight: 700; cursor: pointer; white-space: nowrap; }
.wsv_b::before  { content: ''; width: 18px; height: 18px; background-color: currentColor; -webkit-mask: no-repeat center / contain; mask: no-repeat center / contain; }
/* 닫기 아이콘 — 팝업 공통 icon_close.svg(mask) 로 통일. ★ 반드시 위 .wsv_b::before 뒤에 둔다 — 같은 특이도라 앞에 두면
   기본 규칙의 mask: 축약형이 mask-image 를 none 으로 되돌려 채움 상자(■)로 그려진다(2026-09-04 실기기 "사각도 있고 엑스도 있어").
   원래 ■ 로 보이던 것도 같은 순서 문제였다(문자 '✕' 가 content:'' 에 덮임). */
.wsv_b_x::before { -webkit-mask-image: url('../images/icon_close.svg'); mask-image: url('../images/icon_close.svg'); }
.wsv_b_p        { background: var(--wsv-blue); color: #FFFFFF; }
.wsv_b_p::before { -webkit-mask-image: url('../images/icon_check.svg'); mask-image: url('../images/icon_check.svg'); }
.wsv_b_s        { background: var(--wsv-blue-soft); color: var(--wsv-blue); }
.wsv_b_s::before { -webkit-mask-image: url('../images/icon_edit.svg'); mask-image: url('../images/icon_edit.svg'); }
.wsv_b:hover    { filter: brightness(1.05); }
.wsv_b:focus-visible, .wsv_ib:focus-visible { outline: 2px solid var(--wsv-blue); outline-offset: 2px; }
/* 칸 전체가 눌린다 — 아이콘만 맞히지 않아도 되게 칸 사이 틈을 없애고 위아래 여백을 버튼 안으로(2026-09-03 지적 "대충 눌러도") */
.wsv_bar        { display: flex; gap: 0; margin-top: -6px; }   /* 보이는 버튼 수만큼 등분 + 사이 경계선(예약 2026-09-03) */
.wsv_bar button[hidden] { display: none; }
.wsv_bar .wsv_ib { flex: 1 1 0; border-radius: 0; }
.wsv_bar .wsv_ib:not([hidden]) ~ .wsv_ib:not([hidden]) { border-left: 1px solid var(--wsv-line); }
/* 아이콘 버튼 — 회색 라운드 사각(::before) 위에 역할색 마스크 아이콘(<i>), 아래 작은 라벨 */
.wsv_ib         { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: 4px; padding: 12px 0 10px; min-height: 84px; width: 100%; border: 0; border-radius: 10px;
                  background: transparent; color: var(--wsv-mute); font-family: inherit; font-size: 11.5px; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.wsv_ib:active  { background: var(--wsv-card); }
.wsv_ib::before { content: ''; width: 38px; height: 38px; border-radius: 12px; background: var(--wsv-card); }
.wsv_ib i       { position: absolute; top: 21px; width: 20px; height: 20px; background-color: currentColor; -webkit-mask: no-repeat center / contain; mask: no-repeat center / contain; }
.wsv_ib_share   { color: var(--wsv-purple); }
.wsv_ib_share i { -webkit-mask-image: url('../images/icon_share.svg'); mask-image: url('../images/icon_share.svg'); }
.wsv_ib_reg     { color: var(--wsv-orange); }
.wsv_ib_reg i   { -webkit-mask-image: url('../images/icon_plus.svg');  mask-image: url('../images/icon_plus.svg'); }
.wsv_ib_list    { color: var(--wsv-blue); }   /* 회색은 "사용 불가"로 읽힌다 — 색을 준다(2026-09-03 지적) */
.wsv_ib_list i  { -webkit-mask-image: url('/vendor/moca/images/icon_menu.svg'); mask-image: url('/vendor/moca/images/icon_menu.svg'); }
.wsv_ib_del     { color: var(--wsv-red); }
.wsv_ib_del i   { -webkit-mask-image: url('/vendor/moca/images/icon_trash.svg'); mask-image: url('/vendor/moca/images/icon_trash.svg'); }
.wsv_ib:hover::before { filter: brightness(0.96); }

/* ============================================================
 * POP_SCHSHARE — 일정 공유링크 (wsh_*)
 * ============================================================ */

.wsh_intro      { padding: 11px 13px; color: var(--c-text-sub); font-size: 13px; line-height: 1.65; word-break: keep-all; }
.wsh_intro b    { color: var(--c-text); }
.wsh_intro p    { margin: 6px 0 0; }
.wsh_dim        { color: var(--c-text-muted); font-size: 12px; }
.wsh_make       { margin-top: 12px; }
/* 이 팝업의 주 동작이라 푸터 버튼 크기(28px)로는 작다 — 폭을 다 쓰고 높이를 키운다 */
.wsh_btn_make   { width: 100%; height: 38px; font-size: 14px; }

.wsh_link       { margin-top: 12px; padding: 11px 13px; }
.wsh_link label { display: block; margin-bottom: 6px; color: var(--c-text-sub); font-size: 12px; font-weight: 700; }
.wsh_link_row   { display: flex; gap: 6px; }
/* 주소가 길어 잘려 보이므로 12px + 좌우 스크롤. 직접 길게 눌러 복사하는 길도 열어 둔다 */
.wsh_link_row input { flex: 1 1 auto; min-width: 0; height: 30px; padding: 0 9px; border: 1px solid var(--c-border); border-radius: 6px; background: var(--c-bg-input); color: var(--c-text); font-size: 12px; }

.wsh_sec        { margin: 16px 0 6px; color: var(--c-text-sub); font-size: 12px; font-weight: 700; }
.wsh_list       { display: flex; flex-direction: column; gap: 6px; }
.wsh_item       { display: flex; align-items: center; gap: 8px; padding: 9px 11px; border: 1px solid var(--c-border); border-radius: var(--wp-pop-radius); background: var(--c-surface); }
.wsh_item_main  { flex: 1 1 auto; min-width: 0; }
.wsh_item_main b   { display: block; color: var(--c-text); font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wsh_item_main span { display: block; margin-top: 2px; color: var(--c-text-muted); font-size: 12px; }
/* 기간이 지난 링크도 목록에 남긴다 — "왜 친구가 못 본다지?" 의 답이 여기 있어야 한다 */
.wsh_expired    { opacity: .55; }
.wsh_stop       { flex: 0 0 auto; height: 26px; padding: 0 10px; border: 1px solid var(--c-danger); border-radius: 6px; background: transparent; color: var(--c-danger); font-size: 12px; font-weight: 700; cursor: pointer; }
.wsh_empty      { padding: 14px; border: 1px dashed var(--c-border); border-radius: var(--wp-pop-radius); color: var(--c-text-muted); font-size: 12px; text-align: center; }


/* 반복 범위 3택은 화면이 오버레이를 만들지 않는다 — 엔진 표준 com.confirm 의 radios 옵션을 쓴다.
   자체 오버레이(.wsv_choice)는 word-break·모달 계층을 각자 다시 풀어야 해서 어긋났다. */

/* ============================================================
 * POP_SCHEDULE — 일정 등록/수정 폼 (wsc_*)
 * ============================================================ */

.wsc_body       { min-height: 0; overflow: auto; display: flex; flex-direction: column; gap: 10px; padding: 1px; }
.wsc_sec        { display: flex; flex-direction: column; gap: 7px; padding: 10px; }
.wsc_tit        { display: flex; align-items: center; gap: 6px; margin: 0; color: var(--c-text); font-size: 13px; font-weight: 700; }
.wsc_req        { padding: 0 6px; border-radius: 8px; background: var(--c-danger); color: #fff; font-size: 12px; font-weight: 600; }
.wsc_cont textarea { min-height: 84px; }

/* 달력선택은 flex-wrap 금지 — input/label 이 각각 아이템이라 줄 끝에서 쌍이 갈라진다.
   grid 쌍(2열)으로 정돈하고 라벨 길이·글자 배율이 크면(아래 wp_font_lg) 1열로 낮춘다 */
.wsc_cal        { display: grid; grid-template-columns: repeat(2, auto minmax(0, 1fr)); align-items: center; column-gap: 6px; row-gap: 7px; }
.wsc_cal label  { min-width: 0; margin-right: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }
.wsc_hint       { color: var(--c-text-muted); font-size: 12px; word-break: keep-all; }
.wsc_when       { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.wsc_when[hidden], .wsc_hint[hidden], #div_repeatCnt[hidden] { display: none !important; }

/* 시작·종료일시와 반복등록 combo도 프로젝트 공통 컨트롤 높이를 쓴다.
   달력의 높이·아이콘·텍스트 폭은 파일 상단의 WithPlanPlus 달력 입력 공통 규칙 한 곳이 담당한다. */
.wsc_body .wsc_when .moca_combo select { height: var(--wp-control-h); min-height: 0; box-sizing: border-box; }

/* 시간·반복 콤보 폭도 px 금지 — 글자 배율에 비례해야 "00시"가 안 잘린다(라벨 폭과 같은 이유) */
.wsc_time       { width: 5.4em; }
.wsc_repeat     { width: 8.5em; }
.wsc_notice     { display: grid; grid-template-columns: repeat(3, auto minmax(0, 1fr)); align-items: center; column-gap: 6px; row-gap: 6px; }
.wsc_notice .moca_checkbox_label { margin-right: 0; font-size: 13px; }

/* 이미지첨부 — 선택 버튼(점선 박스) + 썸네일 스트립. 높이는 프로젝트 공통 컨트롤 변수를 따른다 */
.wsc_imgadd     { min-height: var(--wp-control-h); padding: 0 12px; border: 1px dashed var(--c-border-dark); border-radius: 8px; background: var(--c-bg-input); color: var(--c-text-muted); font-family: inherit; font-size: 13px; cursor: pointer; }
.wsc_imgadd:hover { border-color: var(--c-primary); color: var(--c-text); }
.wsc_imgadd:disabled { cursor: default; opacity: 0.7; }
.wsc_thumbs     { display: flex; flex-wrap: wrap; gap: 8px; }
.wsc_thumbs:empty { display: none; }
.wsc_thumb      { position: relative; width: 64px; height: 64px; border: 1px solid var(--c-border); border-radius: 8px; overflow: hidden; background: var(--c-surface); }
.wsc_thumb img  { display: block; width: 100%; height: 100%; object-fit: cover; }
.wsc_ocr_state  { position: absolute; left: 2px; bottom: 2px; max-width: calc(100% - 4px); padding: 1px 4px; border-radius: 4px; background: rgba(0, 0, 0, 0.68); color: #fff; font-size: 9px; line-height: 1.4; white-space: nowrap; }
.wsc_ocr_failed { background: var(--c-danger); }
.wsc_thumb_del  { position: absolute; top: 2px; right: 2px; width: 20px; height: 20px; padding: 0; border: 0; border-radius: 50%; background: rgba(0, 0, 0, 0.55); color: #fff; font-size: 14px; line-height: 1; cursor: pointer; }
.wsc_thumb_del:hover { background: var(--c-danger); }

/* ── 큰 글자 배율(설정 125%↑ — fontScale.js 가 루트에 wp_font_lg 부여) — 열 수를 낮춰 라벨 꺾임 방지.
   3열/2열을 유지하면 "1일전(오전9시)" 같은 긴 라벨만 2줄이 되어 행 높이가 들쭉날쭉해진다(170% 실측) ── */
:root.wp_font_lg .wsc_notice { grid-template-columns: repeat(2, auto minmax(0, 1fr)); }
:root.wp_font_lg .wsc_cal    { grid-template-columns: auto minmax(0, 1fr); }

/* ============================================================
 * POP_SETTING — 설정 팝업 (좌측 드로어 [설정])
 * ============================================================ */

.wps_body       { min-height: 0; overflow: auto; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-content: start; gap: 12px; padding: 1px; }

/* 큰 글자 배율 — 팝업(max-height 92vh)보다 레이아웃 기준높이가 커지면 모달몸통·본문이 둘 다 스크롤되는
   이중 스크롤이 난다(2026-08-10 설정 팝업 지적). 배율에서는 호출측이 height 90dvh 로 팝업을 확정하고
   레이아웃이 그 높이를 채운다 — 본문(auto 칸)만 스크롤되고 푸터(fit 칸)는 고정된다(모바일 768 규칙과 세트) */
:root.wp_font_lg .moca_popup_body :is(.wps_layout, .wsv_layout, .wsc_layout, .wss_layout, .wpl_daylist_layout).moca_layout_fixed { flex: 1 1 auto !important; height: 100% !important; min-height: 0; }
.wps_sec        { display: flex; min-width: 0; flex-direction: column; gap: 8px; padding: 10px; }
.wps_sec_wide   { grid-column: 1 / -1; }
.wps_sec_inline { display: grid; grid-column: 1 / -1; grid-template-columns: minmax(0, 1fr) minmax(220px, 1fr); align-items: center; column-gap: 16px; }
/* 섹션 머리 — 번호 원은 **제목(h3) 안의 inline 요소**다(2026-09-06 3차). 그리드 옆 칸에 두고 start/baseline 으로 맞추려던 두 번은
   글자 배율(OS 글자 크기·앱 배율)마다 어긋났다 — 같은 줄상자 안에서 flex center 로 맞추면 배율 출처와 무관하게 글자 가운데에 앉는다.
   원 크기는 제목 글자의 em — 제목이 커지면 원도 같이 큰다 */
.wps_head       { display: block; }
.wps_head_copy  { min-width: 0; }
.wps_tit        { display: flex; align-items: center; gap: 8px; margin: 0; color: var(--c-text); font-size: 15px; font-weight: 700; line-height: 1.35; }
.wps_no         { display: inline-flex; flex: 0 0 auto; align-items: center; justify-content: center; width: 1.6em; height: 1.6em; border: 1px solid var(--c-primary); border-radius: 50%; background: var(--c-primary-pale); color: var(--c-primary); font-size: .8em; font-weight: 800; line-height: 1; }
.wps_desc       { margin: 3px 0 0; color: var(--c-text-sub); font-size: 13px; line-height: 1.5; word-break: keep-all; }
/* 「이 기기에만 저장한 일정개수」의 건수 — 설명 아래에 굵게. 설명과 같은 기둥(.wps_head_copy) 안에 두어
   왼쪽 끝이 제목·설명과 맞는다(2026-09-05 지시: 들여쓰기·간격 맞춤·bold) */
.wps_cnt        { margin: 6px 0 0; color: var(--c-text); font-size: 14px; font-weight: 700; }
/* 체크박스↔칩은 원래대로 붙여 두고(6px — "체크박스와 텍스트박스는 붙어도 돼"), 글자가 칩 테두리에 붙어 보이던 것은 칩 안쪽 여백(왼 14·오 16px)으로 푼다(2026-09-06 지시) */
.wps_group      { display: grid; width: 100%; align-items: center; column-gap: 6px; row-gap: 8px; }
/* position:relative — 아래 칩 스타일이 input 을 absolute 로 숨기는데, 기준 조상이 없으면 모달까지
   올라가 붙어서 bd_modal_body 에 유령 스크롤(이중 스크롤)을 만든다(2026-08-10 실사고) */
.wps_grid_actions { grid-template-columns: repeat(3, auto minmax(0, 1fr)); }
:root.wp_font_lg .wps_grid_actions { grid-template-columns: auto minmax(0, 1fr); }   /* 큰 배율도 한 줄에 하나(라벨 꺾임 방지) */
/* ★ 한 줄에 하나짜리 그룹은 이 클래스를 반드시 붙인다 — .wps_group 은 열 개수를 스스로 정하지 않는다.
   grid 는 template 이 없으면 **1열**이라, 빠뜨리면 체크상자와 글자가 위아래로 갈라진다
   (2026-09-14 지적: 「블링이가 내 하루기록을 참고」가 두 줄로 나왔다). 에러가 안 나므로 붙이는 쪽이 규칙이다. */
.wps_grid_one   { grid-template-columns: auto minmax(0, 1fr); }
.wps_group .moca_checkbox_input { width: 18px; height: 18px; margin: 0; border-radius: 4px; }
.wps_group .moca_checkbox_label { display: flex; align-items: center; min-width: 0; min-height: 34px; margin-right: 0; padding: 0 9px 0 9px; border-radius: 6px; color: var(--c-text-body); font-size: 13px; line-height: 1.35; }
.wps_group .moca_checkbox_input:checked + .moca_checkbox_label { background: var(--c-primary-light); color: var(--c-text); font-weight: 700; }
.wps_group .moca_checkbox_input:focus-visible { outline: 2px solid var(--c-primary); outline-offset: 2px; }
.wps_group .moca_checkbox_label:hover { background: var(--c-bg-hover); }
.wps_font_options { min-width: 0; }
.wps_font_control { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 10px; min-width: 0; }
.wps_font_slider { min-width: 0; margin-top: 1px; }
/* 에이전트 섹션 안의 소제목·설명·라디오 — 두 항목(방식·신호)을 한 카드 안에 층으로(2026-09-06 앱 화면 통합) */
.wps_agent_tit   { margin: 12px 0 2px; color: var(--c-text); font-size: 13.5px; font-weight: 700; }
.wps_agent_desc  { margin-bottom: 6px; font-size: 12.5px; }
.wps_agent_radio label { white-space: normal; }
.wps_agent_radio3 { grid-template-columns: repeat(3, auto minmax(0, 1fr)); }
:root.wp_font_lg .wps_agent_radio3 { grid-template-columns: auto minmax(0, 1fr); }
.wps_font_reset  { min-height: max(36px, var(--wp-control-h)); padding: 0 12px; border: 1px solid var(--c-primary); border-radius: 7px;
                   background: var(--c-bg-input); color: var(--c-primary); font-family: inherit; font-size: 13px;
                   font-weight: 700; white-space: nowrap; cursor: pointer; }
.wps_font_reset:hover { background: var(--c-primary-light); }
.wps_font_reset:disabled { cursor: default; opacity: 0.6; }
.wps_font_reset:focus-visible { outline: 2px solid var(--c-primary); outline-offset: 2px; }
/* ── 마이페이지(POP_MYPAGE) ── */
.wpg_body       { min-height: 0; overflow: auto; display: flex; flex-direction: column; gap: 12px; padding: 1px; }
.wpg_card       { padding: 14px 14px 10px; }
.wpg_who        { display: flex; align-items: center; gap: 12px; }
.wpg_avatar     { flex: 0 0 auto; width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center; background: var(--c-primary-light); color: var(--c-primary); font-size: 20px; font-weight: 800; }
.wpg_who_txt    { min-width: 0; }
.wpg_name       { display: flex; align-items: center; gap: 8px; font-size: 17px; font-weight: 800; color: var(--c-text); overflow-wrap: anywhere; }
.wpg_hint       { margin-top: 2px; font-size: 12px; color: var(--c-text-muted); }
.wpg_info       { margin-top: 12px; border-top: 1px solid var(--c-border); }
.wpg_row        { display: flex; gap: 14px; align-items: baseline; padding: 8px 0; border-bottom: 1px solid var(--c-border); }
.wpg_row:last-child { border-bottom: 0; }
.wpg_th         { flex: 0 0 auto; min-width: 5.5em; font-size: 12.5px; color: var(--c-text-muted); }
.wpg_td         { min-width: 0; flex: 1; font-size: 13px; color: var(--c-text); overflow-wrap: anywhere; }
.wpg_note       { margin: 0 4px; font-size: 12px; color: var(--c-text-muted); }
/* 내보내기 버튼 두 개 — 카드 폭을 나눠 쓰는 링크 버튼(파일 다운로드) */
.wpg_exports    { display: flex; gap: 8px; margin-top: 4px; }
.wpg_export     { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 2px; padding: 10px 12px; border: 1.5px solid var(--c-primary); border-radius: 9px;
                  background: var(--c-bg); color: var(--c-primary); text-decoration: none; }
.wpg_export b   { font-size: 13px; font-weight: 700; }
.wpg_export small { font-size: 11px; color: var(--c-text-muted); line-height: 1.35; }
.wpg_export:hover { background: var(--c-primary-light); }
@media (max-width: 420px) { .wpg_exports { flex-direction: column; } }
/* 파일 가져오기 — 파일 선택 + 버튼 한 줄, 아래 가져온 기록(취소 버튼) */
.wpg_import     { display: flex; gap: 8px; align-items: center; margin-top: 4px; }
.wpg_file       { flex: 1 1 auto; min-width: 0; font-size: 12.5px; color: var(--c-text-sub); }
.wpg_import_btn { flex: 0 0 auto; min-height: 36px; padding: 0 14px; border: 1.5px solid var(--c-primary); border-radius: 9px; background: var(--c-primary); color: #fff; font: inherit; font-size: 13px; font-weight: 700; cursor: pointer; }
.wpg_import_btn:disabled { opacity: .5; cursor: default; }
.wpg_import_btn_wide { flex: 1 1 auto; }
.wpg_hists      { margin-top: 8px; }
.wpg_hist_tit   { font-size: 11.5px; font-weight: 700; color: var(--c-text-muted); margin-bottom: 4px; }
.wpg_hist       { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 0; border-top: 1px solid var(--c-border); font-size: 12px; color: var(--c-text-sub); }
.wpg_hist_undo  { flex: 0 0 auto; min-height: 28px; padding: 0 10px; border: 1px solid var(--c-danger); border-radius: 7px; background: transparent; color: var(--c-danger); font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; }
/* 탈퇴 규칙 표 — 「삭제」 붉은 라벨 / 「유지」 회색 라벨 + 설명 */
.wpg_rules      { display: flex; flex-direction: column; gap: 4px; margin: 6px 0 2px; }
.wpg_rule       { display: flex; gap: 8px; align-items: flex-start; font-size: 12px; line-height: 1.45; }
.wpg_rule dt    { flex: 0 0 auto; padding: 0 6px; border-radius: 4px; font-size: 11px; font-weight: 700; line-height: 1.6; }
.wpg_rule dd    { margin: 0; min-width: 0; color: var(--c-text-body); }
.wpg_rule_del dt  { background: var(--wp-danger-bg); color: var(--c-danger); }
.wpg_rule_keep dt { background: var(--c-bg-hover); color: var(--c-text-sub); }
.wps_withdraw { border-color: var(--c-danger); }
.wps_withdraw[hidden], .wps_withdraw_form[hidden], .wps_withdraw_btn[hidden] { display: none; }
.wps_withdraw .wps_no { border-color: var(--c-danger); background: transparent; color: var(--c-danger); }
/* 앱 전용 「음성 에이전트」 섹션 — hidden 은 .wps_sec 의 display 에 밀리므로 명시(§ .wps_withdraw[hidden] 과 같은 이유) */
#sec_voice[hidden] { display: none; }
.wps_withdraw .wps_tit { color: var(--c-danger); }
.wps_withdraw_action { display: flex; justify-content: flex-end; }
.wps_withdraw_btn, .wps_withdraw_cancel, .wps_withdraw_submit { min-height: max(36px, var(--wp-control-h)); padding: 0 14px; border: 1px solid; border-radius: 7px; font-family: inherit; font-size: 13px; font-weight: 700; cursor: pointer; }
.wps_withdraw_btn, .wps_withdraw_submit { border-color: var(--c-danger); background: transparent; color: var(--c-danger); }
.wps_withdraw_btn:hover, .wps_withdraw_submit:hover { background: var(--c-danger); color: #FFFFFF; }
.wps_withdraw_cancel { border-color: var(--c-border-dark); background: var(--c-bg-input); color: var(--c-text-body); }
.wps_withdraw_cancel:hover { border-color: var(--c-primary); color: var(--c-primary); }
.wps_withdraw_form { display: grid; gap: 10px; padding-top: 4px; border-top: 1px solid var(--c-border-dark); }
.wps_withdraw_field { display: grid; gap: 5px; color: var(--c-text-sub); font-size: 13px; font-weight: 700; }
/* ★ 폭: 엔진 기본 `div[data-m-type="input"].moca_input { width:140px }` 가 (0,2,1) 이라
   `.wps_withdraw_input { width:100% }`(0,1,0) 로는 못 이긴다 — 같은 특이도로 맞춘다.
   챌린지 화면(.wcg_form)에서 같은 함정을 겪었다(2026-09-05 지적: "인풋이 표준크기 대비 너무 작다"). */
div[data-m-type="input"].wps_withdraw_input { width: 100%; }
/* 높이: 다른 화면과 같은 표준 컨트롤 높이(--wp-control-h — 글자 배율 연동).
   큰 배율 공통규칙 `.wp_font_lg .moca_input input`(0,2,1)에 지지 않도록 폼 클래스를 앞에 붙여 (0,2,1) 로. */
.wps_withdraw_form .moca_input input { height: var(--wp-control-h); min-height: 0; box-sizing: border-box; }
.wps_withdraw_buttons { display: flex; justify-content: flex-end; gap: 8px; }
.wps_footer     { gap: 8px; padding-top: 2px; }

/* ── WithPlanPlus 전체 글자 크기(U_STYLE_OPT) ──
   100%에서 일정 제목은 구 설정의 기본값인 14px이다. fontScale.js 가 각 요소의 원래 px 값을
   비율 적용하고, 달력의 고정 높이는 아래 변수로 함께 늘려 글자가 잘리지 않게 한다. */
/* ★ 상자 높이를 배율만큼 늘리지 않는다 — 글자에 붙이고 남는 여백만 고정 px 로 준다.
   종전에는 높이를 24px·20px × 배율로 잡아서(48px·40px @200%) 26px 글자 둘레에 11px 씩
   빈칸이 생겼다. 그래서 "날짜 아래가 텅 비고" 한 칸에 일정이 두어 개밖에 안 들어갔다
   (2026-08-30 지적 · 실측 48/26 → 32/26). 커져야 하는 건 글자고, 사이 여백은 고정이다. */
.wp_cal_shell .msc_bar {
  height: auto;
  min-height: 0;
  padding: 0;
  /* 1.1 — 줄 사이 간격은 배율과 무관하게 고정(엔진 gap 2px)이어야 한다. 1.2 는 글자에 비례해 줄 상자를 키워 큰 글자에서 벌어졌다(2026-09-02 실측).
     ★ 이 규칙(0,2,0)이 엔진 .msc_bar.msc_bar_line(0,2,0)과 동률이라 뒤에 오는 이쪽이 이긴다 — 엔진만 고치면 안 먹는다 */
  line-height: 1.1;
  font-size: 14px;
}
.wp_cal_shell .msc_date {
  /* min-width 만 em — 오늘 표시가 배경 사각형이라 세로(1.15em+2px)와 비슷해야 정사각으로 보인다 */
  min-width: 1.25em;
  height: auto;
  min-height: 0;
  padding: 1px 4px;
  line-height: 1.15;
}






/* 설정 팝업도 큰 글자에서는 한 열+본문 스크롤로 바꿔 고정 높이 안에서 겹치지 않게 한다. */
.wp_font_lg .wps_body { overflow: auto; grid-template-columns: minmax(0, 1fr); padding-right: 2px; }
.wp_font_lg .wps_sec_inline { grid-template-columns: minmax(0, 1fr); align-items: stretch; }
.wp_font_lg .wps_font_control { grid-template-columns: minmax(0, 1fr); }

/* 폼/버튼의 고정 높이가 큰 글자를 자르지 않도록 프로젝트 화면에서만 최소 높이를 푼다. */
.wp_font_lg .moca_input input,
.wp_font_lg .moca_combo select,
.wp_font_lg textarea { height: auto; min-height: 34px; }
.wp_font_lg .bd_modal_btns button,
.wp_font_lg .bd_btn_save,
.wp_font_lg .bd_btn_close { height: auto; min-height: max(44px, var(--wp-control-h)); padding-top: 5px; padding-bottom: 5px; }
.wp_font_lg .wp_pop_footer button { min-height: max(44px, var(--wp-control-h)); }
.wp_font_xl .moca_grid_body thead th,
.wp_font_xl .moca_grid_body tbody td { line-height: 1; }

/* ============================================================
 * POP_MYCAL / POP_SUBCAL — 내 달력·구독달력 관리 팝업 (드로어 [달력 관리])
 * wpm_* 는 두 팝업이 공유(상단 검색줄·목록·미니버튼·색칩), wpc_* 는 구독 전용.
 * ============================================================ */

/* 상단 영역 — moca_table_search 카드 위에 한 줄 입력+버튼(내부는 tr/td 대신 flex).
   컨트롤 높이는 프로젝트 공통 --wp-control-h 로 통일(§6-9 대원칙 — 검색 팝업 wss_bar 와 동일) */
.wpm_top        { display: flex; flex-direction: column; gap: 8px; padding: 12px; }
.wpm_new        { display: flex; align-items: center; gap: 8px; }
.wpm_new_ipt    { flex: 1; min-width: 0; }
.wpm_new_ipt input { width: 100%; }
.wpm_new .moca_input input { height: var(--wp-control-h); min-height: 0; }
/* 생성·조회 버튼 — 검색 팝업 조회버튼(wss_btn)과 같은 자체 완성형 + 명도 규칙
   (다크=primary-dark 위 어두운 글자 / 라이트=흰 글자). bd_btn_* 은 팝업 푸터 밖에서 크기를 못 받는다 */
.wpm_new_btn    { flex: 0 0 auto; height: var(--wp-control-h); padding: 0 18px; border: 0; border-radius: var(--radius-sm); background: var(--c-primary-dark); color: #06130F; font-family: inherit; font-size: 13px; font-weight: 700; cursor: pointer; }
.wpm_new_btn:hover { filter: brightness(1.08); }
.wpm_new_btn:focus-visible { outline: 2px solid var(--c-text); outline-offset: 2px; }
:root.theme-light .wpm_new_btn { color: #FFFFFF; }
/* 조회 버튼에 btn_search 를 함께 붙인다 — 엔진 enterSearchEvt(Enter 키)가 그 클래스로 버튼을
   찾기 때문이다. 엔진 CSS 의 .btn_search 는 투명 아웃라인이라 그대로 두면 모양이 바뀌므로,
   여기서 채움 스타일을 다시 못박는다(클래스 두 개 = 더 높은 명시도라 로드 순서와 무관). */
.wpm_new_btn.btn_search { height: var(--wp-control-h); padding: 0 18px; border: 0; background: var(--c-primary-dark); color: #06130F; box-shadow: none; }
.wpm_new_btn.btn_search:hover { background: var(--c-primary-dark); filter: brightness(1.08); }
:root.theme-light .wpm_new_btn.btn_search { color: #FFFFFF; }
.wpm_cnt        { font-size: 12.5px; color: var(--c-text-sub); }
.wpm_cnt b      { color: var(--c-primary); }

/* 목록 (스크롤 영역) */
.wpm_list       { min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 8px; padding: 1px; }
.wpm_empty      { padding: 36px 0; text-align: center; color: var(--c-text-muted); font-size: 13px; line-height: 1.7; }




/* 텍스트 미니 버튼(승인·거절·강퇴·가입신청·탈퇴 등) — 높이는 배율 비례(--wp-control-h) */
.wpm_mini       { flex: 0 0 auto; min-height: var(--wp-control-h); padding: 0 10px; border: 1px solid var(--c-border-dark); border-radius: 6px; background: transparent; color: var(--c-text-sub); font-family: inherit; font-size: 12px; cursor: pointer; }
.wpm_mini:hover { border-color: var(--c-primary); color: var(--c-primary); }
.wpm_mini_save  { border-color: var(--c-primary); background: var(--c-primary); color: #0B1A12; font-weight: 700; }
.wpm_mini_save:hover { background: var(--c-primary-dark); border-color: var(--c-primary-dark); color: #0B1A12; }

/* 라이트는 primary 가 짙은 틸(#0E8E7E)이라 어두운 글자 대신 흰 글자가 맞다 */
:root.theme-light .wpm_mini_save, :root.theme-light .wpm_mini_save:hover { color: #FFFFFF; }

/* 달력명 인라인 편집(펜 버튼) */
.wpm_edit       { display: flex; align-items: center; gap: 6px; }
.wpm_edit_ipt   { flex: 1; min-width: 0; height: var(--wp-control-h); padding: 0 8px; border: 1px solid var(--c-primary); border-radius: 6px; background: var(--c-bg-input); color: var(--c-text); font-family: inherit; font-size: 13px; }


/* ── 달력 카드(wpk_ — POP_MYCAL·POP_SUBCAL 공용, 2026-09-06 재개편) ──
   위 = 색 점(구분색, 없으면 점선 원) + 제목(두 줄까지 감김) + 메타. 제목이 버튼과 자리를 다투지 않도록 동작은 아래 층으로:
   구독달력은 하단 액션바(시안 B), 나의달력은 큼직한 버튼 둘 「회원」·「관리」(시안 2). 실기기(iOS·큰 배율)에서
   「승인 대기」 칩 잘림·「신청취소」가 이메일 위에 겹침·제목 잘림·「색」 버튼이 무슨 색인지 안 보임을 고친 것. */
/* ★ flex: 0 0 auto — 목록(.wpm_list)은 flex column 이고 카드는 overflow:hidden 이라 min-height 가 0 으로 풀려 pane 높이에 맞춰
   **카드가 눌린다**(폰 실측 2026-09-06: 버튼이 반만 보임). PC 는 pane 이 넉넉해 안 나타났다 — 검증은 폰 높이에서(withplan SKILL ③-3). */
.wpk_card       { flex: 0 0 auto; border-color: var(--wp-pop-border); border-radius: var(--wp-pop-radius); background: var(--wp-pop-card-bg); overflow: hidden; }
.wpk_top        { display: flex; gap: 10px; padding: 12px 12px 8px; }
/* 달력 배지(js/com.js wpCalBadge) — 구분색 배경 위에 전경색 달력 아이콘. 달력명이 나오는 곳 전부 공통(2026-09-06 지시).
   기본(카드) 28px, .wp_calbadge_sm 은 글줄 안 20px. 색이 없으면 회색 바탕 + 흐린 아이콘 */
.wp_calbadge    { display: inline-flex; flex: 0 0 auto; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: 8px;
                  background: var(--c-bg-hover, #E9ECF0); color: var(--c-text-muted); vertical-align: middle; }
.wp_calbadge .wp_ico_cal { width: 18px; height: 18px; margin: 0; vertical-align: 0; }
.wp_calbadge_sm { width: 20px; height: 20px; border-radius: 6px; }
/* 제목 줄용 — 제목 글자 크기(em)와 같은 정사각, 글자 앞 여백. 카드 제목(.wpk_title)이 쓴다(2026-09-07) */
.wp_calbadge_t  { width: 1.3em; height: 1.3em; border-radius: 0.3em; flex: 0 0 auto; }   /* 간격은 .wpk_title 의 gap 이 준다 */
.wp_calbadge_t .wp_ico_cal { width: 0.85em; height: 0.85em; }
.wpk_meta_row   { flex-basis: 100%; }   /* 메타 줄(flex-wrap) 안에서 한 줄을 통째로 차지 — 가입일시를 아래로 */
.wp_calbadge_sm .wp_ico_cal { width: 13px; height: 13px; }
/* ★ 수직 중앙 정렬은 배지가 아니라 **담는 쪽**이 맡는다(2026-09-06 지적 "아이콘이 글줄보다 내려와 있다").
   vertical-align 값으로 맞추면 글자 크기·배율마다 어긋난다 — 담는 요소를 inline-flex + align-items:center 로 두면 어떤 배율에서도 가운데다.
   배지를 담는 곳: 일정 상세 메타(.wsv_meta_line > span) · 일자 팝업 달력 칩(.wpl_grp) · 챌린지 줄(.wpl_clg_grp) · 챌린지 카드(.wcg_grp) */
.wsv_meta_line > span, .wpl_grp, .wpl_clg_grp, .wcg_grp { display: inline-flex; align-items: center; gap: 6px; }
.wcg_grp        { max-width: 100%; }
.wcg_grp .wp_calbadge_sm { flex: 0 0 auto; }
/* 카드(나의달력·구독달력)는 제목+메타 두 줄 블록의 세로 가운데에 */
.wpk_dot        { flex: 0 0 auto; display: flex; align-items: center; align-self: center; }
.wpk_txt        { min-width: 0; flex: 1; }
/* 제목 줄 = flex 가운데 정렬 — 앞의 달력 배지(.wp_calbadge_t)가 글자와 항상 나란하다(2026-09-07 지적) */
.wpk_title      { display: flex; align-items: center; gap: 6px; margin-bottom: 2px; /* 배지-이름 간격 표준 = 6px(글줄 배지 .wsv_meta_line·.wpl_grp 와 같음, 2026-09-07) */ font-size: 15px; font-weight: 700; color: var(--c-text); line-height: 1.3; overflow-wrap: anywhere; }
.wpk_metaline   { display: flex; flex-wrap: wrap; align-items: center; gap: 0 10px; margin-top: 6px; }   /* 줄 사이 세로 간격 0 — 줄높이만으로(2026-09-07 지시 "줄간 좁혀") */
.wpk_title + .wpk_meta { margin-top: 6px; }   /* 제목 바로 아래 메타(나의달력 카드) — 제목↔세부 간격은 세부 줄 사이보다 넓게(2026-09-07) */
.wpk_meta       { margin-top: 0; min-width: 0; font-size: 12px; color: var(--c-text-sub); line-height: 1.2; overflow-wrap: anywhere; }   /* 줄높이 1.4→1.2 — 두 줄 메타가 붙어 보이게(2026-09-07 재지적) */
.wpk_meta b     { color: var(--c-text-body); }
.wpk_meta small { color: var(--c-text-muted); font-size: 11px; }   /* 년월일시분 등 부가값은 라벨보다 한 단계 작게(2026-09-07) */
.wpk_chip       { display: inline-flex; padding: 1px 8px; border-radius: 999px; font-size: 11.5px; font-weight: 700; white-space: nowrap; line-height: 1.6; }
.wpk_chip_wait  { background: var(--wp-badge-bg); color: var(--wp-badge-fg); }   /* 같은 배지 색(대비 통일) */
.wpk_chip_ok    { background: var(--c-primary-light); color: var(--c-primary); }
/* 색 견본 — 「색」 글자 대신 실제 색을 보인다 */
/* 색 견본 — 글자 크기(1em)와 같은 정사각, 진한 테두리(연한 색이 바탕과 섞이지 않게 — 2026-09-07 지적) */
.wpk_sw         { display: inline-block; width: 1em; height: 1em; border-radius: 4px; border: 1.5px solid var(--c-text-sub); vertical-align: -0.1em; }
.wpk_sw_none    { border: 1.5px dashed var(--c-border-dark); background: transparent; }
/* 하단 액션바(구독달력) — 칸 균등, 글자는 한 줄 */
/* 액션바 = 카드 안쪽 여백 안의 **테두리 버튼 두 개**(2026-09-07 시안 C 채택). 종전 「칸 나누기(색면)」는 파란 틴트가 팝업 푸터 [닫기]와
   같은 색이라 카드가 바닥에 붙으면 한 덩어리로 보였다. 파랑 테두리 = 일반, 빨강 테두리 = 경고(구독 탈퇴·거절·강퇴). 큰 글자에서 글자가
   길어지면 두 줄로 감기게 white-space 는 normal. */
.wpk_bar        { display: flex; gap: 8px; padding: 0 12px 12px; }
.wpk_bar_btn    { flex: 1 1 0; min-width: 0; min-height: max(38px, var(--wp-control-h)); padding: 6px 8px; border: 1.5px solid var(--c-primary); border-radius: 9px;
                  background: var(--c-bg); color: var(--c-primary); font-family: inherit; font-size: 13px; font-weight: 700; line-height: 1.25; cursor: pointer;
                  display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
.wpk_bar_btn:hover { background: var(--c-primary-light); }
.wpk_bar_btn.wpk_warn { color: var(--c-danger); border-color: var(--c-danger); }
.wpk_bar_btn.wpk_warn:hover { background: var(--wp-danger-bg); }
/* 두 버튼(나의달력) + 관리 펼침 */
.wpk_btns       { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; padding: 0 12px 12px; }
.wpk_btn        { min-height: max(38px, var(--wp-control-h)); padding: 6px 8px; border: 1px solid var(--c-border-dark); border-radius: 8px; background: var(--c-surface);
                  color: var(--c-text); font-family: inherit; font-size: 13.5px; font-weight: 700; white-space: nowrap; cursor: pointer;
                  display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
.wpk_btn:hover  { border-color: var(--c-primary); color: var(--c-primary); }
.wpk_btn.wpk_warn { color: var(--c-danger); border-color: var(--c-danger); background: var(--wp-danger-bg); }
/* 대기 수 배지 — 진한 바탕 + 흰 글자로 대비를 주고 한 치수 크게(2026-09-06 지적: 갈색 바탕에 검정 숫자가 안 읽힘) */
.wpk_n          { display: inline-flex; align-items: center; justify-content: center; min-width: 24px; height: 24px; padding: 0 8px; border-radius: 999px; background: var(--wp-badge-bg); color: var(--wp-badge-fg); font-size: 13px; font-weight: 800; line-height: 1; }

/* ── POP_MYCALMEM(회원 목록)·POP_MYCALMANAGE(달력 관리) — 카드 안에 펼치던 것을 팝업으로(2026-09-06 지시 "크고 직관적으로") ── */
.wkm_head       { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; padding: 10px 12px; }
.wkm_label      { font-size: 15px; font-weight: 700; color: var(--c-text); overflow-wrap: anywhere; }
.wkm_waitcnt    { font-style: normal; color: var(--wp-badge-bg); font-weight: 700; }
.wkm_row        { flex: 0 0 auto; border-color: var(--wp-pop-border); border-radius: var(--wp-pop-radius); background: var(--wp-pop-card-bg); overflow: hidden; }
.wkm_row.wkm_wait { border-color: var(--c-warning); }
.wkm_top        { display: flex; gap: 10px; padding: 12px 12px 10px; }
/* 회원 아이콘 — 누를 수 있는 버튼(2026-09-07). 테두리로 「바꿀 수 있다」를 알린다 */
.wkm_ico        { flex: 0 0 auto; width: 40px; height: 40px; padding: 0; border: 1px solid var(--c-border); border-radius: 10px; background: var(--c-bg);
                  font-size: 22px; line-height: 1; text-align: center; cursor: pointer; }
.wkm_ico:hover  { border-color: var(--c-primary); }
/* 이모지 선택 줄 — 카드 안에서 펼쳐진다. 칸은 44px(터치), 글자 배율과 무관하게 고정 */
.wkm_picker     { display: grid; grid-template-columns: repeat(auto-fill, minmax(44px, 1fr)); gap: 4px; padding: 0 12px 10px; }
.wkm_pick       { height: 44px; padding: 0; border: 1px solid transparent; border-radius: 8px; background: var(--c-bg); font-size: 22px; line-height: 1; cursor: pointer; }
.wkm_pick:hover { border-color: var(--c-border-dark); }
.wkm_pick_on    { border-color: var(--c-primary); background: var(--c-primary-light); }
.wkm_txt        { min-width: 0; flex: 1; }
.wkm_nm         { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font-size: 15px; font-weight: 700; color: var(--c-text); overflow-wrap: anywhere; }
.wpk_bar_btn.wkm_ok { color: var(--c-primary); font-weight: 700; }
.wkg_body       { min-height: 0; overflow: auto; display: flex; flex-direction: column; gap: 12px; padding: 4px 2px; }
.wkg_head       { display: flex; gap: 10px; padding: 8px 10px; }
.wkg_acts       { display: flex; flex-direction: column; gap: 10px; }
.wkg_btn        { min-height: max(48px, calc(var(--wp-control-h) * 1.5)); padding: 8px 12px; border: 1px solid var(--c-border-dark); border-radius: 10px; background: var(--c-surface);
                  color: var(--c-text); font-family: inherit; font-size: 15px; font-weight: 700; cursor: pointer;
                  display: flex; align-items: center; justify-content: center; gap: 8px; }
.wkg_btn:hover  { border-color: var(--c-primary); color: var(--c-primary); }
.wkg_ico        { display: inline-block; width: 1.4em; font-size: 20px; line-height: 1; text-align: center; vertical-align: -0.15em; }
.wkg_acts .wkm_picker { padding: 0; }
/* 두 줄 버튼(내 아이콘) — 위 본문, 아래 작은 안내가 버튼 안에 함께 */
.wkg_btn_2line  { flex-direction: column; gap: 3px; padding-top: 9px; padding-bottom: 9px; }
.wkg_btn_main   { display: inline-flex; align-items: center; gap: 8px; }
.wkg_btn_sub    { font-size: 11.5px; font-weight: 500; line-height: 1.4; color: var(--c-text-muted); text-align: center; word-break: keep-all; }  /* 두 줄은 <br> 로 고정 — anywhere 는 단어 중간을 끊어 깨져 보였다(2026-09-07) */
.wkg_btn:hover .wkg_btn_sub { color: inherit; opacity: .8; }
.wkg_btn_warn   { color: var(--c-danger); border-color: var(--c-danger); background: var(--wp-danger-bg); }

/* ── POP_SUBCAL 전용 ── */
.wpc_head       { padding: 2px 2px 0; font-size: 13px; font-weight: 700; color: var(--c-text); }
.wpc_head b     { color: var(--c-primary); }

/* 검색 결과 섹션 — 구독중 목록 위에 잠깐 뜨는 영역이라 강조 테두리로 구분 */
.wpc_found      { border: 1px solid var(--c-primary); border-radius: var(--wp-pop-radius); background: var(--c-primary-pale); padding: 8px 10px; }
.wpc_found_head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding-bottom: 6px; font-size: 13px; font-weight: 700; color: var(--c-text); }
.wpc_found_head b { color: var(--c-primary); }
.wpc_found_empty { padding: 10px 0; color: var(--c-text-muted); font-size: 12.5px; }
.wpc_found_row  { display: flex; align-items: center; gap: 8px; padding: 7px 0; border-top: 1px dashed var(--c-border); }
.wpc_found_main { min-width: 0; flex: 1; display: flex; align-items: baseline; gap: 8px; overflow: hidden; }
.wpc_found_nm   { font-size: 13px; font-weight: 700; color: var(--c-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wpc_found_mgr  { flex: 0 0 auto; font-size: 12px; color: var(--c-text-sub); }

/* ============================================================
 * POP_CALCOLOR — 달력 구분색 선택 (내달력·구독달력 공용)
 * ============================================================ */
/* grid-auto-rows: max-content · align-content: start — 칸이 레이아웃 pane(고정 높이)이라 기본 stretch 면 행이 균등 분할돼
   내용보다 작아진다(실측: 13행 × 33px = pane 높이, 글자가 상자를 넘침). 행은 내용 높이, 남는 자리는 아래 여백 + 스크롤. */
/* 3열 = 「한 줄 = 한 색상(파스텔 | 진한 | 선명한)」 — SORT_NO 가 그 순서로 온다(2026-09-06 3차) */
.wcl_grid       { min-height: 0; overflow-y: auto; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-auto-rows: 56px; align-content: start; gap: 8px; padding: 1px; }
/* 색 상자는 전부 같은 크기(56px 고정) — 글자는 정보가 아니라 「색 견본」이라 배율(fontScale.js EXCLUDE_SELECTORS)에서 빼고
   상자도 키우지 않는다(2026-09-06 지시). 글자에 맞춰 키웠더니 글자수·배율에 따라 상자가 들쭉날쭉했다. 긴 이름은 말줄임 — 색을 보고 고른다. */
.wcl_swatch     { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 56px; padding: 0 6px; overflow: hidden;
                  border: 1px solid var(--wp-pop-border); border-radius: var(--wp-pop-radius); font-family: inherit;
                  font-size: 13px; line-height: 1.25; font-weight: 700; cursor: pointer; }
/* 견본 안 세로 바 — 달력 칸의 바(3px)와 같은 모양으로 왼쪽에. 글자는 그만큼 오른쪽으로 */
/* 견본 안 세로 바 — 배경보다 한 단계 진한 바 색(wpCalAccent)을 견본 배경 위에 그대로. 흰 받침은 폐기(2026-09-07 지시 — 바 규칙이 바뀌어 필요 없어졌다) */
.wcl_bar        { position: absolute; left: 7px; top: 9px; bottom: 9px; width: 4px; border-radius: 2px; background: var(--bar, var(--c-primary)); }
.wcl_swatch     { padding-left: 16px; }
.wcl_swatch em    { font-style: normal; max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wcl_swatch small { display: block; max-width: 100%; margin-top: 2px; font-size: 12px; font-weight: 400; opacity: 0.85; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 기본색은 한 줄 전체 — 아래 24색이 「한 줄 = 한 색상(파스텔 | 진한)」 으로 정렬되게(2026-09-06 팔레트 확장) */
.wcl_swatch.wcl_def { grid-column: 1 / -1; }
.wcl_swatch:hover { border-color: var(--c-primary); box-shadow: 0 0 0 2px var(--c-primary-light); }
.wcl_cur        { border-color: var(--c-primary); box-shadow: 0 0 0 2px var(--c-primary-light); }
.wcl_swatch .wcl_chk { position: absolute; top: 4px; right: 7px; font-size: 13px; }   /* 선택자에 .wcl_swatch 를 붙여 배율 제외 규칙에 같이 걸린다 */

/* ============================================================
 * POP_CLG / POP_CLGHIST — 챌린지 관리·이력 팝업 (드로어 [챌린지])
 * wcg_* = 관리(POP_CLG). wpc_* 는 POP_SUBCAL 이 선점해 쓰지 않는다.
 * ============================================================ */

/* 상단 — 새 챌린지 버튼(AS-IS 의 전체폭 + 버튼) 과 인라인 등록/수정 폼 */
/* ★ 챌린지 팝업 재설계(2026-09-03) — 본문은 일정 등록 팝업의 wsc_sec 카드 절, 푸터는 공통 큰 버튼 */
.wcg_layout .wsc_body { gap: 10px; }
.wcg_form       { display: flex; flex-direction: column; gap: 10px; }
/* ★ 설명 칸은 남는 세로 공간을 바닥까지 채운다(2026-09-05 지시).
   폼이 열리면 목록이 감춰져 아래가 비는데, 마지막 칸인 설명이 그 자리를 먹으면 화면이 정리되고
   긴 설명도 스크롤 없이 보인다. 늘리려면 **바깥부터 안까지 한 줄로 이어야** 한다 —
   스크롤 영역(.wsc_body, 이미 flex column) → .wcg_form → 마지막 섹션 → 텍스트영역 래퍼 → textarea.
   한 군데라도 flex:1 이 끊기면 아무 일도 일어나지 않는다. */
#div_form:not([hidden]) { flex: 1 1 auto; min-height: 0; }
.wcg_form > section:last-child { flex: 1 1 auto; min-height: 0; }
/* 엔진은 래퍼 자식에 align-self:flex-start 를 준다(내용 높이로 멈춘다) — 늘리려면 stretch 로 덮는다 */
div[data-m-type="textarea"].wcg_form_desc { flex: 1 1 auto; min-height: 96px; align-items: stretch; }
.wcg_form_desc textarea { height: 100%; align-self: stretch; resize: none; }
.wcg_form[hidden] { display: none !important; }
/* 입력·콤보는 카드 폭에 꽉 차게만 잡는다 — 엔진 wrapper 가 inline 이라 블록으로 편다(2026-09-03 지적).
   ★ 높이·둥글기·패딩·글자는 여기서 정하지 않는다(2026-09-04 지시 — 표준화). 일정등록(moca_ica·moca_combo)처럼
   엔진 기본 + --wp-control-h(글자 배율 연동)를 그대로 따라야 모든 팝업의 입력·콤보가 같아진다.
   종전 48px·10px·15px 강제가 일정등록과 어긋나게 만들었다. */
/* ★ 폭: 엔진 기본 `div[data-m-type="input"].moca_input { width:140px }` 가 (0,2,1) 이라 `.wcg_form_nm { width:100% }`(0,1,0) 로는
   지고 140px 로 좁아졌다(실기기 2026-09-04 "표준 안 됨"). 나의달력(wpm_new_ipt flex:1)·일정등록(wsc_when flex)이 카드 폭을
   가득 채우는 표준과 같아지도록 같은 특이도(0,2,1)로 편다. */
div[data-m-type="input"].wcg_form_nm, div[data-m-type="combo"].wcg_form_grp, div[data-m-type="textarea"].wcg_form_desc { display: flex; width: 100%; min-width: 0; }
.wcg_form_nm input, .wcg_form_grp select, .wcg_form_desc textarea { flex: 1 1 auto; width: 100%; min-width: 0; box-sizing: border-box; }
/* 높이: 나의달력 생성줄과 똑같은 규칙(.wpm_new .moca_input input) — 표준 컨트롤 높이 --wp-control-h(글자 배율 연동) */
.wcg_form .moca_input input { height: var(--wp-control-h); min-height: 0; box-sizing: border-box; }
/* 콤보 높이: 일정등록 시간 콤보와 똑같은 규칙(.wsc_body .wsc_when .moca_combo select) — 그 규칙은 wsc_when 줄에만 걸려
   챌린지 콤보는 큰 글자 기본(min-height 34px)만 받아 낮았다(실기기 2026-09-04). 같은 값을 챌린지 폼에도 준다. */
.wcg_form .moca_combo select { height: var(--wp-control-h); min-height: 0; box-sizing: border-box; }
.wcg_cnt        { color: var(--wpp-blue); font-weight: 700; }
/* ★ hidden 이 .wsc_sec 의 display:flex 에 밀린다 — 폼이 열릴 때 목록을 감추려면 명시해야 한다
   (.wps_withdraw[hidden] · sec_voice 와 같은 이유. 2026-09-05) */
.wcg_listsec[hidden] { display: none; }
.wcg_listsec    { gap: 8px; }
.wcg_listsec .wsc_tit { margin-bottom: 2px; }
.wcg_top        { display: flex; flex-direction: column; gap: 8px; padding: 12px; }
.wcg_new        { width: 100%; min-height: max(48px, var(--wp-control-h)); border: 1.5px dashed var(--wpp-blue); border-radius: var(--wp-pop-radius); font-size: 14px; font-weight: 700; color: var(--wpp-blue); background: transparent; color: var(--c-primary); font-family: inherit; font-size: 13px; font-weight: 700; cursor: pointer; }
.wcg_new:hover  { background: var(--c-primary-pale); }
/* (옛 설계의 중복 규칙 — .wcg_form 재정의·wcg_form_tit/row/btns·.wcg_top — 은 2026-09-04 삭제. HTML 에 없는 클래스였고
   .wcg_form gap 을 8px 로 되돌려 위 10px 과 충돌했다. 남은 것은 이모지 격자뿐이다.) */
/* 버튼 규격은 위 공통(.moca_popup_body .bd_btn_*)이 준다 — 여기서 따로 잡지 않는다 */

/* 목록 (스크롤 영역) */
.wcg_list       { display: flex; flex-direction: column; gap: 8px; }
/* ★ 목록 칸이 남는 세로 공간을 차지한다(2026-09-05 지시).
   종전에는 카드가 내용 높이에서 멈춰 그 아래가 통째로 비었다 — 특히 빈 상태에서 화면 2/3가 여백이었다.
   설명 칸과 같은 방식으로 바깥부터 이어 준다(.wsc_body → #sec_list → .wcg_list). */
#sec_list:not([hidden]) { flex: 1 1 auto; min-height: 0; }
.wcg_list       { flex: 1 1 auto; min-height: 0; }
/* 빈 상태에서는 카드 자체가 안내판이 되므로 가운데 정렬한다 */
.wcg_listsec_empty .wcg_list { display: flex; align-items: center; justify-content: center; }

/* 빈 상태 — 「없다」 를 알리는 대신 **바로 시작할 것**을 준다(2026-09-05 시안 C 채택).
   첫 챌린지의 가장 큰 마찰은 "무엇을 만들지" 라, 흔한 것 몇 개를 눌러 이름이 채워진 폼으로 보낸다.
   위 점선 버튼은 이때 감춘다(JS) — 같은 동작의 버튼이 둘이면 어느 쪽인지 묻게 된다. */
.wcg_empty      { display: flex; flex-direction: column; align-items: center; gap: 6px;
                  padding: 18px 12px; text-align: center; }
.wcg_empty_tit  { color: var(--c-text); font-size: 15.5px; font-weight: 700; }
.wcg_empty_txt  { color: var(--c-text-muted); font-size: 12.5px; }
.wcg_chips      { display: flex; flex-wrap: wrap; justify-content: center; gap: 7px; margin-top: 8px; }
/* 칩은 카드와 같은 흰 바탕에 옅은 테두리 — 회색으로 채우면 회색 카드 배경에 묻혀 버튼으로 안 읽힌다(2026-09-05 시안 대조) */
.wcg_chip       { min-height: max(34px, var(--wp-control-h)); padding: 0 13px; border: 1px solid var(--c-border);
                  border-radius: 999px; background: var(--wpp-bg, var(--wp-pop-card-bg)); color: var(--c-text);
                  font-family: inherit; font-size: 13px; font-weight: 600; cursor: pointer; white-space: nowrap; }
.wcg_chip:hover { border-color: var(--c-primary); color: var(--c-primary); background: var(--c-primary-pale); }
.wcg_empty_or   { margin-top: 14px; color: var(--c-text-muted); font-size: 12px; }
.wcg_empty_new  { min-height: max(42px, var(--wp-control-h)); padding: 0 20px; border: 1.5px dashed var(--c-primary);
                  border-radius: 12px; background: transparent; color: var(--c-primary);
                  font-family: inherit; font-size: 13.5px; font-weight: 700; cursor: pointer; }
.wcg_empty_new:hover { background: var(--c-primary-pale); }

/* 챌린지 카드 한 장 — [참여체크] [이모지] [이름/달력] [수정·삭제(작성자만)] */
.wcg_item       { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding: 10px 12px; border: 1px solid var(--wp-pop-border); border-radius: var(--wp-pop-radius); background: var(--wpp-bg, var(--wp-pop-card-bg)); }
/* 화면에서 숨기고 보조기기에만 읽히는 텍스트(챌린지 「참여」 스위치 라벨 등) */
.wp_sr_only     { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.wcg_parti      { flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; gap: 2px; font-size: 12px; color: var(--c-text-sub); cursor: pointer; }
/* 참여 — 표준 스위치 모양(사이드 패널 토글과 같은 느낌). 실제 input 은 숨기고 .wcg_sw 가 그린다 */
.wcg_parti input { position: absolute; opacity: 0; width: 0; height: 0; }
.wcg_parti      { position: relative; }
.wcg_sw         { display: block; width: 40px; height: 24px; border-radius: 12px; background: var(--c-border-dark, #C9CFD6); position: relative; transition: background .15s; }
.wcg_sw::after  { content: ''; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.25); transition: left .15s; }
.wcg_parti input:checked + .wcg_sw { background: var(--wpp-blue); }
.wcg_parti input:checked + .wcg_sw::after { left: 19px; }
.wcg_parti input:focus-visible + .wcg_sw { outline: 2px solid var(--wpp-blue); outline-offset: 2px; }
.wcg_main       { min-width: 0; flex: 1; display: flex; align-items: center; gap: 10px; padding: 0; border: 0; background: transparent; font-family: inherit; text-align: left; cursor: pointer; }
.wcg_txt        { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.wcg_nm         { font-size: 14px; font-weight: 700; color: var(--c-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wcg_grp        { font-size: 12px; color: var(--c-text-sub); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 카드 미니 잔디(최근 14일) — 2026-09-05 개편. 목록에서 "지금 잘 하고 있나" 가 바로 보이게.
   규칙은 상세의 1년 잔디와 같다(칸 = 하루, 색은 함/안 함 두 단계) — 눈이 따로 배울 것이 없다. */
/* 카드 아래 한 줄을 통째로 쓴다(flex-wrap 로 줄바꿈) — 같은 줄에 두면 폭이 모자라 버튼과 겹친다 */
.wcg_mini_row   { flex: 1 0 100%; display: flex; align-items: center; gap: 8px; padding-top: 2px; border-top: 1px solid var(--c-border); }
.wcg_mini       { display: flex; gap: 2px; }
.wcg_mini i     { display: block; width: 8px; height: 8px; border-radius: 2px; background: var(--c-bg-hover); }
.wcg_c_on       { background: var(--c-primary) !important; }
.wcg_c_today    { outline: 1px solid var(--c-primary); outline-offset: 1px; }
.wcg_mini_txt   { font-size: 11px; color: var(--c-text-muted); white-space: nowrap; }
.wcg_mini_txt b { color: var(--c-primary); }
.wcg_btns       { flex: 0 0 auto; display: flex; gap: 5px; }

/* ── POP_CLGHIST (wph_*) — 헤더 카드 + 세그먼트 탭 + 랭킹/이력 ── */
.wph_head       { display: flex; align-items: center; gap: 10px; padding: 10px 12px; }
.wph_head_ico   { flex: 0 0 auto; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; border: 1px solid var(--c-border); border-radius: 50%; background: var(--c-bg-elevated); font-size: 24px; }
.wph_head_txt   { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.wph_head_nm    { font-size: 15px; font-weight: 700; color: var(--c-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wph_head_grp   { font-size: 12px; color: var(--c-text-sub); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ── 챌린지 기록장(POP_CLGHIST) — 2026-09-05 시안 2 개편 ──
   탭 3개를 없애고 한 화면에 통계 → 잔디판 → 기록 → 랭킹을 쌓는다. 세부 의도는 화면 주석 참조. */
.wph_body       { min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; padding: 1px; }
.wph_empty      { padding: 28px 0; text-align: center; color: var(--c-text-muted); font-size: 13px; line-height: 1.7; }
/* 남의 기록을 보는 중임을 알리는 줄 — 내 기록일 때는 그리지 않는다 */
.wph_who        { display: flex; align-items: center; gap: 8px; padding: 7px 10px; border-radius: 10px;
                  background: var(--c-primary-pale); color: var(--c-text-body); font-size: 12.5px; }
.wph_who_back   { margin-left: auto; padding: 0; border: 0; background: transparent; color: var(--c-primary);
                  font-family: inherit; font-size: 12.5px; font-weight: 700; cursor: pointer; }
/* 구역 제목 — 통계/잔디/기록/랭킹을 나누는 유일한 장치라 굵고 작게 */
.wph_sec_tit    { margin-top: 8px; padding: 0 2px; font-size: 13px; font-weight: 700; color: var(--c-text); }
.wph_sec_tit b  { color: var(--c-primary); }
.wph_sec_tit small { margin-left: 4px; color: var(--c-text-muted); font-size: 11.5px; font-weight: 400; }

/* 통계 3개 — 이번 달 / 올해 / 누적 */
.wph_stats      { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.wph_stat       { padding: 9px 6px; border: 1px solid var(--c-border); border-radius: 12px;
                  background: var(--c-bg-elevated); text-align: center; }
.wph_stat b     { display: block; font-size: 19px; font-weight: 800; color: var(--c-text); letter-spacing: -.02em; }
.wph_stat span  { font-size: 11.5px; color: var(--c-text-muted); }

/* 1년 잔디판 — 세로 7칸(일~토) × 가로 주. 폰 폭에 53주가 안 들어가 가로 스크롤을 둔다.
   칸 색은 두 단계뿐이다(함/안 함) — 하루에 한 번만 기록되므로 단계를 더 두면 없는 정보를 꾸며내는 셈이다. */
/* ★ flex: none 이 없으면 부모(.wph_body, flex column)가 이 블록을 눌러 **아래 줄이 잘린다**.
   overflow-y:hidden 이라 잘린 줄은 스크롤도 안 되고 그냥 사라진다 — 목·금·토(아래 세 줄)에 수행한 날이
   화면에서 통째로 없어져 「3건인데 점이 하나」로 보였다(2026-09-05 지적). 세로로는 줄지 않게 못 박는다. */
.wph_heat_wrap  { flex: none; overflow-x: auto; overflow-y: hidden; padding: 2px 2px 4px; -webkit-overflow-scrolling: touch; }
.wph_heat_in    { display: inline-block; min-width: 100%; }
/* 월 표시 줄 — 높이를 15px 로 못박으면 글자 배율에서 라벨이 아래로 반쯤 잘린다(폰 실측 2026-09-06). 글자만큼 늘어나게 */
.wph_heat_mons  { display: grid; grid-template-columns: repeat(var(--wk), 16px); min-height: 15px; line-height: 1.3; padding-bottom: 2px; }
.wph_heat_mon   { font-size: 10px; color: var(--c-text-muted); white-space: nowrap; }
.wph_heat       { display: grid; grid-auto-flow: column; grid-template-rows: repeat(7, 13px);
                  grid-auto-columns: 13px; gap: 3px; }
.wph_heat i     { display: block; width: 13px; height: 13px; border-radius: 3px; }
.wph_c_off      { background: var(--c-bg-hover); }
.wph_c_on       { background: var(--c-primary); }
.wph_c_out      { background: transparent; }
/* 오늘 표시는 잉크색 테두리로 — 파란 테두리를 쓰면 9px 칸에서 「수행(파란 칸)」과 구별이 안 됐다(2026-09-05) */
.wph_c_today    { outline: 2px solid var(--c-text); outline-offset: 1px; }
.wph_heat_legend{ display: flex; align-items: center; justify-content: flex-end; gap: 4px;
                  padding-right: 2px; font-size: 11px; color: var(--c-text-muted); }
.wph_heat_legend i { display: block; width: 13px; height: 13px; border-radius: 3px; }

/* 기록 타임라인 — 왼쪽 세로선에 점을 찍고, 본문은 그날의 기록·코멘트다(날짜만 있던 것을 바꿨다) */
.wph_tl         { margin: 2px 0 0 5px; padding-left: 12px; border-left: 2px solid var(--c-border); }
.wph_tl_it      { position: relative; padding: 7px 0; }
.wph_tl_it::before { content: ''; position: absolute; left: -17px; top: 13px; width: 8px; height: 8px;
                  border-radius: 50%; background: var(--c-primary); }
.wph_tl_hd      { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.wph_tl_hd b    { font-size: 13px; font-weight: 700; color: var(--c-text); }
.wph_tl_tm      { font-size: 12px; color: var(--c-text-muted); }
.wph_tl_rec     { padding: 0 7px; border-radius: 6px; background: var(--c-primary-pale);
                  color: var(--c-primary); font-size: 11.5px; font-weight: 700; }
.wph_tl_memo    { margin-top: 2px; font-size: 12.5px; color: var(--c-text-body);
                  word-break: keep-all; overflow-wrap: anywhere; }
.wph_ai_btn     { margin-top: 4px; padding: 0; border: 0; background: transparent; color: var(--c-primary); font-family: inherit; font-size: 12px; cursor: pointer; }
.wph_ai         { margin-top: 4px; padding: 8px 10px; border-radius: 8px; background: var(--c-bg-elevated); font-size: 12.5px; color: var(--c-text-body); line-height: 1.6; word-break: keep-all; overflow-wrap: anywhere; }

/* 회원 랭킹 — 숫자 셋을 나란히 두면 안 읽힌다(개편 전 지적). 올해 횟수를 막대로 견주고 나머지는 작게. */
.wph_rank       { display: flex; align-items: center; gap: 9px; padding: 9px 10px; font-family: inherit; text-align: left; cursor: pointer; }
.wph_rank:hover { border-color: var(--c-primary); }
.wph_rank_on    { border-color: var(--c-primary); background: var(--c-primary-pale); }
.wph_rank_no    { flex: 0 0 auto; width: 22px; height: 22px; display: flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--c-bg-elevated); font-size: 12px; font-weight: 700; color: var(--c-text-sub); }
.wph_rank_no1   { background: var(--c-primary); color: #FFFFFF; }
.wph_rank_main  { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 3px; }
.wph_rank_nm    { font-size: 13.5px; font-weight: 700; color: var(--c-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wph_rank_nm small { margin-left: 2px; color: var(--c-text-muted); font-size: 12px; font-weight: 400; }
.wph_rank_bar   { display: block; height: 6px; border-radius: 99px; background: var(--c-bg-hover); overflow: hidden; }
.wph_rank_bar i { display: block; height: 100%; border-radius: 99px; background: var(--c-primary); }
.wph_rank_sub   { font-size: 11.5px; color: var(--c-text-muted); }
.wph_rank_big   { flex: 0 0 auto; color: var(--c-text-sub); font-size: 11.5px; }
.wph_rank_big b { font-size: 16px; font-weight: 800; color: var(--c-primary); }

/* ============================================================
 * CAL001 옵션·메뉴 드로어 — 2026-09-02 전면 개편(A안, 시안 https://claude.ai/code/artifact/a0312e79-52c1-496a-840e-9b5afa221386)
 *   레퍼런스(네이버 서비스 메뉴) 문법: 순백 바탕 · 섹션은 옅은 회색 카드 · 항목마다 흰 라운드 사각 위 색 아이콘 ·
 *   섹션 제목 옆 개수 · 체크박스는 토글. 초록은 로고(w+)에만.
 *   ★ 강조색은 역할별로 한 색씩 — 파랑=달력/탐색(개수·토글·나의달력), 오렌지=행동/가져오기·찾기 FAB, 퍼플=구독·챌린지·음성.
 *     세 색이 한 화면에 있어도 "이건 무슨 종류" 가 색으로 읽히게. 달력 안(월 그리드)에는 오렌지를 쓰지 않는다(일요일·공휴일 빨강과 충돌).
 *   컨테이너(.wp_side/.wp_side_dim)와 id(div_side·spn_sideUser·cbg_*)는 JS 계약이라 그대로, 안쪽 클래스는 wpm_* 로 새로 만들었다.
 * ============================================================ */
.wp_side { --wpm-bg: #FFFFFF; --wpm-card: #F4F6F8; --wpm-line: #E9ECF0; --wpm-ink: #1B1F24; --wpm-mute: #6B7280; --wpm-track: #D6DBE1;
           --wpm-blue: #1F5EFF; --wpm-blue-soft: #EAF0FF; --wpm-orange: #F26B1D; --wpm-purple: #7C4DFF; --wpm-icon-bg: #FFFFFF;
           background: var(--wpm-bg); border-right-color: var(--wpm-line); color: var(--wpm-ink); }
/* 다크 — 같은 구조를 어두운 바탕으로. 기본 테마(클래스 없음)가 다크라 :not(.theme-light) */
:root:not(.theme-light) .wp_side { --wpm-bg: #151B19; --wpm-card: #1F2724; --wpm-line: #2C3532; --wpm-ink: #EEF2F0; --wpm-mute: #98A39E; --wpm-track: #3A4541;
           --wpm-blue: #6E97FF; --wpm-blue-soft: #20304A; --wpm-orange: #FF8A4C; --wpm-purple: #A78BFF; --wpm-icon-bg: #2A3330; }

/* 머리 — 이름(+ⓘ)·로그아웃·닫기. 로그아웃을 맨 아래 글자 버튼으로 내렸더니 일반 사용자가 못 찾았다(2026-09-06 지시) →
   머리로 올리고 이메일은 숨겨 자리를 만든다 */
.wpm_hd   { display: flex; flex-direction: column; gap: 8px; padding: 16px 16px 10px; }
.wpm_user { min-width: 0; }
.wpm_nm   { display: block; font-size: 19px; font-weight: 700; line-height: 1.2; color: var(--wpm-ink); }
.wpm_nmrow { display: flex; align-items: center; gap: 6px; min-width: 0; }
.wpm_nmrow .wpm_nm { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wpm_mail { display: none; }   /* 2026-09-06: 로그아웃 버튼에 자리를 내줌(값은 DOM 에 남아 있어 되살리기 쉽다) */

/* 머리 버튼셋(2026-09-08 지시 "x 아이콘처럼 넷 모두 한 줄로 아이콘화") — 앱정보·마이페이지·로그아웃·닫기가 **같은 정사각 아이콘 버튼** 넷이다.
   글자를 두면 기기 글자 배율에 따라 폭이 제각각이라 줄이 넘치거나 ✕ 가 밀려났다. 이름은 툴팁·스크린리더로만 남긴다(.wp_a11y).
   닫기는 오른쪽 끝(margin-left:auto) — 위치 습관을 지킨다. */
.wpm_acts { display: flex; align-items: center; gap: 8px; }   /* 글자가 커지면 다음 줄로 흘린다 — 잘리거나 화면 밖으로 나가지 않게(2026-09-08) */
.wpm_btn  { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
            width: 36px; height: 36px; padding: 0; border: 1px solid var(--wpm-line); border-radius: 10px;
            background: var(--wpm-bg); color: var(--wpm-ink); cursor: pointer; }
.wpm_btn i { display: inline-block; width: 19px; height: 19px; background-color: currentColor;
            -webkit-mask-position: center; mask-position: center; -webkit-mask-size: contain; mask-size: contain;
            -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; }
.wpm_btn:hover { border-color: var(--wpm-blue); color: var(--wpm-blue); }
.wpm_btn:focus-visible { outline: 2px solid var(--wpm-blue); outline-offset: 2px; }
.wpm_btn_info i { -webkit-mask-image: url('../images/menu_info.svg'); mask-image: url('../images/menu_info.svg'); }
.wpm_btn_user i { -webkit-mask-image: url('/vendor/moca/images/icon_user.svg'); mask-image: url('/vendor/moca/images/icon_user.svg'); }
.wpm_btn_out  i { -webkit-mask-image: url('/vendor/moca/images/icon_logout.svg'); mask-image: url('/vendor/moca/images/icon_logout.svg'); }
.wpm_btn_x    { margin-left: auto; }   /* 닫기만 오른쪽 끝 */
.wpm_btn_x i  { -webkit-mask-image: url('/vendor/moca/images/icon_close.svg'); mask-image: url('/vendor/moca/images/icon_close.svg'); }
/* 좁은 폰(≤380px)은 글자를 빼고 아이콘만 — 네 버튼이 한 줄에 남는다 */
.wp_a11y  { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.wpm_x:focus-visible, .wpm_link:focus-visible, .wpm_txtbtn:focus-visible { outline: 2px solid var(--wpm-blue); outline-offset: 2px; }

/* 본문 — 1열, 섹션 카드 세로 나열. 폭이 넓어도 2열로 쪼개지 않는다(레퍼런스와 같은 한 줄 리듬) */
.wpm_body { flex: 1; min-height: 0; overflow-y: auto; padding: 0 12px 12px; display: flex; flex-direction: column; gap: 12px; font-size: 13px; }
.wpm_sec  { background: var(--wpm-card); border-radius: 14px; padding: 10px 12px 10px; }
.wpm_tit  { display: flex; align-items: center; gap: 6px; margin: 0 0 6px; font-size: 14px; font-weight: 700; color: var(--wpm-ink); }
.wpm_tit b { color: var(--wpm-blue); font-weight: 700; }
.wpm_tit_r { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 400; color: var(--wpm-mute); }
/* 화면 테마 토글(엔진 toggle 컴포넌트) — 제목줄 오른쪽에 작게 */
.wpm_tit_r .wpm_theme { display: inline-flex; align-items: center; gap: 6px; }
.wpm_tit_r .wpm_theme .mtg_label { font-size: 12px; font-weight: 400; color: var(--wpm-mute); }
.wpm_tit_r .wpm_theme .mtg_switch { width: 36px; height: 22px; border-radius: 11px; }
.wpm_tit_r .wpm_theme .mtg_knob { width: 16px; height: 16px; }
.wpm_tit_r .wpm_theme .mtg_switch.mtg_on .mtg_knob { transform: translateX(14px); }

/* 이동 메뉴 — 2열 그리드, 항목 = 색 아이콘 + 이름 + 꺾쇠. 색은 아이콘에만(면·테두리 없음) */
.wpm_grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2px 10px; }
.wpm_link { display: flex; align-items: center; gap: 9px; min-width: 0; min-height: 44px; padding: 5px 4px; margin: 0;
            border: 0; border-radius: 8px; background: transparent; color: var(--wpm-ink);
            font-family: inherit; font-size: 13.5px; font-weight: 500; text-align: left; cursor: pointer; }
.wpm_link:hover { background: var(--wpm-blue-soft); }
.wpm_link > span { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wpm_link::after { content: ''; flex: 0 0 auto; width: 0.42em; height: 0.42em; margin-right: 2px;
            border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(-45deg); opacity: 0.35; }
/* 아이콘 — 흰 라운드 사각 위 SVG(images/menu_*.svg — §9 규칙, 색은 SVG 안에). 크기는 글자를 따르지 않는다(아이콘 격자가 흔들리면 목록이 어지럽다) */
.wpm_ic   { flex: none; width: 32px; height: 32px; border-radius: 10px; background: var(--wpm-icon-bg) center / 18px 18px no-repeat; box-shadow: 0 1px 2px rgba(0,0,0,.08); }
.wpm_ic_mycal     { background-image: url('../images/menu_mycal.svg'); }
.wpm_ic_subcal    { background-image: url('../images/menu_subcal.svg'); }
.wpm_ic_challenge { background-image: url('../images/menu_challenge.svg'); }
.wpm_ic_setting   { background-image: url('../images/menu_setting.svg'); }
.wpm_ic_info      { background-image: url('../images/menu_info.svg'); }

/* 옵션 목록(엔진 checkboxGroup 마크업 = input + label 형제) — 라벨 왼쪽·토글 오른쪽의 한 줄로 배치한다.
   grid dense: input(먼저 온다)을 2열로 보내고 label 이 1열의 빈 칸을 채운다 → 한 쌍이 한 행 */
.wp_side .checkboxGroup { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-auto-flow: row dense; align-items: center; column-gap: 10px; row-gap: 0; width: 100%; }
.wp_side .checkboxGroup + .checkboxGroup { border-top: 1px solid var(--wpm-line); margin-top: 2px; padding-top: 2px; }
.wp_side .checkboxGroup .moca_checkbox_label { grid-column: 1; margin: 0; padding: 8px 0; min-width: 0;
            font-size: 13.5px; font-weight: 400; color: var(--wpm-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; }
/* 토글 — 체크박스 input 자체를 알약 트랙으로, ::after 가 손잡이. 엔진 체크 아이콘(background-image)은 끈다 */
:root .wp_side .checkboxGroup .moca_checkbox_input { grid-column: 2; appearance: none; -webkit-appearance: none;
            width: 36px; height: 22px; margin: 0; border: 0; border-radius: 999px; background: var(--wpm-track) !important; background-image: none !important;
            position: relative; cursor: pointer; flex: none; }
:root .wp_side .checkboxGroup .moca_checkbox_input::after { content: ''; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%;
            background: #FFFFFF; box-shadow: 0 1px 2px rgba(0,0,0,.25); transition: left .15s; }
:root .wp_side .checkboxGroup .moca_checkbox_input:checked { background: var(--wpm-blue) !important; }
:root .wp_side .checkboxGroup .moca_checkbox_input:checked::after { left: 17px; }
:root .wp_side .checkboxGroup .moca_checkbox_input:disabled { opacity: 0.4; cursor: default; }
/* 공유달력·챌린지 토글은 그 종류의 색으로 — 구독/챌린지 = 퍼플(역할별 색 규칙) */
:root .wp_side #div_secClg .checkboxGroup .moca_checkbox_input:checked { background: var(--wpm-purple) !important; }
#div_secClg .wpm_tit b { color: var(--wpm-purple); }
.wp_side_soon { color: var(--wpm-mute); font-size: 12px; }
/* 공유달력 항목 앞 구분색 점(예약 2026-09-03) — 달력 관리자가 고른 색(TWP_GRP_MYCOLOR), 없으면 순번 팔레트 */
/* ── 메시지 박스(com.alert/confirm) 초록 계열 제거 → 팝업 공통 파란 계열(예약 2026-09-03). :root 접두로 엔진 규칙을 이긴다 ── */
:root .moca_messagebox { --wpp-blue: #6E97FF; --wpp-orange: #FF8A4C; border-color: var(--c-border-dark); border-radius: 16px; }
:root.theme-light .moca_messagebox { --wpp-blue: #1F5EFF; --wpp-orange: #F26B1D; }
:root .moca_messagebox.alert .ico { color: var(--wpp-blue, #1F5EFF); border-color: var(--wpp-blue, #1F5EFF); }
:root .moca_messagebox.confirm .ico { color: var(--wpp-orange, #F26B1D); border-color: var(--wpp-orange, #F26B1D); }
:root .moca_messagebox .moca_btn_confirm { background: var(--wpp-blue, #1F5EFF); border-color: var(--wpp-blue, #1F5EFF); color: #FFFFFF; border-radius: 12px; }
:root .moca_messagebox .moca_btn_cancel { background: #20304A; border-color: #20304A; color: var(--wpp-blue); border-radius: 12px; }
:root.theme-light .moca_messagebox .moca_btn_cancel { background: #EAF0FF; border-color: #EAF0FF; }
.wp_side_dot  { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 8px; vertical-align: -1px; box-shadow: 0 0 0 1px rgba(0,0,0,.08); }

/* 바닥 — 로그아웃 글자 버튼 */
.wpm_foot { padding: 4px 0 8px; text-align: center; }
.wpm_txtbtn { border: 1px solid var(--wpm-line); border-radius: 999px; background: transparent; color: var(--wpm-mute);
            font-family: inherit; font-size: 12.5px; padding: 6px 16px; cursor: pointer; }
.wpm_txtbtn:hover { color: var(--wpm-ink); border-color: var(--wpm-mute); }

/* 큰 글자 배율 — 라벨 2줄 허용(잘리는 것보다 낫다), 이동 메뉴는 1열로 */
.wp_font_lg .wp_side .checkboxGroup .moca_checkbox_label { white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-height: 1.35; }
.wp_font_lg .wpm_grid { grid-template-columns: 1fr; }
/* 화면 테마 토글도 파랑 — 엔진 기본(primary 초록)이 이 드로어에서 유일하게 남는 초록이었다 */
:root .wpm_theme .mtg_switch { border-color: var(--wpm-track); background: var(--wpm-track); }
:root .wpm_theme .mtg_switch.mtg_on { border-color: var(--wpm-blue); background: var(--wpm-blue); }
:root .wpm_theme .mtg_knob { border-color: transparent; background: #FFFFFF; }
:root .wpm_theme .mtg_knob::before { background-color: var(--wpm-blue); }

/* ── 공지 보내기(PSH001) — 상태·글자수 표시 ─────────────────────────────
   ★ 읽기만 하는 값에는 **테두리도 입력칸도 주지 않는다**(2026-09-05 두 번 지적).
     input 은 "쳐도 되나", 테두리 상자는 "눌러도 되나"를 판단하게 만든다.
     상태는 그냥 글자로 두고 색(성공 초록 / 실패 빨강)만으로 알린다. */
.wps_state { font-size: 12px; line-height: 1.6; color: var(--c-text-sub); }
.wps_state.is_ok  { color: var(--c-success); }
.wps_state.is_bad { color: var(--c-danger); }
.wps_count { align-self: center; margin-right: 8px; font-size: 12px; color: var(--c-text-sub); }

/* ── 타이틀바 도움말 버튼(?) ──────────────────────────────────────────────
   엔진이 묶어 둔 타이틀바 아이콘 버튼(소스경로·소스보기·새로고침)과 **같은 박스**로 맞춘다
   — 같은 줄에서 크기·테두리가 다르면 서로 다른 물건처럼 보인다(엔진 moca.css 「타이틀바 아이콘 버튼」).
   아이콘 파일이 없어 글자 ? 를 그대로 쓰되, 색은 currentColor 를 따라 테마를 추종한다. */
.page_title_bar .page_help_btn { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; padding: 0; flex-shrink: 0; border: 1px solid var(--c-primary); border-radius: var(--radius-sm); background: var(--c-bg-elevated); color: var(--c-primary); font-size: 13px; font-weight: 700; line-height: 1; cursor: pointer; transition: box-shadow 0.15s; }
.page_title_bar .page_help_btn:hover { box-shadow: 0 0 6px rgba(0,240,255,0.35); }

/* ============================================================
 * 하루기록 (2026-09-14) — 하루 1장, 본인만 보는 기록
 *   ① 일자목록 팝업(POP_DAYLIST) 맨 위 카드  ② 편집 팝업(POP_DIARY)  ③ 달력 격자 표식
 * 색은 주황(--wp-diary) 하나로 통일한다 — 파랑은 일정 바와 「오늘」 표시가 이미 선점했고,
 * 세 자리가 같은 색이어야 "이게 그거구나" 가 설명 없이 전달된다.
 * ============================================================ */

/* ── ① 일자목록 팝업의 카드 ────────────────────────────────
   레이아웃 fit 칸이라 내용 높이만 차지한다. 기록이 없어도 그린다 —
   빈 카드가 곧 "여기에 쓰세요" 라는 초대이고, 기록은 눈에 보여야 습관이 붙는다. */
.wpl_diary_slot { min-height: 0; }
.wpl_diary      { display: flex; align-items: center; gap: 10px; padding: 13px 14px; cursor: pointer;
                  border: 1px solid var(--wp-pop-border); border-radius: var(--wp-pop-radius);
                  background: var(--wp-pop-card-bg); }
.wpl_diary:hover { background: var(--c-bg-hover); }
.wpl_diary:focus-visible { outline: 2px solid var(--wp-diary); outline-offset: 2px; }
/* 기록이 있는 카드는 가로 flex 가 아니라 세로 스택 — 머리줄(라벨·저장시각) 아래 본문 2줄 */
.wpl_diary_on   { display: block; padding: 11px 14px 12px; }
.wpl_diary_head { display: flex; align-items: center; gap: 7px; margin-bottom: 7px; }
.wpl_diary_ico  { flex: 0 0 auto; width: 17px; height: 17px; background-color: var(--wp-diary);
                  -webkit-mask: url('../images/icon_edit.svg') no-repeat center / contain;
                          mask: url('../images/icon_edit.svg') no-repeat center / contain; }
.wpl_diary_on .wpl_diary_ico { width: 15px; height: 15px; }
.wpl_diary_label{ flex: 1 1 auto; font-size: 11px; font-weight: 800; letter-spacing: .03em; color: var(--wp-diary); }
.wpl_diary_time { flex: 0 0 auto; font-size: 11px; color: var(--c-text-muted); }
.wpl_diary_empty{ flex: 1 1 auto; min-width: 0; font-size: 14px; font-weight: 600; color: var(--c-text-sub); }
.wpl_diary_chev { flex: 0 0 auto; width: 16px; height: 16px; background-color: var(--c-text-muted);
                  -webkit-mask: url('/vendor/moca/images/icon_chevron.svg') no-repeat center / contain;
                          mask: url('/vendor/moca/images/icon_chevron.svg') no-repeat center / contain; }
/* 본문 미리보기 2줄 — 그 이상은 편집 팝업에서 본다. 한글이 아무 데서나 끊기지 않게 keep-all */
.wpl_diary_text { margin: 0; font-size: 14px; line-height: 1.6; color: var(--c-text-body); word-break: keep-all;
                  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
                  white-space: pre-wrap; }
/* 조회 실패 — "기록 없음" 과 같은 모양이면 사용자가 있는 기록을 없다고 믿고 덮어쓴다 */
.wpl_diary_err  { border-color: var(--c-danger); }
.wpl_diary_err .wpl_diary_ico   { background-color: var(--c-danger); }
.wpl_diary_err .wpl_diary_empty { color: var(--c-danger); font-weight: 500; }

/* ── ② 편집 팝업(POP_DIARY) ────────────────────────────────
   일정 등록 팝업의 카드 절(.wsc_sec/.wp_pop_card)을 그대로 쓴다 — 새 문법을 늘리지 않는다. */
.wdy_body       { min-height: 0; overflow: auto; display: flex; flex-direction: column; gap: 10px; padding: 1px; }
.wdy_body > *   { flex: 0 0 auto; }
/* 본문 칸이 팝업 높이를 채우게 — 기록은 길게 쓰는 것이라 남는 공간을 전부 입력칸에 준다 */
.wdy_body .wsc_sec { flex: 1 1 auto; min-height: 0; }
/* ★ 입력칸을 **세로 flex** 로 채운다 — 가로 flex + height:100% 로는 WebView 에서 조용히 실패한다.
   엔진 기본값 .moca_textarea > * 는 height:100% + align-self:flex-start 다. 늘리기(stretch)를 끈 채
   퍼센트 높이에 기대는 구조라, 부모 높이가 flex 로만 정해진(지정 height 가 auto 인) 이 팝업에서는
   브라우저에 따라 100% 가 안 풀린다 — 그러면 입력칸만 rows 높이로 남고 카드 안에 빈 칸이 생긴다.
   실측(390x760 하니스): 100% 가 풀릴 때 595px, 안 풀릴 때 216px → 379px 가 빈 칸으로 남았다(앱 실사진과 같은 증상).
   세로 flex 에서는 flex-grow 가 **높이를 직접** 정하므로 퍼센트 해석이 끼어들 자리가 없다. */
.wdy_body .wdy_cont { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.wdy_body .wdy_cont > * { flex: 1 1 auto; height: auto; min-height: 120px; align-self: stretch; width: 100%;
                          resize: none; line-height: 1.7;
    /* ★ 본문 글자는 14px 기준 — 엔진 기본값 .moca_textarea > * 는 12px 이고 그건 **보조문구 크기**다.
         이 팝업은 글을 읽고 쓰는 곳이라 본문이 주인공인데, 안내문(.wsc_hint 12px)과 같은 크기였다
         (2026-09-15 지적 "내용쪽 폰트 크기 적용해줘" — 배율 200%에서 제목 30px / 본문 24px 로 실측).
       ★ 값은 반드시 **px** 로 쓴다 — 글자배율(js/fontScale.js)은 px 값만 비례로 다시 쓴다.
         em·rem 으로 두면 설정을 따라가지 않는다. 14px 이면 200%에서 28px 로 제목(30px)과 나란해진다. */
                          font-size: 14px; }

/* 제목줄 — 날짜와 저장시각은 **토막나지 않는다**. 글자배율 125%↑ 에서 둘을 한 줄에 못 넣으면
   낱말 중간에서 꺾일 게 아니라 저장시각이 통째로 아랫줄로 내려가야 한다(2026-09-14 지적:
   "2026-09-15 / (화)", "2026-09-14 14:52 / 저장" 처럼 갈라져 보였다). */
.wdy_layout .wsc_tit { display: flex; align-items: baseline; flex-wrap: wrap; gap: 2px 8px; }
.wdy_date       { font-size: 15px; font-weight: 700; color: var(--c-text); white-space: nowrap; }
.wdy_stamp      { margin-left: auto; font-size: 11px; font-weight: 500; color: var(--c-text-muted); white-space: nowrap; }

/* ── ③ 달력 격자 표식 — 칸 오른쪽 위 펜 ────────────────────
   엔진 scheduleCalendar 의 dayInfo.badges 자리(.msc_meta — position:absolute; top:5px; right:6px)를
   그대로 쓴다. 새 엔진 기능을 만들지 않은 이유가 이것이다: 자리도 규격도 이미 있었다. */
.wp_diary_mark  { display: inline-block; width: 12px; height: 12px; vertical-align: middle;
                  background-color: var(--wp-diary);
                  -webkit-mask: url('../images/icon_edit.svg') no-repeat center / contain;
                          mask: url('../images/icon_edit.svg') no-repeat center / contain; }

/* ── 달력 칸의 하루기록 «줄» (2026-09-15 지시 「시안 3」) ────────────────────────
   칸 오른쪽 위 10px 펜을 대신한다. 그 펜은 **고정 px** 이라 글자배율을 올린 폰에서
   상대적으로 절반이 돼 거의 안 보였다(200% 실사용 화면 지적).
   ★ 크기를 전부 em 으로 잡는다 — 배율을 그대로 따라간다. 이게 이 시안의 핵심이다.
   ★ 엔진 바 마크업(.msc_bar > .msc_ico)을 그대로 쓴다. CAL001 이 ico 자리에 빈 <i> 를 넣어
     여기에 걸리게 한다 — 엔진에 항목별 클래스 훅이 없어서 택한 통로다. */
.wp_cal_shell .msc_ico > .wp_diary_ico {
    /* 0.85em — 1em 이면 글자 높이와 같아져 좁은 칸에서 제목 자리를 크게 먹는다(200% 실측: 136px 바에서 28px) */
    display: inline-block; width: 0.85em; height: 0.85em; vertical-align: -0.06em;
    background-color: var(--wp-diary);
    -webkit-mask: url('../images/icon_edit.svg') no-repeat center / contain;
            mask: url('../images/icon_edit.svg') no-repeat center / contain; }
/* 펜이 든 줄은 이모지 자리의 기본 여백을 쓰지 않는다 — 글자와 붙여 한 덩어리로 읽히게 */
.wp_cal_shell .msc_bar:has(.wp_diary_ico) .msc_ico { margin-right: 0.15em; font-size: inherit; }
/* ★ 기록 줄에는 세로 바를 그리지 않는다 — 그 자리를 펜이 쓴다 (2026-09-15 지시 「시안 4」).
   종전엔 세로 막대(3×28.8) 바로 위에 대각선 펜이 **겹쳐**(실측 간격 -4px, 둘 다 바 왼쪽 끝에서 시작)
   두 획이 이어져 **체크(✓)로 읽혔다**. 겹치는 둘 중 하나를 없애면 이어질 획 자체가 사라진다.
   덤으로 역할이 모양으로 갈린다 — 일정은 막대, 기록은 펜. 색을 못 알아봐도 구분된다.
   ★ .msc_line 은 절대배치라 숨겨도 글자 자리가 밀리지 않는다(펜은 이미 바 왼쪽 끝에 있다). */
.wp_cal_shell .msc_bar:has(.wp_diary_ico) .msc_line { display: none; }


/* ── 일자 목록 좌우 스와이프 (2026-09-14) ─────────────────────────────
   슬라이드 3장 = [전날][보는 날][다음날]. 스크롤은 **각 슬라이드 안에서** 일어난다 —
   바깥(.wpl_list)이 스크롤하면 가로 전환과 세로 스크롤이 같은 축에서 싸운다.
   Swiper 는 터치 각도로 가로/세로를 가르므로 세로 스크롤은 그대로 살아 있다. */
.wpl_list:has(> .wpl_swiper) { overflow: hidden; padding: 0; }
.wpl_swiper        { width: 100%; height: 100%; min-height: 0; }
.wpl_swiper > .swiper-wrapper { height: 100%; }
.wpl_swiper .swiper-slide     { height: 100%; min-height: 0; overflow-y: auto; overflow-x: hidden;
                                overscroll-behavior: contain; padding: 0 8px 4px; box-sizing: border-box; }
/* 슬라이드가 바뀌는 동안 바깥으로 삐져나오지 않게 — 팝업 카드 모서리 안쪽에서만 움직인다 */
.wpl_swiper .swiper-slide > .wpl_schedule_head { margin: 0 -8px; padding-left: 14px; padding-right: 14px; }


/* ── 일정 상세: 같은 날 일정끼리 좌우 스와이프 (2026-09-14) ─────────────
   슬라이드 3장을 그리는 대신 본문을 제자리에서 갈아끼우고, 넘어가는 느낌만 CSS 로 준다
   (상세 렌더가 고정 id 를 채우는 큰 함수라 3벌 복제가 불가 — POP_SCHVIEW 머리주석). */
/* ★ 세로 스크롤은 브라우저에, 가로는 우리에게 — 이 선언이 없으면 안드로이드 웹뷰가 가로 끌기를
   패닝으로 가져가 스와이프가 통째로 안 먹는다(2026-09-14 앱 실사고). JS 에서도 같은 값을 넣지만
   선언을 CSS 에도 둔다 — 한 줄짜리 방어를 코드 한 곳에만 두지 않는다. */
.wsv_body            { touch-action: pan-y; }
/* 끌림 추적(2026-09-14) — 전환은 화면 스크립트가 인라인 transform 으로 직접 몬다.
   여기서는 그 움직임이 팝업 밖으로 삐져나오지 않게 가두기만 한다.
   (복제본을 겹쳐 미는 안도 있었지만 같은 id 가 잠시 둘이 되는 위험이 있어 택하지 않았다.) */
.wsv_layout          { overflow: hidden; }
.wsv_body            { will-change: transform; }
/* 끝에 닿으면 살짝 튕긴다 — "더 없다" 를 문구 없이 알린다 */
.wsv_bounce_left     { animation: wsvBounceL .22s ease; }
.wsv_bounce_right    { animation: wsvBounceR .22s ease; }
@keyframes wsvBounceL { 0%,100% { transform: none; } 50% { transform: translateX(-5%); } }
@keyframes wsvBounceR { 0%,100% { transform: none; } 50% { transform: translateX(5%); } }
/* 그 날 몇 번째인지 — 메타 줄 오른쪽 끝의 작은 칩 */
.wsv_pos             { margin-left: auto; flex: 0 0 auto; padding: 1px 7px; border-radius: 999px;
                       border: 1px solid var(--wp-pop-border); background: var(--wp-pop-card-bg);
                       color: var(--c-text-sub); font-size: 11px; font-weight: 700; }
/* 움직임을 줄이라는 기기 설정은 존중한다 — 전환만 끄고 기능은 그대로 */
@media (prefers-reduced-motion: reduce) {
  .wsv_body, .wsv_in_right, .wsv_in_left, .wsv_bounce_left, .wsv_bounce_right { transition: none; animation: none; }
  .wsv_out_left, .wsv_out_right { transform: none; opacity: 1; }
}


/* ── 팝업 제목의 요일 색 (2026-09-14 지시) ────────────────────────────
   달력 칸(.msc_sun/.msc_sat)과 **같은 토큰**을 쓴다 — 같은 요일이 화면마다 다른 색이면
   그 색이 무슨 뜻인지 읽히지 않는다. 평일은 제목 색 그대로 둔다. */
.wp_dow          { font-weight: inherit; }
/* flex 컨테이너 안에서 "한 덩어리"로 묶어야 할 때 — 조각들이 각각 flex 항목이 되어
   벌어지거나 줄이 갈라지는 것을 막는다(팝업 제목·상세 일시에서 실제로 겪었다) */
.wp_inline       { display: inline; }
.wp_dow_sun      { color: var(--c-danger); }
.wp_dow_sat      { color: var(--c-info); }
