/* ==========================================================================
   MOBILE SHELL — 하단 탭 · 얇은 상단바 · 현재 모듈 드로어 · 화면별 FAB
   spec docs/superpowers/specs/2026-09-23-mobile-shell-design.md
   규칙: >768px 에서 새 요소는 전부 display:none 이고 기존 모양은 바뀌지 않는다.
   모든 미디어 쿼리는 screen 전용이다 — 인쇄 폭(A4 ≈ 718px)은 768px 보다 좁아 bare max-width 가
   인쇄에도 걸린다 (리뷰 I4).
   근태(ATTENDANCE)·일정(CALENDAR) 블록은 Task 5·6·8·9 가 이 파일 끝에 더한다.
   ========================================================================== */
:root { --m-tabbar-h: 0px; }
.m-title, .m-tabbar, .m-addr, .m-sheet, .m-bar-actions, .m-fab, .m-only, .gnav-m-others { display: none; }
.m-sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
/* [data-m-fold] <details>: 데스크톱에서는 늘 열린 채 요약 줄이 없다 (mobile-shell.js 가 모바일에서만 닫는다) */
details[data-m-fold] > summary { display: none; }

@media screen and (max-width: 768px), screen and (pointer: coarse) and (max-height: 500px) and (max-width: 1000px) {
    /* 탭바는 아이콘 스프라이트가 있는 화면에서만 선다 (리뷰 I2): 인증·인쇄·오류처럼 앱 크롬이 없는 화면은
       스프라이트도 없으므로 빈 아이콘 탭바 대신 아무것도 그리지 않고, 여백도 0 이다 (리뷰 M7).
       id 대신 속성 선택자를 쓴다 — 아래 키보드 규칙이 명시도로 이겨야 한다. */
    html:has(.m-tabbar):has([id="ico-nav-home"]) { --m-tabbar-h: calc(56px + var(--m-addr-h, 0px) + env(safe-area-inset-bottom, 0px)); }
    /* 가상 키보드: 키보드를 띄우는 칸에 포커스가 있으면 탭바·FAB 를 걷는다 (Review Focus 4) — 손가락 화면만
       (마우스에는 가상 키보드가 없다). html.m-typing 은 mobile-shell.js 가 세우고, 칸을 떠날 때는 누르기·탭 흐름이
       끝난 뒤에 푼다(누른 순간 탭바가 다시 서면 떼는 곳이 탭바가 되어 클릭이 사라진다). 위의 높이 규칙(0,2,1)을
       이기도록 :has(.m-tabbar) 를 붙여 명시도를 맞추고 뒤에 둔다. */
    @media (pointer: coarse) {
        html.m-typing:has(.m-tabbar) { --m-tabbar-h: 0px; }
        html.m-typing :is(.m-tabbar, .m-fab, .m-addr) { display: none; }
    }
    body { padding-bottom: var(--m-tabbar-h); }
    .m-only { display: block; }
    .m-hide { display: none !important; }
    details[data-m-fold] > summary { display: flex; align-items: center; justify-content: space-between; min-height: 44px; cursor: pointer; font-weight: 600; }

    /* ── 상단바 (§2.2): ☰ · 제목 · (화면 액션) · 🔔 ── */
    .navbar { padding-left: 0; padding-right: 0; padding-top: env(safe-area-inset-top, 0px); }
    .navbar .container { padding: 0 8px; }
    .navbar .navbar-brand, .navbar .navbar-tabs, .navbar .user-menu-wrapper { display: none !important; }
    .navbar-inner > .hamburger-menu, .navbar-inner:has(.admin-header-actions) > .hamburger-menu { order: -1; margin: 0 2px 0 0; }
    .navbar-nav.admin-header-actions { margin-right: 0; }
    .m-title { display: block; order: 0; flex: 1 1 auto; min-width: 0; color: #fff; font-size: 18px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    body:not(:has(.impersonation-banner)):has(.m-bar-actions > :nth-child(1)) .m-title { padding-right: 44px; }
    body:not(:has(.impersonation-banner)):has(.m-bar-actions > :nth-child(2)) .m-title { padding-right: 88px; }

    /* ── 화면 액션 · FAB (§2.6): 본문 안에 선언하고 여기서 위치만 정한다 ── */
    .m-bar-actions { display: flex; align-items: center; gap: 4px; position: fixed; top: env(safe-area-inset-top, 0px); right: 52px; height: 56px; z-index: calc(var(--z-sticky) + 1); }
    .m-bar-btn { position: relative; display: grid; place-items: center; width: 40px; height: 40px; padding: 0; border: 0; border-radius: 10px; background: none; color: rgba(255, 255, 255, .92); font: inherit; text-decoration: none; cursor: pointer; }
    .m-bar-btn:active { background: rgba(255, 255, 255, .14); }
    .m-bar-btn:focus-visible { outline: 2px solid #fff; outline-offset: -2px; }
    /* 다른 사용자로 보기: 배너가 상단바 위에 서므로 상단바 안의 고정 자리를 쓸 수 없다 — 액션을 본문
       맨 위 한 줄로 내려 그대로 쓸 수 있게 둔다 (M11, 예전엔 숨겨서 일정 필터에 닿을 수 없었다). */
    body:has(.impersonation-banner) .m-bar-actions { position: static; height: auto; justify-content: flex-end; margin: 0 0 8px; }
    body:has(.impersonation-banner) .m-bar-btn { color: var(--color-text); }
    body:has(.impersonation-banner) .m-bar-btn:active { background: var(--gray-100, #f3f4f6); }
    body:has(.impersonation-banner) .m-bar-btn:focus-visible { outline-color: var(--color-primary); }
    .m-today-icon { display: grid; place-items: center; width: 24px; height: 22px; border: 2px solid currentColor; border-top-width: 5px; border-radius: 4px; font-size: 11px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
    .m-fab { display: grid; place-items: center; position: fixed; right: calc(16px + env(safe-area-inset-right, 0px)); bottom: calc(var(--m-tabbar-h) + 16px); z-index: calc(var(--z-sticky) + 1); width: 56px; height: 56px; padding: 0; border: 0; border-radius: 50%; background: var(--color-primary); color: #fff; box-shadow: 0 6px 16px rgba(15, 23, 42, .25); text-decoration: none; cursor: pointer; }
    .m-fab:active { transform: scale(.96); }
    .m-fab:focus-visible { outline: 3px solid var(--color-primary-light); outline-offset: 2px; }
    body.modal-scroll-lock .m-fab { display: none; }

    /* ── 서브바: 화면의 기간·월 이동 줄 (근태 내역 · 일정) ── */
    .m-subbar { position: sticky; top: calc(var(--navbar-h, 56px) + env(safe-area-inset-top, 0px)); z-index: 5; display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 0 calc(-1 * var(--space-4)) 12px; padding: 6px var(--space-4); background: var(--color-background); }
    .m-subbar-nav { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 10px; color: var(--color-text); font-size: 22px; text-decoration: none; }
    .m-subbar-title { flex: 1; min-width: 0; display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 40px; padding: 0 4px; border: 0; background: none; color: var(--color-text); font: inherit; font-size: 17px; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; }

    /* ── 하단 탭 (§2.3) ── */
    .m-tabbar { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-sticky); height: calc(var(--m-tabbar-h) - var(--m-addr-h, 0px)); padding: 0 env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px); background: var(--color-surface, #fff); border-top: 1px solid var(--color-border); box-shadow: 0 -2px 10px rgba(15, 23, 42, .05); }
    html:not(:has([id="ico-nav-home"])) .m-tabbar { display: none; }
    .m-tab { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; min-width: 0; min-height: 44px; padding: 6px 2px 4px; border: 0; background: none; color: var(--color-text-secondary); font: inherit; font-size: 11px; line-height: 1.2; text-decoration: none; cursor: pointer; -webkit-tap-highlight-color: transparent; }
    .m-tab.active { color: var(--color-primary); font-weight: 600; }
    .m-tab:focus-visible { outline: 2px solid var(--color-primary); outline-offset: -4px; border-radius: 8px; }
    .m-tab-label { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .m-tab-dot { position: absolute; top: 6px; left: calc(50% + 7px); width: 7px; height: 7px; border-radius: 50%; background: var(--color-error, #ef4444); box-shadow: 0 0 0 2px var(--color-surface, #fff); }
    .m-tab-preview { position: absolute; top: 2px; right: 2px; padding: 0 4px; border-radius: 6px; font-size: 9px; font-weight: 600; line-height: 14px; background: #fef3c7; color: #92400e; }
    .m-tab-avatar { display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: var(--gray-200, #e5e7eb); color: var(--color-text); font-size: 12px; font-weight: 700; }
    .m-tab-all.active .m-tab-avatar { background: var(--color-primary); color: #fff; }

    /* ── 바텀 시트 (「전체」 · 근태 ▾ · 일정 ⋯) ── */
    .m-sheet:not([hidden]) { display: block; position: fixed; inset: 0; z-index: var(--z-modal); }
    .m-sheet-backdrop { position: absolute; inset: 0; background: rgba(15, 23, 42, .45); }
    .m-sheet-panel { position: absolute; left: 0; right: 0; bottom: 0; max-height: calc(100dvh - 32px); overflow-y: auto; overscroll-behavior: contain; padding: 6px 16px calc(16px + env(safe-area-inset-bottom, 0px)); background: var(--color-surface, #fff); color: var(--color-text); border-radius: 16px 16px 0 0; box-shadow: 0 -8px 30px rgba(15, 23, 42, .2); animation: m-sheet-up .18s ease-out; }
    .m-sheet-grip { width: 36px; height: 4px; margin: 4px auto 12px; border-radius: 2px; background: var(--gray-300, #d1d5db); }
    .m-sheet-title { margin: 0 0 8px; font-size: 16px; font-weight: 700; }
    .m-sheet-item { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 48px; padding: 0 4px; border: 0; border-bottom: 1px solid var(--color-border); background: none; color: inherit; font: inherit; font-size: 15px; text-align: left; text-decoration: none; cursor: pointer; }
    .m-sheet-item[aria-current="page"] { color: var(--color-primary); font-weight: 600; }

    .m-all-me { display: flex; align-items: center; gap: 12px; padding: 8px 4px 14px; border-bottom: 1px solid var(--color-border); color: inherit; text-decoration: none; }
    .m-all-me .avatar { width: 44px; height: 44px; font-size: 18px; }
    .m-all-me-text { display: flex; flex-direction: column; min-width: 0; }
    .m-all-me-text strong { font-size: 16px; }
    .m-all-me-text small { color: var(--color-text-secondary); font-size: 13px; }
    .m-all-list { display: flex; flex-direction: column; padding: 6px 0 10px; }
    .m-all-item { display: flex; align-items: center; gap: 12px; min-height: 46px; padding: 0 4px; border: 0; background: none; color: inherit; font: inherit; font-size: 15px; text-align: left; text-decoration: none; cursor: pointer; }
    .m-all-item.danger { color: var(--color-error, #dc2626); }
    .m-all-head { display: flex; align-items: center; justify-content: space-between; padding: 10px 4px 6px; border-top: 1px solid var(--color-border); }
    .m-all-head h3 { margin: 0; color: var(--color-text-secondary); font-size: 14px; font-weight: 700; }
    .m-all-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; padding: 4px 0 8px; }
    .m-all-mod { position: relative; display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 10px 2px; border-radius: 12px; color: inherit; font-size: 12px; text-align: center; text-decoration: none; }
    .m-all-mod.active { background: var(--color-primary-light); color: var(--color-primary); font-weight: 600; }
    .m-all-mod-ico { position: relative; display: grid; place-items: center; width: 44px; height: 44px; border-radius: 14px; background: var(--gray-100, #f3f4f6); }
    .m-all-mod-label { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .m-all-mod .m-tab-dot { top: 2px; left: auto; right: 2px; }
    .m-all-hint { margin: 0 4px 8px; color: var(--color-text-secondary); font-size: 13px; }
    .m-all-max { color: #92400e; }
    .m-edit-list { list-style: none; margin: 0; padding: 0; }
    .m-edit-row { display: flex; align-items: center; gap: 4px; min-height: 48px; border-bottom: 1px solid var(--color-border); }
    .m-edit-label { display: flex; align-items: center; gap: 10px; flex: 1; min-width: 0; font-size: 15px; }
    .m-edit-check { width: 20px; height: 20px; }
    .m-edit-move { width: 40px; height: 40px; border: 0; border-radius: 8px; background: none; color: var(--color-text-secondary); font-size: 16px; cursor: pointer; }
    .m-edit-row:first-child [data-m-move="up"], .m-edit-row:last-child [data-m-move="down"] { visibility: hidden; }
    .m-edit-bar { position: sticky; bottom: 0; display: flex; align-items: center; gap: 8px; padding: 12px 0 0; background: var(--color-surface, #fff); }
    .m-edit-spacer { flex: 1; }

    /* ── 드로어: 현재 모듈 그룹을 맨 위에 (§2.5) ── */
    .global-sidebar .gnav { display: flex; flex-direction: column; }
    .global-sidebar .gnav > [data-m-current] { order: -2; }
    .global-sidebar .gnav > .gnav-m-others { display: block; order: -1; margin: 8px 0 0; padding: 12px 20px 4px; border-top: 1px solid var(--color-border); color: var(--color-text-muted); font-size: 12px; font-weight: 600; }
    .global-sidebar .gnav > [data-group="account"] { display: none; }

    /* ── 바닥 고정 요소는 탭바 위로 (§2.7). 목록 밖의 것은 e2e 겹침 프로브가 잡는다 ── */
    body #notificationStack { bottom: calc(var(--m-tabbar-h) + 12px); }
    body .cal-undo-toast, body .totp-reveal-toast, body .cred-copy-toast { bottom: calc(var(--m-tabbar-h) + 24px); }
    body .cal-selbar { bottom: calc(var(--m-tabbar-h) + 16px); }
    body .calp-bulkprop, body .calp-dates-pop { bottom: calc(var(--m-tabbar-h) + 72px); }
    body .apc-actions { bottom: var(--m-tabbar-h); }
    body .eval-right { bottom: var(--m-tabbar-h); }
    body #bulkEditBar { bottom: var(--m-tabbar-h) !important; }
    /* 스티키 바닥 막대도 탭바 위에서 멈춘다 (리뷰 I1). 모듈 CSS 가 이 파일 뒤에 실리므로 html body 로 명시도를 올린다.
       문서 모달(#apvDocBody) 안의 결재 바는 모달이 탭바를 덮으므로 바닥 그대로다. */
    html body .apv-decide { bottom: var(--m-tabbar-h); }
    html body #apvDocBody .apv-decide { bottom: 0; }
    html body .apv-bulk-bar { bottom: calc(var(--m-tabbar-h) + 8px); }
    html body #userEditForm[data-dirty] .card-footer[data-save-bar] { bottom: var(--m-tabbar-h); }
    html body .erp-doc-foot { bottom: var(--m-tabbar-h); }
    html body .eval-rubric-bar { bottom: var(--m-tabbar-h); }
    /* 검토 줄은 바닥의 증거 시트(.eval-right) 위에 선다 — 그 시트가 탭바만큼 올라갔으니 같이 올린다 */
    html body .eval-review-bar { bottom: calc(52px + var(--m-tabbar-h)); }
    /* FAB 가 있는 화면은 마지막 행 아래에 FAB 만큼 자리를 둔다 (리뷰 M12) */
    body:has(.m-fab) main.admin-main { padding-bottom: calc(var(--space-4) + 72px); }
    /* /apps: 앱 영역은 탭바 위에서 끝나고, 집중 모드(⛶)는 탭바도 걷는다 (리뷰 I6) */
    body[data-page="apps"] .apps-shell { min-height: 0; height: calc(100dvh - var(--navbar-h, 56px) - var(--m-tabbar-h)); }
    body[data-page="apps"] .apps-shell > main { flex: 1; min-height: 0; }
    html:has(#appsContainer.zen) { --m-tabbar-h: 0px; }
    html:has(#appsContainer.zen) :is(.m-tabbar, .m-addr) { display: none; }
}
@media screen and (max-width: 768px) and (prefers-reduced-motion: reduce), screen and (pointer: coarse) and (max-height: 500px) and (max-width: 1000px) and (prefers-reduced-motion: reduce) { .m-sheet-panel { animation: none; } }
@keyframes m-sheet-up { from { transform: translateY(24px); opacity: .6; } to { transform: none; opacity: 1; } }
/* ── ATTENDANCE (spec §3) ─────────────────────────────────────────────── */
@media screen and (max-width: 768px), screen and (pointer: coarse) and (max-height: 500px) and (max-width: 1000px) {
    .att-m-totals { margin: 0 0 16px; padding: 16px 18px; border: 1px solid var(--color-border); border-radius: 16px; background: var(--color-surface, #fff); }
    .att-m-total { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
    .att-m-total span { font-size: 16px; font-weight: 600; }
    .att-m-total strong { font-size: 28px; font-weight: 800; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
    .att-m-facts { margin-top: 10px; color: var(--color-text-secondary); font-size: 14px; font-variant-numeric: tabular-nums; }
    .att-m-days { display: flex; flex-direction: column; }
    .att-m-day { display: flex; flex-direction: column; gap: 4px; padding: 14px 2px; border-bottom: 1px solid var(--color-border); color: inherit; text-decoration: none; }
    .att-m-day.today { margin: 0 -8px; padding-left: 10px; padding-right: 10px; border-radius: 8px; background: linear-gradient(90deg, var(--color-primary-light), transparent); }
    .att-m-day.off .att-m-date { color: var(--color-text-muted); }
    .att-m-date { color: var(--color-text-secondary); font-size: 14px; font-variant-numeric: tabular-nums; }
    .att-m-today { margin-left: 6px; color: var(--color-primary); font-style: normal; font-weight: 600; }
    .att-m-line { font-size: 15px; font-variant-numeric: tabular-nums; }
    .att-m-badges { display: flex; flex-wrap: wrap; gap: 8px; font-size: 14px; }
    .att-m-badge.error { color: var(--color-error, #dc2626); font-weight: 600; }
    .att-m-badge.warning { color: #b45309; }
    .att-m-badge.info { color: var(--color-primary); }
    .att-m-badge.secondary { color: var(--color-text-secondary); }
    .att-m-empty { padding: 24px 0; color: var(--color-text-muted); text-align: center; }
    /* 명시적 월 달력(view=calendar)도 390px 에서 읽힐 만하게 — 인라인 <style> 을 이기려고 body 접두 */
    body .att-cal-table td { height: 56px; padding: 4px 2px; }
    body .att-cal-table .att-cal-time { display: none; }
    body .att-cal-table td .badge { display: block; margin: 2px 0 0; padding: 0 2px; font-size: 9px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
}
@media screen and (max-width: 768px), screen and (pointer: coarse) and (max-height: 500px) and (max-width: 1000px) {
    /* 출퇴근 (§3.2) */
    .attendance-ring-box { --att-ring: 180px; }
    .att-quick-cards { flex-wrap: nowrap !important; overflow-x: auto; scroll-snap-type: x mandatory; padding-bottom: 4px; scrollbar-width: none; }
    .att-quick-cards > * { flex: 0 0 72% !important; min-width: 0 !important; scroll-snap-align: start; }
    .att-team-fold > summary { list-style: none; }
    .att-team-fold > summary::-webkit-details-marker { display: none; }
    .att-team-fold > summary::after { content: "▾"; color: var(--color-text-muted); }
    .att-team-fold[open] > summary::after { content: "▴"; }
    /* 근태 문서 (§3.3): 칩 줄은 가로 스크롤, 신청 모달은 바텀 시트 (.att-modal 은 layout.css 의 ≤768 규칙이 이미 시트다).
       신청 모달의 상자는 인라인 스타일이라 !important 로만 덮는다. */
    .att-chips { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
    #attReqModal { align-items: flex-end !important; }
    #attReqModal > div:not(.att-req-backdrop) { width: 100% !important; max-width: none !important; max-height: 92dvh !important; border-radius: 16px 16px 0 0 !important; }
    /* 제출 줄은 긴 양식을 스크롤해도 시트 바닥에 남는다 (M9). 줄의 여백은 인라인이라 !important 로 덮는다. */
    #attReqModal .att-req-actions { position: sticky; bottom: 0; z-index: 1; margin: var(--space-5) calc(-1 * var(--space-5)) calc(-1 * var(--space-5)) !important; padding: 12px var(--space-5) calc(12px + env(safe-area-inset-bottom, 0px)); border-top: 1px solid var(--color-border); background: var(--color-surface, #fff); }
}
/* ── CALENDAR (spec §4) ───────────────────────────────────────────────── */
.cal-mdots, .cal-agenda, .cal-m-search-close { display: none; }
@media screen and (max-width: 768px), screen and (pointer: coarse) and (max-height: 500px) and (max-width: 1000px) {
    #calGrid .cal-bar { display: none; }
    /* .cal-week-days 는 절대 위치라 줄 높이는 min-height 로만 정해진다 — 월·주 모두 한 줄 58px (막대가 없으니 레인도 없다) */
    #calGrid .cal-week, #calGrid[data-week] .cal-week { min-height: 58px; border-bottom: 0; }
    #calGrid .cal-day, #calGrid .cal-day.pad { border-right: 0; background: transparent; }
    #calGrid .cal-day { display: flex; flex-direction: column; align-items: center; gap: 3px; min-height: 54px; padding: 4px 0 6px; cursor: pointer; }
    #calGrid .cal-day-num { display: flex; justify-content: center; }
    #calGrid .cal-day-num b { display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; font-size: 15px; font-weight: 500; font-variant-numeric: tabular-nums; }
    #calGrid .cal-day .cal-hol { display: none; }
    #calGrid .cal-day.hol .cal-day-num b { color: var(--color-error, #dc2626); }
    #calGrid .cal-day.today .cal-day-num b { background: var(--color-primary-light); color: var(--color-primary); font-weight: 700; }
    #calGrid .cal-day.m-selected .cal-day-num b { background: var(--color-primary); color: #fff; font-weight: 700; }
    .cal-mdots { display: flex; align-items: center; gap: 3px; height: 6px; }
    .cal-mdot { width: 5px; height: 5px; border-radius: 50%; }
    .cal-mdot.done { opacity: .4; }
    .cal-mdot-more { color: var(--color-text-muted); font-size: 9px; font-style: normal; line-height: 6px; }
    .cal-agenda:not([hidden]) { display: block; min-height: 40vh; margin: 12px calc(-1 * var(--space-4)) 0; padding: 12px var(--space-4) 16px; border-top: 1px solid var(--color-border); background: var(--gray-50, #f8fafc); }
    .cal-agenda-head { margin: 0 0 10px; font-size: 16px; font-weight: 600; font-variant-numeric: tabular-nums; }
    .cal-agenda-list { display: flex; flex-direction: column; gap: 8px; }
    .cal-agenda-row { display: grid; grid-template-columns: 64px 4px minmax(0, 1fr); align-items: center; gap: 12px; width: 100%; padding: 14px; border: 0; border-radius: 12px; background: var(--color-surface, #fff); box-shadow: 0 1px 2px rgba(15, 23, 42, .06); color: inherit; font: inherit; text-align: left; cursor: pointer; }
    .cal-agenda-row.done .cal-agenda-main strong { text-decoration: line-through; opacity: .6; }
    .cal-agenda-time { display: flex; flex-direction: column; gap: 4px; color: var(--color-text-secondary); font-size: 13px; font-variant-numeric: tabular-nums; }
    .cal-agenda-time b { color: var(--color-text); font-weight: 600; }
    .cal-agenda-stripe { align-self: stretch; width: 4px; border-radius: 2px; }
    .cal-agenda-main { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
    .cal-agenda-main strong { font-size: 16px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .cal-agenda-sub { color: var(--color-text-secondary); font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .cal-agenda-empty { margin: 16px 0 8px; color: var(--color-text-muted); text-align: center; }
    .cal-agenda-add { display: block; margin: 0 auto; }
}
@media screen and (max-width: 768px), screen and (pointer: coarse) and (max-height: 500px) and (max-width: 1000px) {
    /* 서브바: ‹ 2026년 9월 › 오늘 (기존 툴바 왼쪽), 오른쪽(검색·실행 취소)은 접는다 */
    body[data-page="calendar"] .cal-toolbar { position: sticky; top: calc(var(--navbar-h, 56px) + env(safe-area-inset-top, 0px)); z-index: 5; margin: 0 calc(-1 * var(--space-4)) 8px; padding: 6px var(--space-4); background: var(--color-background); }
    body[data-page="calendar"] .cal-month-title { font-size: 18px; }
    body[data-page="calendar"] .cal-toolbar-right, #calUndoBtn, #calRedoBtn { display: none; }
    html.cal-m-search body[data-page="calendar"] .cal-toolbar-right { display: block; }
    /* sticky 서브바(z 5)가 쌓임 맥락을 만들므로, 검색이 열린 동안에는 그 서브바째 상단바 위로 올린다 — 안 그러면 고정 검색 폼이 상단바 아래에 깔린다 */
    html.cal-m-search body[data-page="calendar"] .cal-toolbar { z-index: calc(var(--z-sticky) + 2); }
    html.cal-m-search .cal-search { position: fixed; top: env(safe-area-inset-top, 0px); left: 0; right: 0; z-index: calc(var(--z-sticky) + 2); display: flex; align-items: center; gap: 8px; height: 56px; padding: 8px 12px; background: var(--gray-900, #111827); }
    html.cal-m-search .cal-search input:not([type="hidden"]) { flex: 1; height: 40px; }
    html.cal-m-search .cal-m-search-close { display: grid; place-items: center; width: 40px; height: 40px; border: 0; background: none; color: #fff; font-size: 18px; }
    /* 뷰 탭은 화면에 남는다 (가로 스크롤 한 줄); 뷰 툴바와 필터는 ⋯ 시트 안에서만 */
    body[data-page="calendar"] .cal-vtabs { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
    body[data-page="calendar"] :not(.cal-sheet-slot) > .cal-vbar-region,
    body[data-page="calendar"] :not(.cal-sheet-slot) > .cal-filter-aside { display: none; }
    .cal-sheet-slot > .cal-vbar-region { display: block; margin-bottom: 12px; }
    .cal-sheet-slot .cal-vbar, .cal-sheet-slot .cal-vbar-left { flex-wrap: wrap; overflow: visible; }
    .cal-sheet-slot > .cal-filter-aside { display: block; width: 100%; min-width: 0; flex: none; }
}

/* ── GESTURES · TOUCH (spec 2026-09-25-phone-landscape §E) ─────────────────
   제스처 자체는 modules/touch-gestures.js 다. 여기는 그 무대와 손가락용 다듬기만. */
@media screen and (max-width: 768px), screen and (pointer: coarse) and (max-height: 500px) and (max-width: 1000px) {
    /* 기간 넘기기 루트: 세로 스크롤·확대는 브라우저가, 가로는 JS 가 (preventDefault 없이 가로 이동을 받는다) */
    [data-m-swipe] { touch-action: pan-y pinch-zoom; }
    /* 시트를 잡는 머리: 브라우저가 먼저 스크롤·당겨서 새로고침으로 가져가지 않게(끌기는 JS 가 받는다).
       단추가 안에 있어도 탭은 그대로다 — touch-action 은 끌기·확대만 막는다. */
    .m-sheet-panel > .m-sheet-grip, .m-sheet-panel > .m-sheet-title,
    [data-m-drag] .work-panel-head, [data-m-drag] .att-modal-head, [data-m-drag] .eval-issue-pop-head { touch-action: none; }
    /* 드로어가 열린 동안 뒤 화면은 멈춘다 */
    html.m-drawer-open, html.m-drawer-open body { overflow: hidden; }
    /* 끝까지 스크롤한 손가락이 뒤 화면을 끌고 가지 않게 */
    #adminSidebar, .work-panel-sheet, .work-panel-body, .eval-issue-pop, .att-modal-box, .apv-modal-panel, .cal-peek-root, .cal-peek-body, .cal-tg-body { overscroll-behavior: contain; }
    /* 당겨서 새로고침 표시(설치한 앱에서만 생긴다) */
    .m-ptr { position: fixed; top: calc(var(--navbar-h, 56px) + env(safe-area-inset-top, 0px) - 30px); left: 50%; z-index: calc(var(--z-modal, 400) + 2); display: grid; place-items: center; width: 36px; height: 36px; border-radius: 50%; background: var(--color-surface, #fff); color: var(--color-text-secondary); box-shadow: 0 2px 10px rgba(15, 23, 42, .18); transform: translate(-50%, 0); pointer-events: none; }
    .m-ptr[data-ready="1"] { color: var(--color-primary); }
    .m-ptr-icon { font-size: 20px; line-height: 1; }
    .m-ptr.m-ptr-spin .m-ptr-icon { animation: m-ptr-spin .7s linear infinite; }
}
@keyframes m-ptr-spin { to { transform: rotate(360deg); } }
/* 손가락에는 hover 가 없다: 마우스를 올려야 나타나던 조작을 늘 보인다 (§E.3).
   hover 는 값을 올리기만 하므로 !important 가 안전하다 — 기준 규칙이 id·템플릿 인라인 스타일에 있어도 이긴다.
   끌기 전용 손잡이(.calp-grip·.erp-handle·.calp-link-h)는 터치로 끌 수 없으니 그대로 둔다. */
@media (hover: none) {
    .cal-list-sel, .cal-list-gadd, .cal-proj-del, .cal-prop-rm, .cal-list-check input,
    .calp-open, .calp-sel,
    .crm-row-actions, .crm-team-x, .crm-star, .crm-ico-group, .crm-x,
    .erp-remove, .erp-pay-x, .erp-alloc-x { opacity: 1 !important; }
    .dept-row-acts, .calp-propmgr-acts { opacity: 1; }
    /* 누른 느낌 — 회색 탭 하이라이트 대신 살짝 옅어진다 */
    .btn, .m-tab, .m-sheet-item, .m-bar-btn, .m-fab, .m-subbar-nav { -webkit-tap-highlight-color: transparent; }
    .btn:active, .m-tab:active, .m-sheet-item:active, .m-bar-btn:active, .m-fab:active, .m-subbar-nav:active { opacity: .72; }
}
/* 두 번 탭 확대 없음 — 달력 칸·단추를 빠르게 두 번 누르면 화면이 확대되던 것 */
@media (pointer: coarse) {
    a, button, input, select, textarea, label, summary, [role="button"] { touch-action: manipulation; }
}

/* ── 폰 설치 앱의 주소 줄 (2026-09-30, partials/mobile-shell.html #mAddrBar · modules/mobile-addr.js) ──
   설치한 앱에는 브라우저 주소창이 없다. html.is-standalone(index.html 머리의 인라인 스크립트)일 때 탭바 바로 위에
   얇은 줄 하나 — 높이 --m-addr-h 는 --m-tabbar-h 에 들어가 저장 줄 · FAB · 토스트가 함께 비키고, 탭바가 걷히는
   경우(키보드 · /apps 전체 화면 앱 · 집중 모드 — --m-tabbar-h 가 0)에는 화면 밖으로 내려가 함께 사라진다. */
@media screen and (max-width: 768px), screen and (pointer: coarse) and (max-height: 500px) and (max-width: 1000px) {
    html.is-standalone { --m-addr-h: 36px; }
    html.is-standalone:has(.m-tabbar):has([id="ico-nav-home"]) .m-addr {
        display: flex; align-items: center; gap: 2px; position: fixed; left: 0; right: 0; z-index: var(--z-sticky);
        bottom: calc(var(--m-tabbar-h) - var(--m-addr-h)); height: var(--m-addr-h); box-sizing: border-box;
        padding: 0 calc(4px + env(safe-area-inset-right, 0px)) 0 calc(4px + env(safe-area-inset-left, 0px));
        background: var(--color-surface, #fff); border-top: 1px solid var(--color-border); box-shadow: 0 -2px 10px rgba(15, 23, 42, .05);
    }
    html.is-standalone .m-tabbar { box-shadow: none; }
    .m-addr-btn { display: grid; place-items: center; flex: none; width: 34px; height: 32px; padding: 0; border: 0; border-radius: 8px; background: none; color: var(--color-text-secondary); cursor: pointer; }
    .m-addr-btn svg { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
    .m-addr-btn:disabled { opacity: .35; cursor: default; }
    .m-addr-btn[hidden] { display: none; }
    .m-addr-btn:active:not(:disabled), .m-addr-url:active { background: var(--color-background); }
    .m-addr-url { flex: 1; min-width: 0; height: 26px; margin: 0 2px; padding: 0 12px; border: 0; border-radius: 13px; background: var(--gray-100, #f1f3f4);
                  color: var(--color-text); font: inherit; font-size: 12.5px; text-align: left; cursor: pointer; }
    .m-addr-path { display: block; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
    .m-addr-btn:focus-visible, .m-addr-url:focus-visible { outline: 2px solid var(--color-primary); outline-offset: -2px; }
}
