  /* ══════════════════════════════════════════════════════════════════════
     ERP 디자인시스템 v4 — 「밝은 옷」 (2026-10-16 대표 확정 · 과제 414a)
     기준서 = 루트 DESIGN.md(v4) · 값 정본 = 루트 디자인시스템v4/css/tokens.css · 부품 = 디자인시스템v4/지침.md
     기준 = 드리블 「LoopAI – CRM Dashboard for B2B SaaS」(모양 · 색) + 피그마 「ERP 디자인」 2 · 부품.

     ★ 색의 역할이 **둘**이다 :
         인디고 --accent #4351AC = **가리키는 것**(글 · 선 · 초점 고리 · 고른 줄 · 진도)
         보라 --fill-brand #5B4FC4 · --grad-brand = **채움**(주 단추 = 그라데이션 하나 · 숫자 배지 · 체크 · 토글)
     면 = 흰 위 흰(바탕 · 메뉴 · 카드 모두 #FFFFFF) · 층은 선으로(메뉴 = 오른쪽 선 · 카드 = 1px --line + 16) · 그림자 = 떠 있는 것만.
     글자 = 굵기 셋(400 · 450 · 500 — 600 · 700 ✗ · 10-16 대표 「C 이대로 확정」) · 글꼴 = 우리 서버 Pretendard Variable.
     v3 「Polaris」(09-11 · 검정 주 단추 · 회색 바탕)는 은퇴 — 이력 = DESIGN.md §10 · 진행일지.

     요소 id · 클래스 이름 · Supabase 로직은 하나도 바뀌지 않았다 — 껍데기만 v4.
     ══════════════════════════════════════════════════════════════════════ */
  /* ★ 과제 414a — 글꼴 = **우리 서버 먼저**(app/fonts/PretendardVariable.woff2 · Pretendard 공식 배포본 v1.3.9 · SIL OFL 1.1) · CDN 둘은 뒤.
        CDN 이 막히면 Apple SD Gothic Neo 는 450 → 500 으로 붙고 Windows 맑은 고딕은 셋 다 400 이 되어 굵기 위계가 사라진다(지침 Y).
        index.html 에 preload 한 줄(같은 주소) — 첫 그림에서 글꼴이 바뀌는 깜빡임을 줄인다.
     ⚠ Pretendard v1.3.9 부터 저장소가 모노레포로 바뀌어 gh 경로가 한 단계 깊어졌습니다
        (…/dist/… → …/packages/pretendard/dist/…). 옛 주소는 404 입니다 — 2026-08-14 실측.
        아래 세 줄은 규칙 23(CDN 다중화)과 같은 뜻 : 앞 줄이 실패하면 브라우저가 다음 줄을 받습니다. */
  @font-face{
    font-family:"Pretendard Variable";font-weight:45 920;font-style:normal;font-display:swap;
    src:url("../fonts/PretendardVariable.woff2") format("woff2-variations"),
        url("https://cdn.jsdelivr.net/npm/pretendard@1.3.9/dist/web/variable/woff2/PretendardVariable.woff2") format("woff2-variations"),
        url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/packages/pretendard/dist/web/variable/woff2/PretendardVariable.woff2") format("woff2-variations");
  }
  :root{
    /* ═══ v4 토큰 — 값 = 디자인시스템v4/css/tokens.css 그대로(관문 v433 ⓐ 가 이름마다 맞댐) · 이름은 v3 그대로 · ★ = v4 새 이름 ═══ */
    /* ── 면 (흰 위 흰 — 층은 선으로) ── */
    --bg-app:#FFFFFF; --bg-side:#FFFFFF; --bg-card:#FFFFFF;
    --bg-fill:#F6F6FA;             /* 카드 안 묶음 · 칩 neutral · 보기 전환 바탕 · 꺼진 단추 */
    --bg-hover:#EDEDF3;            /* 줄 hover 1.17 */
    --bg-active:#E6E3F8;           /* 고른 줄 · 키보드 커서 줄 1.26 (+ 왼쪽 2px --accent) */
    /* ── 선 ── */
    --line:#E7E7EE;                /* 카드 테두리 · 표 가로선 1.23 */
    --line-soft:#EDEDF2;           /* 카드 안 구분선 1.17 */
    --line-input:#D6D5DF;          /* 적는 칸 1.45 — 회색 얇은 선(대표 G-675 · 10-22 · 적는 자리는 초점 고리가 알림) */
    --line-tool:var(--line);       /* ★ 도구 줄 검색 알약 · 보조 단추 */
    /* ── 글 ── */
    --ink:#1E1D24; --text:#1E1D24; /* 16.7 */
    --text-2:#6B6A75;              /* 5.3 */
    --text-3:#76757F;              /* 4.54 — 글자로 쓰는 회색 바닥 */
    --deco:#B4B3BE;                /* ★ 글자 아닌 장식만(빈 동그라미 · 빗금 · 정렬 바탕) */
    /* 고르기 칸 꺾쇠 — ⚠ 그림(url) 안에는 var() 가 안 들어가서 값을 적는다 : --text-2 · --text-3 을 바꾸면 이 두 줄도 같이(선 = --ic-stroke 1.5) */
    --ic-chevron:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236B6A75' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    --ic-chevron-off:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2376757F' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    /* ── ★ 색의 역할 둘 : 인디고 = 글 · 선 · 고리 / 보라 = 채움 ── */
    --accent:#4351AC; --accent-hover:#36418F; --accent-active:#2A3373;
    --accent-soft:#EEEDFB;          /* 길잡이 상자 · 고른 메뉴 · 고른 알약 */
    --accent-line:#D9D4F5;          /* ★ 길잡이 · 고른 알약 테두리 */
    --fill-brand:#5B4FC4; --fill-brand-hover:#4A3FB0;   /* 숫자 배지 · 체크 · 그래프 선 · 토글 켬 */
    --grad-brand:linear-gradient(120deg,#6D61D3 0%,#4F6FCC 100%);        /* ★ 주 단추만(흰 글 4.7 ~ 6.0) */
    --grad-brand-hover:linear-gradient(120deg,#5E52C6 0%,#4462BD 100%);
    --grad-brand-press:linear-gradient(120deg,#5246B8 0%,#3B57AD 100%);  /* ★ 누름 */
    --btn-off-bg:var(--bg-fill); --btn-off-ink:var(--text-3);            /* ★ 꺼진 단추 */
    --on-fill:#FFFFFF;              /* ★ 채움 위 글 · 아이콘(주 단추 · 배지 · 체크) */
    --skel-hi:#FBFBFD;              /* ★ 뼈대 반짝 밝은 띠 */
    /* ── 상태 (칠 + 선 + 모양 + 글 · 칠 위 글 5.0+) ── */
    --ok:#1B6E45;   --ok-bg:#E8F7EF;   --ok-line:#BFE6D0;
    --warn:#8A6100; --warn-bg:#FFF6DB; --warn-line:#F3DE9E;
    --bad:#B42318;  --bad-bg:#FDECEA;  --bad-line:#F5C4BF;
    --info:#2F5FC4; --info-bg:#EAF1FF; --info-line:#C6D6F7;        /* ★ 검토 · 대기 */
    --nt:#5F5E69;   --nt-bg:#F4F4F7;   --nt-line:#E1E1E8;          /* ★ 초안 · 없음 */
    --purple:#8E3B9E; --purple-bg:#FBEFFC; --purple-line:#EBC9F0;  /* 매체사확인중(자두) 전용 */
    --src-kakao:#FEE500; --src-kakao-ink:#191919; --src-web:#2A4B85; --src-web-ink:#FFFFFF;   /* ★ 과제 375(10-12 대표 허락) — 광고문의 「문의경로」 알약 두 자리만 */
    --fill-editing:#C2410C; --fill-editing-hover:#9A3412; --fill-editing-ink:#FFFFFF;   /* ★ 과제 367b(10-13 대표 「PPT 그대로 주황」) — 당사 리스트 [수정중] 단추 **한 자리에만** · 흰 글 대비 5.2 */
    /* ── 그래프 (414b 가 모양을 쓴다 · 414a = 값만) ── */
    --viz-1:#7FD8B5; --viz-2:#8B80DB; --viz-3:#F6C9A8; --viz-4:#9DC3F2; --viz-5:#F2DE8C;
    --viz-1-ink:#1B6E45; --viz-2-ink:#4A3FB0; --viz-3-ink:#9A4A16; --viz-4-ink:#2F5FC4; --viz-5-ink:#8A6100;   /* ★ 막대 위 값 글자 */
    --viz-3-bg:#FFF0E3;             /* ★ 살구 그림 상자 바탕(바로가기 타일) */
    --viz-grid:#EDEDF2; --viz-axis:var(--text-3);
    --grad-viz-a:linear-gradient(90deg,#F2E6A8 0%,#A8E6CC 100%);   /* 값 글자 붙은 합계 막대만 */
    --grad-viz-b:linear-gradient(90deg,#F8D3B8 0%,#F3B8C8 100%);
    --hatch:repeating-linear-gradient(135deg,var(--line) 0 6px,var(--bg-card) 6px 10px);   /* ★ 남은 몫 빗금 */
    /* ── 모양 (여섯 단 · 계산식) ── */
    --r-pill:999px; --r-card:16px; --r-panel:16px; --r-ctl:10px;
    --r-chip:calc(var(--r-ctl) - 4px);   /* 6 — 칩 · 증감 · 코드 · 막대 위 */
    --r-key:calc(var(--r-ctl) / 2);      /* 5 — 키캡 · 체크 칸 */
    --r-inner:calc(var(--r-ctl) - 2px);  /* 8 — 메뉴 안 줄 · 타일 그림 상자 */
    /* ── 높이 한 벌 ── */
    --h-ctl:32px;      /* ★ 단추 · 입력 · 검색 알약 · 아이콘 단추 */
    --lh-ctl:calc(var(--h-ctl) - 2px);   /* ★ 과제 580 — 고르기 칸 줄 높이 = 칸 안 높이(tokens.css 와 같은 값) */
    --h-tab:28px;      /* ★ 알약 탭 · 작은 단추 */
    --h-chip:20px;     /* ★ 칩 · 배지 */
    --sz-check:16px; --sz-avatar:24px;   /* ★ 체크 칸 · 이니셜 동그라미 */
    --sz-ic:16px; --sz-ic-nav:18px; --ic-stroke:1.5;   /* ★ 아이콘 — 선 1.5(지침 I) */
    /* ★ v3.4 「할 일 기준」 (09-18 대표 결정) — 표 문법을 **한 자리에서 되돌릴 수 있게** (사양 §2)
       v4 : 표 머리 = 불투명 흰 · 세로선 없음(대표 10-15 Q-V1 ⓐ — 넓은 표 .tbl-wide 만 세로선 · 414b) · 줄 키 44 그대로 */
    --row-h: 44px;                    /* 줄 키 — 머리줄·몸줄 같은 값 */
    --row-hover:var(--bg-hover); --row-hover-soft:var(--bg-fill);   /* 줄 호버 · 고치는 칸이 있는 줄의 호버(한 단 옅게) */
    --tbl-head-bg:var(--bg-card);     /* 표 머리 = 불투명 흰(sticky 겹침 막음) */
    --grp-row-bg:var(--bg-fill);      /* ★ 묶음 줄 */
    --cell-line:transparent;          /* 칸 세로줄 — 없음 */
    --ic-mark: 14px;   /* ★ 과제 286 — 표 칸 끝 표시(↗ 열기 · ✎ 고침 · 🔒 잠김) 크기 · 머리 표시 = --fs-cap */
    --ic-open: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 17 17 7'/%3E%3Cpath d='M8 7h9v9'/%3E%3C/svg%3E");
    --ic-pen: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 20h9'/%3E%3Cpath d='M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4Z'/%3E%3C/svg%3E");
    --ic-lock: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='5' y='11' width='14' height='10' rx='2'/%3E%3Cpath d='M8 11V7a4 4 0 0 1 8 0v4'/%3E%3C/svg%3E");
    --ic-search: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E");   /* ★ 과제 414a (1차 검토 #1) — 검색 돋보기(마스크 그림 · 색 = 쓰는 쪽 background · 선 1.5) · 옛 = 자리 셋에 박힌 #8A8A8A · #94939C · 선 1.8 · 2 */
    /* ── 깊이 (떠 있는 것만 — 카드 · 단추 그림자 0 · 층은 선으로) ── */
    --sh-card:none; --sh-btn:none; --sh-btn-pri:none;
    --sh-float:0 18px 40px -12px rgba(30,29,36,.18), 0 0 0 1px var(--line);   /* 토스트 · 팝업 */
    --sh-pop:0 8px 20px -6px rgba(30,29,36,.14), 0 0 0 1px var(--line);       /* 펼침 메뉴 · 풍선 */
    /* 초점 고리 — 흰 틈 1px + 인디고 테 3px(box-shadow 라 자리는 안 밀린다 · 투명 outline 과 함께 = 고대비 모드에서도 보임) */
    --ring:0 0 0 1px var(--bg-card), 0 0 0 3px var(--accent);
    /* 딤 3단 (§12-2) */
    --dim-sheet:rgba(30,29,36,.24); --dim-modal:rgba(30,29,36,.40); --dim-layer2:rgba(30,29,36,.24);
    /* ── 모션 (지침 §M — 움직임 부품 motion.css 는 414b) ── */
    --ease:cubic-bezier(.2,.8,.2,1);          /* ★ 들어옴 · 펼침 */
    --ease-out:cubic-bezier(.16,1,.3,1);      /* ★ 그래프 자람 */
    --ease-in:cubic-bezier(.4,0,1,1);         /* ★ 나감 */
    --duration-fast:120ms; --duration-base:200ms;
    --duration-slow:240ms;    /* ★ 팝업 · 시트(300 안) */
    --duration-chart:560ms;   /* ★ 그래프 자람 */
    --stagger:30ms; --rise:8px;
    /* ── 글자 (✔ 10-16 대표 확정 · 크기 = 안 B · 굵기 = 안 C 「더 가볍게」 · 지침 Y) ── */
    --font-sans:"Pretendard Variable",Pretendard,-apple-system,BlinkMacSystemFont,system-ui,"Apple SD Gothic Neo",sans-serif;
    --font-mono:ui-monospace,"SF Mono",Menlo,monospace;
    /* 굵기 셋 — 400 본문 · 450 단추 · 탭 · 라벨 · 작은 회색 · 500 제목 · 숫자 · 표 이름 칸. 600 · 700 ✗(박지 말 것 · 관문 v433 ⓒ) */
    --weight-body:400; --weight-regular:400;
    --weight-medium:450;                                             /* ★ 단추 · 탭 · 라벨 · 표 머리 · 메뉴 고른 줄 */
    --weight-strong:500; --weight-bold:500; --weight-semibold:500;   /* 카드 · 팝업 제목 · 고른 탭 · 칩 글 */
    --weight-num:500;                                                /* 숫자 · 돈 · KPI · 페이지 제목 */
    --weight-name:500;                                               /* ★ 표 이름 칸(450 은 400 과 안 갈림) */
    /* ★ 글자 크기 (DESIGN.md §2 · v4 = 카드 16 · 큰 값 18 · KPI 28 · 제목 26 · 본문 14 · 바닥 12 · 키캡 10)
       그 사이 값을 새로 만들지 않는다. px 를 직접 적지 말고 이 단만 쓴다.
       ⚠ 견적서 문서(.qsdoc · .qd-* · #qsTable · 인쇄 서식)는 이 스케일 밖이다 —
         A4 한 장에 맞춰 고정된 별도 서식(DESIGN.md §13 · 규칙 60). 거기 px 는 그대로 둔다.
       관문 = 검증도구/…글자크기검사_v148.js */
    --fs-cap:12px;      /* 캡션 — 코드 · 단위 · 배지 · 표 머리 (바닥) */
    --fs-key:10px;      /* ★ v2.70 (과제 138) 메뉴 키캡 전용 — 장식 글자라 12px 바닥의 **유일한 예외**(DESIGN §2) · 메뉴 밖에 쓰지 말 것 */
    --fs-sm:13px;       /* 보조 — 라벨 · 도움말 · 비교 글 */
    --fs-body:14px;     /* 본문 — 행 이름 · 값 · 입력칸 · 버튼 · 메뉴 */
    --fs-card:16px;     /* 카드 · 팝업 머리(v4 15 → 16) */
    --fs-page:18px;     /* 카드 안 큰 값 · 견적 합계(v4 17 → 18) */
    --fs-num:28px;      /* KPI 숫자(v4 22 → 28 · 페이지 제목 26 과 겨루지 않게 한 단 위) */
    --fs-title:26px;    /* 페이지 제목 · 오른쪽 팝업 큰 제목 */
    --ls-title:-0.02em; --ls-head:-0.01em;   /* ★ 자간 — 제목 26 · KPI / 카드 · 팝업 제목 */
    /* 카드 안 여백 — 전 화면 .card 가 읽는다 */
    --card-pad-y:22px; --card-pad-x:24px;
    /* ★ 과제 268 (10-01) — 「할 일 기준」 간격 토큰(DESIGN §1-6 · 값 = 할 일 화면 실측 · 간격실측 v354) · 이름 = 뜻.
       있는 토큰에서 셀 수 있는 것은 셈으로(검토자 제안) · 할 일 쪽이 예외로 갈리던 넷 = 과제 274(G-030 「할 일을 다른 화면에 맞춤」)로 한 값 */
    --gap-title:12px; --pad-tool-y:16px; --gap-tool:8px;
    --inset-x:var(--card-pad-x); --inset-tbl:calc(var(--card-pad-x) + 1px);   /* 과제 274 — 할 일도 한 겹(옛 = 두 겹 48) */
    --gap-tool-body:20px;   /* 과제 274 — 한 값(옛 = 할 일 두 겹 40 · Dashboard 60) · 할 일 · 표 화면 · Dashboard 모두 */
    --gap-card:16px; --gap-card-x:16px; --gap-tile:12px; --pad-cell-x:14px;
    --pad-pop-x:22px; --gap-field:14px; --gap-field-x:16px;
    --gap-group:32px;   /* ★ 과제 556 (10-29 대표 「상하 여백이 다 같아 구분이 안 간다」) — 묶음이 바뀌는 자리 = 32(tokens.css 값 그대로 · DESIGN §12-0) · 머리 → 첫 줄 = --gap-tool · 같은 묶음 줄 사이 그대로 */
    --pk-w:104px;
    --pk-w2:76px;    /* ★ 과제 378b (10-14 대표 「B 두 칸」 · 기획 그림 과제378b_광고주담당자_B_두칸.png · 이름 열 76) — 두 칸으로 나란한 줄(광고주 담당자)의 **왼쪽 항목명 폭** */   /* ★ 과제 378a (10-13 대표 컨펌 시안 「팝업 표준」) — 팝업 칸의 **왼쪽 항목명 폭** 한 자리(한 줄에 한 칸 · 이름 왼쪽 · 상자 오른쪽) */
    /* ★ v2.12 (09-17 · 대표 지시 「나머지 페이지도 동일한 폭 · 창 크기에 따라 반응형으로 자연스러운 여백」) —
       본문 좌우 여백 하나. 창이 넓을수록 커진다 : 대표 모니터(2560) 에서 **100px**(v2.11 에서 승인한 그 값) ·
       1920 에서 57 · 1440 이하 **24**(종전 main padding 그대로 — 노트북·반쪽 창에서는 조금도 좁아지지 않는다) · 상한 120.
       직선 하나(6.8vw − 74px)로 2560→100 · 1440→24 두 점을 지난다. main 의 좌우 padding 이 이 값을 읽고, section 은 상한 없이 그 안을 채운다. */
    --page-gutter:clamp(24px, 6.8vw - 74px, 120px);
    /* 옛 이름 — 전부 위 단으로 연결 */
    --text-xs:var(--fs-sm); --text-sm:var(--fs-body); --text-base:var(--fs-body);

    /* ── 호환 별칭 (인라인 style·JS 가 참조 — 전부 v4 값으로 연결 · 새 hex 0) ── */
    --brand-ink:var(--ink); --brand-indigo:var(--accent); --brand-navy:var(--accent);
    --brand-blue:var(--accent); --brand-azure:var(--accent); --brand-sky:var(--viz-4);
    --brand-900:var(--accent-active); --brand-800:var(--ink); --brand-700:var(--accent-active);
    --brand-600:var(--accent); --brand-500:var(--fill-brand); --brand-400:var(--viz-2);
    --brand-300:var(--viz-2); --brand-200:var(--accent-line); --brand-100:var(--accent-soft); --brand-50:var(--bg-active);
    --gray-0:var(--bg-card); --gray-50:var(--bg-fill); --gray-100:var(--bg-hover);
    --gray-200:var(--line-soft); --gray-300:var(--line); --gray-400:var(--deco);
    --gray-500:var(--text-3); --gray-600:var(--text-2); --gray-700:var(--text);
    --gray-800:var(--ink); --gray-900:var(--ink);
    --line-2:var(--line);
    --green:var(--ok); --amber:var(--warn); --red:var(--bad);
    --success:var(--ok); --warning:var(--warn); --danger:var(--bad);
    --text-primary:var(--text); --text-secondary:var(--text-2); --text-tertiary:var(--text-3);
    --text-muted:var(--text-2); --text-on-brand:var(--on-fill);
    --text-link:var(--accent); --text-link-hover:var(--accent-hover);
    --surface-page:var(--bg-card); --surface-subtle:var(--bg-fill); --surface-muted:var(--bg-hover);
    --surface-card:var(--bg-card); --surface-inverse:var(--ink); --surface-brand:var(--fill-brand);
    --border:var(--line); --border-light:var(--line-soft);
    --border-subtle:var(--line-soft); --border-default:var(--line); --border-strong:var(--line-input);
    --radius-sm:var(--r-ctl); --radius-lg:var(--r-card); --radius-pill:var(--r-pill); --radius-circle:50%;
    --shadow-sm:var(--sh-card); --shadow-md:var(--sh-pop);
    --shadow-lg:var(--sh-float); --shadow-xl:var(--sh-float);
    --leading-normal:1.5;
    --ease-standard:var(--ease); --ease-in-out:var(--ease);
    --dim:var(--text-2); --soft:var(--accent-soft);
  }
  *{box-sizing:border-box}
  body{margin:0;background:var(--bg-app);color:var(--text);
       font-family:var(--font-sans);font-size:var(--text-sm);line-height:1.5;
       -webkit-font-smoothing:antialiased;letter-spacing:0}
  /* ★ 과제 414a (지침 Y · 굵기 셋 400 · 450 · 500) — 브라우저 기본 700(b · strong · th · h*)을 **한 줄에서** 500 으로 막는다(과제 358 h4 줄을 넓힘) */
  b,strong,th,h1,h2,h3,h4,h5,h6{font-weight:var(--weight-strong)}
  b,strong{color:var(--ink)}
  /* ★ 과제 414a (지침 I) — 선 아이콘(stroke="currentColor" 를 svg 에 단 것) = 선 1.5 한 벌. 자리마다 박힌 2 · 1.8 · 2.4 를 CSS 가 덮는다(그림 속성보다 CSS 가 이김)
     · 그래프 · 진도 고리처럼 선을 도형마다 따로 단 것(svg 에 stroke 없음)은 이 줄 밖 */
  svg[stroke="currentColor"]{stroke-width:var(--ic-stroke)}
  /* ★ 과제 414a (지침 §0-10 · 부록 B) — 초점 = **투명 outline 2 + 고리**(--ring). outline:none 은 고대비(forced-colors) 모드에서 초점을 지운다 —
     투명 outline 은 평소엔 안 보이고 고대비 모드에서 시스템 색으로 그려진다. 자리마다 적던 `outline:none` 은 아래 :focus-visible 가 이긴다. */
  :focus-visible{outline:2px solid transparent !important;outline-offset:2px}
  @media (forced-colors:active){
    :focus-visible{outline-color:Highlight !important}
    input[type="checkbox"],input[type="radio"],.pill,.nbdg{border:1px solid CanvasText}
  }
  a{color:var(--accent)}   /* ★ 과제 276 (G-031) — 규칙 없는 자리의 링크 = 가리킴 파랑(브라우저 기본 #00e · 들른 뒤 보라 막음) · 줄 이름 링크 검정 규칙은 더 세서 그대로 */

  /* ── 옛 상단 헤더 : 요소는 남고(내부 자원·id 보존) 화면에서는 사라진다 ──
     #connDot·#ver·#logBtn·#gSearch 는 boot.js shell53 이 사이드바로 옮긴다. */
  header{display:none}
  header .mark{width:22px;height:22px;border-radius:var(--r-ctl);display:block}
  header h1{display:none}
  #brandMarkW{position:absolute;visibility:hidden}   /* 숨김 자원(작업요청서용) */

  /* ── 셸 : 사이드바 232px (로고·계정·메뉴·연결 상태 전부 흡수 — DESIGN.md §4) ── */
  .wrap{display:block;margin-left:232px;min-height:100vh}
  nav{position:fixed;left:0;top:0;bottom:0;width:232px;z-index:20;
      display:flex;flex-direction:column;background:var(--bg-side);
      border-right:1px solid var(--line);padding:0;overflow:hidden}
  #sideBrand{display:flex;align-items:center;gap:9px;padding:14px 14px 10px;flex-shrink:0}
  #sideBrand img{width:22px;height:22px;border-radius:var(--r-ctl);flex-shrink:0}
  #sideBrand .sb-t1{font-size:var(--fs-body);font-weight:var(--weight-strong);letter-spacing:-.01em;color:var(--ink);line-height:1.2}
  #sideBrand .sb-t2{font-size:var(--fs-cap);font-weight:var(--weight-medium);letter-spacing:.02em;color:var(--text-2)}
  nav #gSearch{margin:2px 12px 8px;width:auto;height:30px;flex-shrink:0;
      border:1px solid var(--line-soft);border-radius:var(--r-ctl);background:var(--bg-card);
      font-size:var(--fs-sm);padding:0 12px;box-shadow:none}
  /* ★ 과제 414a (지침 F-3) — 검색 = **알약**(999 · 1px --line-tool) · 높이 30 은 메뉴 넘침(900px · v1.53)을 막는 자리라 그대로 */
  nav #gSearch{border-radius:var(--r-pill);border-color:var(--line-tool)}
  nav #gSearch:focus{outline:none;border-color:var(--accent);box-shadow:var(--ring)}
  #sideNavScroll{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:1px;padding:0 8px 8px}
  /* ★ v1.53 — 메뉴 이름을 본문과 같은 **14px** 로 올렸다(대표 요청 · 종전 13px).
     ⚠ v1.48 실측 : 글자만 14px 로 올리면 19개 항목이 900px 높이에서 33px 넘쳐 「안전망 점검판」이 숨는다.
     그래서 **줄 간격을 1.5 → 1.25 로 조여** 항목 높이를 32px 그대로 두었다(넘침 0 · 실측으로 다시 확인).
     그림 글자(`.grp` 그룹 이름)도 12 → 13px 로 한 단 같이 올렸다. */
  nav a{display:flex;align-items:center;gap:9px;padding:6px 8px;margin:0;border-radius:var(--r-ctl);
        font-size:var(--fs-body);line-height:1.25;font-weight:var(--weight-body);color:var(--text);text-decoration:none;cursor:pointer;
        transition:background var(--duration-fast) var(--ease),color var(--duration-fast) var(--ease);
        position:relative}
  nav a:hover{background:var(--bg-hover)}
  /* ★ v4 (과제 414a · 지침 §S) — 메뉴는 흰 면 · 오른쪽 선 하나. 「지금 있는 곳」= **--accent-soft 칠 + 인디고 글 · 450**(그림자 0).
     (v3 = 회색 사이드바 위의 흰 카드 · 은퇴) · 아이콘 18 · 선 = --ic-stroke · 보통 --text-2 · 고른 줄 인디고. */
  nav a.on{background:var(--accent-soft);color:var(--accent);font-weight:var(--weight-medium);box-shadow:none}
  nav a.on:hover{background:var(--accent-soft)}
  nav a .nico{display:block;flex-shrink:0;width:var(--sz-ic-nav);height:var(--sz-ic-nav);color:var(--text-2);stroke-width:var(--ic-stroke);
              transition:color var(--duration-fast) var(--ease)}
  nav a:hover .nico{color:var(--text)}
  nav a.on .nico{color:var(--accent)}
  nav a .ntxt{flex:1;min-width:0;white-space:nowrap}
  nav a .nnum{display:none}
  nav a .nbdg{display:none;min-width:18px;border-radius:var(--r-ctl);background:var(--fill-brand);color:var(--on-fill);   /* v4 C-3 색 = 보라 채움 흰 글(빨강 = 지남만) · 모양 = 414b */
              font-size:var(--fs-cap);font-weight:var(--weight-strong);line-height:18px;text-align:center;
              padding:0 5px;flex-shrink:0}
  nav a .nbdg.show{display:inline-block}
  nav a .nbdg.red{background:var(--bad)}
  /* ★ v2.36 (과제 99 · 09-21 대표 컨펌 「항상 흐리게」 · 대표 수정 지시 「메뉴명 바로 우측에 옅은 글자로」) — 메뉴 단축키 글자.
     **상자 없이 글자만** · 이름(.ntxt) 안에 붙어 이름 끝을 따라간다 · 장식 글자라 --text-3(DESIGN §1-2 가 허락한 자리)
     · G 를 누르면 nav.gkey 로 파랑(--accent = 가리키는 색 · 「지금 고를 것」). 원천 = boot.js navHotkeys() 의 K 표(글자·붙이기 둘 다 거기).
     ⚠ 12px 글자는 줄 간격 17.5px 안 — 항목 높이가 한 픽셀도 안 바뀐다(v1.53 실측 : 항목이 커지면 900px 화면에서 「안전망 점검판」이 숨는다). */
  /* ★ v2.68 (과제 130 · DESIGN §6-8 · 09-23 대표 「키보드모양+키보드모양」) — 글자 「G H」 → 키캡 [G]+[H].
     .nkey 는 자리(이름 바로 뒤 · 한 줄)만 맡고, 옷은 전역 키캡 .kbd 가 맡는다(할 일 [N] 과 같은 값 · 규칙 124). */
  nav a .nkey{margin-left:6px;white-space:nowrap}   /* [G]+[H] 가 한 줄에 */
  nav a .kbd{transition:color var(--duration-fast) var(--ease)}
  /* ★ v2.70 (과제 138 · 09-23 대표 「좌측 대메뉴 단축키 사이즈 더 축소 해」 → 사진 C) — **메뉴 안 키캡만** 작게.
     글자 --fs-key(10px) · 안여백 0 2px · 라운드 3px · 굵기 --weight-regular — 네 값 모두 대표가 사진으로 고른 모양(발명 아님).
     전역 .kbd(할 일 [N] · 보기 단추 숫자)는 12px 그대로(대표 「위 12px 그대로」) — 이 두 줄은 nav 안에서만 이긴다. */
  nav a .kbd{font-size:var(--fs-key);padding:0 2px;border-radius:3px;font-weight:var(--weight-medium)}   /* v4 지침 §S — 키캡 10 · 450 */
  nav a .kbd-plus{font-size:var(--fs-key)}
  nav.gkey a .kbd{color:var(--accent)}
  /* ★ v2.68 (과제 130 · DESIGN §6-8) — 키캡 부품. **새 값 0** : 할 일 「＋ Add To-Do」 안 [N](.tk-kbd)의 **지금 계산값**을 옮겼다
     (글자 --fs-cap · --weight-strong · --text-2 · 숫자 고정폭 · 바탕 = 글자색 18% · 안여백 1px 5px · 라운드 4 · 불투명 .9 · 테두리·그림자 0).
     ★ 09-23 대표 지적 「사이즈 조금 줄이고, 색상도 조금 더 옅게」 → **상자만 작게**(안여백 0 4px · 굵기 --weight-medium · 글자 12px 그대로)
       · **글자 --text-3**(바탕은 currentColor 18% 라 함께 옅어진다) · [N] 도 같이(키 모양은 어디서나 한 벌). G 누름 = --accent 그대로.
     <kbd> 의 기본 고정폭 글꼴을 끊는다(font-family:inherit). 만드는 자리 = core.js kbdHtml() 한 곳.
     .kbds = 키 둘 [G]+[H] — 사이 「+」 는 맨 글자 --text-3. 간격 토큰이 없어 gap 을 두지 않는다(가정 G · 새 px 0). */
  .kbd{padding:0 4px;border-radius:var(--r-key);font-family:inherit;font-size:var(--fs-cap);font-weight:var(--weight-medium);
       color:var(--text-3);font-variant-numeric:tabular-nums;background:color-mix(in srgb, currentColor 18%, transparent);opacity:.9}
  .kbds{white-space:nowrap}   /* 줄 글자(inline) 그대로 — flex 로 묶으면 키캡이 블록이 되어 안여백이 줄 높이를 민다(메뉴 항목 +0.5px 실측) */
  .kbd-plus{color:var(--text-3);font-size:var(--fs-cap)}
  /* v2.69 (과제 131 · §9-7) — 보기 전환 단추 끝의 숫자 키캡. 간격은 이미 쓰는 6px(메뉴 .nkey 와 같다) ·
     할 일 세그먼트 단추는 제 gap 6px 이 이미 있어 여백을 더하지 않는다. */
  .seg button .kbds{margin-left:6px}
  #tkTools .seg button .kbds{margin-left:0}
  nav a:focus-visible{outline:none;box-shadow:var(--ring)}
  nav .grp{padding:13px 8px 4px;font-size:var(--fs-cap);color:var(--text-3);font-weight:var(--weight-medium);   /* v4 지침 §S — 묶음 이름 12 · 450 · --text-3 */
           letter-spacing:.04em;text-transform:uppercase}
  /* ★★ 과제 429 ③ (10-18 점검 A3) — 900 창에서 메뉴가 넘쳐 「시스템」 묶음(연결 · 점검 · 업무 흐름 안내 · 안전망 점검판)이 접힌 아래로 사라졌다(대표 메뉴 19줄 · 넘침 30px).
     줄 높이 32(실측 30 · 숫자 배지 줄 32) → **28 한 벌**(`--h-tab` · 위아래 안여백 0 · 가운데 맞춤) · 묶음 이름 위 여백 13 → `--gap-tool`(8) · 키캡은 그대로(09-21 대표 「항상 흐리게」 · 숨김 ✗).
     폭 1025 이상(세로 메뉴)만 — 1024 아래 가로 메뉴는 지금대로(아래 @media). 관문 = v451 ⓐ③. */
  @media (min-width:1025px){
    nav a{height:var(--h-tab);padding-top:0;padding-bottom:0}
    nav .grp{padding-top:var(--gap-tool)}
  }
  /* 사용자 블록 + 연결 상태 발치 */
  #sideUser{flex-shrink:0;border-top:1px solid var(--line);margin-top:auto;padding:10px 14px 8px;
      display:flex;align-items:center;gap:9px;cursor:pointer}
  /* ★ v4 — 메뉴가 흰 면이 되어 hover 는 다른 흰 면과 같은 --bg-hover(v3 의 「--bg-app 로 밝힘」 은퇴 · nav a:hover 와 같은 규칙) */
  #sideUser:hover{background:var(--bg-hover)}
  #sideUser .su-av{width:26px;height:26px;border-radius:50%;background:var(--accent-soft);color:var(--accent);
      font-size:var(--fs-sm);font-weight:var(--weight-strong);display:flex;align-items:center;justify-content:center;flex-shrink:0}
  #sideUser .su-mid{flex:1;min-width:0}
  #sideUser .su-nm{font-size:var(--fs-sm);font-weight:var(--weight-strong);color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  #sideUser .su-rl{font-size:var(--fs-cap);color:var(--text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  #sideUser .su-dot{width:7px;height:7px;border-radius:50%;background:var(--line);flex-shrink:0}
  #sideUser .su-dot.onn{background:var(--ok)}
  #who{display:none}                 /* 원본은 계속 JS가 채웁니다 — 사용자 블록이 미러 */
  #sideFoot{flex-shrink:0;padding:8px 14px 12px;display:flex;align-items:center;gap:6px;
      font-size:var(--fs-cap);color:var(--text-2);flex-wrap:wrap}
  .conndot{font-size:var(--fs-cap);font-weight:var(--weight-medium);cursor:pointer;padding:2px 8px;
           border-radius:var(--r-ctl);letter-spacing:0;white-space:nowrap}
  .conndot.off{background:var(--warn-bg);color:var(--warn)}
  .conndot.onn{background:var(--ok-bg);color:var(--ok)}
  #sideFoot #ver{font-size:var(--fs-cap);padding:2px 7px}
  #logBtn{flex-shrink:0}
  #sideFoot #logBtn{height:22px;padding:0 8px;font-size:var(--fs-cap);margin-left:auto}
  /* ★★ 과제 429 ① (10-18 점검 A1) — 발치 = **한 줄** : [사람 블록 = 이름 · 역할 / 상태 알약] ··· [로그 그림 단추]. 상태는 알약 하나(#connDot · core.js connPillPaint)
     · 옛 넷(「미연결 · 로그인해 주십시오」 · 연결됨 · DB — · [로그] 글) 중 #ver · 연결 점(#suDot)은 숨김 자원 · 미연결이면 이름 줄 · 동그라미도 숨김(boot.js applyWho)
     · 사람 블록의 위 선 · margin-top:auto 는 발치로 옮김(블록이 발치 안에 들어갔다) · 새 값 0(토큰 · 옛 자리 값) */
  #sideFoot{border-top:1px solid var(--line);margin-top:auto;flex-wrap:nowrap;padding:6px 10px 10px 6px}
  #sideFoot #sideUser{border-top:0;margin-top:0;flex:1;min-width:0;padding:6px 8px;border-radius:var(--r-ctl)}
  #sideUser .su-mid{display:flex;flex-direction:column;align-items:flex-start;gap:2px}
  #sideUser .su-l1{display:flex;align-items:baseline;gap:6px;min-width:0;max-width:100%}
  #sideUser .su-l1[hidden],#sideUser .su-av[hidden],#sideUser .su-dot[hidden],#sideFoot #ver[hidden]{display:none}
  #sideUser .su-nm{flex:0 1 auto;min-width:0}
  #sideUser .su-rl{flex:0 1 auto;min-width:0}
  #sideUser .conndot{max-width:100%;white-space:normal}
  .conndot.onn.cd-warn{background:var(--warn-bg);color:var(--warn)}
  .conndot.onn.cd-bad{background:var(--bad-bg);color:var(--bad)}
  #sideFoot #logBtn{width:var(--h-tab);height:var(--h-tab);padding:0;display:inline-flex;align-items:center;justify-content:center;
      margin-left:0;position:relative;color:var(--text-2)}
  #sideFoot #logBtn svg{width:var(--sz-ic);height:var(--sz-ic);stroke-width:var(--ic-stroke);display:block}
  #sideFoot #logBtn:hover{color:var(--text)}
  #logBtn.has-err::after{content:"";position:absolute;top:4px;right:4px;width:6px;height:6px;border-radius:var(--r-pill);background:var(--bad)}   /* 오류 = 빨강 점(색 + 모양 · 글은 title 「로그」) */

  /* ── 본문 ── */
  main{min-width:0;padding:32px var(--page-gutter) 72px;max-width:none}   /* ★ v1.53 — 제목 위 숨 쉴 자리(20 → 32px · 대표 요청) · ★ v2.12 — 좌우는 --page-gutter(창 너비에 따라 24~120) */
  section{display:none;max-width:none;margin-left:auto;margin-right:auto}   /* ★ v2.12 — 1200px 상한 은퇴 · 전 화면이 main 안을 채운다(여백은 main 이 --page-gutter 로 낸다) */
  section.on{display:block}
  section.appear{animation:secIn var(--duration-base) var(--ease)}
  @keyframes secIn{from{opacity:0;transform:translateY(3px)}to{opacity:1;transform:none}}
  /* ★ v2.12 (09-17) — 옛 폭 상한 셋(section 1200 · 넓은 표 화면 1360 · v2.11 의 #task max()) 은 전부 은퇴.
     v2.11 이 할 일 한 곳에 「좌우 100px」을 두었고, 대표가 「나머지도 동일하게 · 창 크기에 따라 반응형으로」로 넓혔다.
     이제 폭을 정하는 자리는 :root 의 --page-gutter 하나다(main 의 좌우 padding). 화면별 예외 없음 — 예외가 필요해지면 여기에 적는다. */
  #connBar{margin-left:auto;margin-right:auto}

  /* ── 페이지 머리 : 제목 **22px/600**(`--fs-num` · 6단의 맨 윗단 · v1.53 대표 요청으로 17px 에서 올림)
     ⚠ 6단(12·13·14·15·17·22) 밖의 값을 만들지 않았다 — 한 단 위로 옮긴 것뿐이다(DESIGN.md §2). ── */
  h2{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
     font-size:var(--fs-title);margin:2px 0 12px;font-weight:var(--weight-strong);letter-spacing:var(--ls-title);color:var(--ink)}
  h2 .hico{display:none}
  h2 .pill{font-size:var(--text-xs)}
  .sub{color:var(--text-2);margin:0 0 16px;font-size:var(--fs-sm)}

  /* ── 카드 : 흰 면 + 1px 보더 + 라운드 8 ── */
  .card{background:var(--bg-card);border:1px solid var(--line);border-radius:var(--r-card);
        box-shadow:var(--sh-card);                                       /* ★ v3 — 깊이는 여기 한 겹만(§3) */
        padding:var(--card-pad-y) var(--card-pad-x);margin-bottom:16px}   /* 여백은 토큰 둘(§1) */
  .card h3{margin:0 0 12px;font-size:var(--fs-card);font-weight:var(--weight-strong);letter-spacing:var(--ls-head);color:var(--ink);
           display:flex;align-items:center;gap:10px;flex-wrap:wrap}
  .card h3 .muted{font-weight:var(--weight-body);min-width:0}
  /* ★ v2.89 (과제 160 · 로딩 한 벌) — 화면 옮길 때 **가운데 도는 동그라미는 없앴다**(옛 `::before`).
     흐린 막(`::after`)도 **뼈대가 있는 화면**(`sk-owned` = 그 화면 목록이 skelOn 을 부른 적이 있다)에서는 안 깐다 — 뼈대가 그 역할을 한다.
     목록이 없는 화면(홈 등)은 0.35초 흐린 막만(core.js secVeil). */
  .sec-veil{position:relative}
  .sec-veil:not(.sk-owned)::after{content:"";position:absolute;inset:0;background:rgba(252,252,253,.55);
    backdrop-filter:blur(1px);z-index:5;border-radius:var(--r-card)}

  /* ── 폼 입력 ── */
  label{display:block;font-size:var(--fs-sm);color:var(--text-2);margin:10px 0 4px;font-weight:var(--weight-medium)}
  /* ★ 과제 479 (대표 G-675 · 10-22) — 적는 칸 선 = 회색 얇은 선 1px(--line-input · 카드 선 --line 보다 한 단 짙은 같은 회색).
     옛 짙은 선(3:1)은 팝업 안에서 혼자 검게 보였다 → 「여기에 적는다」 는 초점 고리(--accent + --ring) · 꼭 채울 칸 .in-need 가 알린다. */
  /* ★ v3 — 체크박스·라디오·진행바의 「켜진 색」도 가리키는 색 하나로(§1-3).
     자리마다 accent-color 를 따로 적던 것을 여기 한 줄이 받는다(개별 지정은 그대로 이긴다). */
  input[type="checkbox"],input[type="radio"],progress{accent-color:var(--fill-brand)}   /* v4 지침 F-4 — 체크 · 토글 켬 = 보라 채움(--fill-brand) */
  input,select,textarea{width:100%;padding:7px 10px;border:1px solid var(--line-input);
        border-radius:var(--r-ctl);font-size:var(--text-sm);font-family:inherit;background:var(--bg-card);
        color:var(--text);transition:border-color var(--duration-fast) var(--ease),box-shadow var(--duration-fast) var(--ease)}
  /* ★★ 과제 126 (09-23 감사 14회차) — **적는 칸 높이는 32px 한 벌.**
     위 규칙이 높이를 안 정해 **브라우저 기본**이 그대로 나왔고, **날짜 칸은 달력 아이콘 때문에 34** 라
     한 폼 안에서 `select 32 · text 32 · date 34` 로 **2px 씩 어긋났다**(인사·집행에서 실측).
     ⚠ `DESIGN.md` 에 「적는 칸 높이」 기준이 **없었다** — 32 로 통일돼 있던 것은 **도구 줄뿐**이었다(§6-1 ⑦).
        그래서 이번에 **기준을 정하고**(§9) 그 값을 여기 한 자리에 둔다.
     ⚠ `textarea` 는 **여러 줄을 적는 칸**이라 높이를 안 정한다(늘어나야 한다).
     ⚠ 도구 줄 32 규칙(`h3 .tools …`)은 **건드리지 않는다**(§6-1 ⑦ · 값이 같아 어차피 32 다). */
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),select{height:32px}
  input:focus,select:focus,textarea:focus{outline:none;border-color:var(--accent);box-shadow:var(--ring)}
  /* ★ 과제 272 — 「이 칸(이 줄)을 채우셔야 합니다」 를 2.6초 짚는 표시(jumpToField 가 붙이고 스스로 걷음) · v1.23 그대로 되살림 — v1.49(1df24e3) 정리 때 빠져
     그 뒤로 짚음 = 굴림 · 초점뿐이었다(마우스로 누른 뒤의 초점은 테두리가 안 보인다) · 새 색 · 새 크기 0(초점 고리 + 경고 틴트 토큰) */
  .needfill{box-shadow:var(--ring);background:var(--warn-bg);border-radius:var(--r-ctl)}
  input::placeholder,textarea::placeholder{color:var(--text-3)}
  textarea{min-height:64px;resize:vertical;font-size:var(--fs-body);line-height:1.55}
  input[type="date"]{max-width:170px}
  /* ★ v2.93 (과제 167 · 대표 지적) — **고르기 칸 = 화살표 안쪽으로 · 앱 전체 한 벌.** 브라우저 기본 화살표는 칸 오른쪽 끝에 붙고 자리를 못 옮긴다
     → appearance none + 꺾쇠 배경 그림 하나 · 오른쪽 안 여백 12(적는 칸 글자 여백과 같은 값) · 꺾쇠 12 · 글자는 꺾쇠 앞 8 에서 끝남(padding-right 32)
     ⚠ !important : 도구 줄(0 10px) · 팝업 적는 칸 · 목록 줄 안의 고르기 칸 규칙이 padding · background 를 따로 준다 — 그 모두를 이긴다(색은 background-color 라 그대로 산다)
     ⚠ multiple · size(목록 상자)는 화살표가 없는 칸이라 뺀다 · 숨긴 옛 칸은 안 보이니 상관없다 · 견적서 인쇄(#qsPrintHost)는 select 를 숨긴다 */
  select:not([multiple]):not([size]){appearance:none;-webkit-appearance:none;
    background-image:var(--ic-chevron) !important;background-repeat:no-repeat !important;background-position:right 12px center !important;background-size:12px 12px !important;
    padding-right:32px !important}
  select:not([multiple]):not([size]):disabled{background-image:var(--ic-chevron-off) !important}
  /* ★★ 과제 580 (10-30 대표 「선택하는 박스의 경우 한글 아래가 잘린다」 · 상담 등록 「(고르십시오)」 · 「김태훈 (대표)」) — **고르기 칸 글자 상자 = 칸 안 높이 통째.**
     옛 = 위아래 안여백 7(자리마다 8) + 줄 높이 미지정(normal) → 높이 32 − 테두리 2 − 안여백 14 = 글자 상자 16 · 한글 글꼴 글 높이 16~18 이 아래로 깎였다(appearance none 이라 그대로 잘림).
     → 세로 안여백 0 + 줄 높이 = 안 높이(--lh-ctl) : 높이 --h-ctl 32 한 벌 그대로(과제 126) · 글자는 세로 가운데 · 가로 안여백 · 꺾쇠 자리 그대로
     ⚠ !important : 자리마다 select 안여백을 따로 주는 규칙(팝업 · 도구 줄 · 표)을 모두 이긴다(위 꺾쇠 규칙과 같은 까닭) · .tsel(표 안 작은 고르기) · multiple · size 는 뺀다 · 관문 v560 */
  select:not([multiple]):not([size]):not(.tsel){padding-top:0 !important;padding-bottom:0 !important;line-height:var(--lh-ctl)}

  /* ── 버튼 (DESIGN.md §6-1 · 지침 B) ──
     ★ v4 (과제 414a) — **주 행동 단추 = 그라데이션 한 벌**(--grad-brand · 흰 글 450 · 그림자 0) · **한 화면 · 한 팝업에 하나**(관문 v433 ⓓ).
       보조 = 흰 + 1px 선(.ghost) · 작게 = 28(.mini) · 위험 = 흰 + 빨강 선 · 빨강 글(.danger) · 꺼짐 = --btn-off-*(그라데이션 없음).
     ★ 앱은 클래스 없는 `button` 이 주 단추다(지침 부록 A) — 그라데이션은 **배경 그림**이라 다른 자리가 background-color 만 바꾸면
       그림이 남는다. 그래서 그라데이션은 :where() 로 좁힌 선택자에만 건다(세기 0-0-1 = 옛 `button` 과 같아 다른 규칙이 그대로 이긴다) :
       보조 · 작게 · 위험 · 링크 꼴(.tk-dmore) · 보기 전환(.seg) · 메뉴 · 탭 · 닫기(.xclose · .x) · 알약(.pill) · 메뉴 안 · 펼침 메뉴(.umenu) 단추 = 뺌. */
  button{background:var(--fill-brand);color:var(--on-fill);border:1px solid transparent;border-radius:var(--r-ctl);
         height:var(--h-ctl);padding:0 14px;font-size:var(--text-sm);cursor:pointer;font-family:inherit;
         font-weight:var(--weight-medium);letter-spacing:0;box-shadow:var(--sh-btn-pri);
         display:inline-flex;align-items:center;gap:6px;
         transition:background var(--duration-fast) var(--ease),border-color var(--duration-fast) var(--ease),transform var(--duration-fast) var(--ease)}
  button:where(:not(.ghost):not(.mini:not(.primary)):not(.danger):not(.tk-dmore):not(.xclose):not(.x):not(.pill):not([role=tab]):not(.seg *):not(nav *):not(.umenu *):not([disabled])){
         background:var(--grad-brand);background-origin:border-box}
  button:where(:not(.ghost):not(.mini:not(.primary)):not(.danger):not(.tk-dmore):not(.xclose):not(.x):not(.pill):not([role=tab]):not(.seg *):not(nav *):not(.umenu *):not([disabled])):hover{background:var(--grad-brand-hover);background-origin:border-box}
  button:where(:not(.ghost):not(.mini:not(.primary)):not(.danger):not(.tk-dmore):not(.xclose):not(.x):not(.pill):not([role=tab]):not(.seg *):not(nav *):not(.umenu *):not([disabled])):active{background:var(--grad-brand-press);background-origin:border-box}
  button:where(:not(.ghost):not(.mini:not(.primary)):not(.danger):not(.tk-dmore):not(.xclose):not(.x):not(.pill):not([role=tab]):not(.seg *):not(nav *):not(.umenu *):not([disabled])) .kbd,button:where(:not(.ghost):not(.mini:not(.primary)):not(.danger):not(.tk-dmore):not(.xclose):not(.x):not(.pill):not([role=tab]):not(.seg *):not(nav *):not(.umenu *):not([disabled])) .kbd-plus{background:transparent;color:var(--on-fill);opacity:1;box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--on-fill) 45%, transparent)}   /* v4 지침 B — 주 단추 안 키캡 = 칠 없이 흰 45% 선(대비) */
  button:hover{background-color:var(--fill-brand-hover)}
  button:active{transform:translateY(1px)}   /* v4 지침 B — 누름 = 1px 내려감(꺼진 단추 제외) */
  button:disabled:active,button[aria-disabled="true"]:active{transform:none}
  /* ★ v1.58 — 보조 단추는 **보조 단추 그림자**(--sh-btn · v4 = 0). */
  button.ghost{background:var(--bg-card);color:var(--text);border:1px solid var(--line);
      font-weight:var(--weight-medium);box-shadow:var(--sh-btn)}
  button.ghost:hover{background:var(--bg-hover);border-color:var(--line)}
  button.mini{height:var(--h-tab);padding:0 10px;font-size:var(--fs-sm);font-weight:var(--weight-medium)}
  /* ★ 과제 414a (G-350) — 작은 단추(.mini)는 클래스가 더 없으면 **보라 채움**(--fill-brand · 그라데이션 ✗ — 그라데이션 = 한 화면 하나) · v3 의 검정 작은 단추 자리 그대로(받은 함 줄마다 「가져가기」 = 대표 과제 375) · 작은 주 단추 = .mini.primary(그라데이션) */
  button:disabled,button[aria-disabled="true"],button[aria-disabled="true"]:hover{background:var(--btn-off-bg);color:var(--btn-off-ink);border-color:transparent;box-shadow:none;cursor:not-allowed}   /* v4 꺼짐 = --btn-off-*(옛 = 흐림 .45) · 까닭은 title · ★ 과제 582 — aria-disabled = 같은 꺼짐 옷(Tab 으로 닿고 누르면 까닭 글 · 권한 밖 단추를 숨기지 않음) */
  button:focus-visible{outline:none;box-shadow:var(--ring)}
  :is(h2,h3)[tabindex="-1"]:focus-visible{outline:none;box-shadow:var(--ring);border-radius:var(--r-ctl)}   /* ★ 과제 510 디자이너 6 [2] — 스크립트가 옮긴 초점(짝짓기 머리 등 tabindex -1 제목)도 고리 */
  button.danger{background:var(--bg-card);color:var(--bad);border-color:var(--bad-line);box-shadow:var(--sh-btn)}
  button.danger:hover{background:var(--bad-bg);border-color:var(--bad-line)}
  button.ghost.danger,button.mini.danger{color:var(--bad);border-color:var(--bad-line);background:var(--bg-card)}
  button.ghost.danger:hover,button.mini.danger:hover{background:var(--bad-bg)}
  @media print{ button{background:var(--bg-card) !important;color:var(--ink) !important;border-color:var(--ink) !important} }   /* v4 지침 B — 인쇄 = 흰 바탕 + 검은 선 */
  .btns>button.danger{margin-left:auto}
  .row{display:flex;gap:12px;flex-wrap:wrap}
  .row>div{flex:1;min-width:150px}
  .btns{margin-top:14px;display:flex;gap:8px;flex-wrap:wrap;align-items:center}

  /* ── 표 ── */
  table{width:100%;border-collapse:collapse;font-size:var(--fs-body);margin-top:8px;font-variant-numeric:tabular-nums}
  th,td{text-align:left;padding:8px 10px;border-bottom:1px solid var(--line-soft);vertical-align:middle}
  /* ★ v1.56 (표 문법 v2 · R1 — 대표 결정 09-12) — 머리줄은 **회색 띠가 아니라 아래 선 하나**다.
     대문자·자간 넓힘도 뗐다 : 한글에는 효과가 없고 라틴 코드만 늘어져 보였다. */
  th{color:var(--text-2);font-weight:var(--weight-strong);font-size:var(--fs-cap);background:var(--bg-card);
     letter-spacing:0;white-space:nowrap;border-bottom:1px solid var(--line);
     position:sticky;top:0;z-index:1}
  tbody tr:hover td,table tr:hover td{background:var(--bg-hover)}
  tr.sel td{background:var(--bg-active)}
  /* ★ v1.56 (R5) — 목록 안 링크는 **검정**이다. 종전에는 번호(견적·발주)만 파란 밑줄이라
     한 표 안에 규칙이 둘이었다. 「누를 수 있다」는 hover 에서 파랑+밑줄이 말한다.
     ⚠ 표 밖의 본문 링크(안내문·빈 목록의 「검색어 지우기」)는 종전대로 파랑이다. */
  table a{color:var(--ink);text-decoration:none;font-weight:var(--weight-medium)}
  table a:hover{color:var(--accent);text-decoration:underline}
  .clrow a{color:var(--ink);text-decoration:none}
  .sub a[data-go],.hint a[data-go]{color:var(--accent)}   /* ★ 과제 268 정산 — 안내 글 속 「다른 화면으로」 링크 = 파랑(가리킴 · DESIGN 색의 역할) · 옛 = 브라우저 기본 파랑(#00e · 들른 뒤 보라) */
  .clrow a:hover{color:var(--accent);text-decoration:underline}
  tr:has(td a[data-adv]),tr:has(td a[data-lead]),tr:has(td a[data-task]),tr:has(td a[data-camp]),
  tr:has(td a[data-vend]),tr:has(td a[data-school]),tr:has(td a[data-qrow]){cursor:pointer}
  .scrolltbl{max-height:64vh;overflow:auto;border-radius:var(--r-ctl)}
  .scrolltbl th{position:sticky;top:0;z-index:1}
  /* §11 목록 표준 — 구형 표(.scrolltbl)를 clrow 규격에 맞춥니다 */
  .scrolltbl table{font-size:var(--fs-body);margin-top:0}
  .scrolltbl th{font-size:var(--fs-cap);letter-spacing:0;text-transform:none;color:var(--text-2);
    background:var(--bg-card);padding:9px 12px;border-bottom:1px solid var(--line)}
  /* ⚠ v1.56 실측 — 여기에 height:44px 를 넣었더니 **견적서 문서(#qsTable)가 A4 를 45px 넘겼다**
     (견적 시트가 이 규칙을 함께 받는다 · 인쇄 관문 빨간불). 줄 키는 padding 이 만든다(11+21+11 = 43px). */
  .scrolltbl td{padding:11px 12px;border-bottom:1px solid var(--line-soft);vertical-align:middle}
  .scrolltbl th:first-child,.scrolltbl td:first-child{padding-left:24px}
  .scrolltbl th:last-child,.scrolltbl td:last-child{padding-right:24px}
  .scrolltbl tr:hover td{background:var(--row-hover)}
  /* ★ v3.4 (과제 90) — 스크롤 표도 같은 문법 : 회색 머리줄 · 줄 키 · 칸 세로줄(마지막 칸 제외) */
  .scrolltbl th{background:var(--tbl-head-bg);height:var(--row-h)}
  .scrolltbl td{height:var(--row-h)}
  .scrolltbl th,.scrolltbl td{border-right:1px solid var(--cell-line)}
  .scrolltbl th:last-child,.scrolltbl td:last-child{border-right:0}
  .scrolltbl tr.sel td,.scrolltbl tr.sel:hover td{background:var(--bg-active)}
  .scrolltbl tr:has(a[data-lead]),.scrolltbl tr:has(a[data-adv]),.scrolltbl tr:has(a[data-vend]){cursor:pointer}
  #vendList td{padding-top:8px;padding-bottom:8px}   /* v2.78 (과제 137) — #mList 는 표가 아니라 격자가 되어 뺐다 */
  th.sortable{cursor:pointer;user-select:none;-webkit-user-select:none}
  th.sortable:hover{color:var(--text)}
  /* ★ v1.56 (R2) — 화살표는 **마우스를 올린 열 · 지금 정렬 중인 열**에만. 기능은 그대로, 소음만 걷는다.
     종전에는 한 화면에 ↕ 가 일곱씩 늘 떠 있었다(캠페인 7 · 발주 7). */
  th.sortable::after{content:"";margin-left:5px;font-size:var(--fs-cap);color:var(--text-3);font-weight:var(--weight-body)}
  th.sortable:hover::after{content:"↕"}
  th.sortable[data-sort="asc"],th.sortable[data-sort="desc"]{color:var(--accent)}
  th.sortable[data-sort="asc"]::after{content:"▲";color:var(--accent)}
  th.sortable[data-sort="desc"]::after{content:"▼";color:var(--accent)}
  /* v0.99 (점검 ④) — 격자 목록(.clrow) 머리줄도 같은 손맛으로 정렬. 표와 표시를 똑같이 씁니다 */
  .clrow.clhead > *{user-select:none;-webkit-user-select:none}
  .clrow.clhead > .gsort,.clrow.clhead > .tk-gsort{cursor:pointer}   /* ★ 과제 230 — 손가락 = 정렬하는 머리 칸만(Dashboard 카드 · 홈 보드의 작은 표 머리는 누를 수 없는데 손가락이었다 · v331 ①) */
  /* ★ v2.70 (과제 132 · DESIGN §11-3) — 정렬 표시 = 할 일과 같은 SVG(`core.js CL_SORT_SVG` · class="tk-si cl-si" 라 크기·색은 할 일 .tk-si 규칙을 그대로 받는다).
     옛 글자 표시(::after 의 ↕ ▲ ▼)는 은퇴 — 할 일처럼 **늘 보이고**, 정렬 중이면 파랑(방향은 글자로 안 보인다 · 할 일과 같다). */
  .clrow.clhead > .gsort:hover{color:var(--text-2)}
  .clrow.clhead > .gsort[data-sort="asc"],.clrow.clhead > .gsort[data-sort="desc"]{color:var(--accent)}
  .clrow.clhead > .gsort[data-sort] .cl-si{color:var(--accent)}
  /* 단계 약칭 칸은 글자가 여섯 개라 화살표를 붙이지 않습니다(자리가 없음) */
  /* v1.49 — 단계 열도 이제 정렬됩니다(진도 순 · data-sortv). 화살표를 죽이던 규칙을 뗐습니다. */
  #advList table{white-space:nowrap}
  /* ★ 과제 244 — 광고주 실적 칸 */
  #advList .clrow > .r{text-align:right;justify-content:flex-end}
  #advList .adv-mg{display:flex;align-items:center;gap:6px;white-space:nowrap}
  #advList .adv-pend{flex:0 0 auto}
  .adv-low{color:var(--bad)}
  #advList td:nth-child(4),#advList td:nth-child(5){max-width:210px;overflow:hidden;text-overflow:ellipsis}
  #advList td,#advList th{vertical-align:middle}
  .numcell{display:block;text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}

  /* ── 상태 배지 : 컴팩트 사각 칩 (알약 폐지 — 강조 자리 전용 §1) ── */
  .pill{display:inline-flex;align-items:center;height:20px;padding:0 8px;border-radius:var(--r-ctl);
        font-size:var(--fs-cap);font-weight:var(--weight-strong);letter-spacing:0;white-space:nowrap}
  .pill.ok{background:var(--ok-bg);color:var(--ok)}
  .pill.warn{background:var(--warn-bg);color:var(--warn)}
  .pill.bad{background:var(--bad-bg);color:var(--bad)}
  .pill.dim{background:var(--bg-hover);color:var(--text-2)}
  /* ★ v1.23 (야간 UX R06 · 발견 107) — 누르면 그 칸으로 데려가는 칩. 눌리는 것으로 보여야 눌러 봅니다 */
  .pill.jump{cursor:pointer;text-decoration:underline;text-underline-offset:.2em}
  .pill.jump:hover{filter:brightness(.97)}
  .pill.blue{background:var(--accent-soft);color:var(--accent)}
  .pill.purple{background:var(--purple-bg);color:var(--purple)}
  /* 단계 배지(캠페인 상세 cdstgline) — 램프 폐지 · 강조 하나 (시안 §1) */
  .pill.stg1,.pill.stg2,.pill.stg3,.pill.stg4,.pill.stg5{background:var(--accent-soft);color:var(--accent)}
  .pill.stg6{background:var(--ok-bg);color:var(--ok)}
  .delpill{margin-left:6px;vertical-align:1px}
  /* ── 상태 점+글자 (v2 신설 — stagePill 이 씁니다 · 배지 최소화) ── */
  .st{display:inline-flex;align-items:center;gap:6px;font-size:var(--fs-body);font-weight:var(--weight-medium);white-space:nowrap}
  .st i{width:8px;height:8px;border-radius:50%;flex:0 0 auto;background:var(--text-2)}
  .st.prop{color:var(--text-2)}   .st.prop i{background:var(--text-2)}
  .st.s1,.st.s2{color:var(--accent)} .st.s1 i,.st.s2 i{background:var(--accent)}
  .st.s3,.st.s4{color:var(--ok)}     .st.s3 i,.st.s4 i{background:var(--ok)}
  .st.s5{color:var(--warn)}          .st.s5 i{background:var(--warn)}
  .st.s6{color:var(--text-2)}        .st.s6 i{background:transparent;border:1.5px solid var(--ok);width:7px;height:7px}
  .st.bad{color:var(--bad)}          .st.bad i{background:var(--bad)}
  /* ★ v1.49 (가독성 3단계) — 상태 열에서 쓰는 이름 붙은 색 두 개(새 색 아님 · §1 토큰 그대로) */
  .st.ok{color:var(--ok)}            .st.ok i{background:var(--ok)}
  .st.warn{color:var(--warn)}        .st.warn i{background:var(--warn)}
  .st.dim{color:var(--text-2)}       .st.dim i{background:var(--text-2)}
  /* ★★ 색만으로 뜻을 전하지 않는다(§1 · §7) — **모양도 함께.**
     적록색약(남성 20명 중 1명)에게 ok 와 bad 는 같은 톤이고, 흑백 인쇄에서도 구별이 사라진다.
     채운 원 = 끝난 것 · **빈 원 = 예정** · **모난 사각 = 문제**. 새 색·새 크기 없음.
     ⚠⚠ **모양 클래스는 색을 건드리지 않는다.** 처음엔 `.st.plan{color:var(--text-2)}` 을 함께 얹었다가
        같은 명시도(0,2,0)에서 **뒤에 있다는 이유로 `.st.warn` 을 이겨** 「오늘·임박」이 회색으로 나왔다
        (09-11 실측 · 규칙 90 그대로). 색은 `.ok`·`.warn`·`.bad`·`.dim` 넷이 정하고,
        모양은 `.plan`·`.late` 가 정한다 — 두 축을 섞지 않는다.
     ⚠ 모양 규칙은 색 규칙보다 **뒤에** 있어야 점 배경을 덮는다(같은 명시도 0,2,1). */
  .st.plan i{background:transparent;border:1.5px solid currentColor;width:7px;height:7px}
  .st.late i{border-radius:2px}
  /* ★ v1.49 (F-6) — 날짜 열 한 벌. 상자를 두르지 않고 **글자 색**으로만 급한 정도를 말한다.
     한 열에 「맨 글자」와 「틴트 상자」가 섞이던 것을 없앤다(§11-3). */
  .dcell{white-space:nowrap;font-variant-numeric:tabular-nums;color:var(--text-2)}
  .dcell.soon{color:var(--warn);font-weight:var(--weight-strong)}
  .dcell.over{color:var(--bad);font-weight:var(--weight-strong)}
  /* 직원 색 칩 (§12-4 사람 팔레트 — JS 가 색을 인라인으로 입힘) */
  /* ★ v1.59 (대표 「뱃지 사이즈가 제각각」) — 배지 세 벌(.pill · .uchip · .ccode)을 **한 규격**으로 :
     높이 20px · padding 0 8px · 라운드 --r-ctl · 12px. 다른 것은 **색과 굵기뿐**이다.
     종전 : uchip 13px/라운드 5 · ccode 12px/라운드 4 · pill 12px/라운드 8 — 셋이 다 달랐다. */
  .uchip{display:inline-flex;align-items:center;height:20px;padding:0 8px;border-radius:var(--r-ctl);
      font-size:var(--fs-cap);font-weight:var(--weight-strong);white-space:nowrap}

  /* ★★ v2.35 (09-18 · 과제 84) — 주민등록번호 : 「전체 보기」는 **가리키는 것**이라 파랑(`--accent`).
     ⚠ 전체 번호는 **20초만** 보이므로 옆의 남은 시간 알약(`.pill.warn`)이 늘 함께 보인다. */
  #hrDetRrn a{color:var(--accent);cursor:pointer}
  #hrDetRrn b{font-variant-numeric:tabular-nums;letter-spacing:.02em}
  #hrRrnLogBody .clrow{grid-template-columns:minmax(0,130px) minmax(0,110px) minmax(0,110px) minmax(0,110px) minmax(0,1fr);min-width:0}
  /* ★★ v3.4 (09-18 · 과제 97 · 사양 §3-7) — **목록·팝 안의 사람 = 24 동그라미 + 이름**.
     동그라미는 할 일 화면의 `.tk-av`·`.tk-avs` 를 **그대로 쓴다**(그 CSS 는 한 글자도 안 고친다).
     여기서는 **감싸는 옷**(`.uav`)과 **공용 목록 위의 겹침 테두리**만 더한다. */
  .uav{display:inline-flex;align-items:center;gap:8px;min-width:0}
  .uav .uav-nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
  .clrow:hover .tk-avs .tk-av,
  .umenu-it.hl .tk-avs .tk-av{box-shadow:0 0 0 2px var(--bg-fill)}   /* 줄 호버 위에서도 겹친 테두리가 보이게 */

  /* ── 견적 시트 — 대조 칩 + 줄 입력표 ── */
  .qschips{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 14px}
  .qschip{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;
          border-radius:var(--r-ctl);font-size:var(--fs-sm);font-weight:var(--weight-strong);
          border:1px solid var(--line-soft);background:var(--bg-card)}
  .qschip b{font-weight:var(--weight-strong)}
  .qschip.ok{background:var(--ok-bg);color:var(--ok);border-color:rgba(44,159,107,.3)}
  .qschip.warn{background:var(--warn-bg);color:var(--warn);border-color:rgba(178,122,0,.3)}
  .qschip.bad{background:var(--bad-bg);color:var(--bad);border-color:rgba(222,76,76,.3)}
  #qsTable td{padding:4px 6px;vertical-align:middle}
  #qsTable input{width:100%;min-width:0;margin:0;padding:5px 8px;font-size:var(--fs-body);border-radius:var(--r-ctl)}   /* ★ 과제 324 — 시트 = 문서 밖 화면 표(13px → 본문 토큰) */
  #qsTable input:disabled{background:var(--bg-hover);border-color:var(--line-soft);color:var(--text-3)}
  #qsTable td[style*="text-align:right"] input{font-variant-numeric:tabular-nums}

  /* ── 캠페인 상세 : 머리줄 + 금액 4상자 + 정보 격자 ── */
  .cdhead{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:6px 0 10px;font-size:var(--fs-card)}
  .cdhead .cdright{margin-left:auto}
  .cdstats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;margin-bottom:10px}
  .cdstat{border:1px solid var(--line);border-radius:var(--r-ctl);padding:9px 11px;min-width:0}
  .cdstat .l{font-size:var(--fs-cap);color:var(--text-2);margin-bottom:3px;white-space:nowrap}
  .cdstat .v{font-size:var(--fs-page);font-weight:var(--weight-strong);color:var(--ink);font-variant-numeric:tabular-nums}
  .cdgrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px 14px;margin-bottom:6px}
  .cdgrid .l{font-size:var(--fs-cap);color:var(--text-2)}
  .cdgrid .v2{font-size:var(--fs-body)}
  @media (max-width:880px){.cdstats,.cdgrid{grid-template-columns:repeat(2,minmax(0,1fr))}}
  /* v0.94 — 알약 뒤 밑줄을 떼고(campHtml) 여백으로 띕니다 (08-25 대표 확정) */
  .ccode{display:inline-flex;align-items:center;height:20px;font-size:var(--fs-cap);font-weight:var(--weight-medium);
         color:var(--text-2);background:var(--bg-hover);box-sizing:border-box;
         border:1px solid var(--line-soft);border-radius:var(--r-ctl);padding:0 8px;margin-right:6px;
         letter-spacing:0;white-space:nowrap;font-variant-numeric:tabular-nums}
  .board .cardlet .ccode{display:inline-block;margin:1px 6px 2px 0}   /* v0.94 — 오른쪽 여백 보존 */

  /* ── 판매매체관리 : 내려가기 카드 ── */
  .drillrow{display:flex;gap:10px;flex-wrap:wrap;margin:8px 0}
  .drillcard{border:1px solid var(--line);border-radius:var(--r-ctl);padding:12px 14px;cursor:pointer;min-width:200px;
      background:var(--bg-card);transition:background var(--duration-fast) var(--ease)}
  .drillcard:hover{background:var(--bg-hover)}
  /* v1.40 (야간 UX R23 · 발견 2202) — 고른 카드는 목록 줄(.clrow.sel)과 **같은 옷**. 새 색·크기 없음 */
  .drillcard.sel,.drillcard.sel:hover,.drillcard:focus-visible{background:var(--bg-active);
      box-shadow:inset 2px 0 0 var(--accent)}
  .drillcard:focus-visible{outline:none}
  .drillcard b{display:block;margin-bottom:3px}
  .drillcard .muted{font-size:var(--fs-sm)}
  #mCrumb a{cursor:pointer}
  /* ★ 과제 215 (B7) — 빵부스러기 = 단추(Tab · Enter) · 옷은 글자 링크 그대로(높이 · 테두리 · 채움 0 · 초점 테 = 공용 --ring) */
  #mCrumb button.crumb{height:auto;min-width:0;padding:0;border:0;background:none;box-shadow:none;font:inherit;color:inherit;cursor:pointer;border-radius:var(--r-ctl)}
  #mCrumb button.crumb:hover{color:var(--accent);background:none}
  #mCrumb button.crumb:focus-visible{outline:none;box-shadow:var(--ring)}

  /* ── 할 일 상태 셀렉트 — 상태색 틴트 ── */
  select.tsel{font-weight:var(--weight-strong);border-radius:var(--r-ctl);padding:2px 26px 2px 10px;border-color:transparent}
  select.tsel.todo{background-color:var(--bg-hover);color:var(--text-2)}
  select.tsel.doing{background-color:var(--accent-soft);color:var(--accent)}
  select.tsel.client_check{background-color:var(--warn-bg);color:var(--warn)}
  select.tsel.media_check{background-color:var(--purple-bg);color:var(--purple)}
  select.tsel.done{background-color:var(--ok-bg);color:var(--ok)}

  /* ── 로그 콘솔 ── */
  /* v4 (과제 414a) — 로그 콘솔도 밝은 옷 : 카드 안 묶음 칠(--bg-fill) · 글 = --text-2 · 성공 = --ok · 실패 = --bad · 알림 = --text-3(옛 = 검정 바탕 + 박힌 색 넷) */
  .log{background:var(--bg-fill);color:var(--text-2);border-radius:var(--r-ctl);padding:12px 14px;
       font-size:var(--fs-sm);font-family:var(--font-mono);max-height:260px;
       overflow:auto;white-space:pre-wrap;line-height:1.55}
  .log .t{color:var(--ok)}
  .log .e{color:var(--bad)}
  .log .n{color:var(--text-3)}

  /* ── 안내 상자 ── */
  /* ★ v1.02 (08-25 대표 결정 · 팝업 구조 개선 ①) — 안내와 경고를 **부품으로 나눕니다.**
     종전에는 `.hint` 하나가 경고색(--warn-bg)을 써서, 단순 안내가 주의를 요구하는 것처럼
     보이고 정작 진짜 경고와 구분이 되지 않았습니다(화면 16곳 · 대부분 경고가 아님).
       .hint  = 안내 — 배경 없이 회색 작은 글씨 · 왼쪽 선 하나로 묶음만 표시
       .warn  = 진짜 경고 — 노란 상자(종전 .hint 모양 그대로) */
  .hint{background:transparent;border:0;border-left:2px solid var(--line);
        border-radius:0;padding:2px 0 2px 11px;font-size:var(--fs-sm);line-height:1.65;
        color:var(--text-2);margin:12px 0;word-break:keep-all;overflow-wrap:anywhere}   /* ★ 과제 584 — 낱말 가운데서 안 꺾음(390 「[끊 / 기]」 ✗) · 한 줄보다 긴 낱말만 꺾임 · v564 */
  .hint b{color:var(--text)}
  /* ★★ v1.17 (규칙 90) — `:not(.pill)` 이 꼭 있어야 합니다. `<span class="pill warn">` 은 두 클래스를
     함께 달고 있고, `.warn`(0,1,0) 은 `.pill`(0,1,0· 259줄)보다 **뒤에 있어 이깁니다** — 그래서 노란
     알약만 상자 padding 11/14 · 1px 보더 · 글자 13px · **margin 12px** 를 뒤집어써 목록에서 한 줄만
     커지고 위아래가 벌어졌습니다(할 일 업무상태 팝오버 실측 : 그 줄만 60px · 나머지 32px · 규칙 71 과 같은 결).
     ⚠ 알약을 예외로 두는 이 자리를 지우면 노란 알약 30곳이 한꺼번에 다시 깨집니다.
     ★★ v1.25 (규칙 71·90) — 예외는 반드시 **`:where(:not(.pill))`** 로 씁니다. 맨 `:not(.pill)` 은
     명시도를 (0,1,0) → (0,2,0) 으로 올려, 규칙 71 대로 **한 클래스로 margin 을 못박아 둔 부품**
     (`.qmatch-tile` · `.qmatch-add-msg`)을 순서와 무관하게 이겨 버립니다 — v1.17 직후 붙여넣기 팝업
     요약 3칸이 다시 89/65/89px 로 어긋났습니다(09-10 실측 · 견적작성팝업검사 3건 빨간불).
     `:where()` 는 명시도가 0 이므로 v1.17 이전과 **같은 (0,1,0)** 을 유지하면서 알약만 빼 줍니다.
     ★★ v3.34 (과제 240) — 알약은 `.pill` 하나가 아니었다 : 점 + 글자 알약 `.st`(캠페인 결제 오늘 · 임박 · 홈 「내 할 일」 오늘 · 내일) ·
     할인 신호등 `.lamp`(견적) · 목표 칩 `.qschip`(견적) · 아이콘 타일 `.tile`(홈 「내 할 일」 오늘 줄 · 할 일 Dashboard 「오늘 마감」 — 기획 · 대표 예외 09-30) 도 `warn` 을 함께 달아 노란 상자(padding 11/14 · margin 12 · 보더)를
     뒤집어썼다(09-30 실측 : 그 줄만 44 → 70 · 홈 할 일 줄 60 → 89). 다섯을 같은 자리에서 뺀다 — 새 알약 부품이 `warn` 을 달면 **여기에 더한다**(관문 v343). */
  .warn:where(:not(.pill):not(.st):not(.lamp):not(.qschip):not(.tile)){background:var(--warn-bg);border:1px solid rgba(178,122,0,.28);
        border-radius:var(--r-card);padding:11px 14px;font-size:var(--fs-body);line-height:1.6;margin:12px 0}
  /* v1.02 — 등록·수정 폼 부품 셋 (팝업 구조 개선)
     ⚠ 필수 별표 색은 새로 정하지 않습니다 — `.cdprop .pk .req` 가 이미 빨강으로 통일되어 있어
       그것을 그대로 씁니다(시안에서는 강조색으로 그렸지만, 있는 규칙이 우선입니다). */
  /* 칸 밑 도움말 — ⚠ `.cdprop` 은 flex 라 그냥 넣으면 값 **옆**에 붙습니다. 라벨 폭(112px)+간격(10px)
     만큼 들여쓴 **형제 블록**으로 둡니다(마크업에서 .cdprop 밖). */
  .pfhelp{font-size:var(--fs-cap);color:var(--text-2);line-height:1.55;margin:-2px 0 8px;padding-left:122px}
  @media (max-width:520px){.pfhelp{padding-left:0}}
  .pfnote{font-size:var(--fs-sm);color:var(--text-2);line-height:1.6;margin:14px 0 0}
  /* 하단 바 : 내용 → 액션 순서로 맨 아래. ⚠ sticky 는 쓰지 않습니다 — 이 팝업은 네 칸이라
     스크롤이 없고, sticky 로 두면 바로 위 안내 줄을 덮습니다(실측). */
  .slideover .btns.pnl-foot{margin:16px -22px -22px;padding:13px 22px;
      background:var(--bg-app);border-top:1px solid var(--line)}
  /* ★★ v2.84 (과제 158 · 기획 실측 → 시안 FIX) — **입력 팝업 옷 한 벌**(공용 · 화면마다 손대지 않는다 · 값은 전부 토큰)
     ⓐ 팝업 안 단추 그림자 0(화면 도구 줄과 같게) ⓑ 입력칸 · 고르기 · 긴 글 칸 테두리 = --line(옛 --line-input 은 진했다) · 누르면 --accent + --ring
     ⓒ 구역 제목 = --fs-body · --weight-strong · --text(옛 12px 가 필드 이름 13px 보다 작아 위계가 뒤집혔다) · 필드 이름은 그대로
     ⓓ 검정 단추 = 발 오른쪽 끝 하나(발 밖 검정 단추는 보조 옷) ⓔ 폼 안 여러 줄 안내 상자(.hint · 왼쪽 막대) → 칸 밑 한 줄 도움말 옷(막대 없음 · 작은 회색) */
  /* 발은 창 맨 아래(시안 ③B) — 몸을 세로 flex 로 · 발 margin-top:auto(글이 짧아도 발이 가운데 뜨지 않는다 · 길면 142 sticky 가 붙잡는다) */
  aside.slideover.modal:not([data-panel="qcompose"]) .pnl-body{display:flex;flex-direction:column}
  aside.slideover.modal:not([data-panel="qcompose"]) .pnl-body > .btns.pnl-foot{margin-top:auto !important}   /* v2.88 (과제 159) — 발에 붙은 인라인 margin-top(옛 폼들)을 이긴다 : 짧은 폼에서 발이 가운데 떠 있었다 */
  aside.slideover.modal:not([data-panel="qcompose"]) .pnl-body > *{flex-shrink:0}
  /* 상세 넓음 820 의 2단 — 표 안 단추 글이 한 글자씩 꺾이지 않게 */
  #campSide td button,#campSide td .mini,#ciBody td button,#ciBody td .mini{white-space:nowrap}
  aside.slideover button{box-shadow:none}
  aside.slideover input:not([type=checkbox]):not([type=radio]),aside.slideover select,aside.slideover textarea{border-color:var(--line-input)}   /* v4 지침 F-1 — 팝업 안 적는 칸도 --line-input(회색 얇은 선 · 과제 479 G-675 · 화면 적는 칸과 한 값) */
  aside.slideover input:not([type=checkbox]):not([type=radio]):focus,aside.slideover select:focus,aside.slideover textarea:focus{border-color:var(--accent);box-shadow:var(--ring)}
  aside.slideover .cdprops.asform .cdprop > input:not([type=checkbox]):not([type=radio]),aside.slideover .cdprops.asform .cdprop > select,aside.slideover .cdprops.asform .cdprop > textarea{border-color:var(--line-input)}   /* 적는 칸 폼(asform)의 칸 규칙이 더 세다 — 같은 세기로 */
  aside.slideover .cdprops.asform .cdprop > input:not([type=checkbox]):not([type=radio]):focus,aside.slideover .cdprops.asform .cdprop > select:focus,aside.slideover .cdprops.asform .cdprop > textarea:focus{border-color:var(--accent);box-shadow:var(--ring)}
  aside.slideover .cdprops.asform .cdprop > input:not([type=checkbox]):not([type=radio]):disabled,aside.slideover .cdprops.asform .cdprop > select:disabled{background-color:var(--bg-hover);border-color:var(--line-soft);color:var(--text-3);cursor:not-allowed}   /* ★ v2.94 (과제 165 #3) — 잠긴 칸 = 눈에도 잠김(견적 #qsTable input:disabled 와 같은 세 토큰 · 사진 10 = 열린 칸과 똑같았다) */
  #spComposeWrap [data-part~="locknote"] > .pv{color:var(--text-3);font-size:var(--fs-sm)}   /* v2.94 — 「돈이 나가 금액은 잠겼습니다」 = 흐린 한 줄 */
  aside.slideover .pnl-sect,aside.slideover .pnl-body .card > h3{font-size:var(--fs-body);font-weight:var(--weight-strong);color:var(--text)}
  aside.slideover .pnl-body button:not(.ghost):not(.danger):not(.pill):not(.xclose):not(.x):not(.pnl-foot *){background:var(--bg-card);color:var(--text);border:1px solid var(--line)}
  aside.slideover .pnl-body .hint{border-left:0;padding:0;margin:6px 0 0;font-size:var(--fs-sm);line-height:1.5;color:var(--text-2)}
  /* ★ v2.80 (과제 142 수정 · 09-24 기획 지적 「900 높이에서 발 단추가 반쯤 잘린다」) — **팝업이 창보다 길면 몸만 스크롤 · 발은 늘 보인다.**
     발(.pnl-foot)은 몸(.pnl-body · 스크롤 칸)의 맨 끝 자식(_pnlNormalize 가 옮긴다) → sticky 로 몸 아래 끝에 붙인다(요소 이동 0 · id 0).
     아래 여백 −22 가 몸 안여백을 먹어 끝까지 내린 자리 = 붙은 자리(두 자리가 같아 튀지 않는다) · 머리 · 요약 띠는 몸 밖이라 원래 늘 보인다.
     ⚠ 옛 주석(v1.95 무렵) 「sticky 는 위 안내 줄을 덮는다」 — 스크롤이 없을 때는 제자리라 덮지 않는다(관문 v280 ⓔ14 가 끝까지 내려 잰다). */
  .slideover .pnl-body > .btns.pnl-foot{position:sticky;bottom:-22px;z-index:2}   /* −22 = 위 아래 여백 −22 를 sticky 가 한 번 더 세는 몫(0 이면 22 떠서 위 줄을 덮는다 · 실측) */
  /* ★ v1.91 (과제 46) — 팝업 발(pnl-foot) 한 벌 : 오른쪽 = 주 행동 · 왼쪽 = 위험한 것(삭제). 등록·상세가 같은 발을 신는다 */
  .pnl-foot{justify-content:flex-end}
  /* ★ v2.81 (과제 143) — 팝업 안 「라벨 + 체크(동그라미)」 는 체크가 제 크기(전역 input{width:100%} 이 173px 로 늘려 글이 멀리 밀렸다 · 지출 판관비 고정비 · 비밀 · main 에도 있던 것) */
  .slideover label > input[type=checkbox],
  .slideover label > input[type=radio]{width:auto;flex:0 0 auto;margin:0}
  .pnl-foot>button.danger{margin-left:0;margin-right:auto}
  .slideover[data-panel="task"] #tFormTitle{display:none}   /* 제목은 팝업 머리 한 줄만 (v1.91) */
  .slideover[data-panel="adv"] #advFormTitle{display:none}  /* v1.93 — 광고주도 제목 한 줄(과제 47) */
  .err{background:var(--bad-bg);border:1px solid rgba(176,32,15,.3);
       border-radius:var(--r-card);padding:11px 14px;font-size:var(--fs-body);line-height:1.6;margin:12px 0;
       color:var(--bad);white-space:pre-wrap}
  .good{background:var(--ok-bg);border:1px solid rgba(12,81,50,.3);
        border-radius:var(--r-card);padding:11px 14px;font-size:var(--fs-body);line-height:1.6;margin:12px 0;
        color:var(--ok);white-space:pre-wrap}

  /* ── 단계 흐름 ── */
  .flow{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin:14px 0}
  .flow .st{background:var(--bg-card);border:1px solid var(--line);border-radius:var(--r-ctl);
            padding:7px 12px;font-size:var(--fs-sm);display:block;color:var(--text)}
  .flow .st b{display:block;font-size:var(--fs-cap);color:var(--accent);font-weight:var(--weight-strong);letter-spacing:.05em}
  .flow .ar{color:var(--text-2);font-weight:var(--weight-body)}
  /* ★ v1.32 (야간 UX 루프 R15 · 발견 1402) — 「업무 흐름 안내」의 단계 칸은 눌러서 그 화면으로 갑니다.
     손맛은 숫자 카드(.stat:hover)와 같은 토큰 · 초점 테두리는 공용 --ring (새 색·크기 없음). */
  .flow .st[data-go]{cursor:pointer}
  .flow .st[data-go]:hover{border-color:var(--brand-azure);background:var(--bg-fill)}
  .flow .st[data-go]:focus-visible{outline:none;box-shadow:var(--ring)}
  .kv{display:grid;grid-template-columns:120px 1fr;gap:4px 12px;font-size:var(--fs-body)}
  .kv .k{color:var(--text-2)}
  .photo{width:92px;height:70px;background:var(--bg-hover);border-radius:var(--r-ctl);
         margin:4px;font-size:var(--fs-cap);color:var(--text-2);
         display:inline-flex;align-items:center;justify-content:center;text-align:center;padding:4px}
  .muted{color:var(--text-2);font-size:var(--fs-sm)}
  code.q{display:block;background:var(--bg-hover);border-radius:var(--r-ctl);padding:9px 11px;
         font-size:var(--fs-sm);font-family:var(--font-mono);margin-top:8px;
         white-space:pre-wrap;color:var(--text)}

  /* ── 상태 보드 ── */
  .board{display:flex;gap:10px;overflow-x:auto;padding-bottom:6px}
  .board .col{min-width:170px;flex:1;background:var(--bg-fill);border:1px solid var(--line-soft);
              border-radius:var(--r-ctl);padding:9px}
  .board .col h4{margin:0 0 8px;font-size:var(--fs-cap);color:var(--text-2);font-weight:var(--weight-strong);
              letter-spacing:.05em;text-transform:uppercase}
  .board .cardlet{background:var(--bg-card);border:1px solid var(--line);border-radius:var(--r-ctl);
                  padding:8px 10px;font-size:var(--fs-sm);margin-bottom:6px;cursor:pointer;
                  transition:border-color var(--duration-fast) var(--ease),background var(--duration-fast) var(--ease)}
  .board .cardlet:hover{border-color:var(--brand-azure);background:var(--bg-hover)}
  .board .cardlet b{display:block;font-size:var(--fs-sm);font-weight:var(--weight-strong)}

  /* ── 레이아웃 유틸 ── */
  .split{display:grid;grid-template-columns:minmax(330px,25.5rem) minmax(0,1fr);gap:16px;align-items:start;margin-bottom:16px}
  .split>.side{position:sticky;top:16px}
  .grid2{display:grid;grid-template-columns:repeat(auto-fit,minmax(430px,1fr));gap:16px;align-items:start;margin-bottom:16px}
  .grid2 .card,.split .card{margin-bottom:0}
  .split.fullwidth{grid-template-columns:minmax(0,1fr)}
  .split.fullwidth>.side{display:none}

  /* ── 홈 대시보드 ── */
  #home>h2,#home>.sub{display:none}
  .homehero{display:flex;align-items:flex-end;gap:10px;margin:2px 0 20px;flex-wrap:wrap}
  .homehero .hh-l{flex:1;min-width:220px}
  .overline{font-size:var(--fs-cap);font-weight:var(--weight-strong);letter-spacing:.05em;color:var(--text-2);
      text-transform:uppercase;margin-bottom:4px}
  .hh-title{font-size:var(--fs-title);font-weight:var(--weight-strong);letter-spacing:var(--ls-title);color:var(--ink)}   /* v4 (414a) — 홈 인사말 = 이 화면의 제목 자리 → 제목 26 · 500(옛 = KPI 숫자 단 · v4 에서 28 로 커져 제목과 겨룸) */
  /* ★ v1.50 (홈 대시보드 · 대표 승인 시안 = 시제품/…260911…디자인시안_홈대시보드_아이콘KPI.html)
     KPI 카드 문법 = 라벨(13px --text-2) → 큰 숫자(--fs-num) → 변화 칩(.delta · 색 + ▲▼ 모양) · 오른쪽 아이콘 타일(.tile.lg).
     5장이 한 줄(1100px 아래는 흐름). 규격 = DESIGN.md §6 「KPI 카드」·「아이콘 타일」·「변화 칩」. 새 색·크기 없음. */
  .stats{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:12px;margin-bottom:16px}
  @media (max-width:1100px){.stats{grid-template-columns:repeat(auto-fit,minmax(190px,1fr))}}
  .stat{background:var(--bg-card);border:1px solid var(--line);border-radius:var(--r-card);
        padding:18px 20px;cursor:pointer;display:flex;gap:12px;align-items:flex-start;min-width:0;
        transition:border-color var(--duration-fast) var(--ease),background var(--duration-fast) var(--ease)}
  .stat:hover{border-color:var(--accent);background:var(--bg-fill)}
  .stat:focus-visible{outline:none;box-shadow:var(--ring)}
  .stat .body{flex:1;min-width:0}
  .stat .k{font-size:var(--fs-sm);color:var(--text-2);font-weight:var(--weight-body);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  @media (max-width:1366px){ #home .stat .k{white-space:normal} }   /* ★ v3.08 (과제 176) — 홈 타일 이름 「진행 중 상담 회사 전체」 가 1280 에서 「진행 중 상담 회…」 : 좁을 때만 두 줄(흐린 「회사 전체」 가 아래 줄로) · 다른 화면 타일은 이름이 짧아 그대로 */
  .stat .k .muted{font-size:var(--fs-cap)}
  .stat .k::before{display:none}
  .stat .v{font-size:var(--fs-num);font-weight:var(--weight-strong);color:var(--ink);letter-spacing:-.01em;margin-top:6px;
      font-variant-numeric:tabular-nums;line-height:1.1}
  .stat .v2{font-size:var(--fs-sm);color:var(--text-2);font-variant-numeric:tabular-nums;margin-top:2px}   /* ★ 과제 180 — 숫자 밑 한 줄(합계 금액 · 금액 기준 %) */
  .stat .v small{font-size:var(--fs-sm);font-weight:var(--weight-body);color:var(--text-2);margin-left:4px}
  .stat .delta-slot{display:block;min-height:20px;margin-top:10px}
  .stats .stat:nth-child(4) .v{color:var(--accent)}
  /* § 아이콘 타일 — 목록 줄 앞 · KPI 카드 오른쪽. 그림은 사이드바 메뉴 아이콘(navDecor P)의 복제(core.js tileHtml · boot.js homeTiles) */
  .tile{width:32px;height:32px;border-radius:var(--r-card);background:var(--accent-soft);color:var(--accent);
        display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}
  .tile svg{width:16px;height:16px;display:block}
  .tile.lg{width:40px;height:40px;border-radius:var(--r-panel)} .tile.lg svg{width:20px;height:20px}
  /* ★ 과제 355(10-08 대표 디자인 점검 · DESIGN 「색은 두 역할」) — **타일 아이콘 칩 = 중립 회색 한 벌**(색 칩이 파랑 · 초록 · 분홍 · 회색으로 섞여 「계약 0건」 에 초록 방패가 떴다) · 색은 상태 알약(.pill · .st · .delta)에만 */
  .tile, .tile.ok, .tile.warn, .tile.bad, .tile.dim{background:var(--bg-hover);color:var(--text-2)}
  /* § 변화 칩 — 색 축(.ok/.warn/.bad/.dim) + 모양 축(▲▼ 화살 svg). 규칙 71 : 부품 자리에서 여백·크기를 못박는다(전역 .warn 상자 규칙에 안 걸리게 :where) */
  .delta{display:inline-flex;align-items:center;gap:4px;height:20px;padding:0 7px;margin:0;border:0;
         border-radius:var(--r-ctl);font-size:var(--fs-cap);font-weight:var(--weight-medium);white-space:nowrap;line-height:20px}
  .delta svg{width:12px;height:12px;display:block}
  .delta.ok{background:var(--ok-bg);color:var(--ok)} .delta.bad{background:var(--bad-bg);color:var(--bad)}
  .delta.warn:where(:not(.pill)){background:var(--warn-bg);color:var(--warn);border:0;padding:0 7px;margin:0;font-size:var(--fs-cap);line-height:20px}
  .delta.dim{background:var(--bg-hover);color:var(--text-2)}
  .delta .vs{font-weight:var(--weight-body)}
  .hh-sub{font-size:var(--fs-body);color:var(--text-2);margin-top:4px;min-height:1.5em}
  .hh-sub b{color:var(--ink)}
  #home .grid2{grid-template-columns:1.35fr 1fr}
  #hDelCard{border:1px solid rgba(178,122,0,.4)}
  #hDelList td{vertical-align:middle}
  .hbars{display:flex;flex-direction:column;gap:12px;margin-top:6px}
  .hbar{display:flex;align-items:center;gap:12px}
  .hbar .hb-l{width:88px;font-size:var(--fs-sm);color:var(--text-2);flex-shrink:0;white-space:nowrap;
      overflow:hidden;text-overflow:ellipsis}
  .hbar .hb-track{flex:1;height:6px;border-radius:3px;background:var(--bg-hover);overflow:hidden}
  .hbar .hb-fill{height:100%;border-radius:3px;transition:width var(--duration-base) var(--ease)}
  .hbar .hb-n{width:24px;text-align:right;font-size:var(--fs-body);font-weight:var(--weight-strong);color:var(--ink);
      font-variant-numeric:tabular-nums}
  .hb-sum{margin-top:16px;padding-top:12px;border-top:1px solid var(--line-soft);font-size:var(--fs-sm);color:var(--text-2)}
  .htasks{display:flex;flex-direction:column}
  .htask{display:flex;align-items:center;gap:10px;padding:9px 4px;border-bottom:1px solid var(--line-soft);
      cursor:pointer;border-radius:var(--r-ctl)}
  #hWeekCard,#hWeek,#hWeek .htasks,#hWeek .ht-mid{min-width:0}   /* ★ 과제 346 — 이번 주 칸 「지남」 줄의 긴 업무명이 두 칸 격자(.grid2)를 밀어 폰 390 가로 넘침 78px(v363 ⓐ) → 줄 안에서 말줄임 */
  #hWeek .hw-grp{margin:var(--gap-field) 0 var(--gap-tool)}   /* ★ 과제 424 — 「지난 할 일 n」 · 「이번 주 n」 묶음 머리(있는 .overline 옷) */
  #hWeek .hw-grp:first-child{margin-top:0}
  /* ★★ 과제 430b (10-18 · 시안 430 ① 02 · 03 · 06 · 12) — 홈 역할별 · 목표 카드 · 내 할 일 세 묶음 · 새로 받을 것 · 공용 「접힌 줄」(DESIGN §6) · 토큰만 · 그림자 0 */
  #home .stat[hidden],#home .card[hidden],#home .kpi-fold[hidden],#home button[hidden]{display:none}   /* 규칙 58 — 작성자 display(flex) 가 [hidden] 을 이김 */
  .hgoal .hg-head{display:flex;align-items:center;gap:10px}
  .hgoal .hg-head h3{flex:1;min-width:0;margin:0}
  .hg-nums{display:flex;align-items:baseline;flex-wrap:wrap;gap:4px 10px;margin-top:12px}
  .hg-k{font-size:var(--fs-sm);color:var(--text-2)}
  .hg-big{font-size:var(--fs-num);font-weight:var(--weight-strong);color:var(--ink);font-variant-numeric:tabular-nums;line-height:1.1;letter-spacing:-.01em}
  .hg-of{font-size:var(--fs-body);color:var(--text-2);font-variant-numeric:tabular-nums}
  .hg-rate{font-size:var(--fs-card);font-weight:var(--weight-strong);color:var(--accent);font-variant-numeric:tabular-nums}   /* 진도 = 가리키는 색(한 장 요약 2) */
  .hg-bar{height:8px;border-radius:var(--r-pill);background:var(--bg-hover);overflow:hidden;margin:12px 0 10px}
  .hg-bar > i{display:block;height:100%;border-radius:var(--r-pill);background:var(--accent)}
  .hg-mine{font-size:var(--fs-body);color:var(--text-2)}
  .hg-mine b{color:var(--ink);font-weight:var(--weight-medium);font-variant-numeric:tabular-nums}
  .hgoal .hg-none{margin:12px 0 0}
  .hgoal .hg-people{margin-top:14px}
  .hgoal .hb-fill{display:block;background:var(--accent)}
  .hgoal .hbar .hb-n{width:auto;min-width:150px;font-size:var(--fs-sm);font-weight:var(--weight-medium)}
  #hTaskCard > h3{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
  #hTaskCard .tk-dmore{margin-left:auto}
  .hmine{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px;align-items:start}
  .hmine .hw-grp{margin:0 0 var(--gap-tool)}
  .hm-col,.hm-col .ht-mid,#hBoardCard,#hInboxCard,#hInbox,#hInbox .htasks,#hInbox .ht-mid,#hTaskCard,#hTaskList{min-width:0}
  .hm-rest{margin:12px 0 0}
  .htask.hin{cursor:default}
  .htask.hin:hover{background:transparent}
  .htask.hin > button{flex:0 0 auto}
  /* 대표 홈 — 「지금 할 일」 카드 = #hStats 첫 칸(두 칸 폭) · 타일 · 접힌 줄은 그 뒤(order) */
  #hStats > #hTaskCard{grid-column:span 2;margin:0}   /* DOM 첫 칸(home.js hArrange prepend · order 로 앞에 두지 않음 = Tab 차례 그대로) */
  @media (max-width:1100px){ #hStats > #hTaskCard{grid-column:1/-1} .hmine{grid-template-columns:minmax(0,1fr)} }
  /* § 접힌 줄 .kpi-fold(공용 · core.js kpiFold) — 타일 칸 안 맨 끝 한 줄(온 폭) · 0 인 것 n — 이름 n · … [펼치기 ▾] · 펼치면 접힌 타일이 그 아래(order) */
  .kpi-fold{grid-column:1/-1;order:1;display:flex;align-items:center;gap:10px;flex-wrap:wrap;min-height:44px;padding:6px 12px 6px 16px;
      border:1px solid var(--line);border-radius:var(--r-card);background:var(--bg-card);font-size:var(--fs-sm);color:var(--text-2)}
  .kpi-fold .kf-t{flex:1;min-width:0}
  .kpi-fold .kf-t b{color:var(--ink);font-weight:var(--weight-medium);font-variant-numeric:tabular-nums}
  .kpi-fold .kf-btn{flex:0 0 auto}
  .kf-in{order:2}
  .kf-shut > .kf-in{display:none}
  /* ★ 과제 430c — 공용으로 올림(홈 밖 요약 화면 · 할 일) : 작성자 display 가 [hidden] 을 이김(규칙 58) · 「지금 할 일」 로 간 타일 · 접을 것 없는 접힌 줄 */
  .kpi-fold[hidden],.tk-dstats > .stat[hidden],.tk-dstats > .card[hidden]{display:none}
  .htask:hover{background:var(--bg-hover)}
  .htask .ht-dot,:where(#cTasks) .htask [data-part~="dot"]{width:8px;height:8px;border-radius:50%;flex-shrink:0}
  .htask .ht-mid,:where(#cTasks) .htask [data-part~="mid"]{flex:1;min-width:0}
  .htask .ht-t,:where(#cTasks) .htask [data-part~="t"]{font-size:var(--fs-body);font-weight:var(--weight-medium);color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .htask .ht-c{font-size:var(--fs-sm);color:var(--text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .htask .ht-due,:where(#cTasks) .htask [data-part~="due"]{font-size:var(--fs-cap);font-weight:var(--weight-strong);padding:2px 8px;border-radius:var(--r-ctl);
      white-space:nowrap;flex-shrink:0;font-variant-numeric:tabular-nums}
  .ht-due.over,:where(#cTasks) [data-part~="due"][data-st="over"]{background:var(--bad-bg);color:var(--bad)}
  .ht-due.soon,:where(#cTasks) [data-part~="due"][data-st="soon"]{background:var(--warn-bg);color:var(--warn)}
  .ht-due.far,:where(#cTasks) [data-part~="due"][data-st="far"]{background:var(--bg-hover);color:var(--text-2)}
  /* ★ v1.50 — 홈 「내 할 일」 줄 : 앞에 타일(급한 정도 = 타일 색) · 마감 = .st 점+글자(색 + 모양 : ■ 지남 · ● 오늘 · ○ 예정 — §1).
     .ht-due 틴트 칩은 캠페인 상세(#cTasks · tasks.js)가 계속 쓴다 — 여기서 손대지 않는다 */
  .htask .st{flex-shrink:0}
  /* ★ v1.50 — 홈 캠페인 줄(#hBoard) : 공용 .clrow 를 쓰고 열만 이 자리에서 정한다(규칙 67 · min-width 818 되찾기 · 규칙 28 minmax(0,1fr)) */
  #hBoard .clrow{grid-template-columns:32px minmax(0,1.6fr) minmax(0,1fr) 150px;min-width:0;gap:12px;padding:9px 10px;align-items:center}
  #hBoard .clrow.clhead,#hBoard .clrow.clhead:hover{padding:0 10px 8px;background:transparent}
  #hBoard .hc-t{font-size:var(--fs-body);font-weight:var(--weight-medium);color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
  #hBoard .hc-c{font-size:var(--fs-sm);color:var(--text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:1px;min-width:0}
  #hBoard .hc-c .ccode{margin-right:6px}
  #hBoard .hc-mid{min-width:0}
  #hBoard .hb-sum{border-top:0;padding-top:0;margin-top:12px}   /* 줄의 아랫선과 겹치는 두 줄 선을 없앤다(실측 스크린샷) */
  @media (max-width:1100px){#hBoard .clrow{grid-template-columns:32px minmax(0,1.6fr) minmax(0,1fr) 120px}}
  /* ★ 과제 514 — 폰 390 : 네 칸 그대로면 캠페인 · 광고주 칸이 39 · 19px 로 눌려 머리 「광고주 · 다음 할 일」 이 한 글자씩 세로로 꺾였다(머리 칸 = nowrap 없음)
     → 할 일 목록 폰 꼴(#taskList .tk-dlist) 그대로 : 머리줄 숨김 · 세 줄로 쌓기(타일 | 캠페인 / 광고주 · 다음 할 일 / 단계 · 칸마다 온 폭) · 1440 = 손 안 댐 */
  @media (max-width:600px){
    #hBoard .clrow.clhead{display:none}
    #hBoard .clrow{grid-template-columns:32px minmax(0,1fr);grid-template-areas:"i c" "i a" "i s";row-gap:calc(var(--gap-tool) / 2)}
    #hBoard .clrow > :nth-child(1){grid-area:i;align-self:start} #hBoard .clrow > :nth-child(2){grid-area:c} #hBoard .clrow > :nth-child(3){grid-area:a} #hBoard .clrow > :nth-child(4){grid-area:s}
  }
  /* ★ v1.50 — 「이번 주 할 일」 막대(#hWeek) : CSS 만 · 라이브러리 없음 · 완료 = accent · 남은 것 = --bg-hover 트랙 · 오늘 = 초점 고리 · 지난 요일 아님(미래) = --line */
  .hweek-top{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
  .hweek-top .big{font-size:var(--fs-num);font-weight:var(--weight-strong);color:var(--ink);letter-spacing:-.01em;font-variant-numeric:tabular-nums}
  .hweek-top .big small{font-size:var(--fs-sm);font-weight:var(--weight-body);color:var(--text-2);margin-left:6px}
  /* ★ v2.42 — 칸 수를 `--hweek-cols` 로(기본 5 = 홈 주간 막대 그대로). 대시보드 「업무 강도」가 주 단위라 아홉 칸이 된다.
     안 바꾸면 여섯째 칸부터 **두 줄로 접힌다**(09-21 실측). 칸 수는 자료에서 오는 값이라 인라인으로 준다(색·크기 토큰과 다름). */
  .hweek{display:grid;grid-template-columns:repeat(var(--hweek-cols,5),minmax(0,1fr));gap:10px;align-items:end;height:150px;margin-top:18px;
         padding-top:20px;border-bottom:1px solid var(--line-soft)}
  .hweek .col{display:flex;flex-direction:column;align-items:center;justify-content:flex-end;height:100%;position:relative}
  .hweek .col .num{position:absolute;top:-20px;font-size:var(--fs-cap);color:var(--text-2);font-variant-numeric:tabular-nums;white-space:nowrap}
  .hweek .col .track{width:100%;max-width:44px;height:100%;background:var(--bg-hover);border-radius:var(--r-ctl) var(--r-ctl) 3px 3px;position:relative;overflow:hidden}
  .hweek .col .fill{position:absolute;left:0;right:0;bottom:0;background:var(--accent);border-radius:var(--r-ctl) var(--r-ctl) 0 0}
  .hweek .col.today .track{box-shadow:var(--ring)}
  .hweek .col.future .fill{background:var(--line)}
  .hweek-x{display:grid;grid-template-columns:repeat(var(--hweek-cols,5),minmax(0,1fr));gap:10px;margin-top:8px;text-align:center;font-size:var(--fs-cap);color:var(--text-2)}
  .hweek-x .today{color:var(--accent);font-weight:var(--weight-strong)}
  .hweek-lg{display:flex;gap:14px;margin-top:14px;font-size:var(--fs-cap);color:var(--text-2);flex-wrap:wrap}
  .hweek-lg i{display:inline-block;width:10px;height:10px;border-radius:3px;vertical-align:-1px;margin-right:5px;background:var(--accent)}
  .hweek-lg i.rest{background:var(--bg-hover);border:1px solid var(--line)}

  /* ── 슬라이드 패널·모달 (§12 팝업 표준 — 규격 유지 · 옷만 v2) ── */
  .pnl-backdrop{position:fixed;inset:0;background:var(--dim-sheet);z-index:30;
                opacity:0;pointer-events:none;transition:opacity var(--duration-base) var(--ease)}
  .pnl-backdrop.open{opacity:1;pointer-events:auto}
  .slideover{position:fixed;top:0;right:0;bottom:0;width:min(500px,94vw);background:var(--bg-app);
             z-index:40;transform:translateX(102%);transition:transform var(--duration-base) var(--ease);
             box-shadow:var(--sh-float);border-left:0;
             display:flex;flex-direction:column;border-radius:var(--r-panel) 0 0 var(--r-panel);overflow:hidden}   /* v4 지침 P — 오른쪽 팝업 = 왼쪽 모서리만 16 · 테두리 = --sh-float 의 1px 선 하나(겹선 ✗) */
  .slideover.wide{width:min(820px,96vw)}
  .slideover.open{transform:none}
  aside.slideover:not(.open){box-shadow:none}   /* ★ 과제 414a — 닫힌 팝업(오른쪽 밖 102%)의 --sh-float 가 창 오른쪽 끝에 회색 띠로 비쳤다(v4 그림자 40 · 390 사진) · 열릴 때만 그림자 */
  /* ★ v1.96 (09-15 · 과제 54 · 대표 신고 「아래 모서리 부분 아래에 사각형이 남아 있습니다」) —
     ⚠ **둥근 모서리를 가진 상자는 자식을 그 모서리에 맞춰 잘라내야 한다.**
     발(`.pnl-foot`)은 회색 면을 칠하는데, 잘라내지 않으면 그 **사각형 모서리가 둥근 모서리 밖으로 삐져나온다**
     (v1.95 에서 발이 팝업 맨 아래로 내려오면서 처음 보였다 — 그 전에는 발이 카드 안이라 안 닿았다).
     `overflow:hidden` 한 줄이 답이다 — 몸(`.pnl-body`)이 스스로 `overflow:auto` 라 스크롤은 그대로다.
     ⚠ 팝오버(담당자 고르기 `umenu`)는 `document.body` 에 붙으므로 이 잘라내기에 안 걸린다. */
  /* ★★ v2.84 (과제 158 · 09-24 대표 결정 「B 지침도 다 수정 해 놔」 · 잣대 = 기획 시안 ③B) — **등록 · 수정 · 상세 = 오른쪽에서 나오는 팝업.**
     창 높이 전부 · 오른쪽에 붙음 · 머리 · 요약 띠 · 발은 늘 보이고 몸만 스크롤(발 = 142 의 sticky) · 폭 세 단 460 / 560 / 820(넓음 = 옛 .slideover.wide 820 · 새 값 0).
     가운데는 **견적 작성(qcompose · C안 예외)** · 확인 창 · 2층 창만(아래 줄 · #delBack · #odPickPop …). 옛 가운데 모달(560 · 88vh · 라운드)은 DESIGN §10 은퇴 표. */
  .slideover.modal{top:0;right:0;bottom:0;left:auto;width:min(560px,94vw);height:100vh;max-height:none;
      transform:translateX(102%);pointer-events:none;overflow:hidden;
      background:var(--bg-card);border:0;border-radius:var(--r-panel) 0 0 var(--r-panel);
      box-shadow:var(--sh-float);
      transition:transform var(--duration-base) var(--ease)}
  .slideover.modal.open{transform:none;pointer-events:auto}
  .slideover.modal.wide{width:min(820px,96vw)}
  /* ★ v1.92 (과제 49 · 대표 결정 B안) — **크기 3단만** : 좁게 460(확인·고르기) · 보통 560(기본) · 넓게 760(칸 많은 것).
     그 밖의 폭은 만들지 않는다(견적 작성 1240 만 예외 — 아래 줄). DESIGN.md §12-2 */
  .slideover.modal.narrow{width:min(460px,94vw)}
  .slideover.modal .pnl-body{padding:18px 22px 22px}
  .slideover.modal .pnl-body .card{border:0;box-shadow:none;background:transparent;padding:0;margin-bottom:0}
  body:has(.slideover.modal.open) .pnl-backdrop.open{background:var(--dim-sheet)}   /* v2.84 — 오른쪽 팝업 = 옅은 딤(뒤 목록이 보인다) */
  /* ══ ★ v1.92 (09-15 · 과제 49 · 대표 결정 **B안 「머리에 요약」**) — 팝업 부품 두 벌 ══
     ⓐ 요약 띠(.pnl-sum) : 머리 바로 아래 · 회색 면 · 12px · **값이 있을 때만**(hidden 이 기본).
        스크롤해도 붙어 있게 머리·발과 같이 flex-shrink:0. 그리는 자리 = core.js popSummary() 하나.
     ⓑ 구역 소제목(.pnl-sect) : 칸이 많은 폼을 묶는다. **구역이 둘 이상일 때만** 단다(하나뿐이면 군더더기).
     ⚠ 새 색·새 글자 크기를 만들지 않았다 — 전부 기존 토큰이다(--bg-fill · --fs-cap · --line). */
  .pnl-sum{display:flex;align-items:center;gap:8px;flex-wrap:wrap;flex-shrink:0;
      padding:9px 18px;background:var(--bg-fill);border-bottom:1px solid var(--line);
      font-size:var(--fs-cap);color:var(--text-2)}
  .pnl-sum[hidden]{display:none}
  .pnl-sum .sep{color:var(--text-3)}
  .pnl-sum .k{color:var(--text-2)}
  .pnl-sum .big{font-size:var(--fs-sm);font-weight:var(--weight-strong);color:var(--ink)}
  .pnl-sect{display:flex;align-items:center;gap:8px;margin:var(--gap-group) 0 var(--gap-tool);   /* ★ 과제 568 디자인수정 2 — 공용 한 줄(옛 18 / 4) · 묶음 경계 = --gap-group · 머리 → 첫 줄 = --gap-tool */
     
      font-size:var(--fs-cap);font-weight:var(--weight-strong);color:var(--text-2)}
  .pnl-sect:first-child{margin-top:0}
  .pnl-sect .cnt{font-weight:var(--weight-body);color:var(--text-2);flex:0 0 auto}   /* v2.94 (과제 144) — 옛 formsec-h 의 덧말 옷 그대로(광고주 「사업자등록증 기준」 · 담당자 「N명」) */
  .pnl-grp{margin-top:var(--gap-group)}  .pnl-grp:first-of-type{margin-top:0}   /* v2.94 (과제 144) — 구역 묶음 = 선 없이 사이만(옛 formsec 겹선 은퇴 · 선은 pnl-sect 한 줄) */
  .pnl-grp > .pnl-sect:first-child{margin-top:0}
  .pnl-sect::after{content:"";flex:1;height:1px;background:var(--line)}
  .pnl-head{display:flex;align-items:center;gap:10px;padding:0 18px;height:52px;box-sizing:border-box;
            background:var(--bg-card);border-bottom:1px solid var(--line-soft);flex-shrink:0}
  .pnl-head b{font-size:var(--fs-card);font-weight:var(--weight-strong);letter-spacing:var(--ls-head);color:var(--ink)}
  .pnl-head .x,button.xclose{margin-left:auto;background:transparent;color:var(--text-2);border:0;
               width:28px;height:28px;flex:0 0 auto;border-radius:var(--r-ctl);padding:0;font-size:var(--fs-card);
               line-height:1;font-weight:var(--weight-body);box-shadow:none;display:flex;align-items:center;justify-content:center}
  .pnl-head .x:hover,button.xclose:hover{background:var(--bg-hover);color:var(--text)}
  .pnl-body{flex:1;overflow-y:auto;padding:18px 20px 36px}
  .pnl-body .card{margin-bottom:14px}
  .pnl-body .side{position:static}
  .pnl-body th{top:0}
  .slideover .grid2{grid-template-columns:1fr}
  .slideover:not([data-panel="qcompose"]) .pnl-body .row{flex-direction:column;align-items:stretch}
  /* ★ v1.97 (과제 55 · 대표 결정 B안) — 클래식 폼(`.row` + label + input)도 **두 칸 격자**로.
     종전에는 모달 안에서 한 칸씩 세로로만 쌓여(width:100%) 팝업이 길어졌다.
     ⚠ `style="flex:2"` 같이 **넓게 쓰라고 적어 둔 칸**은 한 줄을 다 쓰게 옮겨 준다(뜻을 지킨다).
     ⚠ 견적서 작성(qcompose)은 예외 그대로 — 따로 논의(과제 52). */
  .slideover.modal:not([data-panel="qcompose"]) .pnl-body .row{display:grid;
      grid-template-columns:1fr 1fr;gap:14px 16px;align-items:start}
  .slideover.modal:not([data-panel="qcompose"]) .pnl-body .row>div{width:auto;flex:none !important;min-width:0}
  .slideover.modal:not([data-panel="qcompose"]) .pnl-body .row>div[style*="flex:2"],
  .slideover.modal:not([data-panel="qcompose"]) .pnl-body .row>div[style*="flex: 2"],
  .slideover.modal:not([data-panel="qcompose"]) .pnl-body .row>div[style*="flex:1.4"],
  .slideover.modal:not([data-panel="qcompose"]) .pnl-body .row>div:has(textarea){grid-column:1 / -1}
  .slideover.modal:not([data-panel="qcompose"]) .pnl-body .row>div>label{display:block;margin:0 0 5px;
      font-size:var(--fs-sm);color:var(--text-2);font-weight:var(--weight-strong)}
  .slideover.modal:not([data-panel="qcompose"]) .pnl-body .row>div>input[type="date"]{max-width:none}
  @media(max-width:620px){ .slideover.modal .pnl-body .row{grid-template-columns:1fr} }
  .slideover:not([data-panel="qcompose"]):not(.modal) .pnl-body .row>div{width:100%;flex:none !important}
  .pnl-body .row>div[style*="display:none"],.pnl-body .row>div[style*="display: none"]{display:none !important}
  .slideover[data-panel="adv"] .row{flex-direction:column;gap:0}
  .slideover[data-panel="adv"] .row>div{flex:none;width:100%;min-width:0}
  body.pnl-push .wrap{padding-right:var(--pnl-w)}
  body.pnl-push #toasts{right:calc(var(--pnl-w) + 20px)}
  body.pnl-push #logDrawer{right:calc(var(--pnl-w) + 16px)}
  body.pnl-push .pnl-backdrop.open{background:transparent;pointer-events:none}
  body.pnl-push .slideover{box-shadow:var(--sh-float)}
  .wrap{transition:padding-right var(--duration-base) var(--ease)}

  /* ── 토스트 (우하단) ── */
  #toasts{position:fixed;right:20px;bottom:20px;z-index:60;display:flex;flex-direction:column;
          gap:10px;max-width:min(430px,92vw);pointer-events:none}
  .toast{pointer-events:auto;display:flex;gap:10px;align-items:flex-start;
         background:var(--bg-card);border:1px solid var(--line);border-radius:var(--r-card);
         box-shadow:var(--sh-float);padding:12px 14px;font-size:var(--fs-body);line-height:1.5;
         white-space:pre-wrap;word-break:keep-all;overflow-wrap:anywhere;animation:toastIn var(--duration-base) var(--ease)}   /* ★ 과제 584 — 쪽지도 .hint 와 같은 꺾음(390 「0개교 / 면」 ✗) · v564 ⓓ */
  @keyframes toastIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
  .toast.out{opacity:0;transform:translateY(6px);transition:all var(--duration-base) var(--ease)}
  .toast::before{content:"";width:3px;border-radius:2px;flex-shrink:0;align-self:stretch}
  .toast.good::before{background:var(--ok)}
  .toast.err::before{background:var(--bad)}
  .toast.hint::before{background:var(--warn)}
  .toast.good{border-color:rgba(12,81,50,.35)}
  .toast.err{border-color:rgba(176,32,15,.35)}
  .toast.hint{border-color:rgba(79,71,0,.30)}
  /* ★ v1.19 (야간 UX R01 · 발견 103) — 알림 쪽지는 **클릭을 가로채지 않습니다.**
     우하단에 뜬 안내가 그 아래 단추(견적 작성 팝업의 「직접 학교 선택」·하단 바 단추) 위에 그대로 앉아,
     쪽지를 ✕ 로 닫기 전에는 단추가 눌리지 않았습니다(실측 : 단추 가운데를 짚으면 쪽지가 잡혔다).
     쪽지 자신의 단추(✕ · 되돌리기)만 누름을 받고, 나머지는 그대로 아래로 통과합니다.
     ⚠ 위 `.toast{pointer-events:auto}` 는 손대지 않고 여기서 덮습니다 — 그 줄에는 옛 크기 값이 함께 들어 있어
       한 글자만 고쳐도 「새 크기를 발명했나」 검사에 걸립니다(값은 하나도 바꾸지 않았는데도). */
  .toast{pointer-events:none}
  .toast .x,.toast .tact{pointer-events:auto}
  .toast .x{background:none;border:0;color:var(--text-2);padding:0 2px;font-size:var(--fs-card);height:auto;
            cursor:pointer;flex-shrink:0;font-weight:var(--weight-body);border-radius:var(--r-ctl);box-shadow:none}
  .toast .x:hover{color:var(--ink);background:none}
  /* v0.97 — 알림에 얹는 단추(되돌리기). 3초 뒤 스스로 사라집니다 (08-25 대표 결정) */
  .toast .tact{background:none;border:1px solid var(--line-2);border-radius:980px;
      color:var(--accent);font-size:var(--fs-sm);font-weight:var(--weight-medium);
      padding:2px 10px;flex-shrink:0;cursor:pointer;white-space:nowrap}
  .toast .tact:hover{background:var(--bg-hover)}
  .toast .tact:disabled{color:var(--text-3);cursor:default}
  /* ★ 과제 572 (571 걷기 R1 · 디자이너 1) — 알림 단추 안 키캡(⌘⇧N · ⌘Z) = 회색 · 옛 = 주 단추 키캡 규칙(흰 글자)이 .tact 에도 걸려 안 보였다 */
  .toast .tact .kbds{margin-left:var(--gap-tool)}
  .toast .tact .kbd{background:color-mix(in srgb, currentColor 18%, transparent);color:var(--text-3);box-shadow:none;opacity:.9}
  .toast .tact .kbd-plus{background:transparent;color:var(--text-3);box-shadow:none}

  /* ── 로딩 피드백 ── */
  /* ★ v2.89 (과제 160 · 로딩 한 벌) — **저장 중 단추 = 작은 동그라미 + 「…하는 중」**(core.js btnBusy).
     옛 모양(글자를 투명하게 · 가운데 동그라미만)은 「눌렸나?」를 말하지 못했다. 원래 글 · 키캡은 `.bkeep` 안에 그대로 두었다가 끝나면 되돌린다.
     동그라미 색 = 단추 글자색(currentColor) — 검정 단추 위에선 흰색(--text-on-brand) · 흰 단추 위에선 글자색. 새 색 0. */
  button.busy{cursor:progress;display:inline-flex;align-items:center;justify-content:center;gap:8px}
  button.busy:disabled{opacity:1}
  button .bkeep{display:none}
  button .bspin{width:14px;height:14px;flex:0 0 auto;border-radius:50%;
    border:2px solid color-mix(in srgb, currentColor 35%, transparent);border-top-color:currentColor;
    animation:spin .7s linear infinite}
  @keyframes spin{to{transform:rotate(360deg)}}

  /* ★★ v1.69 (과제 21 · 대표 「로딩 중 표시를 해 주세요」) — **기다리는 자리의 뼈대 줄.**
     새 색·새 크기는 없습니다 — 줄 키(44px)·좌우 여백(24px)·회색 면(--bg-fill)·라운드(--r-ctl) 전부
     이미 쓰던 값입니다. 목록이 올 자리에 **같은 모양의 회색 줄**을 깔아 「빈 화면」을 없앱니다.
     ⚠ 0.3초 안에 끝나는 것에는 아예 안 그립니다(core.js skelOn — 깜빡임 금지).
     ⚠ 화면 전체를 덮는 검은 딤은 쓰지 않습니다(팝업 딤과 겹칩니다 — 과제 21 금지).
     ★ v2.89 (과제 160) — 머리줄이 있는 목록은 **표 칸 그대로**(`.sktbl` : 머리줄 사본 + `.clrow.skrow` 9줄 · 칸 수 · 격자 = 머리줄).
       막대 = `--bg-fill` → `--line` 빛이 천천히 지나감(1.4초) · 움직임 줄임이면 멈춘 회색. 건수 칸 · 한 줄 값 자리도 같은 막대. */
  .skel{padding:0}
  .skel:not(.sktbl) .skrow{display:flex;align-items:center;gap:12px;min-height:44px;padding:4px 24px;
      border-bottom:1px solid var(--line-soft)}
  .skel.sktbl{pointer-events:none}
  .skel.sktbl .skrow > div{display:flex;align-items:center}
  .skb{display:inline-block;vertical-align:middle;max-width:100%;height:12px;border-radius:var(--r-ctl);
      background:linear-gradient(90deg, var(--bg-fill) 0%, var(--line) 50%, var(--bg-fill) 100%);background-size:200% 100%;
      animation:skelShine 1.4s ease-in-out infinite}
  .skb.skcnt{width:34px}
  .skb.skline{width:160px}
  @keyframes skelShine{0%{background-position:100% 0}100%{background-position:-100% 0}}
  /* 팝업 속성 줄 자리 — 이름 칸 좁고 값 칸 넓게 (읽는 상세와 같은 비율) */
  .skel.skprops .skrow{padding:6px 0;border-bottom:1px solid var(--line-soft)}
  @media (prefers-reduced-motion:reduce){ .skb{animation:none;background:var(--bg-fill)} }

  /* ★ v2.89 (과제 160) — **처음 열 때 막**(#bootSplash · index.html 맨 앞 정적 요소).
     로고(사이드 메뉴의 그 로고) · 「좋은광고연구소」 · 「GOODADLAB ERP」 · 가는 진행 막대(파랑 --accent · 왔다 갔다) · 「연결하는 중…」.
     ⚠ 0.3초 안에 끝나면 안 보인다(opacity 0 으로 시작 → 0.3초 뒤 보임) · 부트가 끝나면 core.js bootSplashOff 가 걷는다.
     ⚠⚠ 걷는 코드가 아예 안 돌아도(스크립트 오류) **15초 뒤 CSS 가 스스로 걷는다**(안 보임 + 누르기 안 막음) — 막이 남아 화면을 가리는 일 0. */
  #bootSplash{position:fixed;inset:0;z-index:9999;background:var(--bg-app);display:flex;flex-direction:column;
    align-items:center;justify-content:center;gap:18px;opacity:0;
    animation:bsIn .2s var(--ease) .3s forwards, bsOut .3s var(--ease) 15s forwards}
  #bootSplash .bs-brand{display:flex;align-items:center;gap:12px}
  #bootSplash .bs-mark{width:40px;height:40px;object-fit:contain}
  #bootSplash .bs-name{font-size:var(--fs-card);font-weight:var(--weight-strong);color:var(--text)}
  #bootSplash .bs-sub{font-size:var(--fs-sm);color:var(--text-2)}
  #bootSplash .bs-bar{position:relative;width:220px;height:4px;border-radius:var(--r-ctl);background:var(--bg-fill);overflow:hidden}
  #bootSplash .bs-bar > i{position:absolute;left:0;top:0;bottom:0;width:45%;border-radius:var(--r-ctl);background:var(--accent);
    animation:bsBar 1.2s ease-in-out infinite alternate}
  #bootSplash .bs-msg{font-size:var(--fs-sm);color:var(--text-2)}
  @keyframes bsIn{to{opacity:1}}
  @keyframes bsOut{to{opacity:0;visibility:hidden;pointer-events:none}}
  @keyframes bsBar{from{left:0}to{left:55%}}
  @media (prefers-reduced-motion:reduce){ #bootSplash .bs-bar > i{animation:none} }

  /* ── 로그 서랍 ── */
  #logDrawer{position:fixed;right:16px;top:16px;width:min(560px,94vw);z-index:50;display:none;
             background:var(--bg-card);border:1px solid var(--line);border-radius:var(--r-panel);
             box-shadow:var(--sh-float);padding:12px 14px}
  #logDrawer.open{display:block}
  #logDrawer .log{max-height:46vh}

  /* ── 툴바·검색 ── */
  /* ★ v1.57 (대표 지시 09-12) — 도구 줄(고르기·검색·건수·＋새…)이 **표 카드 밖 · 제목 아래**로 나왔다.
     그래서 이 규칙들에서 `.card` 요구를 뗀다 — 어디에 놓이든 컨트롤 모양이 같다. */
  h3 .tools{margin-left:auto;display:flex;align-items:center;gap:8px;
    flex:0 0 auto;max-width:100%;flex-wrap:wrap}
  h3 button{float:none !important;margin:0 !important}
  h3 .tools button{height:32px;padding:0 14px}
  /* ★ 과제 117 (09-22 감사 4회차 ① · 검토자 실측) — **`h3 .tools input` 이 빠져 있었다.**
     그래서 지출 도구 줄의 월 고르기(`#spFMonth`)만 **34px** 이었다(다른 컨트롤은 전부 32).
     ⚠⚠ **`>` (직계 자식) 한 글자가 핵심이다** (09-22 검토자 재검토 · 막음 1건)
       검색칸도 `.tools` **안**에 있다(`span.search > input`). 그래서 `h3 .tools input` 으로 잡으면 **검색칸 열 곳까지 덮는다** —
       높이는 같아도 같은 규칙이 함께 정하는 `padding`·`width`·`box-shadow` 가 달라져 **돋보기 아이콘 위로 글자가 올라탄다.**
       `#spFMonth` 는 `.tools` 의 **직계 자식**이고 검색칸은 한 겹 안이라 `>` 하나로 갈린다.
       ⚠ 아래쪽 `h3 .tools input` 규칙(테두리 색·그림자)은 **원래 있던 것**이고 검색칸에도 맞는 값이라 그대로 둔다.
     ★ 한 자리에서 끝나고, **앞으로 도구 줄에 `input` 을 넣어도 32 로 태어난다.** */
  h3 .tools select,h3 .tools > input,h3 .tools > .tk-left > input,.filterbar select,.filterbar input{
    height:32px;width:auto;flex:0 0 auto;font-size:var(--text-sm);padding:0 10px;box-shadow:var(--sh-btn)}
  h3 .tools select{max-width:190px}
  .filterbar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin:0 0 12px}
  .filterbar .search{flex:0 0 clamp(150px,14vw,200px)}
  .filterbar .search input{width:100%;padding:0 12px 0 30px}
  .search{position:relative;display:block;flex:0 0 clamp(190px,20vw,270px)}
  .search input{height:32px;padding:0 12px 0 30px;font-size:var(--text-sm);appearance:none;-webkit-appearance:none;
    box-shadow:var(--sh-btn);
    background-image:none}
  .search::before{content:"";position:absolute;left:10px;top:50%;width:14px;height:14px;margin-top:-7px;pointer-events:none;z-index:1;   /* ★ 과제 414a (1차 검토 #1) — 돋보기 = 마스크(--ic-search) + 글자 회색 토큰 · 옛 = 칸 배경 그림(#94939C · 선 2) */
      background:var(--text-3);-webkit-mask:var(--ic-search) center / contain no-repeat;mask:var(--ic-search) center / contain no-repeat}
  .search input::-webkit-search-cancel-button{cursor:pointer}
  /* ★★ v3.4 (과제 91 · 사양 §3-2) — 도구 줄 = **큰 상자 안 첫 줄**. 안여백 16/24 · 아래 1px `--line` · gap 8.
     할 일 화면(`.tk-tools`)과 **같은 값**이다 — 두 곳이 어긋나지 않게 값만 맞추고 이름은 그대로 둔다(규칙 110).
     되돌리기 = `boot.js toolsAboveList` 의 `return` 한 줄을 지우면 v1.57 「카드 밖」 자리로 돌아간다. */
  h3.toolsonly{margin:0;padding:16px 24px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:8px;flex-wrap:wrap}
  h3.toolsonly > .tools{gap:8px}
  /* 도구 줄이 상자 안으로 들어오면 카드의 위 여백이 두 번 생긴다 — 도구 줄을 가진 카드는 위 여백을 0 으로. */
  .card:has(> h3.toolsonly){padding-top:0;padding-left:0;padding-right:0;overflow:hidden}
  .card:has(> h3.toolsonly) > *:not(h3.toolsonly):not([id$="List"]):not([id$="list"]):not(.scrolltbl){margin-left:24px;margin-right:24px}
  /* 표 상자는 도구 줄 아래 **20** 을 띄운다 — 할 일 화면(`#taskList{padding:20px 24px 24px}`)과 같은 값.
     ⚠ 안 띄우면 도구 줄의 아래선과 표 상자의 위선이 붙어 **선이 둘로 보인다**(v1.57 이 카드 밖으로 옮긴 그 까닭). */
  /* ★★ v3.4 (과제 119 · 09-22 감사) — **목록은 제 상자를 갖는다. 한 자리에서.**
     과제 90 이 이 상자를 **목록 id 마다 따로** 줘서 넷(`#campList`·`#qListAll`·`#odListAll`·`#spListAll`)만 받았고,
     광고주·상담·거래처·인사·계산서는 **테 없이 떠 보였다**(감사가 눈으로 찾았다 — 관문 어디에도 이것을 보는 항목이 없었다).
     ⚠ 새 목록을 만들 때 **여기에 얹히게** 두십시오 — id 마다 또 박으면 다음 화면이 또 빠집니다.
     ⚠ `overflow` 는 **여기서 정하지 않는다** : `.scrolltbl` 은 `auto`(가로로 넓은 거래처·인사가 잘리면 안 된다),
        `clrow` 목록 넷은 제 규칙에서 `hidden` 이다. 값을 재 보고 화면마다 둔 것이지 빠뜨린 것이 아니다.
     ⛔⛔ **`:not(.tk-box)` 를 지우지 마십시오** — 할 일(`#taskBox.card.tk-box`)은 **잣대**다.
        `#taskList` 가 그 카드의 직계 자식이라, 빼지 않으면 **잣대가 소리 없이 함께 움직인다**
        (09-22 실측 : 테 0 → 1px · 여백이 바뀌어 안내문이 네모 상자 안으로 들어갔다).
        감사 다섯 회차가 전부 「할 일에서는 이런데 여기서는 이렇다」로 적혔다 — **자가 움직이면 그 다섯이 흔들린다.**
        ★ 할 일에도 상자를 줄지는 **따로 결정할 일**이다(작업자 질문 Q-047 · 사양 §4 「할 일 = 기준. 손대지 않는다」).
        `tk-box` 는 `app/index.html:1788` **한 곳에만** 붙는다(작업자가 전수로 확인). */
  /* ① 여백은 **할 일까지 포함해 종전 그대로** — `#taskList` 도 `.scrolltbl` 이라 v3.4(과제 91)부터 이 값을 받아 왔다.
        여기서 빼면 잣대의 여백이 24 → 0 으로 바뀐다(09-22 실측 — 내가 한 번 그렇게 만들었다). */
  .card:has(> h3.toolsonly) > .scrolltbl{margin:20px 24px 24px}
  /* ② 상자(테·라운드)와 아래 여백 20 은 **할 일을 뺀** 나머지에만. */
  .card:has(> h3.toolsonly):not(.tk-box) > .scrolltbl,
  .card:has(> h3.toolsonly):not(.tk-box) > [id$="List"],
  .card:has(> h3.toolsonly):not(.tk-box) > [id$="ListAll"]{
    margin:20px var(--card-pad-x) 20px;border:1px solid var(--line);border-radius:var(--r-ctl)}   /* v2.70 (과제 132 · G-099) — 위 20 은 그대로 : 도구 줄 아래선과 표 상자 위선이 붙으면 선이 둘로 보인다(관문 도구줄 v227 ③) */
  /* ★ v2.73 (과제 139 · 09-23 대표 「표 위에 버튼과 표의 여백이 안 맞네. 표랑 맞춰」) — **도구 줄은 표 상자 끝에 맞춘다.**
     표 상자 = 어느 폭이든 노트북 기준 한 벌(바깥 --card-pad-x 24 · 133 대표 3차) · 도구 줄 = 바깥 0 + 제 안여백 24 → 검색칸 왼끝 = 표 상자 왼끝 · ＋ 오른끝 = 표 상자 오른끝.
     (133 대표 지적 1 의 「도구 줄 x = 할 일」 은 이것으로 뒤집혔다 — 표가 넓어졌으니 도구 줄이 표를 따른다 · 할 일은 도구 줄과 표 사이에 카드가 끼어 따로 논다) */
  /* ★ v2.71 (과제 133 · 대표 지적 2·3차 ⑩⑭) — 발주 두 칸 화면(캠페인 목록 · 학교 목록 · 학교 검색 줄)도 표 상자와 같은 x(어느 폭이든 바깥 --card-pad-x) */
  #order #odV3Wrap{margin-left:var(--card-pad-x);margin-right:var(--card-pad-x)}
  h3.toolsonly .tools{margin-left:0;flex:1 1 auto;flex-wrap:nowrap}
  /* ★ v2.71 (과제 133 · 09-23 대표 지적 2차 ⑨ 「＋ 는 언제나 첫 줄 맨 오른쪽」) — 줄이 넘치면 **왼쪽 무리만** 다음 줄로.
     core.js toolsStdOrder() 가 ①검색 ②필터 ③내 것 을 <span class="tk-left"> 로 감싼다(요소는 옮겨 담기만 · id·핸들러·키보드 차례 그대로).
     오른쪽 무리(건수 · 곁 단추 · 화면 선택 · ＋)는 줄지 않고 한 줄에 선다. (옛 판 = 도구 줄 통째로 wrap → 맨 끝 ＋ 가 먼저 떨어졌다) */
  h3.toolsonly .tools > .tk-left{display:flex;flex-wrap:wrap;align-items:center;gap:8px;flex:0 1 max-content;min-width:0}   /* 기본 = 내용 전체 폭 · 넘칠 때만 줄어 안에서 줄바꿈 */
  h3.toolsonly .tools > :not(.tk-left):not(.tk-sp){flex-shrink:0}
  h3.toolsonly .tools{align-items:flex-start}   /* 왼쪽 무리가 두 줄이 되어도 오른쪽 무리는 **첫 줄**에 선다 */
  h3.toolsonly .tools > [id$="Count"]{display:inline-flex;align-items:center;min-height:32px}   /* 건수 글자는 첫 줄(컨트롤 키 32 · §9-0) 가운데 */
  h3.toolsonly .tools > .tk-left > .search{width:clamp(190px,20vw,270px)}   /* 묶음이 제 폭을 셀 때 검색칸을 제 폭(§6-2 clamp 그대로)으로 세게 — flex-basis 만 있으면 좁게 세어 한 줄에 들어가는데도 꺾였다(실측) */
  /* ★★ 과제 106 (09-22 감사 ③) — **건수부터 오른쪽 무리**(할 일 도구 줄과 같은 모양).
     할 일은 `index.html` 의 `<span class="tk-sp">`(flex:1 1 auto) 한 칸이 왼쪽 무리와 오른쪽 무리를 갈라
     [검색·필터·내 할 일] ⟨채움⟩ [건수·보기·＋ Add To-Do] 로 선다(실측 오른쪽 빈자리 24 = gap 하나).
     다른 화면은 상자만 늘고 **안에 채움이 없어** 오른쪽이 342~697px 씩 비고 주 단추가 가운데에 떴다(09-22 실측).
     ⚠ 마크업에 빈 칸을 열 군데 넣지 않고 **여기 한 줄**로 한다 — 되돌리려면 이 줄만 지우면 된다.
     ⚠ 잡는 자리 = 건수 `<span id="○Count" class="muted">`(§11-2 ⑤) — 열 화면이 모두 갖고 있다. */
  /* v2.71 (과제 133) — 옛 「건수 앞 margin-left:auto」 은퇴 : core.js toolsStdOrder() 가 할 일과 같은 ⟨채움⟩ <span class="tk-sp"> 를 끼운다 */
  h3.toolsonly .search{flex:0 1 clamp(190px,20vw,270px)}
  h3 .tools .usel{width:auto;min-height:32px;height:32px;padding:0 6px 0 10px;
      border-radius:var(--r-ctl);flex:0 0 auto;font-size:var(--text-sm)}
  /* ★★ v1.58 (대표 지시 09-12) — **도구 줄의 윤곽선은 「내 할 일」 단추 하나로 통일.**
     고르기(select)·찾기(search)는 「적는 칸」이 아니라 **단추 무리**다. 그래서 진한 입력칸 선
     (--line-input)이 아니라 단추와 같은 **--line** 을 쓰고, 그림자도 --sh-btn 하나로 맞춘다.
     ⚠ --line-input 은 **등록·수정 폼의 적는 칸** 선이다(DESIGN.md §1-1) — 과제 479(G-675) 부터 회색 얇은 선(--line 보다 한 단 짙음 · hover 에 씀).
     실측(09-12) : 한 줄 안에 #8A8A8A(셀렉트·검색) / #E3E3E3(단추) 두 가지가 섞여 있었다. */
  h3 .tools select,h3 .tools input,.filterbar select,.filterbar input{
      border-color:var(--line);box-shadow:var(--sh-btn)}
  h3 .tools select:hover,h3 .tools input:hover,.filterbar select:hover,.filterbar input:hover{
      border-color:var(--line-input)}
  /* ★★ v2.71 (과제 133 · DESIGN §11-2 · 규칙 124 「공용이 할 일을 베낀다」) — **도구 줄 옷 = 할 일 #tkTools 그대로.**
     할 일 규칙(.tk-search · #tkTools button.ghost · .tk-tgl[aria-pressed])의 값을 **베꼈다** — 할 일 CSS 는 잣대라 건드리지 않는다.
     ① 검색 : 그림자 0 · 돋보기 = 감싸는 span 의 ::before(입력칸 배경 그림 은퇴) · 안여백 0 10px 0 30px · 초점 = 파랑 테 + 링
     ⑤ 곁 단추 · ③ 토글 : 그림자 0 · 14px(옛 mini 13px 은퇴 — 할 일 [내 할 일]과 같은 크기) · 호버 = --bg-fill
     ③ 켜짐 = aria-pressed="true" → --bg-active · 파랑 테·글자(할 일과 같다 · 옛 --accent-soft 바탕 은퇴)
     고르기 칸(select)·월 칸은 134 가 [필터] 팝으로 옮겼다(옛 칸 = 숨김 · 월 칸 = 팝 안) — 아래 「필터 팝」 절.
     ★ v2.74 (과제 134) — [필터] 단추는 `.tk-fwrap` 안에 있어 `> .tk-left > button.ghost` 에 안 걸린다 → 같은 규칙에 선택자만 더했다(값 0 추가). */
  h3.toolsonly .tools .search input{height:32px;padding:0 10px 0 30px;box-shadow:none;border:1px solid var(--line-tool);border-radius:var(--r-pill);background:var(--bg-card)}   /* v4 지침 F-3 — 검색 = 알약(999 · --line-tool) */
  h3.toolsonly .tools .search input:hover{border-color:var(--line-tool)}
  h3.toolsonly .tools .search input:focus{border-color:var(--accent);box-shadow:var(--ring)}
  h3.toolsonly .tools .search::before{content:"";position:absolute;left:10px;top:50%;width:14px;height:14px;margin-top:-7px;pointer-events:none;
      background:var(--text-3);-webkit-mask:var(--ic-search) center / contain no-repeat;mask:var(--ic-search) center / contain no-repeat}
  h3.toolsonly .tools select,h3.toolsonly .tools > input,h3.toolsonly .tools > .tk-left > input{box-shadow:none}
  h3.toolsonly .tools > button.ghost,h3.toolsonly .tools > .tk-left > button.ghost,h3.toolsonly .tools .tk-fwrap > button.ghost{height:32px;padding:0 14px;font-size:var(--text-sm);box-shadow:none;border:1px solid var(--line);border-radius:var(--r-ctl);
      background:var(--bg-card);display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
  h3.toolsonly .tools > button.ghost:hover,h3.toolsonly .tools > .tk-left > button.ghost:hover,h3.toolsonly .tools .tk-fwrap > button.ghost:hover{background:var(--bg-fill);border-color:var(--line)}
  h3.toolsonly .tools > button.ghost[aria-pressed="true"],h3.toolsonly .tools > .tk-left > button.ghost[aria-pressed="true"],h3.toolsonly .tools .tk-fwrap > button.ghost[aria-pressed="true"]{background:var(--bg-active);border-color:var(--accent);color:var(--accent)}
  /* ★ v1.57 — 제목 아래로 나온 도구 줄. 카드가 아니라 **페이지의 줄**이라 좌우 여백이 없다. */
  h3.toolsonly.pagetools{margin:0 0 16px;padding:0;background:transparent}
  h3.toolsonly.pagetools .tools{gap:8px}
  /* 도구 줄이 빠져 **목록만 남은 카드**는 여백을 0 으로 — 줄의 24px 이 그대로 카드 여백이 된다.
     (목록이 이미 음수 바깥마진으로 카드 끝까지 나가 있는 화면은 boot.js 가 이 클래스를 안 붙인다) */
  .card.listcard{padding:0;overflow:hidden}
  .card.listcard>p.muted,.card.listcard>.hint,.card.listcard>.err{margin:16px 24px}

  /* ── 세그먼트 = 보기 전환 `.seg` — ★ v4(과제 414c · DESIGN §6-9 ② · 지침 T-2) : 알약 줄 바깥 32 · --bg-fill · 1px --line · 안 2 · 안 알약 26 · 고른 것 = 흰 + 1px --line + 인디고 · 그림자 0
       한 벌 — 자리마다 높이를 따로 주지 않는다(옛 v3 = --bg-side 트랙 · --r-ctl · 26 · 흰 칩 + ink 600 + --sh-card · .seg-inline 30/24 · .tk-calseg 30/24) ── */
  #cSeg,.seg{display:flex;align-items:center;box-sizing:border-box;height:var(--h-ctl);background:var(--bg-fill);border:1px solid var(--line);border-radius:var(--r-pill);padding:2px;gap:2px}
  #cSeg button,.seg button,h3 .seg button{border:1px solid transparent;border-radius:var(--r-pill);height:calc(var(--h-ctl) - 6px);padding:0 12px;font-size:var(--fs-sm);
      background:transparent;color:var(--text-2);font-weight:var(--weight-medium);box-shadow:none}
  #cSeg button:hover,.seg button:hover{background:var(--bg-hover);color:var(--text)}
  #cSeg button.on,.seg button.on{background:var(--bg-card);border-color:var(--line);color:var(--accent);font-weight:var(--weight-medium);box-shadow:none}
  .card h3 .tools #cSeg,.card h3 .tools .seg{flex:0 0 auto}
  /* ★ v1.05 — 제목 「바로 오른쪽」에 붙는 세그먼트 (.tools 의 margin-left:auto 를 타지 않는다) · 높이 = 위 한 벌(414c) */
  .card h3 .seg.seg-inline{flex:0 0 auto;margin-left:12px}
  /* ── ★ 과제 414c — 알약 탭 `.ptab` 한 벌(DESIGN §6-9 ① · 지침 T-1 · 디자인시스템v4/css/components.css T-1) — 탭 = 다른 자료(거르개 줄 · 카드 안 탭) · 보기(.seg)와 섞지 않음
       옛 클래스(ghost · mini)는 그대로 두고(더함만) 이 규칙이 이긴다(> button.ptab · 뒤에 옴) · 마크업 · 키 = core.js ptabHtml · ptabKeys 한 자리 ── */
  .ptabs{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin:0 0 12px;padding:0 0 12px;border-bottom:1px solid var(--line-soft)}
  .ptabs > button.ptab{display:inline-flex;align-items:center;gap:6px;flex:none;box-sizing:border-box;height:var(--h-tab);padding:0 12px;border:1px solid transparent;border-radius:var(--r-pill);
      background:transparent;color:var(--text-2);font-family:inherit;font-size:var(--fs-body);font-weight:var(--weight-medium);white-space:nowrap;cursor:pointer;box-shadow:none}
  .ptabs > button.ptab:hover{background:var(--bg-hover);border-color:transparent;color:var(--text)}
  .ptabs > button.ptab[aria-selected="true"]{background:var(--accent-soft);border-color:var(--accent-line);color:var(--accent);font-weight:var(--weight-strong)}
  .ptabs > button.ptab .cnt{display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;min-width:var(--h-chip);height:var(--h-chip);padding:0 6px;border-radius:var(--r-pill);
      background:var(--bg-fill);color:var(--text-2);font-size:var(--fs-cap);font-weight:var(--weight-strong);font-variant-numeric:tabular-nums;line-height:1}
  .ptabs > button.ptab[aria-selected="true"] .cnt{background:var(--fill-brand);color:var(--on-fill)}
  /* ── ★ 과제 414c — 길잡이 상자 `.hint.guide`(DESIGN §6-9 ③ · 지침 G-1) : 첫 사용 · 흐름 안내만 · 그 밖 .hint = 칠 없음 그대로 ── */
  .hint.guide{display:flex;gap:10px;align-items:flex-start;margin:12px 0;padding:12px 14px;border:0;border-radius:var(--r-ctl);background:var(--accent-soft);box-shadow:inset 0 0 0 1px var(--accent-line);color:var(--text);font-size:var(--fs-body);line-height:1.6}
  .hint.guide > svg{flex:none;width:var(--sz-ic);height:var(--sz-ic);margin-top:3px;color:var(--accent);stroke-width:var(--ic-stroke)}
  .hint.guide > .guide-b{min-width:0}
  /* ★ 414c 2차(1차 검토 ③) — 목록 상자(.scrolltbl · 현장 .odv3-list)가 길잡이 하나만 품으면 상자 테를 걷는다 = 카드 안 한 겹(갤러리 7 · 옛 = 테 두 겹) */
  .card:has(> h3.toolsonly):not(.tk-box) > :has(> .hint.guide:only-child),.scrolltbl:has(> .hint.guide:only-child),.odv3-list:has(> .hint.guide:only-child){border-color:transparent;background:transparent;box-shadow:none}   /* 앞 = 「도구 줄 카드 안 목록 상자」 테 규칙(무게 0,4,1)을 이긴다 */  .card h3 .tools #cNewToggle{flex:0 0 auto}
  #cFStatus{display:none}

  /* ── 캠페인 마스터-디테일 ── */
  #campBar{display:flex;align-items:center;gap:14px;margin:0 0 0 auto;flex-wrap:wrap;justify-content:flex-end}
  /* ★ 과제 268 — 캠페인 제목 아래 14 → 모든 페이지와 같은 12(h2 기본 · 할 일 기준) · 옛 줄 = #camp>h2{margin-bottom:14px} */
  h2 #campCount{font-size:var(--fs-sm);font-weight:var(--weight-body);letter-spacing:0;color:var(--text-2);
      align-self:center;font-variant-numeric:tabular-nums}
  /* ★ v1.15 (09-10 대표 결정) — 래퍼(#campMD·.mdwrap)는 목록 한 열. 상세 칸(#campSide·.mdside)의
     위치·폭·딤은 아래 「v1.15 — 상세 = 가운데 팝업」 블록이 정합니다. nosel = 선택 없음 = 상세 숨김(스위치 그대로). */
  #campMD{display:grid;grid-template-columns:minmax(0,1fr);gap:16px;align-items:start}
  #campMD .card{margin-bottom:0}
  #campMD.nosel #campSide{display:none}
  #campBar #cNewToggle{height:32px;padding:0 16px;font-size:var(--fs-body);font-weight:var(--weight-strong)}
  #campSide{display:flex;flex-direction:column;gap:14px}
  #campSide .card,#ciBody .card{margin-bottom:0;overflow-x:auto;min-width:0;max-width:100%;border-radius:var(--r-panel)}
  #campSide .cdstats,#ciBody .cdstats{grid-template-columns:repeat(2,minmax(0,1fr))}
  /* v0.99 (점검 ⑧) 의 「셋씩 두 줄」 접기는 396px 패널용이었습니다 — 팝업(920px)에서는 한 줄로 폅니다(v1.15). */
  #campSide .cdstagerow,#ciBody .cdstagerow{display:flex;flex-wrap:wrap;gap:16px;align-items:center}
  /* ★ v1.26 (야간 UX 루프 R09 · 발견 901 = 402) — 위 줄의 「한 줄로 폅니다」는 팝업 폭(920)만 보고
     정한 것이었습니다. 실제로 체크가 놓이는 칸은 팝업 **왼쪽 단 391px** 뿐이고, 여섯 개를 한 줄에
     넣으려면 439px 이 필요해 「결제」 하나만 아래로 떨어졌습니다(1440·1280 실측 · 1024 에서는 두 단이
     위아래로 쌓여 844px 가 되므로 멀쩡했습니다 — 넓은 화면일수록 어긋나 보이는 이유).
     → v0.99 의 「셋씩 두 줄」로 되돌립니다. 폭과 무관하게 3×2 로 가지런합니다. 간격은 윗줄 것 그대로. */
  #campSide .cdstagerow,#ciBody .cdstagerow{display:grid;grid-template-columns:repeat(3,max-content);justify-content:start}
  /* ★ 과제 549 — 「돈」 한 줄(#cdMoney · 상태 칩 셋)은 단계 체크의 3칸 격자를 쓰지 않는다 : 긴 칩(입금 예정 · 다음 날짜)이 왼쪽 단 끝을 넘어 옆 단 칩과 겹쳤다(1440) → 접어 내림 · 칩 글은 한 줄 */
  #cdMoney .cdstagerow{display:flex;flex-wrap:wrap;column-gap:var(--gap-field-x);row-gap:var(--gap-tool)}
  #cdMoney .st{white-space:nowrap}
  #campSide th,#ciBody th{top:0}
  .mdwrap{display:grid;grid-template-columns:minmax(0,1fr);gap:16px;align-items:start}
  .mdwrap .card{margin-bottom:0}
  .mdwrap.nosel>.mdside{display:none}
  .mdside{display:flex;flex-direction:column;gap:14px}
  /* v1.07 — 인사 : 왼쪽 카드 셋을 한 자식으로 묶는다(aside.mdside 는 .mdwrap 직속 자식 · 규칙 68) */
  .hrleft{display:grid;gap:16px;min-width:0}
  /* v1.07 — 인사 목록은 열이 좁다. .clrow 기본 min-width:818px 를 되찾는다 (규칙 54 와 같은 결) */
  #hr .clrow{min-width:0}
  /* v1.10 — 내 정보 연차 이력 줄도 열이 좁다 (규칙 67) · 팝업 안 안내 자리 여백 못박기 (규칙 71) */
  #me .clrow{min-width:0}
  #mlOverlap .warn,#mlOverlap .hint{margin:8px 0 0;padding:8px 10px;font-size:var(--text-sm)}
  /* ── 내 정보 (v1.07) : 연차 원형 게이지 · 인센티브 추이 막대 ── */
  .megauge{display:grid;grid-template-columns:92px auto 1fr;grid-template-rows:auto auto;
    align-items:center;gap:2px 14px}
  .megauge svg{grid-row:1 / span 2}
  .megauge .mg-n{grid-column:2;grid-row:1;align-self:end;font-size:var(--fs-num);font-weight:var(--weight-strong);
    color:var(--ink);font-variant-numeric:tabular-nums;line-height:1}
  .megauge .mg-d{grid-column:2;grid-row:2;align-self:start;font-size:var(--fs-cap);color:var(--text-2)}
  .megauge .mg-side{grid-column:3;grid-row:1 / span 2;min-width:0}
  .mebars{margin-top:12px}
  .mebars .mebar-track{display:flex;align-items:flex-end;gap:6px;height:56px}
  .mebars .mebar{flex:0 1 32px;background:var(--accent-soft);border-radius:3px 3px 0 0;min-height:4px}   /* ★ 과제 349 — 얇은 막대(폭 32 = .tile 과 같은 값 · 옛 flex:1 = 값이 셋이어도 170px 덩어리) */
  .mebars .mebar.on{background:var(--accent)}
  .mebars .mebar-lbl{display:flex;gap:6px;margin-top:4px}
  .mebars .mebar-lbl span{flex:0 1 32px;text-align:center;font-size:var(--fs-cap);color:var(--text-2)}   /* 막대 폭과 같게 → 달 글이 막대 밑에 선다 */
  .mebars .mebar-one{margin:0}
  #map details>summary{cursor:pointer;font-size:var(--fs-body);font-weight:var(--weight-strong);color:var(--ink)}   /* ★ 과제 347 — 접힘 「옛 노션과 대응」 */
  #map details>summary:focus-visible{outline:none;box-shadow:var(--ring);border-radius:var(--r-ctl)}
  #map details[open]>summary{margin-bottom:12px}
  @media (max-width:760px){.megauge{grid-template-columns:92px 1fr}
    .megauge .mg-side{grid-column:1 / span 2;grid-row:3}}
  .mdside .card{margin-bottom:0;overflow-x:auto;min-width:0;max-width:100%;border-radius:var(--r-panel)}
  .mdside th{top:0}
  .cd-ovl{font-size:var(--fs-cap);font-weight:var(--weight-strong);text-transform:uppercase;letter-spacing:.05em;
      color:var(--text-2);margin:0 0 8px}
  .cd-ovl.mt{margin-top:16px;padding-top:12px;border-top:1px solid var(--line-soft)}

  /* ── 목록 행 (clrow — §11 표준 · 행 40px 밀도) ── */
  #campList{overflow:hidden}   /* ★ 상자(테·라운드·여백)는 위 한 자리로 옮겼다(과제 119). 여기 남은 것은 **이 목록만의 것** — clrow 는 모서리를 넘으므로 잘라 준다 */
  #campList>p.muted{padding:0 22px 16px}
  #campList .clfoot{border-radius:var(--r-ctl)}
  /* ★ v1.01 — 할인 신호등(견적 하단). 색만으로 뜻을 전하지 않도록 **글자를 함께** 답니다(규칙 = 색 단독 금지) */
  .lamp{display:inline-flex;align-items:center;gap:6px;font-size:var(--fs-sm);
      font-weight:var(--weight-strong);white-space:nowrap}
  .lamp i{width:8px;height:8px;border-radius:50%;flex-shrink:0}
  .lamp.ok{color:var(--ok)}    .lamp.ok i{background:var(--ok)}
  .lamp.warn{color:var(--warn)} .lamp.warn i{background:var(--warn)}
  .lamp.bad{color:var(--bad)}  .lamp.bad i{background:var(--bad)}
  /* v1.03 (AE 실사용 ①) — 담당 칩 뒤 「나」 표시 · 「내 캠페인」 토글 눌린 상태 */
  .clrow .mine{display:inline-flex;align-items:center;height:20px;margin-left:5px;font-size:var(--fs-cap);
      font-weight:var(--weight-strong);color:var(--accent);background:var(--accent-soft);
      border-radius:var(--r-ctl);padding:0 6px}
  /* ★ 과제 487 (10-23 대표 「나 뱃지가 아래로 내려옴」) — 담당 칸(사람 칩 + 「나」) = **한 줄** · 「나」 = 칩 왼쪽(뱃지는 이름 왼쪽 같은 줄 · 10-12 대표)
     마크업 순서(칩 → 나)는 그대로 · order 로 자리만 · 이름이 줄어들며 말줄임(「나」 는 안 줄어듦) · 캠페인 · 견적 목록 공용
     「나」 줄 = 내 칸 → 내 「휴가」 태그는 숨김(내 화면에서 나에게는 필요 없는 말 · 동료 화면엔 「나」 가 없어 그대로 보임) : 「나」 + 얼굴 + 「김태훈」 = 124 ≤ 담당 열 134 · 136(옛 폭 그대로 · 캠페인 이름 칸 = 449b 폭 그대로 · 1차 176 = 이름 칸 1440 276 → 244 로 「완료」 + 코드 + 이름이 잘려 걷음) */
  .clrow > :has(> .mine) > .uav .uav-lv{display:none}
  .clrow > :has(> .mine){display:flex;align-items:center;gap:6px;min-width:0;white-space:nowrap;overflow:hidden}
  .clrow > :has(> .mine) > .uav{flex:0 1 auto}
  .clrow > :has(> .mine) > .mine{order:-1;flex:none;margin-left:0}
  button#cFMine.on{background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}
  /* ★★ 과제 113 (09-22 · 검토자 실측) — **도구 줄의 토글은 켜지면 한 문법**(DESIGN §6-1 「꺼짐 = 보통 보조 단추 · 켜짐 = 틴트」).
     까닭 : 바로 위 `button#cFMine.on` 은 **캠페인 id 에 못 박힌 규칙**이라, 같은 `ghost mini` 로 만든 새 토글
     셋(`qFMine`·`lFMine`·`spFMine`)이 그 옷을 못 받아 **켜져도 흰 바탕**이었다. AE 는 첫 화면부터 켜진 채로
     시작하는데 켜진 표시가 없으니 「왜 1건만 보이지?」가 된다(검토자 실측 : 새것 셋만 `rgb(255,255,255)`).
     ⚠ 잡는 자리를 **id 가 아니라 `aria-pressed`** 로 둔다 — 다음에 토글을 하나 더 달아도 저절로 같은 옷을 입는다.
     ⚠ `button#cFMine.on` 은 **안 지운다**(값이 같다 · 지우려면 캠페인 토글을 다시 재 볼 것).
     ⚠ 할 일 토글(`tkMine`·`tkFilter`)은 `h3.toolsonly .tools` 안이 아니라 **안 걸린다**(값은 이미 같다). */
  h3.toolsonly .tools button[aria-pressed="true"]{background:var(--bg-active);border-color:var(--accent);color:var(--accent)}   /* v2.71 (과제 133) — 켜짐 바탕 = 할 일 .tk-tgl 과 같은 --bg-active(옛 --accent-soft 은퇴) */
  /* ★ v2.74 (과제 134 · DESIGN §11-2 ②) — **필터 팝** (core.js filterPop) : 팝 · 절 · 줄의 옷은 할 일 `.tk-pop .tk-fpop .tk-fsec .tk-fttl .tk-frow` 규칙을 **그대로** 받는다(여기서 새 값 0).
     여기 있는 것은 걸쇠뿐이다 —
     ① 도구 줄을 가진 카드는 `overflow:hidden`(위 875 줄 · 표 상자 라운드) → **팝이 열린 동안만** 보이게 푼다(짧은 목록에서 팝 아래가 잘렸다)
     ② 옛 칸은 `hidden` 한 낱말로 숨긴다 — `#cSeg{display:flex}` 가 UA 의 [hidden] 을 이긴다(§2339 와 같은 함정) → 되찾는다
     ③ 월 칸은 팝 안 절에 담긴다 — 줄(26)이 아니라 칸(32) 이라 `.tk-frow` 에 넣지 않고 줄과 같은 좌우 8 · 위아래는 절 여백(2)만 */
  .card:has(> h3.toolsonly .tk-fpop.tk-open){overflow:visible}
  h3.toolsonly .tools select[hidden],#cSeg[hidden]{display:none}
  .seg > button[hidden]{display:none}   /* ★ 과제 298 — 같은 함정 : `.seg button{display:flex}` 가 [hidden] 을 이겨 발주 매체 탭(지정게시대 · 아파트게시판)이 숨김인데 보였다(과제 191 · 키캡 없이 · 대학교가 넷째 자리) */
  h3.toolsonly .tools .tk-fwrap svg{width:14px;height:14px}
  /* ④ 팝이 h3 안에 있어 h3 의 글자(15 · 굵기 600 · 자간 -0.15px)를 물려받는다 → 할 일 팝이 받는 몸 글자(body)로 되돌린다.
       줄 굵기 = 할 일 줄과 같은 --weight-medium(할 일 줄은 label 이라 500 · 이쪽은 div) — 09-23 사진으로 잡음 · 관문 v270 ⓒ 「팝 옷」 이 굵기·자간·줄 높이도 잰다 */
  h3.toolsonly .tk-fpop{font-size:var(--text-sm);font-weight:var(--weight-regular);letter-spacing:normal;line-height:1.5}
  h3.toolsonly .tk-fpop .tk-frow{font-weight:var(--weight-medium)}
  .tk-fpop .tk-finp{padding:2px 8px}
  .tk-fpop .tk-finp input{width:100%;box-shadow:none}
  /* ★★ 과제 105 (09-22 감사 ① · 검토자 실측 54/45/45 → 검토 지적 ⓐ 반영판) — 담당 칸에 사진 동그라미+이름+「나」가
     안 들어가 **「나」가 이름 밑으로 내려가** 그 줄만 54px 이 됐다. 줄 키는 44 한 벌이어야 한다(사양 §0 · R3).
     ★ **고치는 것은 아래 「한 줄로 못 박는다」 한 줄이다** — 검토자가 되돌림을 두 단계로 갈라 실측해 주었다
       (폭만 78px 로 되돌려도 45 그대로 · 이 규칙까지 되돌려야 54 로 뒤집힌다).
     ⚠ 첫 판은 폭을 118px 로 **못 박았다** — `min-width` 가 852→892(대표 화면 916→956)로 커져
       **좁은 창에서 가로 스크롤이 40px 일찍** 생겼다. 그래서 지금은 **`minmax(118px,.9fr)`** —
       좁으면 118 로 돌아가 `min-width` 는 안 커지고(852·916 그대로), 넓으면 늘어난다.
     ★ 최소를 78 이 아니라 **118** 로 잡은 까닭(09-22 검토자 재측) : 78 이면 1280 에서 이름이 「김…」으로,
       1100 에서는 7px 로 잘린다. 사진 24 + 여백 8 + 이름 36 + 「나」 22 + 칸 여백 ≈ 106 이라
       **118 이 「세 글자 이름 + 나」가 들어가는 가장 작은 값**이다.
     ★ 잣대 = **할 일 표**(`#taskList .clrow` = `minmax(210px,1.35fr)` + `min-width:1100px`) — 넉넉한 최소를 두고
       **좁으면 칸을 찌그러뜨리는 대신 목록이 옆으로 스크롤**한다. 그 방향을 따른다.
     ⚠ 곁딸린 손실(숨기지 않는다) : 1280 에서 광고주 칸이 두 글자쯤 더 잘린다.
       광고주 이름은 캠페인명에 대개 들어 있고, 담당자는 그 칸 말고는 볼 곳이 없다.
     ⚠ 전역 `.clrow` 기본 격자는 **다른 목록 열둘이 함께 읽으므로 안 건드린다** — 캠페인 목록 구역에만 얹는다. */
  /* v2.71 (과제 133 · 대표 지적 3차 ⑮) — 표 상자가 노트북 기준(바깥 24)으로 돌아와 조였던 칸(캠페인 광고주 · 담당 · 계약금액 · 광고주 담당자명 · 지출 거래처)은 132 값으로 되돌렸다 · max-content 는 쓰지 않는다(줄마다 칸 경계가 어긋난다 · ⑧) */
  #campList .clrow{grid-template-columns:minmax(100px,2.4fr) minmax(90px,.8fr) minmax(134px,.6fr) 122px 136px 176px minmax(128px,.4fr)}   /* ★ 과제 237 — 담당 최소 118 → 134(얼굴 + 이름 + 「나」 = 133 · 결제가 넓어지며 담당이 118 로 줄어 「김태훈 나」 가 잘렸다 · v270 ⓐ) · 결제 122 → 176(가장 긴 알약 「■ 지남 12/31 · D+1000」 네 자리 140 + 딱 붙으면 말줄임이 붙어 여유 8 + 좌우 여백 28 · 1440 잘림 · 말줄임 0 · 이름 · 광고주 · 담당 fr 이 양보) · v2.77 (과제 147) — 계약금액 84~ → 128~ : 한 줄이 된 뒤 「12,400,000원」 이 말줄임됐다(돈은 안 자른다) · 그 폭은 **긴 글 칸**(캠페인 이름 150~ → 124~ · 말줄임 허용)에서 · 광고주 64~ → 90~ : 1280 에서 머리 「광고주」 가 꺾였다(ⓐ3) · 8칸 최소 합 944 ≤ 1280 표 946 */
  /* 담당 칸(세 번째) — **한 줄로 못 박는다.** 이름이 길면 말줄임으로 끝나고 줄바꿈하지 않는다(키가 흔들리지 않게). */
  #campList .clrow > *:nth-child(3){display:flex;align-items:center;min-width:0;white-space:nowrap;overflow:hidden}
  /* ★ 과제 424 (PM 점검 1 걸음 8) — 담당 칸 = **이름 칩만** 고치는 자리(campaigns.js campAeHit) · 칸 빈 곳 = 줄(누르면 상세) → 빈 곳에 올려도 고치는 칸 옷(흰 상자 · 테 · ✎) 0 · 칩에 올리면 ✎ · 칩 바탕 · 키보드 초점은 옛 옷 그대로 */
  #campList .clrow > .cl-ed[data-f="ae_id"]:has(.uav){cursor:pointer}
  #campList .clrow > .cl-ed[data-f="ae_id"]:has(.uav):not(.cl-on):not(:focus-visible):hover{background:transparent;box-shadow:none}
  #campList .clrow > .cl-ed[data-f="ae_id"]:has(.uav):not(.cl-on):not(:focus-visible):not(:has(.uav:hover, .mine:hover)):hover::after{opacity:0}
  #campList .clrow > .cl-ed[data-f="ae_id"]:not(.cl-lock) .uav{cursor:text;border-radius:var(--r-chip)}
  #campList .clrow > .cl-ed[data-f="ae_id"]:not(.cl-lock):not(.cl-on) .uav:hover{background:var(--bg-fill)}
  /* v1.01 — 마진율 열이 붙는 것은 대표·재무일 때만(.mg). 그때만 8칸이 됩니다 */
  /* ★ 과제 121 (09-23 감사) — **`:where()` 로 조건의 무게를 0 으로.**
     「열」 기능은 `#campList > .clrow{…}`(1,1,0)를 나중에 적어 이긴다고 보고 만들어졌는데,
     `#campList.mg .clrow` 는 **(1,2,0)** 이라 **기능이 졌다** — 열을 꺼도 트랙이 8 로 남아 **빈 자리**가 생겼다
     (칸은 `display:none` 이 먹으므로 **칸만 사라지고 자리는 남는** 어긋난 모습이 된다 · v1.77 부터 오늘까지).
     `:where(.mg)` 는 무게가 **0** 이라 이 규칙이 **(1,1,0)** 이 되고, 기능의 `<style>` 이 **나중**이라 이긴다.
     ⚠ 기능 쪽 무게를 올리는 길도 있으나 **열두 목록 전부에 영향**이라 하지 않았다(검토자 권고 ⓐ). */
  #campList:where(.mg) .clrow{grid-template-columns:minmax(100px,2.4fr) minmax(90px,.8fr) minmax(134px,.6fr) 122px 136px 176px minmax(128px,.4fr) 80px;min-width:986px}   /* v2.92 (과제 162) — 늘 보이는 체크 칸(.clsel · 왼쪽 여백 0 → 48)이 1280 에서 가로 스크롤을 냈다(v270 ⓐ · 칸이 이미 최소 · 합 948 = 상자) → 캠페인 124 → 100 · 진행 단계 · 결제 134 → 122(합 −48) */
  /* ★ v3.08 (과제 176 · 09-25 걷기 #5) — 1280 노트북에서 **캠페인 이름이 다섯 글자**로 줄었다(이름 칸 104 · 글 75) · 「완료」 알약이 칸 밖으로 잘렸다.
     좁을 때(≤1366)만 고정 칸 셋을 줄인다 — 진행 단계 122 → 100(머리 「진행 단계」 한 줄 · v270 ⓐ3) · 집행기간 136 → 96(「10/12~11/30」 95) · 결제 122 → 116(「○ 예정 9/30」 110 · v270 ⓐ5 「12,400,000원」 116) = 이름 칸 +68.
     담당 118 · 계약금액 128~ 은 그대로(사진 + 이름 · 돈은 안 자른다). 1440 모습은 그대로. `:where(.mg)` = 열 기능이 이긴다(과제 121). */
  @media (max-width:1366px){
    #campList .clrow{grid-template-columns:minmax(100px,2.4fr) minmax(90px,.8fr) minmax(134px,.6fr) 100px 96px 124px minmax(128px,.4fr)}   /* ★ v3.34 (과제 240) — 담당 최소 118 → 134(1440 과 같이 · 얼굴 + 「김태훈」 + 「나」 = 133 · 1280 대표에서 「나」 가 6px 잘렸다) · 이름 · 광고주 fr 이 양보 */
    #campList:where(.mg) .clrow{grid-template-columns:minmax(100px,2.4fr) minmax(90px,.8fr) minmax(134px,.6fr) 100px 96px 124px minmax(128px,.4fr) 80px;min-width:872px}
    #campList .st-d{display:none}   /* ★ 과제 237 — 좁을 때(≤1366) 결제 알약 = 「○ 계산서 12/31」 까지(87 · 칸 116 → 124 − 여백 28 = 96 · 딱 붙으면 말줄임이 붙어 8 여유 · 1280 사진 실측) · D±N 은 색(주의 · 지남)과 마우스 올리면 전문(title) */
  }
  /* v0.99 (점검 ①) — 집행 칩 칸을 하나 늘려 7칸. 좁으면 목록만 옆으로 스크롤됩니다 */
  /* ★ v1.56 (표 문법 v2 · R3 + 대표 「좌우 여백 조금 더 넓게」) — 줄 키는 **44px 하나**(두 줄 셀도 그 안에),
     좌우 여백 16 → **24px**. 카드의 제목(`--card-pad-x` 24px)과 목록 글자가 **세로로 맞는다**
     (종전에는 카드 24 - 목록 바깥마진 22 + 줄 16 = 18px 라 2px 씩 어긋나 있었다). */
  /* ★ v3.4 (과제 90 · 사양 §3-3) — 줄 키·호버·세로줄을 **토큰**으로. 값은 할 일 표에서 잰 것과 같다. */
  .clrow{display:grid;grid-template-columns:minmax(150px,1.5fr) minmax(64px,.8fr) 78px 118px 120px 118px minmax(84px,.7fr);
      gap:12px;align-items:center;min-height:var(--row-h);padding:4px 14px;border-bottom:1px solid var(--line-soft);
      cursor:pointer;min-width:852px;box-sizing:border-box;transition:background var(--duration-fast) var(--ease)}
  .clrow:hover{background:var(--row-hover)}
  /* 칸 세로줄 — 마지막 칸에는 없다(사양 §3-3). 격자 칸이 곧 열이므로 자식에 오른쪽 선을 준다. */
  .clrow > *{border-right:1px solid var(--cell-line);padding-right:12px;min-width:0}
  .clrow > *:last-child{border-right:0;padding-right:0}
  .clrow > .selbox{border-right:0;padding-right:0}
  /* ★ v1.79 (과제 32) — 여러 줄 고르기. **열 격자는 안 건드린다** :
     체크칸을 칸으로 넣으면 목록마다 손으로 맞춘 grid-template-columns 가 전부 한 칸씩 밀린다.
     그래서 줄의 **왼쪽 여백 위에 띄우고**, 고르기를 켠 동안만 그 여백을 두 배로 준다.
     새 색·새 수치 0 — `--card-pad-x` 와 이미 있는 고른 줄 색(`--bg-active`)만 쓴다. */
  .clsel > .clrow{position:relative;padding-left:calc(var(--card-pad-x) * 2)}
  /* ⚠ 머리줄은 제 여백 규칙(`.clrow.clhead{padding:9px 24px}`)이 뒤에 있어 위 줄을 이긴다.
     실측(09-12) : 그래서 머리줄만 24px 로 남아 **체크칸이 첫 열 글자 위에 겹쳤다**. 무게를 한 단 올린다. */
  .clsel > .clrow.clhead,.clsel > .clrow.clhead:hover{padding-left:calc(var(--card-pad-x) * 2)}   /* ★ 과제 321(대표 사진 3 · 「캠□인」) — :hover 도 같이 : 아래 「머리 :hover{padding:0}」 와 무게가 같아 올리면 여백이 0 → 첫 머리 글이 체크칸 밑으로 들어갔다 */
  .clsel > .clrow > .selbox{position:absolute;left:var(--card-pad-x);top:0;bottom:0;margin:0;
      display:flex;align-items:center;cursor:pointer}   /* v2.87 (과제 157 · 검토자 · 기획 지적) — margin:0 : 전역 label{margin:10px 0 4px} 이 체크 칸을 10px 아래로 밀었다 */
  .clsel > .clrow.selon{background:var(--bg-active)}
  /* ★ v1.29 (야간 UX R12) — 키보드로 고른 줄도 **같은 표시**를 씁니다(새 색·크기 없음).
     :focus-visible 이라 마우스로 누를 때는 나타나지 않습니다 — 마우스 손맛 무변경. */
  /* ★ v2.37 (과제 100) — 스크립트가 잡은 커서 줄도 보이게 `.clrow:focus` 에 같은 옷(크롬은 스크립트 포커스를 :focus-visible 로 안 칠 수 있다 — 자동으로 잡은 첫 줄이 안 보인다). 새 색 없음. */
  .clrow.sel,.clrow.sel:hover,.clrow:focus-visible,.clrow:focus{background:var(--bg-active);box-shadow:inset 2px 0 0 var(--accent)}
  .clrow.needfill,.clrow.needfill:focus{background:var(--warn-bg)}   /* ★ 과제 272 — 「이 줄에서 고르십시오」 2.6초 짚음 = 경고 틴트(초점 줄 파랑은 「골랐다」 로 읽힌다) · 스스로 걷힘 */
  .clrow:focus-visible,.clrow:focus{outline:none}
  /* ★ v1.56 (R1) — 머리줄 = 흰 바닥 + 아래 1px 선 (회색 띠·대문자·자간 은퇴) */
  /* ★ v3.4 (과제 90) — 머리줄은 **회색 띠**(--tbl-head-bg) · 몸줄과 **같은 키**. v1.56 R1 「흰 바닥」을 뒤집는다(대표 09-18 「회색 괜찮아」).
     되돌리기 = :root 의 --tbl-head-bg 를 #FFFFFF 로. */
  .clrow.clhead,.clrow.clhead:hover{min-height:var(--row-h);padding:0 14px;background:var(--tbl-head-bg);cursor:default;
      border-bottom:1px solid var(--line);font-size:var(--fs-sm);font-weight:var(--weight-medium);letter-spacing:0;
      color:var(--text-2);text-transform:none;box-shadow:none}
  /* ★ 과제 493b (디자이너 10 · 대표 G-679 · DESIGN §6-10 ①) — 묶음 머리 줄 `.clrow.clhead.grp` = 칸 머리 위 한 줄(「지급」 「공제」 처럼 여러 칸을 묶는 이름 · 그 칸들에 grid-column 걸침)
     옷 = 머리 그대로 · 키 = --h-ctl · 밑줄 = 글 있는 칸만 --line-soft(묶음 사이 = 칸 안여백만큼 끊김) · 줄 아래 선 0 · 정렬 ✗ · 새 값 0 */
  .clrow.clhead.grp,.clrow.clhead.grp:hover{min-height:var(--h-ctl);border-bottom:0}
  .clrow.clhead.grp > *{cursor:default}
  .clrow.clhead.grp > :not(:empty){margin:0 var(--pad-cell-x);padding:0;border-bottom:1px solid var(--line-soft)}
  /* ★★ v2.70 (과제 132 · 사양 할일기준통일2차 §4-4 · Q-050 답) — **표 한 벌** : 칸 문법을 할 일 List 표(`.tk-row`)와 같게.
     칸 사이 0 · 줄은 칸을 위아래로 채운다(세로줄이 줄 끝까지) · 칸 안여백 0 14px · 칸 키 --row-h(44) · 글자는 세로 가운데(align-content).
     ⚠ **할 일·홈은 뺀다**(Q-050 ⓐ) · **내 정보·사진도 뺀다**(계획 전역 제약 「대상 아님」 · DESIGN §11-5 · 09-23 검토자 지적) — 할 일 Dashboard 의 두 목록과 홈 #hBoard 도 .clrow 라 공용을 바꾸면 할 일이 바뀐다(65→57 실측).
       그래서 `:where(section:not(#task):not(#home))` 안에만 건다(:where = 무게 0 · 목록별 규칙이 그대로 이긴다).
     ⚠ 칸 안여백이 좌우 14+14 가 되면 **고정 폭 칸의 글자 자리가 16 준다**(옛 = 칸 사이 12 + 오른쪽 12) →
       목록별 격자의 고정 px 칸은 「옛 폭 + 16」 으로 환산했다(Q-050 ⓑ · fr·minmax 칸은 그대로). */
  /* ⚠ 고르개 팝업 목록(★ 과제 455 뒤 = [data-part~="list"] · 옛 .cp-list)은 표가 아니라 뺀다 — 지출 section 안에 있어 걸린다(제 여백 규칙이 따로 있다) */
  :where(section:not(#task):not(#home):not(#me):not(#photo)) :where(:not([data-part~="list"])) > .clrow{gap:0;align-items:stretch;padding:0}
  :where(section:not(#task):not(#home):not(#me):not(#photo)) :where(:not([data-part~="list"])) > .clrow > *{padding:0 14px;min-height:var(--row-h);box-sizing:border-box;align-content:center}
  :where(section:not(#task):not(#home):not(#me):not(#photo)) :where(:not([data-part~="list"])) > .clrow > *:last-child{padding-right:14px}
  /* ★ v2.77 (과제 147 · 09-24 기획 점검 · DESIGN §11-3 「표 안 한 줄」) — **몸줄 칸의 글자는 한 줄 + 말줄임**(할 일 표와 같다) : 긴 이름이 줄을 꺾어 줄마다 키가 달라졌다
       (실측 · 칸마다 긴 글을 붙여 보면 캠페인 53 · 견적 99 · 지출 85 · 인사 85 — 나머지 여섯은 이미 45). 무게 0(:where) — 목록별 규칙이 그대로 이긴다.
       ⚠ 칸 안의 블록(캠페인 이름 아래 코드 · 계좌 두 줄 <br>)은 **줄 수가 아니라 꺾임**을 막는 것이라 그대로다 · 온전한 글은 상세에서(견적 캠페인 칸은 풍선말 title 도) */
  :where(section:not(#task):not(#home):not(#me):not(#photo)) :where(:not([data-part~="list"])) > :where(.clrow:not(.clhead)) > *{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  /* 고르기 칸(체크박스 하나 · 발주 학교 38 · 지급 대기 44)은 **자르지 않는다** — 좁은 칸에서 체크박스가 잘리면 누를 자리가 준다(발주 학교 목록이 관문 ⓐ2 로 잡힘) */
  :where(section:not(#task):not(#home):not(#me):not(#photo)) :where(:not([data-part~="list"])) > :where(.clrow:not(.clhead)) > :where(:has(> input[type="checkbox"])){overflow:visible;text-overflow:clip}
  :where(section:not(#task):not(#home):not(#me):not(#photo)) :where(:not([data-part~="list"])) > .clrow > .selbox{padding:0}
  :where(section:not(#task):not(#home):not(#me):not(#photo)) :where(:not([data-part~="list"])) > .clrow.clhead,
  :where(section:not(#task):not(#home):not(#me):not(#photo)) :where(:not([data-part~="list"])) > .clrow.clhead:hover{padding:0}
  :where(section:not(#task):not(#home):not(#me):not(#photo)) :where(:not([data-part~="list"])) > .clrow.clhead > *{display:flex;align-items:center;justify-content:space-between;gap:8px}
  .cl-name{min-width:0}
  /* ★ v1.56 (R3) — 두 줄 셀도 44px 안에 들어오게 줄 간격을 1.35 로 (글자 크기는 6단 그대로) */
  .cl-clip{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}   /* ★ 과제 217 — 줄인 칸(캠페인명) = 말줄임 + title 전문 */
  /* ★★ 과제 220 — 표에서 바로 고치기(공용 core.js clInlineEdit) · 옷 = 할 일 표 .tk-ed · .tk-in · .tk-pop · .tk-frow 값 그대로 베낌(규칙 124 · 할 일 CSS 무변경) */
  .clrow > .cl-ed{cursor:text}
  .clrow > .cl-ed:hover{background:var(--bg-fill)}
  .clrow > .cl-ed.cl-lock{cursor:default}                     /* ★ 220 Q-067 — 잠긴 칸(누르면 까닭 한 줄) · 고치는 칸처럼 안 보이게 */
  .clrow > .cl-ed.cl-lock:hover{background:transparent}
  .clrow > .cl-ed.cl-on{padding:0 6px;background:var(--bg-card)}
  .clrow > .cl-ed.cl-on.cl-anch{background:var(--bg-active)}
  .cl-in{height:30px;width:100%;box-sizing:border-box;font-size:var(--fs-body);   /* 할 일 .tk-in 과 같은 14(과제 274 뒤 · v334 ⓘ) */ padding:0 8px;border:1px solid var(--accent);border-radius:var(--r-inner);background:var(--bg-card);color:var(--text);box-shadow:var(--ring)}
  .cl-in.cl-in-multi{height:auto;min-height:60px;padding:6px 8px;resize:vertical;font:inherit;font-size:var(--fs-sm);line-height:1.5}
  .cl-pop{background:var(--bg-card);border-radius:var(--r-ctl);box-shadow:var(--sh-pop);padding:4px;box-sizing:border-box;position:absolute;z-index:430}
  .cl-frow{display:flex;align-items:center;gap:8px;height:26px;padding:0 8px;margin:0;border-radius:var(--r-inner);cursor:pointer;user-select:none;font-size:var(--fs-sm)}
  .cl-frow:hover{background:var(--bg-fill)}
  .cl-frow.cl-sel{background:var(--bg-active)}
  .cl-frow.cl-hi{background:var(--bg-active)}
  .cl-frow.cl-hide{display:none}
  .cl-frow:focus-visible{outline:none;box-shadow:var(--ring)}
  .cl-fhint{height:22px;display:flex;align-items:center;padding:0 8px;margin-top:4px;border-top:1px solid var(--line);font-size:var(--fs-cap);color:var(--text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .cl-fsrch{padding:2px 4px 4px}
  .cl-fsrch input{height:26px;width:100%;box-sizing:border-box;padding:0 8px;font-size:var(--fs-cap);border:1px solid var(--line);border-radius:var(--r-inner);box-shadow:none;background:var(--bg-card)}
  .cl-fsrch input:focus{border-color:var(--accent);box-shadow:var(--ring)}
  .cl-saved{margin-left:6px;font-size:var(--fs-cap);color:var(--ok);white-space:nowrap;font-weight:var(--weight-body)}
  .clrow > .cl-ed:not(.cl-name){position:relative}
  .clrow > .cl-ed:not(.cl-name) > .cl-saved{position:absolute;right:8px;bottom:2px;margin:0}   /* ★ 과제 221 — 이름 칸 밖 고치는 칸은 「✓ 저장됨」 을 값 아래 오른쪽으로(옆에 붙이면 좁은 칸에서 값이 「김실장…」 · 「✓ …」 로 잘림 · 거래처 04 · 판매 매체 06 사진 실측 · 224 품목 표와 같은 방법) */
  .cl-name .nm{display:block;font-size:var(--fs-body);font-weight:var(--weight-medium);color:var(--ink);
      line-height:1.35;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .cl-name .nm a{color:var(--ink);text-decoration:none;font-weight:var(--weight-medium)}
  .cl-name .cd{font-size:var(--fs-cap);line-height:1.35;color:var(--text-2);font-variant-numeric:tabular-nums;margin-top:1px}
  /* ★ v1.59 (대표 「표 안의 문구 폰트 사이즈가 제각각」) — 목록 셀의 **값은 모두 14px**(--fs-body).
     13px 은 **둘째 줄**(코드·업무내용)만 · 12px 은 **배지**만. 세 크기에 각각 한 가지 뜻만 준다. */
  .cl-adv{font-size:var(--fs-body);color:var(--text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  /* ★ v1.56 (R6) — 코드·번호 한 벌 : 줄바꿈 금지 + 자릿수 고정 글꼴. 열 폭은 이 글자가 정한다. */
  .cnum{white-space:nowrap;font-variant-numeric:tabular-nums;font-weight:var(--weight-medium);color:var(--ink)}
  /* ★ v1.49 (가독성 3단계 · F-5) — 목록의 진행 단계 = **이름 + 진도 + 얇은 바**.
     여섯 점(.cl-stg .dot)과 10px 약칭(.sl · .stgcol · .stgcap)은 은퇴했습니다 —
     「지금 어디」를 알려고 점을 세야 했고, 약칭은 10px·대비 3.04 라 실제로 안 읽혔습니다.
     「어느 단계가 끝났나」는 상세 팝업의 체크 여섯 칸이 그대로 보여 줍니다.
     새 색 없음 — 강조색 하나와 ok 하나뿐(DESIGN.md §11-6 로드맵 6). */
  .cl-stg2{display:flex;flex-direction:column;gap:4px;min-width:0}
  .cl-stg2 .t{font-size:var(--fs-body);font-weight:var(--weight-medium);color:var(--ink);
      white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .cl-stg2 .t em{font-style:normal;font-size:var(--fs-cap);font-weight:var(--weight-body);
      color:var(--text-2);font-variant-numeric:tabular-nums;margin-left:5px}
  .cl-stg2 .tr{height:4px;background:var(--line-soft);border-radius:2px;overflow:hidden}
  .cl-stg2 .tr i{display:block;height:100%;background:var(--accent);border-radius:2px}
  .cl-stg2.all .t{color:var(--ok)}      .cl-stg2.all .tr i{background:var(--ok)}
  .cl-stg2.none .t{color:var(--text-2)}
  /* ★ v1.00 (08-25 대표 지시) — 기간 달력. 종전엔 전체 보기(⤢)에서만 펼쳤습니다 —
     v1.15 팝업(920px)은 폭이 넉넉하므로 상세에 늘 펼칩니다. */
  .calwrap{display:block;margin:10px 0 2px}
  .cal{display:flex;gap:18px;flex-wrap:wrap}
  .cal-m{min-width:196px}
  .cal-h{font-size:var(--fs-sm);font-weight:var(--weight-strong);color:var(--text-2);margin:0 0 6px;
      font-variant-numeric:tabular-nums}
  .cal-g{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}
  .cal-g .wd{font-size:var(--fs-cap);color:var(--text-2);text-align:center;padding:2px 0;font-weight:var(--weight-strong)}
  .cal-g .wd.sun{color:var(--bad)} .cal-g .wd.sat{color:var(--accent)}
  .cal-g .d{font-size:var(--fs-cap);line-height:24px;height:24px;text-align:center;border-radius:var(--r-ctl);
      color:var(--text-2);font-variant-numeric:tabular-nums;border:1px solid transparent}
  .cal-g .d.pad{visibility:hidden}
  .cal-g .d.in{background:var(--accent-soft,var(--bg-active));color:var(--accent);
      font-weight:var(--weight-medium)}
  .cal-g .d.s,.cal-g .d.e{background:var(--accent);color:var(--on-fill);font-weight:var(--weight-strong)}
  .cal-g .d.today{border-color:var(--ink)}
  .cal-g .d.mark{position:relative}
  .cal-g .d.mark::after{content:"";position:absolute;left:50%;bottom:1px;width:4px;height:4px;
      margin-left:-2px;border-radius:50%;background:var(--warn)}
  .cal-g .d.mark.paid::after{background:var(--ok)}
  .cal-g .d.mark.inv::after{background:var(--text-2)}
  .cal-lg{display:flex;gap:14px;flex-wrap:wrap;margin-top:8px;font-size:var(--fs-cap);color:var(--text-2)}
  .cal-lg span{display:flex;gap:5px;align-items:center}
  .cal-lg b{color:var(--ink);font-weight:var(--weight-medium)}
  .cal-lg i{width:11px;height:11px;border-radius:3px;display:inline-block;border:1px solid transparent}
  .cal-lg i.in{background:var(--accent-soft,var(--bg-active));border-color:var(--accent)}
  .cal-lg i.today{border-color:var(--ink)}
  /* ★ v3.08 (과제 177 · 09-25 걷기 #6) — 발주 달력(한 쪽 전체 · 칸이 넓다) 「오늘」 = 캠페인 · 지출 · 할 일 달력(.tk-today .tk-dn)과 같은 파란 동그라미.
     종전 = 칸 크기 검정 테두리 상자(작은 집행기간 달력의 표시가 넓은 칸에 늘어났다). 작은 달력(.cal-g · 캠페인 상세)은 그대로 — 거기선 파랑이 시작 · 끝 칸이다. */
  #odCalView .cal-g .d.today{border-color:transparent}
  #odCalView .cal-g .d .cal-dn{display:inline-flex;align-items:center;justify-content:center;min-width:22px;height:22px;border-radius:50%;background:var(--accent);color:var(--on-fill);font-weight:var(--weight-strong)}
  #odCalView .cal-lg i.today{border-color:transparent;background:var(--accent);border-radius:50%}
  .cal-lg i.mark{background:var(--warn);border-radius:50%;width:6px;height:6px}
  /* v1.49 — 집행 기간 칩(.rchip)은 은퇴했습니다. 날짜 열은 `.dcell` 맨 글자 한 벌입니다(F-6 · §11-3). */
  .cdstgdots{margin:2px 0 8px}
  .cdstgline{margin:2px 0 10px;display:flex;gap:8px;flex-wrap:wrap;align-items:center}
  .cdstagerow .stgchk input{accent-color:var(--accent)}
  .cdstagerow .stgchk:has(input[data-stg="paid"]) input{accent-color:var(--ok)}   /* ★ 과제 330 — 「결제」(받은 돈) = 초록 · 옛 nth-child(6) 은 264 「제안」 이 앞에 붙은 뒤 계산서발행에 먹었다 → 자리 대신 단계 키 */
  .clrow .r{text-align:right;font-size:var(--fs-body);font-variant-numeric:tabular-nums;white-space:nowrap;
      font-weight:var(--weight-medium);color:var(--ink)}
  .clrow.clhead > .r{font-size:inherit;font-weight:inherit;color:inherit}   /* ★ 과제 525 ① — 머리 칸 돈 열(.r)도 다른 머리와 같은 글(12 · 450 · 회색) · 옛 = 위 줄이 머리에도 먹어 「계약금액」 머리만 14 · 짙게 · 정렬 hover · 고른 색(.gsort 규칙)은 그대로 이김 */
  /* ══ ★ v1.55 (2026-09-12 · 대표 결정 = 시안 A안) — 「할 일」 목록 ══════════════════════
     회색 상자(.tbox)를 은퇴시키고 §11 표준 줄(.clrow)로 옮겼다. 면은 **흰 바닥 한 겹**이고,
     묶음(지난·내일·이후)은 상자가 아니라 **제목 줄 + 1px 선**(.tsec)이 가른다.
     ⚠ .tbox·.tgrp·.ttbl 규칙은 아래에 그대로 둔다 — 시안 파일(시제품/…할일화면시안…)이 「지금」을
       보여 줄 때 읽는다. 화면 코드에서는 더 쓰지 않는다. */
  .tsec{display:flex;align-items:baseline;gap:8px;padding:16px 24px 8px;border-top:1px solid var(--line);
        font-size:var(--fs-body);font-weight:var(--weight-strong);color:var(--ink)}
  .tsec:first-child{border-top:0}
  .tsec .n{font-size:var(--fs-sm);font-weight:var(--weight-body);color:var(--text-2)}
  .tsec .over{font-size:var(--fs-sm);font-weight:var(--weight-strong);color:var(--bad)}
  .tsec-empty{padding:2px 24px 14px;color:var(--text-2);font-size:var(--fs-sm)}
  /* 열 = 업무명 · 캠페인 · 담당 · 마감 · 상태 · (완료 단추) */
  /* ★ v1.59 (대표 지시) — 「할 일」은 **지난 · 오늘 · 내일 · 이후 네 묶음이 각각 카드 하나**다.
     그래서 목록을 감싸던 바깥 카드는 틀만 남기고 투명하게 둔다(카드 안의 카드를 만들지 않는다). */
  .card:has(> #taskList){background:transparent;border:0;box-shadow:none;padding:0;margin-bottom:0}
  /* ★ v1.60 (대표 「네 카드 사이에 여백을 넣어 더 잘 구분되게」) — 카드 사이 16 → **24px**.
     바탕이 흰색에 가까워(#FCFCFC) 사이가 좁으면 두 카드가 한 덩어리로 읽힌다.
     24px = `--card-pad-x` 와 같은 값이라 새 수치를 만들지 않았다. */
  .tcard{padding:0;overflow:hidden}
  /* ⚠ 실측 — `.split .card{margin-bottom:0}`(명시도 0,2,0)이 `.tcard`(0,1,0)를 이겨 **네 카드가 붙어 있었다**
     (그래서 카드 넷이 줄만 그어진 한 덩어리로 보였다 · 09-12 대표 지적). id 를 앞세워 이긴다. */
  #taskList>.tcard{margin-bottom:24px}
  #taskList>.tcard:last-child{margin-bottom:0}
  .tcard>h3{margin:0;padding:16px 24px 10px;display:flex;align-items:baseline;gap:8px;
      font-size:var(--fs-card);font-weight:var(--weight-strong);color:var(--ink)}
  .tcard>h3 .tn{font-size:var(--fs-sm);font-weight:var(--weight-body);color:var(--text-2)}
  .tcard>h3 .tover{font-size:var(--fs-sm);font-weight:var(--weight-strong);color:var(--bad)}
  .tcard .clrow:last-child{border-bottom:0}
  .tcard .tsec-empty{padding:0 24px 18px}
  /* 마감 열은 「2026.09.11 (금)」 한 벌이라 폭이 그만큼 필요하다(완료 줄은 「완료 …」가 붙는다) */
  /* ★ v1.62 — 일곱 열 : 업무명 · 업무내용 · 캠페인 · 담당 · 마감 · 상태 · (완료 단추).
     업무명 최소 230px = 「메이캔_대학교광고_삼성월렛」이 한 줄에 드는 폭(대표가 준 기준 · 실측 ~200px).
     캠페인은 코드 알약 + 이름이라 210px 부터. 좁은 화면에서는 목록만 옆으로 스크롤된다(min-width). */
  #taskList .clrow{grid-template-columns:minmax(230px,1.15fr) minmax(170px,1.1fr) minmax(210px,1.35fr)
      84px 148px 124px 56px;min-width:1100px;align-items:center}
  /* ★ v1.62 (대표 지시 09-12) — 업무내용은 **제 열**이다. 다른 항목처럼 왼쪽에 줄맞춤해야
     눈이 훑을 기준선이 생긴다(v1.61 처럼 이름 뒤에 붙이면 줄마다 시작점이 달랐다). */
  .t-name{min-width:0}
  .t-name>a{display:block;min-width:0;font-size:var(--fs-body);font-weight:var(--weight-medium);color:var(--ink);
      line-height:1.35;text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .t-b{min-width:0;font-size:var(--fs-body);line-height:1.35;color:var(--text-2);
      white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  /* ★ 캠페인을 「잘 보이게」(대표 09-12) — 흐린 보조색(--text-2)이 아니라 **읽는 글자**로 적고,
     코드 알약을 앞에 두고, 열 폭을 넉넉히 준다. 누를 수 있는 것은 hover 에서 파랑으로 말한다. */
  .t-camp{min-width:0;font-size:var(--fs-body);color:var(--text);
      white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .t-camp a{color:var(--text);text-decoration:none}
  .t-camp a:hover{color:var(--accent);text-decoration:underline}
  .t-camp .ccode{margin-right:6px}
  /* 다 한 일은 한 번에 — 줄에 마우스를 올리거나 키보드로 고르면 나타난다(늘 보이면 시끄럽다) */
  .t-done{opacity:0;transition:opacity var(--duration-fast) var(--ease)}
  .clrow:hover .t-done,.clrow:focus-within .t-done,.t-done:focus-visible{opacity:1}
  .clfoot{margin:10px 24px 14px;padding:11px 14px;font-size:var(--fs-sm);line-height:2;
      background:var(--warn-bg);border:1px solid rgba(178,122,0,.28);border-radius:var(--r-ctl)}
  .dot{display:inline-block;width:22px;height:22px;border-radius:50%;background:var(--bg-hover);
       border:1px solid var(--line)}
  .dot.on{background:var(--accent);border-color:var(--accent)}
  .stgtd{display:flex;justify-content:flex-start}
  .stgtd .dot{width:15px;height:15px}
  .stgboard{display:grid;grid-template-columns:minmax(240px,1.6fr) repeat(6,minmax(64px,1fr));
            gap:10px 6px;align-items:center}
  .stghead{font-size:var(--fs-sm);color:var(--text-2);font-weight:var(--weight-strong)}
  .stghead.c,.stgdot.c{text-align:center}
  .stgname{border:1px solid var(--line);border-radius:var(--r-ctl);padding:7px 14px;cursor:pointer;min-width:0}
  .stgname:hover{background:var(--bg-hover)}
  .stgname span{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--fs-body)}
  .stgname .stgae{margin-top:2px}
  .cdstages{border-top:1px solid var(--line-soft);margin-top:10px;padding-top:10px}
  .cdstagerow{display:flex;gap:16px;flex-wrap:wrap;margin-top:6px}
  .stgchk{display:flex;gap:6px;align-items:center;font-size:var(--fs-body);cursor:pointer;white-space:nowrap}
  .stgchk input{width:15px;height:15px;accent-color:var(--accent)}
  .stghint{font-size:var(--fs-sm);color:var(--text-2);margin:0 0 8px;line-height:1.7}
  #cPL{display:none}

  /* ── 캠페인 목록(구형 표 흔적) ── */
  #campList table{table-layout:fixed;min-width:1620px}
  #campList th:first-child{width:240px}
  #campList th,#campList td{overflow:hidden;text-overflow:ellipsis}
  #campList th:nth-child(n+14),#campList td:nth-child(n+14){text-align:right}
  #campList td:nth-child(2),#campList td:nth-child(3),
  #campList td:nth-child(11),#campList td:nth-child(12),#campList td:nth-child(13){white-space:nowrap}
  #campList th:nth-child(n+5):nth-child(-n+10),
  #campList td:nth-child(n+5):nth-child(-n+10){padding-left:4px;padding-right:8px}

  /* ── 노션식 속성 목록 (클릭-편집 — §9-3) ── */
/* ══════════════════════════════════════════════════════════════════════
   ★★ v1.97 (09-15 · 과제 55 · **대표 결정 = B안 「두 칸 격자」**) — 「적는 폼」 한 벌
   ──────────────────────────────────────────────────────────────────────
   ★ 규격 한 문장 : **「읽을 때는 줄, 적을 때는 칸」**
     · **읽는 상세** = 지금의 노션식 줄 그대로(라벨 왼쪽 · 값만 · 눌러서 고침) — 한 글자도 안 바꾼다
     · **적는 등록·수정 폼** = **라벨 위 + 테두리 있는 칸 + 두 칸 격자**
   ★ 레퍼런스(09-15 · 시안 2차에 원문) :
     ⓐ **입력칸이 폼의 첫 어포던스 — 보이지 않으면 쓸 수 없다**(Andrew Coyle · Cieden)
     ⓑ **라벨은 위가 가장 빠르다 · 왼쪽이 가장 느리다**(SitePoint · Wufoo · SubUX)
     ⓒ **모달에 스크롤이 생기면 이미 모달을 벗어난 것**(SaaSUI) → 두 칸으로 접어 스크롤을 없앤다
   ★ 실측(시안) : 같은 아홉 칸에서 한 칸 840px(스크롤 생김) → **두 칸 712px(스크롤 없음)**
   ──────────────────────────────────────────────────────────────────────
   ★★ **마크업과 id 를 한 글자도 안 바꾼다.** `.cdprops` 에 `asform` 한 마디만 붙이면
      이미 있는 숨은 입력칸이 겉으로 나오고 라벨이 위로 올라간다(저장 로직은 그 입력칸을 읽으므로 그대로다).
   ⚠ `display:none` 이 **마크업에 직접** 박혀 있어 `!important` 가 필요하다 — 그 한 군데뿐이다.
   ⚠ **고르는 줄 셋**(사람 `data-user` · 상태 `data-tstatus` · 검색 `data-combo`)은 **진짜 칸을 안 보인다** —
     거기서는 누르면 뜨는 고르개가 이미 제 일을 한다. 대신 **그 줄도 칸처럼 테두리를 입어** 폼 안에서 따로 놀지 않는다.
   ══════════════════════════════════════════════════════════════════════ */
  .cdprops.asform{display:grid;grid-template-columns:1fr 1fr;gap:var(--gap-field) var(--gap-field-x);margin-bottom:8px}   /* 268 실행 — 값 그대로 토큰으로(14 · 16) */
  .cdprops.asform .cdprop{display:flex;flex-direction:column;align-items:stretch;gap:5px;
      padding:0;border-bottom:0;min-height:0;min-width:0}
  .cdprops.asform .pk{flex:none;font-size:var(--fs-sm);color:var(--text-2);font-weight:var(--weight-strong)}
  /* 한 줄을 다 쓰는 칸 — 여러 줄 글(textarea)은 늘 · 그 밖은 `wide` 로 지정 */
  /* ★ 과제 448b — 알바 등록의 「더 보기」 · 폰 계정 체크 줄 = 다른 화면 접두어(.moe-more · .sp-ck) 대신 이 팝업 id 규칙(값 그대로 · v460 빚 0 · 모양 0 변화) */
  #vAlbaMore{margin-top:12px}
  #vAlbaMore > summary{cursor:pointer;color:var(--accent);font-size:var(--fs-sm)}
  #vAlbaAccRow > label{display:flex;align-items:center;gap:8px;min-height:32px;cursor:pointer}
  .cdprops.asform .cdprop[hidden],.slideover.pstd .cdprops.asform .cdprop[hidden]{display:none}   /* ★ 과제 448 — 규칙 58 : 위 display(flex · pstd grid)가 [hidden] 을 이겨 숨긴 칸(돈 받을 곳 · 알바 모드)이 보였다 */
  .cdprops.asform .cdprop.wide,
  .cdprops.asform .cdprop:has(> textarea){grid-column:1 / -1}
  .cdprops.asform > .pfhelp,
  .cdprops.asform > .pnl-sect{grid-column:1 / -1;padding-left:0;margin-top:0}
  .slideover.pstd .cdprops.asform > .pnl-sect{margin:calc(var(--gap-group) - 10px) 0 calc(var(--gap-tool) - 10px)}   /* ★ 과제 568 디자인수정 2 — 칸 격자 안 구역 머리(상담 등록 등) : 격자 줄 사이(4596 gap 10)를 빼서 위 32 · 아래 8(옛 = 격자 10 · 4+10) */
  .slideover.pstd .cdprops.asform > .pnl-sect:first-child{margin-top:0}
  /* ── 기본 : 숨어 있던 진짜 칸을 겉으로 · 값 보임줄(.pf-v)은 숨긴다 ── */
  .cdprops.asform .cdprop > .pv.pf-v{display:none !important}
  .cdprops.asform .cdprop > input:not([type=hidden]),
  .cdprops.asform .cdprop > select,
  .cdprops.asform .cdprop > textarea{display:block !important;width:100%;font-family:inherit;
      font-size:var(--fs-body);color:var(--ink);padding:8px 11px;background:var(--bg-card);
      border:1px solid var(--line-input);border-radius:var(--r-ctl);
      /* ⚠ 노션식 인라인 편집이 칸을 300px 로 묶어 둔다(`.cdprop>input{max-width:300px}` · 줄 안에서 값처럼 보이게).
         적는 폼에서는 칸이 **한 칸을 다 써야** 하므로 그 묶음을 푼다 — 날짜 칸의 170px 도 함께(09-15 실측). */
      max-width:none;flex:none;margin:0}
  .cdprops.asform .cdprop > textarea{min-height:120px;resize:vertical}   /* ★ v2.94 (과제 144 · 대표 지적 2차 ④) — 등록 폼 메모 · 내용 = 여러 줄 · 최소 120(옛 64 · 상담내용 300 은 따로) */
  /* ⚠ 한 줄에 **칸이 둘**인 자리가 있다 — 검색해서 치는 `input` 과 값을 담는 `select`(광고주 즉석 등록 따위).
     둘 다 보이면 칸이 두 개로 보인다 → **치는 칸만** 보이고 값 담는 쪽은 숨긴 채 둔다(값 흐름은 그대로). */
  .cdprops.asform .cdprop:has(> input:not([type=hidden])) > select{display:none !important}
  .cdprops.asform .cdprop > input:focus,
  .cdprops.asform .cdprop > select:focus,
  .cdprops.asform .cdprop > textarea:focus{outline:0;border-color:var(--accent);box-shadow:var(--ring)}
  /* ── 고르는 줄 셋 : 진짜 칸 대신 **칸처럼 생긴 고르개**를 보인다 ── */
  .cdprops.asform .cdprop:has(> .pf-v[data-user]) > .pf-v,
  .cdprops.asform .cdprop:has(> .pf-v[data-tstatus]) > .pf-v,
  .cdprops.asform .cdprop:has(> .pf-v[data-combo]) > .pf-v{display:flex !important;align-items:center;gap:6px;
      min-height:38px;padding:7px 11px;border:1px solid var(--line-input);border-radius:var(--r-ctl);
      background:var(--bg-card);cursor:pointer;color:var(--ink);
      width:100%;min-width:0;flex:none;box-sizing:border-box;
      /* ⚠ v1.98 (09-15 · 과제 56 · 대표 신고 「박스의 좌측 정렬이 안 맞습니다」) —
         노션식 줄에서는 **누르는 자리를 넓히려고** `.pv.editable` 에 좌우 -8px 여백을 준다.
         적는 폼에서는 그 줄이 **칸**이므로 그 여백이 그대로 남으면 **좌우로 8px씩 삐져나온다**(실측 4자리).
         → 여백을 0 으로 되돌린다. 누르는 자리는 칸 자체(38px)가 이미 넓다. */
      margin:0}
  .cdprops.asform .cdprop:has(> .pf-v[data-user]) > .pf-v:hover,
  .cdprops.asform .cdprop:has(> .pf-v[data-tstatus]) > .pf-v:hover,
  .cdprops.asform .cdprop:has(> .pf-v[data-combo]) > .pf-v:hover{background:var(--bg-fill)}
  .cdprops.asform .cdprop:has(> .pf-v[data-user]) > .pf-v:focus,
  .cdprops.asform .cdprop:has(> .pf-v[data-tstatus]) > .pf-v:focus,
  .cdprops.asform .cdprop:has(> .pf-v[data-combo]) > .pf-v:focus{outline:0;border-color:var(--accent);box-shadow:var(--ring)}
  .cdprops.asform .cdprop:has(> .pf-v[data-user]) > select,
  .cdprops.asform .cdprop:has(> .pf-v[data-tstatus]) > select,
  .cdprops.asform .cdprop:has(> .pf-v[data-combo]) > select,
  .cdprops.asform .cdprop:has(> .pf-v[data-combo]) > input{display:none !important}
  /* ★ v1.99 (과제 57 · 대표 신고) — **검색 콤보가 열리면 줄과 칸을 맞바꾼다.**
     ⚠ 옛 판은 인라인 `style` 을 보고 판정했는데, `el.style.display=''` 는 **그 선언을 지우는** 것이라
       `[style*="display: "]` 에 안 걸렸다. 그래서 검색 칸이 영영 안 떴다(09-15 실측 · 대표 신고).
     → 여는 쪽이 줄에 `editing` 을 달고, 여기서 그 표시만 본다(인라인 style 과 싸우지 않는다). */
  /* ⚠ 위 「고르는 줄」 규칙이 `:has()` 를 써서 **더 무겁다** — `!important` 만으로는 못 이긴다.
     같은 `:has()` 를 달아 무게를 맞추고 `.editing` 한 마디로 이긴다(09-15 실측 : 안 그러면 줄과 칸이 **둘 다** 보인다). */
  .cdprops.asform .cdprop.editing:has(> .pf-v) > .pf-v{display:none !important}
  .cdprops.asform .cdprop.editing:has(> .pf-v) > input:not([type=hidden]){display:block !important}
  .cdprops.asform .ffhelp{font-size:var(--fs-cap);color:var(--text-2)}
  .cdprops.asform .ffhelp:empty{display:none}
  .cdprops.dtform .ffhelp{font-size:var(--fs-cap);color:var(--text-2)}   /* ★ 과제 327 — 상담 상세 「캠페인 만들기」 캠페인명 밑 한 줄(새 상담 팝업 asform 과 같은 옷) */
  @media(max-width:620px){ .cdprops.asform{grid-template-columns:1fr} }

  .cdprops{display:flex;flex-direction:column;margin-bottom:8px}
  .cdprop{display:flex;align-items:center;gap:10px;padding:1px 0;border-bottom:1px solid var(--line-soft)}
  .cdprop:last-child{border-bottom:0}
  .cdprop .pk{flex:0 0 112px;font-size:var(--fs-sm);color:var(--text-2)}
  .cdprop .pk .pk-hint{font-weight:var(--weight-body);color:var(--text-3)}   /* v2.94 (과제 144) — 칸 이름 옆 흐린 한 줄 */
  .cdprop.stack{flex-direction:column;align-items:stretch;gap:4px;padding:8px 0}   /* v2.94 (과제 144 · 대표 지적 ④ ⓑ) — 한 줄 전체 : 이름 위 · 값 = 줄 폭 전부 */
  .cdprop.stack > .pk{flex:0 0 auto}
  .cdprop.stack > .pv{white-space:pre-wrap;word-break:break-word}
  /* ★ 과제 318 ⓓ — 편집 칸 = 읽기 상자 폭(width 100% · flex:none — 옛 = 뒤의 dtform 「> textarea{flex:1}」 바탕 0% 가 폭 · 높이를 눌러 안내 글이 칸 옆에 뜸) · 높이 = pvBigFit(최소 3줄 · 최대 화면 60%) · 안내 글 = 값 상자 줄바꿈으로 칸 아래 */
  .cdprops .cdprop.stack > .pv > textarea.pv-big{width:100%;flex:none;resize:vertical;box-sizing:border-box}   /* .cdprops 하나 더 = 뒤의 dtform 「> textarea{flex:1}」(바탕 0% 가 높이를 81 로 눌렀다) 보다 세게 */
  .cdprop.stack > .pv > .pv-bighint{margin-top:4px;font-size:var(--fs-cap);color:var(--text-3);white-space:normal}
  #lDraftForm textarea[data-ff="memo"]{min-height:0;height:auto;resize:vertical;overflow-y:auto}   /* v2.95 (과제 144 · 대표 지적 3차 ①) — 5줄 높이(rows=5 · 줄 높이 × 5 + 안쪽 여백) · 넘치면 칸 안에서 스크롤 · 손으로 늘리기 됨 */
/* v2.94 (과제 144 · 대표 지적 ①) — 상담내용 = 크게 */
  #leadMD .mdside #btnLeadClose{margin-left:auto}
  #leadMD .mdside .pnl-foot,#advMD .mdside .pnl-foot{gap:var(--gap-tool)}   /* ★ 과제 441 — 발 단추 사이 = 토큰 하나(팝업 기준 ④ · 옛 = 0 · mini) */
  #advMD .mdside #btnAdvClose,#vendMD .mdside #btnVendClose,.tm-foot .dt-close{margin-left:auto}   /* ★ 과제 146 — 광고주 · 거래처 상세 발도 상담과 같게(왼쪽 [삭제] · 오른쪽 [닫기]) */   /* v2.95 (과제 144 · 대표 23:5x) — 상세 발 = 왼쪽 [삭제] · 오른쪽 [닫기](§12-2 왼쪽 = 위험) */
  #leadMD .mdside{width:min(560px,96vw)}   /* v2.94 (과제 144 · 대표 지적 ③) — 상담 상세 = 560(한 단 · 820 은 두 단 상세만) */
  .cdprop .pv{flex:1;font-size:var(--fs-body);min-height:32px;min-width:0;display:flex;align-items:center;gap:6px;flex-wrap:wrap;color:var(--ink)}
  .cdprop .pv.editable{cursor:pointer;border-radius:var(--r-ctl);padding:4px 8px;margin-left:-8px}
  .cdprop .pv.editable:hover{background:var(--bg-hover)}
  .cdprop .pv input,.cdprop .pv select{width:100%;max-width:300px;margin:0}
  .cdprop .pv textarea{width:100%;margin:0}
  .cdprop .pv .empty{color:var(--text-3)}
  /* ★ 과제 345(10-08 대표 UX 점검) — 견적서 작성 「기본 정보」 의 **빈 칸 = 입력칸 모양**(선 --line-input · 32 · 라운드 = §9 적는 칸 · 옛 = 회색 「비어 있음」 글뿐이라 누를 자리인지 몰랐다) · 값이 들면 지금처럼 글 */
  .qgrp[data-step="1"] .cdprops[data-pf] .cdprop > .pv.pf-v.editable:has(> .empty){border:1px solid var(--line-input);min-height:32px;margin-left:0;padding:5px 11px;background:var(--bg-card);display:flex;align-items:center}
  .qgrp[data-step="1"] .cdprops[data-pf] .cdprop > .pv.pf-v.editable:has(> .empty):hover{border-color:var(--accent);background:var(--bg-card)}
  .cdprop .pv a{color:inherit;text-decoration:none;cursor:pointer;font-weight:inherit;
      border-radius:var(--r-ctl);padding:4px 8px;margin-left:-8px}
  .cdprop .pv a:hover{background:var(--bg-hover)}
  .cdprop>input,.cdprop>select{flex:1;max-width:300px;margin:0}
  .cdprop>textarea{flex:1;max-width:none;margin:4px 0}
  .req{color:var(--bad);font-weight:var(--weight-strong)}   /* ★ v2.94 (과제 144 · 대표 「빨강으로 통일」) — 필수 별표 한 벌(앱 전체 · 새 캠페인이 쓰던 그 토큰) */
  .pv.editable:focus-visible,.pf-v:focus-visible{outline:none;background:var(--bg-hover);
      box-shadow:var(--ring);border-radius:var(--r-ctl)}

  /* ── 팝오버 메뉴 (사람·상태 — §9-1-1) ──
     ★★ v3.4 (09-18 · 과제 96 · 사양 §3-4) — **몸은 한 벌, 고르기 표시는 뜻에 따라 둘.**
     몸(줄 26 · 안여백 4 · 글자 12 · 라운드 6 · 호버·고름 색)을 할 일 팝(`.tk-pop`)과 **같은 값**으로 맞춘다.
     ⚠ **고르기 표시는 합치지 않는다** : 여기(`.umenu-it`)는 **하나만** 고르는 자리라 **✓ 맨 앞 14px**,
       `.tk-pop` 은 **여럿** 고르는 자리라 체크박스다. 합치면 대표님이 **여러 개 고를 수 있다고 오해**하신다.
     ⚠ 뒤집히는 옛 결정 = v1.17(09-10 · 줄 32 · inset 파란 바) — 26px 줄에서는 바가 오히려 지저분해 뺐다(대표 승인 09-18). */
  /* ⚠ 테두리를 뺐다 — 할 일 팝(`.tk-pop`)은 **그림자만**으로 떠 있고, 테두리가 남으면 두 팝이 나란히 있을 때 다르게 보인다. */
  .umenu{position:fixed;z-index:500;background:var(--bg-card);
      border-radius:var(--r-ctl);box-shadow:var(--sh-pop);padding:4px;box-sizing:border-box;
      min-width:190px;max-height:262px;overflow-y:auto}
  /* ★ 과제 318 (10-06 대표 사진) — 줄 높이 = 내용 따라(최소 26 · 옛 = 26 고정이라 긴 글이 줄 밖으로 넘쳐 겹침) · 글 조각은 한 줄 말줄임(전체 = title) */
  .umenu-it{display:flex;align-items:center;gap:8px;min-height:26px;padding:0 8px;
      border-radius:var(--r-inner);cursor:pointer;user-select:none;font-size:var(--fs-cap)}
  .umenu-it > span:not([class]){min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}   /* 글만 든 조각(고르기 칸 · 거래처 · 광고주 이름)만 — 사람 칩(.uav) · 알약 · ✓ 는 그대로 */
  .umenu-it.hl{background:var(--bg-hover)}
  /* ★★ v2.95 (과제 168 · 대표 결정 ⓑ · DESIGN §9 「고르기 칸 한 벌」) — 고르기 칸 목록 = 필터 팝과 같은 판(tk-pop) · 줄 36 · 본문 글자 · 고른 값 = 파랑 + ✓ · 떠 있는 것만 그림자 */
  .tk-pop.sel-pop{position:fixed;z-index:470;display:flex;flex-direction:column;overflow:hidden;box-sizing:border-box;border:1px solid var(--line)}   /* 확인 창(460) 위 · 2층 위 */
  .sel-pop .sel-list{overflow-y:auto;min-height:0;flex:1 1 auto}
  .sel-pop .sel-opt{display:flex;align-items:center;gap:8px;height:36px;padding:0 12px;border-radius:var(--r-ctl);cursor:pointer;user-select:none;
      font-size:var(--fs-body);color:var(--text);white-space:nowrap;flex:0 0 auto}
  .sel-pop .sel-opt .sel-t{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis}
  .sel-pop .sel-opt.act{background:var(--bg-hover)}
  .sel-pop .sel-opt[aria-selected="true"]{color:var(--accent);font-weight:var(--weight-strong)}
  .sel-pop .sel-opt .sel-ck{flex:0 0 auto;color:var(--accent)}
  .sel-pop .sel-opt.dis{color:var(--text-3);cursor:default}
  .sel-pop .sel-opt.dis.act{background:none}
  .sel-pop .sel-grp{height:28px;display:flex;align-items:center;padding:0 12px;font-size:var(--fs-cap);color:var(--text-3);flex:0 0 auto}
  .sel-pop .sel-none{padding:10px 12px;font-size:var(--fs-sm);color:var(--text-2)}
  .sel-pop .sel-kw{margin:0 0 4px;flex:0 0 auto}
  /* ⚠ `.sel` 을 `.hl` **뒤에** 둔다 — 순서를 바꾸면 마우스 색이 선택을 덮어 「어느 것이 지금인지」가 흐려진다(v1.17 실측). */
  .umenu-it.sel,.umenu-it.sel.hl{background:var(--bg-active)}
  /* ✓ = 알약 **앞** 고정 자리(order:-1). 안 고른 줄도 자리를 지켜 알약 시작선이 가지런하다. */
  .umenu-it .uchk{order:-1;flex:0 0 14px;width:14px;color:var(--accent);visibility:hidden;display:inline-flex}
  .umenu-it.sel .uchk{visibility:visible}
  /* ★★ 과제 106 (09-22 감사 ④) — **여럿 고르는 팝(`.multi`)은 체크박스 14**(사양 §3-4 · 할 일 팝과 같은 값).
     쓰는 곳 = 「열」 팝(열을 여러 개 켜고 끈다). 종전에는 줄 글 앞에 `'✓ '` 를 **글자로 찍어**
     하나만 고르는 것처럼 보였다. ⚠ 하나만 고르는 팝은 위의 `.uchk`(✓) 그대로 — 합치지 않는다.
     `.uck-sp` = 「기본으로 되돌리기」처럼 켜고 끄는 값이 아닌 줄의 빈 자리(글 시작선을 맞춘다). */
  .umenu-it.multi .uck,.umenu-it.multi .uck-sp{order:-1;flex:0 0 14px;width:14px;height:14px;margin:0;
      accent-color:var(--accent);pointer-events:none}
  .umenu-it .pill{height:20px;font-size:var(--fs-cap);padding:0 8px}
  .umenu-it .uchip{height:20px}
  .umenu-head{padding:2px 2px 5px;position:sticky;top:-4px;background:var(--bg-card);z-index:1}
  .umenu .umenu-head input[type="text"]{width:100%;height:var(--h-tab);box-sizing:border-box;   /* ★ 과제 529 — 찾기 칸 = --h-tab(DESIGN §9-1-1) · 옛 `.umenu-head input`(0,1,1) 은 378 전역 입력칸 32(0,3,1)에 져 칸 32 · 머리 39 → 같은 무게 + 뒤 자리라 이김 */font:inherit;font-size:var(--fs-cap);
      border:1px solid var(--line);border-radius:var(--r-inner);padding:0 8px;
      background:var(--bg-fill);outline:none}
  .umenu-head input:focus{border-color:var(--accent);box-shadow:var(--ring)}
  .umenu-it mark{background:var(--accent-soft);color:inherit;border-radius:3px;padding:0 1px}
  /* ★ 과제 318 — 안내 글 = 메뉴 맨 아래 **글 한 덩이**(옛 = flex · 높이 22 고정 → 굵은 글 조각마다 따로 기둥이 되어 겹침 · 「(주)지엠컴」 「저장 시 새로 등록」 이 세로로 깨짐) */
  .umenu-none{display:block;min-height:26px;padding:4px 8px;box-sizing:border-box;line-height:var(--leading-normal);
      font-size:var(--fs-cap);color:var(--text-2);overflow-wrap:anywhere}
  .umenu-sep{height:1px;margin:4px 0;background:var(--line)}
  .usel{display:flex;align-items:center;gap:6px;width:100%;box-sizing:border-box;min-height:34px;
      padding:5px 10px;border:1px solid var(--line);border-radius:var(--r-ctl);
      background:var(--bg-card);cursor:pointer;font-size:var(--text-sm);box-shadow:var(--sh-btn)}
  .usel:hover{background:var(--bg-hover)}
  .usel:focus-visible{outline:none;border-color:var(--accent);box-shadow:var(--ring)}
  .usel .empty{color:var(--text-3)}
  .usel .usel-caret{margin-left:auto;color:var(--text-3);display:inline-flex}
  .pf-chips{display:flex;flex-direction:column;align-items:flex-start;gap:4px;padding:4px 0;
      width:100%;max-height:230px;overflow-y:auto}
  .pf-chip{cursor:pointer;display:inline-flex;border-radius:var(--r-ctl)}
  .pf-chip:hover{background:var(--bg-hover)}
  .pf-chip.sel .uchip{box-shadow:0 0 0 2px var(--accent)}

  /* ── 결제 칩 ── */
  .pchip{display:inline-block;font-size:var(--fs-cap);font-weight:var(--weight-strong);padding:2px 8px;border-radius:var(--r-ctl);
      white-space:nowrap;font-variant-numeric:tabular-nums;background:var(--bg-hover);color:var(--text-2)}
  .pchip.over{background:var(--bad-bg);color:var(--bad)}
  .pchip.soon{background:var(--warn-bg);color:var(--warn)}
  .pchip.paid{background:var(--ok-bg);color:var(--ok)}
  .cl-pay{min-width:0}
  #cTasks .htask>.uchip{flex-shrink:0}
  #cTasks .htask [data-part~="due"]{flex-shrink:0}

  /* ── 폴더 버튼 : 보조 버튼 규격 ── */
  .folderbtn,button.folderbtn{display:inline-flex;align-items:center;gap:6px;padding:0 10px;height:26px;
      border:1px solid var(--line);border-radius:var(--r-ctl);background:var(--bg-card);
      color:var(--accent);font-size:var(--fs-sm);font-weight:var(--weight-medium);line-height:1.4;text-decoration:none;
      cursor:pointer;box-shadow:var(--sh-btn);transition:background var(--duration-fast) var(--ease)}
  .folderbtn:hover,button.folderbtn:hover{background:var(--bg-hover)}
  .folderbtn:active,button.folderbtn:active{transform:scale(.98)}
  .folderbtn svg{flex:0 0 auto}

  /* ── 확인 창 (삭제 등) ── */
  /* ★ v2.07 (과제 62-2 · 검토자 09-17) — 확인 창은 온 화면에 하나뿐인 부품이라 **늘 맨 위**(DESIGN.md §12-2 층 표 460).
     종전 80 은 할 일 창(400·401)·캠페인 요약 창(440·441) **아래**여서, 할 일 삭제 확인이 할 일 창에 덮여
     글도 안 보이고 단추도 안 닿았다(검토자가 elementFromPoint 로 실측). 팝오버(500)보다는 아래. */
  #delBack{position:fixed;inset:0;z-index:460;background:var(--dim-modal);display:none;
           align-items:center;justify-content:center;padding:20px}
  #delBack.open{display:flex}
  #delBack.l2{background:var(--dim-layer2)}       /* 다른 모달 위에 2층으로 뜰 때 — 딤 누적 방지(§12-2 딤 3단) */
  #delBox{background:var(--bg-card);border-radius:var(--r-panel);box-shadow:var(--sh-float);
          width:min(460px,94vw);padding:18px 22px 22px;animation:toastIn var(--duration-base) var(--ease)}
  #delBox h3{margin:0 0 10px;font-size:var(--fs-card);font-weight:var(--weight-strong);letter-spacing:-.01em;color:var(--ink)}
  #delBox p{margin:0 0 12px;font-size:var(--fs-body);line-height:1.55;white-space:pre-wrap}
  #delBox h3,#delBox p{word-break:keep-all;overflow-wrap:anywhere}   /* ★ 과제 584 — 확인 창 제목 · 글 = .hint 와 같은 꺾음(390 「광고 / 주」 ✗) · v564 */
  #delBox textarea{min-height:54px;margin-bottom:4px}
  #delBox .btns{margin-top:12px}
  /* v2.79 (과제 141 · DESIGN §12-00 ②) — 실행 = 주 단추(검정 · 오른쪽 끝). 종전 빨강(--bad)은 은퇴 — 위험은 창의 제목·글이 말한다 */
  #delBox .btns{justify-content:flex-end}
  /* v2.82 (과제 150) — 단추 안 키캡 [취소 Esc][실행 Enter] : 글과의 사이 = 할 일 [N] 과 같은 8 · 안내 줄 #delKeys 은 은퇴(hidden) */
  #delBox .btns button .kbds,.pnl-foot button .kbds{margin-left:8px}
  #delKeys[hidden]{display:none}
  #delBox textarea.one{min-height:0;resize:none}     /* askText — 한 줄 칸(옛 prompt 자리) */

  /* ── 폼 구역·담당자 줄 ── */
  .formsec{border-top:1px solid var(--line-soft);margin-top:18px;padding-top:14px}
  .formsec:first-of-type{border-top:0;margin-top:0;padding-top:0}
  .formsec>label:first-of-type{margin-top:6px}
  /* ★ v1.93 (09-15 · 과제 47 · 팝업 시스템 2단계) — 구역 소제목이 **두 벌**이었다 :
     새 시스템의 `.pnl-sect`(선이 따라오는 것)와 옛 `.formsec-h`(대문자·자간 넓힘). 같은 일을 하는 부품이 둘이면 언젠가 또 갈린다.
     → **모양은 `.pnl-sect` 하나로** 맞춘다. 옛 이름은 마크업 13곳에 박혀 있어 **별칭으로 살려 둔다**(마크업을 안 건드리는 쪽이 안전하다).
     ⚠ **새 코드는 `.pnl-sect` 를 쓴다** — `.formsec-h` 는 옛 이름이다(화면규칙 106). */
  .formsec-h{display:flex;align-items:center;gap:8px;margin:0 0 4px;
             font-size:var(--fs-cap);font-weight:var(--weight-strong);color:var(--text-2)}
  .formsec-h::after{content:"";flex:1;height:1px;background:var(--line)}
  .formsec-h .cnt{font-weight:var(--weight-body);color:var(--text-2);flex:0 0 auto}
  /* ══ ★ v1.94 (09-15 · 과제 50 · 대표 결정) — **「여러 개 더해지는 줄」 한 벌** ══
     쓰는 곳 = 광고주 담당자 · (나중에) 견적 품목 · 발주 항목. 그리는 자리 = core.js rrowsHtml() 하나.
     ⓐ 더하는 길은 **맨 아래 「+ 추가」 한 줄**  ⓑ 줄 단추는 **마우스를 올렸을 때만**  ⓒ 세 줄까지 펼치고 접는다
     ⚠ ⓑ 에 `:focus-within` 을 반드시 함께 둔다 — 키보드로 그 줄에 들어갔을 때도 단추가 보여야 한다.
        `visibility` 를 쓰는 이유 = `display:none` 이면 탭 차례에서 빠져 **키보드로는 영영 못 누른다**. */
  .rrow-acts{opacity:0;visibility:hidden;transition:opacity var(--duration-fast) var(--ease)}
  .rrow:hover .rrow-acts,
  .rrow:focus-within .rrow-acts{opacity:1;visibility:visible}
  .rrow-rest[hidden]{display:none}
  .rrow-more{display:flex;margin-top:6px}
  .rrow-add{display:flex;margin-top:8px}
  /* ★ 과제 212 — 캠페인 상세 제목의 캠페인명 = 누르면 고침(다른 클릭-편집 칸과 같은 손짓 · 마우스 올리면 밑줄) */
  :where(#cDetTitle) [data-part~="name"]{cursor:text;border-radius:var(--r-ctl)}   /* ★ 과제 457 — 옛 .cdt-name · .cdt-in */
  :where(#cDetTitle) [data-part~="name"]:hover,:where(#cDetTitle) [data-part~="name"]:focus-visible{text-decoration:underline;text-decoration-color:var(--line);text-underline-offset:4px;outline:0}
  :where(#cDetTitle) [data-part~="in"]{font:inherit;min-width:320px;width:min(560px,70%)}
  /* ★★ 과제 209 (09-28 대표) — 광고주 상세 담당자 = **한 줄씩**(박스 없음) · [수정] [삭제] 늘 보임(규칙 107 의 hover · 세 줄 접기를 이 자리만 대표 예외) */
  /* ★ 과제 453 (팝업 흡수 C1) — 화면 접두어(.ct-) → 공용 되풀이 줄(.pnl-rows · .pnl-row) + 이 화면 id 규칙(#advCtLines) · 칸은 data-part · 값 · 모양 그대로 */
  #advCtLines{display:flex;flex-direction:column;gap:0;margin:0}
  #advCtLines > .pnl-row{display:flex;align-items:center;gap:12px;padding:0;min-height:var(--row-h);border-bottom:1px solid var(--line-soft)}
  #advCtLines > .pnl-row:first-child{border-top:1px solid var(--line-soft)}
  #advCtLines [data-part="txt"]{flex:1;min-width:0;padding:6px 0;line-height:1.5}   /* 길면 두 줄로(잘라 「…」 금지 — 메일 잘림 0 · 과제 195 · v280 ⓤ13 이 잡음) · 이름 · 번호 · 메일은 제각각 한 덩어리 */
  #advCtLines [data-part="sep"]{margin-left:12px;color:var(--text-2);white-space:nowrap}   /* ★ 209 별표 뒤(13:2x) — 이름 · 직책 · 번호 · 메일 사이에 띄움 한 칸(advertisers.js 줄 틀)을 둬 좁으면 덩어리 사이에서 꺾이게(별표 24 만큼 좁아지자 v280 ⓤ13 ctCut 1) */
  #advCtLines [data-part="txt"] > b{white-space:nowrap}
  #advCtLines [data-part="acts"]{display:inline-flex;gap:6px;flex:0 0 auto}
  /* ★ 과제 209 대표 결정(09-28 12:34) — 대표 담당자 = 이름 앞 파란 ★(단추 아님) · 나머지 = 흐린 ☆ 단추(누르면 그 사람이 대표 · 확인 창 없음 · Tab · Enter/Space)
     자리 24 = 담당자 사진 동그라미와 같은 값(§6-4 3단계) · 색은 --accent(가리키는 것) / --text-3(흐림) · 초점 테 = 공용 button:focus-visible(--ring) 그대로 */
  #advCtLines [data-ctstar]{flex:0 0 auto;width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;font-size:var(--fs-card);line-height:1;color:var(--text-3)}
  #advCtLines [data-ctstar="prim"]{color:var(--accent)}
  #advCtLines button[data-ctstar]{min-width:0;padding:0;border:0;background:none;box-shadow:none;border-radius:var(--r-ctl);height:24px}
  #advCtLines button[data-ctstar]:hover{color:var(--accent);background:var(--bg-hover)}
  #advCtLines button[data-ctstar]:active{transform:scale(.98)}
  #advCtLines [data-part="inputs"]{flex:1;min-width:0;display:grid;grid-template-columns:1fr .8fr 1fr 1.4fr;gap:6px}
  #advCtLines [data-part="inputs"] input{min-width:0}
  .contact-row{display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end;
               background:var(--bg-fill);border:1px solid var(--line-soft);
               border-radius:var(--r-ctl);padding:10px 12px;margin-top:8px}
  .contact-row>div{flex:1;min-width:132px}
  .contact-row label{margin:0 0 4px}
  .contact-row .badge{display:none}
  .contact-row .acts{flex:0 0 auto;display:flex;gap:6px;padding-bottom:1px}
  .contact-row.contact-primary{background:var(--accent-soft);border-color:var(--accent-line)}
  .contact-tag{margin:10px 0 -2px}
  /* ★ v2.94 (과제 144 · 대표 지적 2차 ③) — 광고주 등록 폼 담당자 = 한 명 한 줄 2×2 · 대표 알약 · 파란 상자 · 「대표로」 없음(첫 줄이 대표 · 목록 · 메일에서만 쓴다) */
  #advFormCard .contact-tag, #advFormCard [data-act="primary"]{display:none}
  #advFormCard .contact-row{display:grid;grid-template-columns:1fr 1fr;gap:var(--gap-field) var(--gap-field-x);   /* 268 실행 — 토큰으로(검토자 제안) */   /* ★ 과제 268 — 위 칸들(.cdprops.asform 14 · 16)과 같은 사이 · 옛 8 · 10 = 담당자 칸이 3px 어긋남 */
    background:none;border:0;border-radius:0;padding:0;margin-top:10px}
  #advFormCard .contact-row.contact-primary{background:none;border:0}
  #advFormCard .contact-row > div{min-width:0}
  #advFormCard .contact-row > .acts{grid-column:1 / -1;justify-content:flex-end}
  #advFormCard #advContactList .contact-row{border-top:1px solid var(--line-soft);padding-top:10px}
  #advViewBody .viewsec{margin-top:var(--gap-group)}   /* ★ 과제 568 — 묶음 사이 = --gap-group 32 · 머리 → 첫 줄 = --gap-tool 8(556 규칙 · 디자이너 묶음 표) */
  #advViewBody .viewsec:first-child{margin-top:0}
  #advViewBody .advcol > .viewsec:first-child{margin-top:var(--gap-group)}   /* ★ 과제 568 디자인수정 3 — .advcol = display:contents 라 단 첫 묶음(기업 내용 · 메모)도 경계(옛 0) */
  #advViewBody .viewsec>.pnl-sect{margin-bottom:var(--gap-tool)}
  #advViewBody table{margin-top:4px}
  #advViewBody .cperson{padding:10px 12px;border:1px solid var(--line-soft);border-radius:var(--r-ctl)}
  #advViewBody .cperson + .cperson{margin-top:8px}
  #advViewBody .cperson .cname{display:flex;align-items:center;gap:8px;font-size:var(--fs-body)}
  #advViewBody .cperson .cname b{font-weight:var(--weight-strong)}
  #advViewBody .cperson table{margin-top:2px}
  #leadViewCard > .pnl-sum > .dt-band,#advViewCard > .pnl-sum > .dt-band,#campSide > .pnl-sum > .dt-band,#ciSum > .dt-band,#alViewSum > .dt-band{margin:0;padding:0;background:none;border-radius:0}   /* ★ 과제 498 — 알바 상세 세부정보 한 줄도 · ★ 과제 453 — 세부정보 한 줄 = 몸 밖 흰 글줄(dtBand 값 그대로 · 회색 상자 0 · §12-0000) */
  #leadViewBody .viewsec{margin-top:var(--gap-group)}   /* ★ 과제 556 — 묶음 사이 = 32(메일 원문 ↔ 광고주 · 유입경로 ↔ 연결된 캠페인 · 옛 16) · 줄 사이(10)는 그대로 */
  #leadViewBody .viewsec:first-child{margin-top:0}
  #leadViewBody .viewsec>.pnl-sect{margin-bottom:var(--gap-tool)}   /* ★ 과제 556 — 머리 → 첫 줄 = 8(머리는 아래 묶음에 붙음 · 옛 6) */
  #leadViewBody table{margin-top:4px}
  #alViewBody .viewsec + .viewsec{margin-top:var(--gap-group)}   /* ★ 과제 568 — 알바 상세 묶음 사이(옛 4~8) = 32 */
  #alViewBody .viewsec>.pnl-sect{margin-bottom:var(--gap-tool)}
  #hrSide .cdprops:not(:has(> :not([hidden]))){display:none}   /* ★ 과제 568 디자인수정 2 — 숨은 칸만 든 빈 묶음(#hrDetPay)의 아래 여백 8 이 보상 → 연차 경계를 40 으로 */
  #hrSide .pnl-sect + #hrLvAuto,#hrSide .pnl-sect + #hrLvDet > :first-child{margin-top:0}   /* ★ 과제 568 — 연차 · 근태 머리 → 첫 줄도 8(옛 10 · 빈 글 p 13) */
  #campSide #cdMoney{margin-top:var(--gap-group)}   /* ★ 과제 568 — 「완료 단계 체크」 상자 → 「돈」 상자(옛 12) */
  .cdprops.asform > .pfhelp:has(+ #tNewCampAdvRow[style*="none"]){margin-bottom:0}
  .cdprops.asform > .cdprop:has(> #tAssignee),.cdprops.asform > .cdprop:has(> #tBody){margin-top:calc(var(--gap-group) - 10px)}   /* ★ 과제 568 — 할 일 등록 머리 없는 묶음 셋(업무명 · 캠페인 / 담당자 · 마감일 · 상태 / 내용) = 줄 사이(4596 gap 10) + 22 = 32 */
  #advFormCard .hint{margin:0 0 4px}

  /* ── 할 일 ── */
  /* ★ 과제 453 (팝업 흡수 C1 · DESIGN §12-000 · 시안 ⓔ) — 할 일 상세 · 캠페인 요약 = 표준 옷(.pstd · 머리 · 큰 제목 · 세부정보 · 몸 · 발 = app.css 「과제 440」)
     자리만 여기 id 규칙 : 할 일 상세 = 가운데 → **오른쪽 560 · 창 높이 전부 · 옅은 딤**(등록 · 상세 팝업과 같은 자리) ·
     캠페인 요약 = 1층(data-side) 오른쪽 · 2층 가운데 그대로(규칙 126) · 캠페인 상세 몸을 담는 동안(data-host) 820 · 모양(왼쪽 모서리 · 떠 있는 그림자) = 오른쪽 상세(.mdside > .card)와 같은 값 */
  #taskModalBack{position:fixed;inset:0;background:var(--dim-sheet);z-index:400}
  #taskModal{position:fixed;top:0;right:0;bottom:0;left:auto;width:min(560px,96vw);height:100vh;
    border:0;border-radius:var(--r-panel) 0 0 var(--r-panel);box-shadow:var(--sh-float);z-index:401}
  /* v1.09 — 판매매체 기본 정보 카드 : 대표·재무가 아니면 읽기 줄 (권한을 미리 보인다) */
  #mBaseCard.ro .pf-v.editable{pointer-events:none;cursor:default}
  #mBaseCard [data-part="retire"]{margin-top:14px;padding-top:12px;border-top:1px solid var(--line-soft);display:flex;justify-content:flex-start}   /* ★ 과제 454 — 학교 승인 [은퇴] 줄(옛 .tm-foot 값 그대로 · 발 없는 예외 §12-000) */
  .tm-foot{margin-top:14px;padding-top:12px;border-top:1px solid var(--line-soft);
      display:flex;justify-content:flex-start;gap:var(--gap-tool)}   /* ★ 과제 491 디자인수정 2 [1](디자이너 10) — 발 단추 사이 8(v354 「팝업 발 단추 사이」 · 옛 = 0 이라 [삭제][쉼으로] 붙음) */
  #campInfoBack{position:fixed;inset:0;background:var(--dim-modal);z-index:440}
  #campInfoModal{position:fixed;top:50%;left:50%;right:auto;bottom:auto;transform:translate(-50%,-50%);
    width:min(820px,96vw);max-height:86vh;border:1px solid var(--line);border-radius:var(--r-panel);box-shadow:var(--sh-float);z-index:441;background:var(--bg-card)}   /* ★ 과제 479c — 폭 820 · 흰 바탕 = 늘(옛 [data-host] 옮겨 담기 끝) */
  /* ★ v2.94 (과제 144 · 규칙 126) — 1층에서 연 요약 = 오른쪽 · 창 높이 전부 · 딤 옅게(등록 · 상세 팝업과 같은 자리) · 2층이면 위 가운데 그대로 */
  #campInfoModal[data-side]{top:0;right:0;bottom:0;left:auto;transform:none;height:100vh;max-height:none;border:0;border-radius:var(--r-panel) 0 0 var(--r-panel)}
  #campInfoBack[data-side]{background:var(--dim-sheet)}

  /* ══ v2.15 (09-17 · 대표 컨펌 시안 24판) — **할 일 = 표 하나에서 모든 일** (규격 = 시제품/…260917…할일화면시안_목록칸반달력_v212.html)
     큰 상자 하나(#taskBox) = 도구 줄 · 1px 선 · 카드 다섯 · 카드 사이 16 · 카드 안 표 상자(선 · 라운드 8 · 회색 머리줄 44 · 몸줄 44 · 세로줄)
     열 = ☐44 · 업무명 170~ · 광고주 100~ · 캠페인 190~ · 담당자 210 · 마감일 184 · 상태 140 · 내용 210~(2fr) · 🗑40 · 최소 합 1288
     팝 규격 하나(.tk-pop) = Filter 팝 · 담당자 팝 · 상태 팝 · 검색 결과 팝 : 줄 26 · 체크 14 · 글자 12 · 안여백 4 · 칸 아래 6px · 폭 = 칸
     ⚠ 이름은 전부 tk- 접두어 — 화면에 있는 이름(mini·warn·pill·bad…)과 겹치면 다른 부품이 깨진다(시안 5판·18판 실측) ══ */
  #taskBox.card{background:var(--bg-card);border:1px solid var(--line);box-shadow:var(--sh-card);padding:0;overflow:visible;margin-bottom:0}   /* .card:has(> #taskList) 의 투명 규칙을 이긴다 */
  #task h3.toolsonly[hidden]{display:none}
  .tk-tools{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:16px 24px;border-bottom:1px solid var(--line);position:relative}
  .tk-search{position:relative;display:block;flex:0 1 clamp(190px,20vw,270px)}
  .tk-search input{width:100%;height:32px;padding:0 10px 0 30px;box-shadow:none;border:1px solid var(--line-tool);border-radius:var(--r-pill);background:var(--bg-card)}   /* v4 지침 F-3 — 검색 = 알약 */
  .tk-search input:focus{border-color:var(--accent);box-shadow:var(--ring)}
  .tk-search::before{content:"";position:absolute;left:10px;top:50%;width:14px;height:14px;margin-top:-7px;pointer-events:none;
      background:var(--text-3);-webkit-mask:var(--ic-search) center / contain no-repeat;mask:var(--ic-search) center / contain no-repeat}
  #tkTools button.ghost{height:32px;box-shadow:none;border:1px solid var(--line);border-radius:var(--r-ctl);background:var(--bg-card);display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
  #tkTools button.ghost:hover{background:var(--bg-fill)}
  #tkTools button.ghost svg{width:14px;height:14px}
  #tkTools button.tk-tgl[aria-pressed="true"]{background:var(--bg-active);border-color:var(--accent);color:var(--accent)}   /* 파랑 = 켜짐(§1) */
  #tkTools .seg{height:32px;box-sizing:border-box;align-items:center;flex:0 0 auto}
  #tkTools .seg button{height:26px;display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
  #tkTools .seg button[disabled]{opacity:.45;cursor:default}
  /* ★ v2.40 (과제 104) — 위 display 가 UA 의 [hidden]{display:none} 을 이긴다(§2339 와 같은 함정) → 되찾는다.
     칸반 단추를 감추는 자리 : 되살리기 = index.html 의 hidden 한 낱말을 지우면 된다(코드는 보존). */
  #tkTools .seg button[hidden]{display:none}
  #univPrevWrap .btns button[hidden]{display:none}   /* ★ 과제 368a — 같은 함정 : 점검판 [번호표 매기기] 는 미리 보기 뒤 · 번호표 전에만 보여야 한다 */
  #univNameDiff label.univ-cand{display:flex;align-items:center;gap:var(--gap-tool);margin:0;padding:var(--gap-tool) 0}   /* ★ 과제 368a — 이름 다름 후보 체크 줄(한 줄에 하나 · 토큰만) */
  #univNameDiff label.univ-cand > input[type=checkbox]{width:auto;flex:0 0 auto;margin:0}   /* ★ 과제 368a — 전역 input{width:100%} 이 체크 칸을 늘려 글이 오른쪽 끝으로 밀림(과제 143 과 같은 함정 · 사진 1 로 찾음) */
  #ownPrevWrap .btns button[hidden]{display:none}   /* ★ 과제 401 — 같은 함정 : button{display:flex} 가 [hidden] 을 이겨 점검판 [첫 적재](367a 부터) · [옮기기] 가 숨김인데 보였다 */
  #tkTools .seg svg{width:14px;height:14px}
  #tkAdd{height:32px;padding:0 14px;font-weight:var(--weight-medium);white-space:nowrap}   /* ★ 과제 414a — v4 단추 글 = 450(지침 B · 다른 화면 주 단추와 한 값) */
  .tk-sp{flex:1 1 auto}
  .tk-cnt{font-size:var(--fs-sm);color:var(--text-2);margin:0 4px;white-space:nowrap}
  .tk-fwrap{position:relative;display:inline-flex}
  /* ★ v2.41 (09-21 대표 「큰 박스 높이가 낮아 작은 박스가 삐져나온다」) — **max-height 를 함께 풀어야 한다.**
     `#taskList` 는 `class="scrolltbl"` 을 달고 있어 `.scrolltbl{max-height:64vh;overflow:auto}`(§308)를 받는다.
     앞서 안쪽 스크롤만 끄고(`overflow:visible`) 높이 상한을 안 풀어, 상자가 64vh 에서 멈추고 나머지가 **밖으로 새어 나왔다**
     (창 1100 → 상자 704 · 내용 927 · 198 삐져나옴 · **List 보기도 넷째·다섯째 카드가 69·141 삐져나와 있었다**).
     이제 상자가 내용만큼 자라고 **페이지가 스크롤된다**(안쪽 스크롤 두 겹 없음). 되돌리기 = 이 `max-height:none` 한 낱말. */
  #taskList{padding:20px 24px 24px;overflow:visible;max-height:none}
  /* ★★ 과제 274 (10-01 · G-030 대표 답 「할 일을 다른 화면에 맞춤」 · 규칙 124 대표 예외 — 할일불변 기준 다시 찍음) — **할 일 한 겹**
     옛 = 도구 줄 바깥 24(공용 .card:has(> h3.toolsonly) > * 의 좌우 24) + 안 24 = 검색칸 48 · 목록 상자 바깥 24 + 안 24 = 카드 48 · Dashboard = 그 안 24 더 = 72 · 위 60
     → 다른 표 화면과 같이 : 도구 줄 바깥 0(선 = 끝에서 끝) · 목록 = 바깥 24 · 안 0(카드 들임 24 · 도구 줄 → 첫 카드 20) · Dashboard = 위 0 + tk-dash 안 20 · 24 → 타일 들임 48 · 도구 줄 → 타일 20
     로직 · id · 네 카드 구조 · 색 · 라운드 = 그대로(CSS 만) */
  #taskBox > .tk-tools{margin-left:0;margin-right:0}
  #taskBox > #taskList{padding:0;margin:var(--gap-tool-body) var(--card-pad-x) var(--card-pad-x)}
  #taskBox > #taskList:has(> .tk-dash){margin-top:0}
  #taskList>p.muted{margin:0}
  /* ── 팝 규격 하나 ── */
  .tk-pop{background:var(--bg-card);border-radius:var(--r-ctl);box-shadow:var(--sh-pop);padding:4px;box-sizing:border-box;position:absolute;z-index:430}
  .tk-fpop{top:38px;left:0;z-index:5;display:none;min-width:172px}
  .tk-fpop.tk-open{display:block}
  .tk-fsec{padding:2px 0}
  .tk-fsec + .tk-fsec{border-top:1px solid var(--line);margin-top:4px;padding-top:6px}
  .tk-fttl{height:22px;display:flex;align-items:center;padding:0 8px;font-size:var(--fs-cap);color:var(--text-2);font-weight:var(--weight-medium)}
  .tk-frow{display:flex;align-items:center;gap:8px;height:26px;padding:0 8px;margin:0;border-radius:var(--r-inner);cursor:pointer;user-select:none;
      font-size:var(--fs-cap);color:var(--text);white-space:nowrap;overflow:hidden}
  .tk-frow:hover{background:var(--bg-hover)}
  .tk-frow.tk-sel{background:var(--bg-active)}
  .tk-frow.tk-hi{background:var(--bg-active)}
  .tk-frow.tk-hide{display:none}
  .tk-frow.tk-new{color:var(--accent)}
  .tk-frow:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
  .tk-frow .tk-nm{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
  .tk-frow .ccode{margin-right:0}
  .tk-frow .tk-role{margin-left:auto;font-size:var(--fs-cap);color:var(--text-3)}
  .tk-pop .tk-frow input[type="checkbox"]{appearance:none;-webkit-appearance:none;width:14px;height:14px;min-width:0;min-height:0;padding:0;margin:0;flex:0 0 auto;
      border:1px solid var(--line-input);border-radius:var(--r-key);background:var(--bg-card);display:grid;place-content:center;cursor:pointer;box-shadow:none}   /* ⚠ 전역 input{width:100%} 이 체크를 늘린다 · 과제 479 — 적는 칸 테 = 회색 1px 한 벌 */
  .tk-pop .tk-frow input[type="checkbox"]:checked{background:var(--accent);border-color:var(--accent)}
  .tk-pop .tk-frow input[type="checkbox"]:checked::after{content:"";width:3px;height:7px;border:solid var(--on-fill);border-width:0 2px 2px 0;transform:rotate(45deg) translate(-1px,-1px)}
  .tk-pop .tk-frow .pill{height:20px;font-size:var(--fs-cap);padding:0 8px}
  .tk-pop .tk-frow .uchip{height:20px}
  .tk-fall{display:flex;align-items:center;justify-content:space-between;height:30px;padding:4px 8px 0;margin-top:4px;border-top:1px solid var(--line);box-sizing:border-box;
      font-size:var(--fs-cap);font-weight:var(--weight-strong);color:var(--ink)}
  .tk-fallbtn{width:16px;height:16px;min-height:16px;padding:0;border:1px solid var(--line-input);border-radius:var(--r-key);background:var(--bg-card);color:var(--ink);
      display:grid;place-content:center;box-shadow:none;font-size:var(--fs-cap);line-height:1}
  .tk-fallbtn:hover{background:var(--bg-hover)}
  h3 .tools .tk-fpop .tk-fallbtn{width:16px;height:16px;min-height:16px;padding:0;border:1px solid var(--line-input)}   /* v2.87 (과제 157 · 기획 지적) — 도구 줄 안 [필터] 팝의 「전체 선택」 칸이 h3 .tools button(32 · 14) 옷을 받아 커졌다 → 할 일 팝과 같은 16 칸 */
  .tk-fhint{height:22px;display:flex;align-items:center;padding:0 8px;margin-top:4px;border-top:1px solid var(--line);font-size:var(--fs-cap);color:var(--text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .tk-fsrch{padding:2px 4px 4px}
  .tk-fsrch input{height:26px;width:100%;box-sizing:border-box;padding:0 8px;font-size:var(--fs-cap);border:1px solid var(--line);border-radius:var(--r-inner);box-shadow:none;background:var(--bg-card)}
  .tk-fsrch input:focus{border-color:var(--accent);box-shadow:var(--ring)}
  /* ── 카드 다섯 ── */
  #taskList>.tk-card{padding:0;overflow:hidden;margin-bottom:16px;transition:box-shadow var(--duration-fast) var(--ease)}
  #taskList>.tk-card:last-child{margin-bottom:0}
  .tk-card.tk-drop{box-shadow:var(--ring)}
  .tk-h{display:flex;align-items:center;gap:10px;padding:14px 24px;user-select:none}
  .tk-gchip{display:inline-flex;align-items:center;gap:8px;height:26px;padding:0 10px 0 8px;border-radius:var(--r-ctl);font-size:var(--fs-body);font-weight:var(--weight-strong);white-space:nowrap}
  .tk-gchip .tk-bar{width:3px;height:14px;border-radius:2px;background:currentColor}
  .tk-g-bad{background:var(--bad-bg);color:var(--bad)} .tk-g-warn{background:var(--warn-bg);color:var(--warn)} .tk-g-purple{background:var(--purple-bg);color:var(--purple)}
  .tk-g-blue{background:var(--accent-soft);color:var(--accent)} .tk-g-ok{background:var(--ok-bg);color:var(--ok)}
  .tk-chev{margin-left:2px;width:26px;height:26px;min-height:26px;padding:0;border:0;background:transparent;box-shadow:none;border-radius:var(--r-inner);color:var(--text-3);display:inline-flex;align-items:center;justify-content:center}
  .tk-chev:hover{background:var(--bg-hover);color:var(--ink)}
  .tk-chev:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
  .tk-chev svg{transition:transform var(--duration-base) var(--ease)}
  .tk-card.tk-closed .tk-chev svg{transform:rotate(-90deg)}
  /* ★ v2.24 (대표 컨펌 09-18) — 카드 머리 화살표 **오른쪽 ＋** : 그 카드의 날짜로 새 할 일.
     화살표와 같은 부품(.tk-chev)을 그대로 쓰고 글자만 바꾼다 — 새 부품을 만들지 않는다(DESIGN §7).
     접힌 카드에서 화살표만 도는데 ＋ 까지 돌면 안 되므로 transform 을 막는다. */
  .tk-cadd{font-size:var(--fs-body);line-height:1;font-weight:var(--weight-strong)}
  /* ★ 과제 321 ⑦(대표 사진 2 · 「＋ 아이콘 화살표 아이콘 옆으로」) — ⌄ 와 ＋ 한 묶음 : 사이 = 아이콘 간격(--gap-tool / 2) · 옛 = 머리 gap 10 + 여백 2 로 벌어짐 */
  .tk-hbtns{display:inline-flex;align-items:center;gap:calc(var(--gap-tool) / 2)}
  .tk-hbtns > .tk-chev{margin-left:0}
  .tk-card.tk-closed .tk-cadd{transform:none}
  /* ★ v2.24 — 단추 안의 단축키 표기. 표 글자보다 작지 않게 캡션 바닥(--fs-cap)을 쓴다(규칙 = 글자 6단 밖 금지). */
  .tk-kbd{margin-left:8px;padding:0 4px;border-radius:var(--r-key);font-size:var(--fs-cap);font-weight:var(--weight-medium);
          background:color-mix(in srgb, currentColor 18%, transparent);opacity:.9;
          color:var(--text-3);font-variant-numeric:tabular-nums}   /* v2.68 (과제 130) — 칸반 마감일(.tk-kdue)과 겹쳐 받던 색·고정폭을 제 자리에 적음 · 09-23 대표 지적 「작고 옅게」로 메뉴 키캡 .kbd 와 한 벌(값을 바꾸면 둘 다) */
  /* ★ 과제 205 — 화면마다 주 등록 단추 옆 흐린 「N」(할 일 .tk-kbd 와 같은 값 · 글을 JS 가 바꿔도 안 사라지게 ::after) */
  button[data-hotn]::after{content:'N' / '';margin-left:8px;padding:0 4px;border-radius:var(--r-key);font-size:var(--fs-cap);font-weight:var(--weight-medium);
          background:color-mix(in srgb, currentColor 18%, transparent);opacity:.9;color:var(--text-3);font-variant-numeric:tabular-nums}
  /* ★ 과제 205 검토(12:02 · v304 ⓚ · v308 n7) — 「N」(+31px)을 더해도 지출 도구 줄 한 줄 : 1440~1599 는 **보기 단추만** 조임(여백 12 → 5 · 숫자 틈 6 → 3 = 다섯 단추 70px) ·
     1439 아래는 도구 줄 틈 8 → 4 · 새 등록 여백 · 지출 칸의 「N」 은 조금 좁게(실측 1280 72 → 32 · 1440 72 → 32)
     ⚠ [필터] · 「내가 만든 것」 여백은 1440 에서 안 줄인다 — v270 ⓑ ⓒ 가 1440 에서 할 일 옷(12)과 맞대므로(12:44 실측 아니오 둘 → 뺌 · 205 는 main 위이므로 203 의 1439 아래 조이기와 겹치지 않음) */
  @media (min-width:1440px) and (max-width:1599px){
    #spend h3.toolsonly #spSeg button{padding-left:5px;padding-right:5px}
    #spend h3.toolsonly #spSeg button .kbds{margin-left:3px}
  }
  @media (max-width:1439px){ #spend h3.toolsonly .tools{gap:4px} #spend h3.toolsonly .tk-left{gap:4px} #spNewBtn{padding-left:8px;padding-right:8px} }
  /* ★ 과제 232(병합 확인 21:38 ② — 203 판 되살림 · 203 되돌림 때 빠졌음) — 1440 아래 지출 도구 줄 : 보기 단추 여백 12 → 5 · 숫자 틈 6 → 3 · [필터] · 「내가 만든 것」 여백 → 8
     (보기 단추 다섯 532px + 205 의 「N」 · 1280 실측 1004 > 950 → 「내가 만든 것」 이 둘째 줄) · 검색 하한 190 · 글자 크기 · 단축키 숫자 그대로 */
  @media (max-width:1439px){
    #spend h3.toolsonly #spSeg button{padding-left:5px;padding-right:5px}
    #spend h3.toolsonly #spSeg button .kbds{margin-left:3px}
    #spend h3.toolsonly .tk-left > button.ghost.mini,#spend h3.toolsonly .tk-fwrap > button{padding-left:8px;padding-right:8px}
  }
  #spend h3.toolsonly button[data-hotn]::after{margin-left:4px;padding:0 3px}
  .tk-card.tk-closed .tk-body{display:none}
  .tk-drophint{margin-left:auto;font-size:var(--fs-cap);color:var(--accent);display:none}
  .tk-card.tk-drop .tk-drophint{display:inline}
  /* ★ v2.40 (과제 104 · 09-21 대표 결정) — 할 일 Dashboard. 부품은 홈·목록의 것 그대로(.stat · .hweek · .clrow · .st · 사람 동그라미) —
     가로 막대(.tk-hbar · .tk-dstack)만 주간 막대 트랙을 눕힌 것(DESIGN §6-6 등재). 값은 전부 토큰. */
  .tk-dash{padding:20px 24px 24px;display:grid;gap:16px}
  .tk-dstats{grid-template-columns:repeat(4,minmax(0,1fr));margin-bottom:0}
  /* ★ 과제 430c — 요약 첫 줄 = 「지금 할 일」(첫 칸 · 넓게) + 뜻 있는 타일(data-dn = 보이는 타일 수 · core.js dashFoldSync) · 0 인 타일 = 접힌 줄(온 폭) · 셋 이상 = 「지금 할 일」 이 한 줄 · 타일은 그 아래 */
  .tk-dstats[data-dn="0"]{grid-template-columns:minmax(0,1fr)}
  .tk-dstats[data-dn="1"]{grid-template-columns:minmax(0,3fr) minmax(0,1fr)}
  .tk-dstats[data-dn="2"]{grid-template-columns:calc((100% - var(--gap-card-x)) / 2) repeat(2,minmax(0,1fr))}   /* ★ 과제 530 ②(525 ④ A) — 「지금 할 일」 = 아래 두 칸 줄(.tk-dtwo · 틈 16 = --gap-card-x)의 왼쪽 반과 같은 폭 · 옛 2fr = 타일 틈 12 로 나눠 4px 좁았음(1440 568 ↔ 572) */
  .tk-dstats[data-dn="3"]{grid-template-columns:repeat(3,minmax(0,1fr))}
  .tk-dstats[data-dn="4"]{grid-template-columns:repeat(4,minmax(0,1fr))}
  .tk-dstats[data-dn="5"]{grid-template-columns:repeat(5,minmax(0,1fr))}
  .tk-dstats[data-dn="3"] > [data-dcard="dnow"],.tk-dstats[data-dn="4"] > [data-dcard="dnow"],.tk-dstats[data-dn="5"] > [data-dcard="dnow"]{grid-column:1/-1}
  .tk-dstats > [data-dcard="dnow"]{margin:0;min-width:0}
  .tk-dstats > [data-dcard="dnow"] .tk-dh .pill{flex:none}
  .tk-dstats > [data-dcard="dnow"] .htask{gap:10px;white-space:nowrap}
  .tk-dstats > [data-dcard="dnow"] .htask .ht-mid{display:flex;align-items:baseline;gap:10px;min-width:0;overflow:hidden}
  .tk-dstats > [data-dcard="dnow"] .htask .ht-t{flex:none;max-width:100%}
  .tk-dstats > [data-dcard="dnow"] .htask .ht-c{min-width:0}
  .tk-dstats > [data-dcard="dnow"] .htask .tk-dmore,.tk-dstats > .stat .tk-dmore{flex:none}
  .tk-dstats > .stat .tk-dmore{display:block;margin:6px 0 0;text-align:right}
  #vDashView .tk-dstats:not([data-dn]):not(:has(> :nth-child(4))){grid-template-columns:repeat(3,minmax(0,1fr))}   /* ★ 과제 186 — AE = 지급액 타일 없음 → 셋이 빈칸 없이 */
  #spend:not(.sp-ae) #spDashView .tk-dstats:not([data-dn]){grid-template-columns:repeat(5,minmax(0,1fr))}
  @media (max-width:1599px){ #spend:not(.sp-ae) #spDashView .tk-dstats .stat .v{font-size:var(--fs-page);white-space:nowrap} }   /* ★ 과제 184 — 타일 다섯이면 1440 에서 「4,756,400원」 이 두 줄로 꺾였다 → 좁을 때만 숫자 한 단 작게 · 한 줄 */   /* ★ 과제 184 — 지출(대표 · 재무) = 타일 다섯(「예정일 지남」 을 「7일 안 지급」 에서 가름 · 증빙 누락 그대로) */
  #spDashView .tk-dlist .late{color:var(--bad);font-weight:var(--weight-strong)}
  /* ★ 과제 202 — 지출 상세 : 제목 = 지출 내용(본문 큰 이름 숨김 · 캠페인 상세 197 과 같게) · 돈 = 지급액 크게 한 줄 + 아래 작게 공급가 · 부가세 */
  #spDetail .cdhead{display:none}
  #spDetail > .refcard,#spDetail > h3,#spDetail > #spEvCard > h3:first-child{margin-top:var(--gap-group)}   /* ★ 과제 568 — 지출 상세 묶음 경계 넷(세부정보 → 캠페인 · 두 칸 → 증빙 · 증빙 → 증빙 정리 · → 지급 · 옛 = spend.js 인라인 14 · dt-band 18) · 머리 아래 · 옷 = 그대로(§12 옷 갈아입히기 = 따로) */
  #spDetail .sp-big{font-size:var(--fs-page);font-weight:var(--weight-strong);font-variant-numeric:tabular-nums}
  #spDetail .sp-sub{font-size:var(--fs-cap);margin-top:2px;font-variant-numeric:tabular-nums}
  #spDetBtns #spDetPaid{align-self:center}   /* ★ 과제 184 — 지급할 것 : 예정일 지난 날 = 빨강 */
  /* ★ 과제 199 (걷기 2차 · 1280) — 타일 다섯이 1400 아래에서 좁아져 「4,756,400원」 이 아이콘 밑으로 파고들고 알약이 타일 밖으로 나갔다
     → 1400 아래 = 셋씩 두 줄(글자를 더 줄이지 않는다) · 「지급할 것」 지급액 칸 = 금액이 다 들어가는 폭(금액은 말줄임 금지) */
  @media (max-width:1399px){ #spend:not(.sp-ae) #spDashView .tk-dstats:not([data-dn]){grid-template-columns:repeat(3,minmax(0,1fr))} }
  #spDashView .tk-dlist .clrow{grid-template-columns:minmax(0,1.5fr) minmax(0,.8fr) minmax(120px,1fr)}
  /* 할 일 밖 Dashboard 의 타일 알약 = **한 줄**(넘치면 말줄임 · 풍선말 = 공용 autoTitleScan) · 할 일 화면은 잣대라 안 건드림 · 규칙 124
     ★ 과제 342(10-08 대표 UX 점검) — 옛 = white-space:normal(타일 안에서 꺾임) → 알약 높이는 20px 로 못박혀 있어 글만 두 줄이 되고 배경이 반 줄에서 끊겼다 */
  .dash-host .tk-dstats .stat .delta{max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:inline-block}
  @media (max-width:599px){ .dash-host .tk-dstats .stat .delta .dmoney,.dash-host .tk-dstats .stat .k .dmoney{display:none} }   /* ★ 과제 530 ③ — 타일 이름 옆 보조글 뒤 조각도(「받을 돈 입금 전」 · core.js dashSubHtml) */   /* ★ 과제 523 2차(디자이너 ㉢) — 폰 타일 둘씩 = 표시는 건수만(「지남 1건」) · 금액 = title · 목록(core.js dashDeltaHtml) */
  /* 알약 줄은 아이콘 칸 밑까지 씀(타일 폭 전부) — 몸 칸만 쓰면 「지난달보다 ▲1,9…」 처럼 금액이 잘림(금액 말줄임 금지)
     아이콘 = 오른쪽 위 고정(제자리 · 18 · 20 = .stat 안여백) · 몸은 타일 폭 전부 · 라벨 · 숫자 줄만 아이콘 자리(40 = .tile.lg + 12 = .stat gap)를 비움 — 높이 · 넘침 그대로(새 값 아님) */
  .dash-host .tk-dstats .stat{position:relative}
  .dash-host .tk-dstats .stat > .tile{position:absolute;top:18px;right:20px}
  .dash-host .tk-dstats .stat > .body > :not(.delta-slot){padding-right:calc(40px + 12px)}
  .tk-dash .stat{cursor:pointer}
  .tk-dash .stat:focus-visible{outline:none;box-shadow:var(--ring)}
  /* ★ v2.42 (09-21 대표 「6개 할일은 모두 동일한 폭사이즈로」) — 세 줄 모두 반반. 종전엔 첫 줄만 1.45 : 1 이라
     여섯 카드의 폭이 두 가지였다. `.even` 은 이제 필요 없지만 남겨 둔다(다른 데서 쓰면 같은 값). */
  .tk-dtwo,.tk-dtwo.even{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px}
  .tk-dcard{padding:0;min-width:0}
  /* ★ 과제 170 — 넓은 카드(상담 추이) · ⓘ 셈 규칙 · 추이 차트 · 필터 적용 중 한 줄 */
  .tk-dtwo.tk-dwide{grid-template-columns:minmax(0,1fr)}
  /* ★ 과제 244 — 한 줄 세 칸(광고주 업종 · 서비스 · 지역) · 카드 아닌 띠(인사이트 · 설명) — dashGrid three · strip */
  .tk-dtwo.tk-dthree{grid-template-columns:repeat(3,minmax(0,1fr))}
  .tk-dstrip{display:grid;grid-template-columns:repeat(auto-fit,minmax(0,1fr));gap:16px}
  .tk-dstrip:has(> .adv-foot){display:block}
  .adv-ins{border:1px solid var(--line);border-left:4px solid var(--accent);border-radius:var(--r-ctl);background:var(--bg-card);padding:10px 14px;font-size:var(--fs-sm);color:var(--text-2)}
  .adv-ins b{color:var(--text);font-weight:var(--weight-strong)}
  .adv-foot{margin:8px 0 0;font-size:var(--fs-cap);color:var(--text-3)}
  .adv-rank{display:grid;grid-template-columns:24px 150px minmax(60px,1fr) 176px;align-items:center;gap:12px;padding:8px 10px;border-radius:var(--r-ctl);cursor:pointer}
  .adv-rank:hover,.adv-rank:focus-visible{background:var(--bg-hover)}
  .adv-rank.me{background:var(--bg-active)}
  .adv-rk{color:var(--text-3);font-variant-numeric:tabular-nums;text-align:right}
  .adv-rbar{display:block;position:relative;height:10px;background:var(--bg-hover);border-radius:var(--r-ctl);overflow:hidden}
  .adv-rbar i{position:absolute;left:0;top:0;bottom:0;border-radius:var(--r-ctl)}
  .adv-rbar i.rv{background:var(--brand-300)} .adv-rbar i.mg{background:var(--accent)}
  .adv-rv,.adv-byv{display:flex;flex-direction:column;align-items:flex-end;line-height:1.35;font-variant-numeric:tabular-nums}
  .adv-rv .muted,.adv-byv .muted{font-size:var(--fs-cap);white-space:nowrap}
  .adv-back{display:grid;grid-template-columns:minmax(0,1fr) auto 120px;gap:12px;align-items:center;padding:7px 6px;border-bottom:1px solid var(--line-soft);cursor:pointer;font-size:var(--fs-sm)}
  .adv-back:hover,.adv-back:focus-visible{background:var(--bg-hover)}
  .adv-back .r,.adv-top .r{text-align:right;font-variant-numeric:tabular-nums}
  .adv-by{display:grid;grid-template-columns:84px minmax(40px,1fr) auto;column-gap:10px;row-gap:2px;align-items:center;padding:6px;border-radius:var(--r-ctl);cursor:pointer}
  .adv-by .adv-bys{grid-column:2 / 4;text-align:right;font-size:var(--fs-cap);color:var(--text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .adv-by .adv-bym{font-variant-numeric:tabular-nums;font-weight:var(--weight-strong);text-align:right}
  .adv-by:hover,.adv-by:focus-visible,.adv-top:hover,.adv-top:focus-visible{background:var(--bg-hover)}
  .adv-byk{font-weight:var(--weight-strong);font-size:var(--fs-sm);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .adv-top{display:grid;grid-template-columns:24px 120px minmax(0,1fr) 120px;gap:12px;align-items:center;padding:5px 6px;border-radius:var(--r-ctl);cursor:pointer;font-size:var(--fs-sm)}
  /* ★ 과제 244 — 광고주 상세 「실적」 판(여섯 칸 · 읽기) · 산 서비스 한 줄 · 캠페인 카드 밑 돈 한 줄 */
  /* ★ 과제 453 (팝업 흡수 C1) — 광고주 상세 「실적」 숫자 판 = 화면 접두어(.adv-perf · .adv-pc) → 이 화면 id 규칙(#advPerf · #advPerfL) · 값 그대로 */
  #advPerf{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));border:1px solid var(--line);border-radius:var(--r-ctl);overflow:hidden}
  #advPerf > div{padding:12px 14px;border-right:1px solid var(--line-soft);border-bottom:1px solid var(--line-soft)}
  #advPerf > div:nth-child(3n){border-right:0} #advPerf > div:nth-child(n+4){border-bottom:0}
  #advPerf > div > .k{font-size:var(--fs-sm);color:var(--text-2)} #advPerf > div > .v{font-size:var(--fs-card);font-weight:var(--weight-strong);font-variant-numeric:tabular-nums;margin:2px 0}
  #advPerf > div > .s{font-size:var(--fs-cap);color:var(--text-3);min-height:1.3em}
  #advPerfL{margin:8px 0 16px;font-size:var(--fs-sm);color:var(--text-2)} #advPerfL b{color:var(--text)}
  .adv-cm{margin:-4px 0 10px;padding:0 4px;font-size:var(--fs-cap);color:var(--text-2);font-variant-numeric:tabular-nums}
  .adv-lowrow{grid-template-columns:minmax(0,1fr) 120px 110px 64px;min-width:0}
  @media (max-width:1399px){ .tk-dtwo.tk-dthree{grid-template-columns:minmax(0,1fr)} .adv-rank{grid-template-columns:24px 120px minmax(40px,1fr) 170px} }
  .tk-dinfo{color:var(--text-3);cursor:help;font-size:var(--fs-sm)}
  /* ★ 과제 357(10-12 대표 「좋아」) — ⓘ 풍선 = 정렬 · 순위 · 누르는 법 · **Tab 으로 닿고 초점 · 마우스 올림 = 풍선**(옛 = title 만이라 키보드로 못 봄 · 규칙 134) · 떠 있는 것 = 그림자 허용 */
  .tk-dh:has(.tk-dinfo[data-tip]){position:relative}   /* ★ 과제 357 검토 — 풍선 기준 = 카드 머리(ⓘ 가 제목 끝에 있어도 카드 · 화면 안 · 폰 390 잘림 25곳 고침) */
  .tk-dinfo[data-tip]{border-radius:50%;outline:none}
  .tk-dinfo[data-tip]:focus-visible{box-shadow:var(--ring);color:var(--accent)}
  .tk-dinfo[data-tip]:hover::after,.tk-dinfo[data-tip]:focus::after{content:attr(data-tip);position:absolute;left:20px;top:calc(100% + 6px);z-index:30;
      width:max-content;max-width:min(280px, calc(100% - 40px));white-space:normal;padding:6px 10px;border-radius:var(--r-ctl);background:var(--ink);color:var(--bg-card);
      font-size:var(--fs-cap);font-weight:var(--weight-body);line-height:1.45;text-align:left;box-shadow:var(--sh-pop);pointer-events:none}
  .ld-trend-top{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:8px;flex-wrap:wrap}
  .ld-trend-segs{display:inline-flex;align-items:center;gap:8px}   /* ★ 과제 180 — [건수|금액] + [주|월|연] 나란히(같은 부품 .seg) */
  .ld-legend{display:flex;gap:14px;font-size:var(--fs-cap);color:var(--text-2)}
  .ld-legend i{display:inline-block;width:10px;height:10px;margin-right:5px;vertical-align:middle}
  .ld-legend i.ln{height:2px;border-radius:0}
  .ld-trend svg{display:block;width:100%;height:auto}
  .ld-note{margin:6px 0 0;font-size:var(--fs-cap);color:var(--text-3)}   /* ★ 과제 245 — 추이 아래 한 줄 설명(캠페인 [금액] 마진) */
  .ld-trend [data-tb]{cursor:pointer;outline:0}
  .ld-trend [data-tb]:hover .ld-hit,.ld-trend [data-tb]:focus-visible .ld-hit{fill:var(--bg-hover)}
  /* ★★ 과제 146 (대표 결정 1 · 기획 시안 09 · 10) — **상세 팝업 = 등록 팝업과 같은 옷** : 칸 이름 위 · 값 = 입력칸 모양 상자(선 --line · 32 · 라운드) · 두 칸 격자 · 긴 값 = 한 줄 전체
     고치는 법은 그대로(누르는 줄 = bindPropEdit) — 누르면 그 자리가 입력칸 · 저장 = 「✓ 저장됨」 · 실패 = 칸 밑 빨간 까닭 · 잠긴 칸(누를 수 없는 줄) = 흐리게 */
  .cdprops.dtform{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:14px 16px;margin:0 0 8px;border:0}
  .cdprops.dtform .cdprop{display:flex;flex-direction:column;align-items:stretch;gap:5px;border:0;padding:0;min-height:0;min-width:0}
  .cdprops.dtform .cdprop.wide,.cdprops.dtform .cdprop.stack,.cdprops.dtform .cdprop:has(> .pv[data-t="multiline"]){grid-column:1 / -1}
  .cdprops.dtform .cdprop > .pk{flex:none;width:auto;min-width:0;padding:0;font-size:var(--fs-sm);color:var(--text-2);font-weight:var(--weight-strong)}
  .cdprops.dtform .cdprop > .pv{position:relative;display:flex;align-items:center;gap:6px;flex:none;width:auto;min-width:0;min-height:32px;margin:0;
      padding:5px 11px;border:1px solid var(--line);border-radius:var(--r-ctl);background-color:var(--bg-card);font-size:var(--fs-body);color:var(--ink)}
  /* ★ 과제 353(10-08 대표 디자인 점검) — **읽기만 하는 값 = 상자 · 테두리 없음**(이름 작은 회색 위 + 값 본문 글 · 왼쪽 안여백 0 = 이름과 같은 줄) · **상자는 고치는 칸만**(옛 = 회색 채움 상자 → 눌러 고치는 칸으로 보였다 · 내 정보 「현재 연봉」)
     높이 · 자리는 그대로(테두리 투명 · min-height 32) — 단추 · 링크가 든 읽기 줄도 같이 상자 없음(링크 = 파랑 · 단추 = 제 모양이 누를 자리를 말한다 · 수정요청 10-09) */
  .cdprops.dtform .cdprop > .pv:not(.editable){background-color:transparent;border-color:transparent;padding-left:0;padding-right:0}
  .cdprops.dtform .cdprop > .pv.editable{cursor:text}
  .cdprops.dtform .cdprop > .pv.editable:hover{border-color:var(--line-input)}
  .cdprops.dtform .cdprop > .pv.editable:focus-visible{outline:0;border-color:var(--accent);box-shadow:var(--ring)}
  .cdprops.dtform .cdprop > .pv.editable:not(.pv-sel):hover:not(:has(input,select,textarea,.pv-saved))::after{content:'누르면 고침';margin-left:auto;padding-left:8px;font-size:var(--fs-cap);color:var(--text-3);white-space:nowrap}
  .cdprops.dtform .cdprop > .pv.pv-sel{padding-right:32px;background-image:var(--ic-chevron);background-repeat:no-repeat;background-position:right 12px center;background-size:12px}
  .cdprops.dtform .cdprop > .pv[data-t="multiline"]{align-items:flex-start;white-space:pre-wrap;min-height:64px}
  .cdprops.dtform .cdprop > .pv:has(> input, > select, > textarea){padding:0;border-color:transparent;background:none}
  /* ★ 과제 318 ⓑ — 고르는 칸(.pv-sel)을 고칠 때 : 위 줄보다 .pv-sel 줄(⌄ 그림 · 오른쪽 32)이 더 세서 칸 밖에 ⌄ 가 하나 더 · 고르기 칸이 32 좁았다 → 같은 세기로 끔 */
  .cdprops.dtform .cdprop > .pv.pv-sel:has(> select){padding:0;background:none}
  .cdprops.dtform .cdprop > .pv > input,.cdprops.dtform .cdprop > .pv > select,.cdprops.dtform .cdprop > .pv > textarea{width:100%;max-width:none;flex:1;margin:0}
  .pv-saved{margin-left:auto;padding-left:8px;font-size:var(--fs-cap);color:var(--ok);white-space:nowrap}
  .pk .pv-saved{margin-left:6px;padding-left:0;font-weight:var(--weight-body);transition:opacity .4s}   /* ★ 과제 193 — 칸 이름 옆 · 같은 줄 · 값 상자 높이 그대로 */
  .pv-saved.fade{opacity:0}
  .dt-band{grid-column:1 / -1;margin:0 0 18px;padding:10px 12px;background:var(--bg-fill);border-radius:var(--r-ctl);font-size:var(--fs-sm);color:var(--text-2)}
  /* ★ 과제 194 — 머리 띠 「마지막 수정」 = 누르면 띠 바로 아래 수정 이력(언제 · 누가 · 칸 · 앞 → 새) · 팝업을 겹치지 않는다 */
  .dt-band .dt-histlink{color:var(--accent);text-decoration:none}
  .dt-band .dt-histlink:hover{text-decoration:underline}
  /* ★ 과제 228 — 점검판 광고문의 맥박 줄 끝 「확인 필요 n건」 = 가리키는 것(파랑 · 브라우저 기본 파랑 아님) */
  #intakePulse a{color:var(--accent);text-decoration:none} #intakePulse a:hover{text-decoration:underline}
  .dt-hist{grid-column:1 / -1;margin:-10px 0 18px;padding:8px 12px;border:1px solid var(--line);border-radius:var(--r-ctl);
    font-size:var(--fs-sm);color:var(--text);max-height:240px;overflow:auto}
  .dt-hist .dt-hrow{padding:4px 0;border-bottom:1px solid var(--line-soft);overflow-wrap:anywhere}
  .dt-hist .dt-hrow:last-child{border-bottom:none}
  .dt-hist .dt-hwho{color:var(--text-2);font-variant-numeric:tabular-nums}
  .dt-hist b{font-weight:var(--weight-medium)}
  .stat .delta-slot:has(.dash-cmp){display:flex;flex-direction:column;align-items:flex-start;gap:4px}   /* ★ 과제 171 — 기준 알약 + ▲▼ = 늘 두 줄(짧아도 옆으로 붙지 않게 · 타일끼리 같은 모양) */
  .dash-fnote{display:flex;align-items:center;gap:8px;margin:var(--gap-tool-body) var(--card-pad-x) 0;font-size:var(--fs-sm);color:var(--text-2)}   /* 과제 274 — 옛 = 도구 줄 선에 붙고(0) 타일보다 24 왼쪽 → 도구 줄 아래 20 · 타일과 같은 왼끝 · 아래는 Dashboard 위 20 */
  .dash-fnote + .dash-fnote{margin-top:8px}
  .tk-dh{display:flex;align-items:center;gap:10px;padding:14px 20px 0;flex-wrap:wrap}
  .tk-dh h3{margin:0;font-size:var(--fs-card);font-weight:var(--weight-strong);color:var(--ink)}
  .tk-dh .muted{font-size:var(--fs-sm)}
  .tk-dmore{margin-left:auto;background:none;border:0;padding:0;box-shadow:none;height:auto;font-size:var(--fs-sm);color:var(--accent);cursor:pointer;white-space:nowrap}
  .tk-dmore:hover{text-decoration:underline;background:none}
  .tk-dbody{padding:12px 20px 18px}
  /* ★ v2.40 — #taskList 를 앞에 붙여야 한다. 옛 일곱 열 규칙 `#taskList .clrow{…min-width:1100px}`(§1084) 이
     id 우선순위로 이겨, 안 붙이면 대시보드 줄이 **폭 1100 으로 굳어 카드를 뚫고 나간다**(09-21 실측 : 카드 724 · 줄 1100). */
  /* ★ v2.42 — 여섯 카드가 반반이 되어 카드가 좁아졌다(724 → 611) → 고정 열을 줄이고 머리줄이 안 접히게 한다. */
  #taskList .tk-dlist .clrow{min-width:0;grid-template-columns:minmax(0,1fr) auto 76px 80px}   /* ★ 과제 340 — 다섯 칸 → 넷(광고주 · 캠페인 = 업무명 밑 작은 줄 · 담당 = 동그라미만) */
  #taskList .tk-dlist .clrow.clhead > div{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  #taskList .tk-ddone .clrow{min-width:0;grid-template-columns:minmax(0,1.6fr) minmax(0,1fr) 110px 80px}
  .tk-dlist .clrow.clhead{font-size:var(--fs-cap)}
  /* ★ v2.88 (과제 152) — 다른 화면 Dashboard(core.js dashGrid · 틀 .dash-host)의 카드 속 목록 = 세 칸(이름 · 사실 · 사람/값) · 칸 안은 한 줄 말줄임 · 할 일(#taskList) 규칙은 그대로 */
  .dash-host .tk-dlist .clrow{min-width:0;grid-template-columns:minmax(0,1.5fr) minmax(0,1.2fr) minmax(0,.9fr)}
  .dash-host .tk-dlist .clrow > div{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  /* ★★ 과제 191 (09-28 대표 시안 OK) — 발주 Dashboard : 작업자 진행판 · 캠페인별 진행 · 타일 다섯(대표 · 재무 = 「7일 안 지급」 · 지출 Dashboard 와 같은 꼴) */
  #odDashView .tk-dlist .clrow.od-wkp{grid-template-columns:minmax(130px,1.3fr) 56px 56px minmax(112px,1fr) 56px 56px minmax(110px,1.3fr) minmax(176px,1.2fr)}
  #odDashView .tk-dlist .clrow.od-cprog{grid-template-columns:minmax(200px,2fr) minmax(120px,1.4fr) 80px 72px minmax(150px,1.2fr)}
  #odDashView .od-bad{color:var(--bad);font-weight:var(--weight-strong)}
  #odDashView .tk-dlist .clrow.od-cprog > .od-cname{display:flex;align-items:center;gap:var(--gap-tool)}   /* 코드 칩 · 이름 = 한 줄 가운데 맞춤(옛 = 칩이 이름보다 위) · 이름만 말줄임 */
  #odDashView .od-cname > .ccode{flex:none}   /* 코드는 줄지 않음 — 좁으면 이름만 말줄임(폰 390 실측 「C26-0…」) */
  #odDashView .od-cname > .cl-clip{min-width:0;overflow:hidden;text-overflow:ellipsis}
  #odDashView .od-wkp-bar{display:flex;justify-content:flex-end;margin:0 0 var(--gap-tile)}
  /* ★ 과제 430c (시안 430 ② 09) — 현장 보기 줄 = 도구 줄 밑 표 머리 한 줄(「보기」 + .seg + 오른쪽 매체별 수) · 아래 1px 선 · 그림자 0 */
  #odViewBar{display:flex;align-items:center;gap:10px;padding:0 var(--card-pad-x) 10px;margin:0 0 12px;border-bottom:1px solid var(--line);min-width:0}   /* ★ 과제 523 — 옆 여백 = 카드 안 여백(옛 0 = 「보기」 · 오른쪽 안내가 카드 테에 붙음 · 카드 옆 패딩 0 뒤) */
  #odViewBar > #odViewLab{font-size:var(--fs-cap);color:var(--text-2);font-weight:var(--weight-medium);flex:none}
  #odViewBar > .seg{flex:none;max-width:100%;overflow-x:auto}
  #odViewBar > #odViewNote{margin-left:auto;font-size:var(--fs-sm);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  @media (max-width:760px){ #odViewBar > #odViewLab,#odViewBar > #odViewNote{display:none} #odViewBar > .seg{flex:1 1 auto;min-width:0} }   /* ★ 과제 523 2차(디자이너) — 폰도 옆 여백 = 카드 안 여백(보기 넷이 두 줄로 꺾여도 됨 · DESIGN 폰 두 줄 허용 · 여백 0 에서도 이미 두 줄) */
  /* 작업자 진행판 · 캠페인 진행 = 완료 0 이면 막대 없이 「0 / 3」 · 「아직 0곳」 글 · 1 이상 = 막대 + 글(한 줄) */
  #odDashView .clrow.od-wkp > :nth-child(7),#odDashView .clrow.od-cprog > :nth-child(2){display:flex;align-items:center;gap:8px;white-space:nowrap;min-width:0}
  #odDashView .clrow.od-wkp > :nth-child(7) > .tk-hbar,#odDashView .clrow.od-cprog > :nth-child(2) > .tk-hbar{flex:1;min-width:0}
  #odDashView .clrow.od-wkp > :nth-child(7) > .tk-dnum,#odDashView .clrow.od-cprog > :nth-child(2) > .tk-dnum{flex:none;font-size:var(--fs-sm);color:var(--text-2);font-variant-numeric:tabular-nums}
  #odDashView .tk-dstats:not([data-dn]):has(> :nth-child(5)){grid-template-columns:repeat(5,minmax(0,1fr))}
  @media (max-width:1399px){ #odDashView .tk-dstats:not([data-dn]):has(> :nth-child(5)){grid-template-columns:repeat(3,minmax(0,1fr))} }
  /* ★ 과제 191 — 폰(≤600) : 타일 = 한 줄에 하나(과제 274 공용 규칙을 위 id 규칙이 이기던 것) · 진행판 = 작업자 · 맡은 · 완료 · 늦음 한 줄 + 막대(사진 · 남음 · 시각 = 타일 · 표에서) · 캠페인 = 이름 / 막대 · 완료 / 결과보고 세 단 */
  @media (max-width:600px){
    #odDashView .tk-dstats:not([data-dn]):has(> :nth-child(5)){grid-template-columns:1fr}
    #odDashView .tk-dlist .clrow.od-wkp{grid-template-columns:minmax(0,1fr) 40px 40px 40px;grid-template-areas:"n a c l" "g g g g";row-gap:var(--gap-tool)}
    #odDashView .clrow.od-wkp > :nth-child(1){grid-area:n} #odDashView .clrow.od-wkp > :nth-child(2){grid-area:a} #odDashView .clrow.od-wkp > :nth-child(3){grid-area:c}
    #odDashView .clrow.od-wkp > :nth-child(6){grid-area:l} #odDashView .clrow.od-wkp > :nth-child(7){grid-area:g}
    #odDashView .clrow.od-wkp > :nth-child(4), #odDashView .clrow.od-wkp > :nth-child(5), #odDashView .clrow.od-wkp > :nth-child(8), #odDashView .clrow.clhead.od-wkp > :nth-child(7){display:none}
    #odDashView .tk-dlist .clrow.od-cprog{grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"n n" "g d" "r r";row-gap:var(--gap-tool)}
    #odDashView .clrow.od-cprog > :nth-child(1){grid-area:n} #odDashView .clrow.od-cprog > :nth-child(2){grid-area:g} #odDashView .clrow.od-cprog > :nth-child(3){grid-area:d} #odDashView .clrow.od-cprog > :nth-child(5){grid-area:r}
    #odDashView .clrow.od-cprog > :nth-child(4), #odDashView .clrow.clhead.od-cprog{display:none}
    #odDashView .tk-dlist .clrow.od-wkp > div, #odDashView .tk-dlist .clrow.od-cprog > div{border-right:0;padding-right:0}
  }
  .dash-host .tk-dlist.adv-one4 .clrow{grid-template-columns:minmax(0,1.2fr) minmax(0,.9fr) minmax(118px,1fr) minmax(0,.8fr)}   /* ★ 과제 185 — 두 번째 캠페인 앞둔 광고주 = 네 칸(첫 캠페인 금액 · 대표 · 재무) */
  /* ★ 과제 183 — 캠페인 「지금 손댈 것」 할 일 칸(「결과보고 전 · 끝난 지 21일」)이 1440 · 1280 에서 잘렸다 → 할 일 칸을 넓히고 두 줄까지(줄 키 44 안 · §11) */
  #cDashView [data-dcard="now"] .clrow{grid-template-columns:minmax(0,1.3fr) minmax(0,1.5fr) auto}   /* ★ 과제 340 — 담당 = 동그라미만(auto) */ #cDashView [data-dcard="now"] .clrow:not(.clhead) > div:nth-child(2){white-space:normal;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;line-height:1.35}
  /* ★ 과제 188 — 계산서 · 입금 Dashboard : 현금 흐름 표 = 네 칸(주 · 들어올 · 나갈 · 차액 · 돈 칸 오른쪽 맞춤) · 음수 차액 · 지난 날 = 빨강 · 예정일 지남 줄 = 흐린 바탕 · 「입금 예정 · 매출 대조」 = List 보기에만 */
  #bDashView .bill-cf .clrow{grid-template-columns:minmax(0,1.1fr) minmax(0,1fr) minmax(0,1fr) minmax(0,1fr)}
  #bDashView .bill-cf .clrow > div.r,#bDashView .bill-cf .clrow.clhead > div:not(:first-child){text-align:right}
  #bDashView .bill-cf .clrow.clhead > div:not(:first-child){justify-content:flex-end}   /* 머리 칸은 flex(정렬 단추 틀) — text-align 이 안 먹는다 */
  #bDashView .bill-cf .bill-cf-over{background:var(--surface-subtle)}
  #bDashView .bill-cf .bill-cf-lab{display:none}   /* ★ 과제 531 — 칸 이름 글(들어올 · 나갈 · 차액) = 폰 두 줄에서만(넓은 화면은 머리줄) */
  #bDashView .tk-dlist .late{color:var(--bad);font-weight:var(--weight-strong)}
  #bDashView .tk-dtwo > .card{margin-bottom:0}   /* ★ 과제 268 정산 — 격자 안 카드 = 격자 틈 16 한 번(할 일 · 카드↔카드 16) · 옛 = 틈 16 + 카드 아래 16 = 32 */
  #bill[data-bview="dash"] .bill-recon{display:none}
  /* ★ 과제 254 — 「주 마감」 보기(pages/weekclose.js) · 시안 v1 · 새 색 0(토큰만) */
  #fin:not([data-fview="week"]) #billWeek2{display:none}   /* ★ 과제 452 — 자리 = 재무 「마감」 보기(옛 = 계산서 · 입금 세 번째 보기 · #bill[data-bview="cal"]) */
  #billWeek .wk-head{padding:0 24px 20px}
  #billWeek .wk-nav{display:flex;align-items:center;gap:8px;margin-bottom:12px;font-size:var(--fs-body)}
  #billWeek .wk-tiles{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:12px}
  #billWeek .wk-tile{border:1px solid var(--line);border-radius:var(--r-card);padding:14px 16px;min-width:0;display:flex;flex-direction:column;gap:4px}
  #billWeek .wk-tile.short{border:2px dashed var(--warn-bg)}
  #billWeek .wk-th{display:flex;align-items:center;justify-content:space-between;gap:6px;font-size:var(--fs-sm);color:var(--text-2)}
  #billWeek .wk-tv{font-size:var(--fs-page);font-weight:var(--weight-strong);font-variant-numeric:tabular-nums}
  #billWeek .wk-ts{font-size:var(--fs-cap);line-height:1.4}
  #billWeek .wk-closebox{justify-content:center}
  #billWeek .wk-closebox button{width:100%}
  @media (max-width:1399px){ #billWeek .wk-tiles{grid-template-columns:repeat(3,minmax(0,1fr))} }
  body.pnl-push #billWeek .wk-tiles{grid-template-columns:repeat(3,minmax(0,1fr))}   /* ★ 과제 563 ③ — 오른쪽 창(판관비로 잇기)이 밀어 좁아지면 1399 아래와 같은 세 칸(옛 = 여섯 칸이 세로 글로 깨짐) */
  @media (max-width:760px){ #billWeek .wk-tiles{grid-template-columns:repeat(2,minmax(0,1fr))} #billWeek .wk-tile{word-break:keep-all} #billWeek .wk-th{flex-wrap:wrap} #billWeek .wk-th > span:first-child{flex:none} #billWeek .wk-closebox{grid-column:1 / -1} }   /* ★ 과제 478 — 폰 두 칸(카드 116) = 라벨이 먼저 자리(줄어듦 ✗ · 상태 알약은 다음 줄) · 낱말 중간 안 꺾음(「짝 남음 / 5건」) · 마감 단추 = 한 줄 다 */
  #billWeek2 .card h3{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
  #billWeek2 .card h3 .muted{font-size:var(--fs-sm);font-weight:var(--weight-body)}
  #billWeek2 .wk-all{margin-left:auto}
  #billWeek2 .wk-drop{display:flex;flex-direction:column;align-items:center;gap:4px;padding:22px;border:2px dashed var(--line);border-radius:var(--r-card);cursor:pointer;text-align:center}
  #billWeek2 .wk-drop.over,#billWeek2 .wk-drop:focus-visible{border-color:var(--accent);background:var(--accent-soft)}
  #billWeek2 .wk-sub{margin:14px 0 6px;font-size:var(--fs-sm)}
  #billWeek2 .wk-tbl{border:1px solid var(--line);border-radius:var(--r-ctl)}
  #billWeek2 .wk-tbl .clrow > .r{text-align:right;justify-content:flex-end;font-variant-numeric:tabular-nums}
  #billWeek2 .wk-tbl .clrow > div{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
  #wkUps .clrow{grid-template-columns:minmax(160px,1.5fr) 110px 232px 72px 84px 64px minmax(170px,1.4fr)}   /* 과제 279 뒤 — 기간 「26년 9월 28일 (월) ~ 10월 2일 (금)」 230 · 옛 170 */
  #wkRows .clrow{grid-template-columns:112px minmax(140px,1.3fr) 140px 36px minmax(150px,1.8fr) 96px 232px;align-items:center}
  #wkCloses .clrow{grid-template-columns:minmax(236px,1.5fr) repeat(5,minmax(90px,1fr)) 72px minmax(200px,1.2fr)}
  #wkRows .wk-arr{padding:0;text-align:center;justify-content:center}
  #wkCloses .wk-by{display:flex;flex-wrap:wrap;column-gap:6px;align-items:center}
  @media (max-width:1399px){ #wkCloses .clrow{grid-template-columns:minmax(200px,1.2fr) repeat(5,minmax(112px,1fr)) 48px minmax(140px,.9fr)}   /* 과제 279 뒤 — 주 「26년 9월 14일 (월) ~ 9월 20일 (일)」 198 · 잠김 칸 126 → 140(.wk-by 줄바꿈 그대로) · 1280 = 948 */ #wkCloses .wk-y{display:none}
    #wkCloses .clrow > .r{font-size:var(--fs-sm)} #wkCloses .wk-by{white-space:normal;line-height:1.35} #wkCloses .wk-by > span:last-child{display:inline-flex;flex-wrap:wrap;align-items:center;column-gap:6px}   /* 과제 279 뒤 — 날짜(「9월 28일 (월)」)와 [풀기] 도 따로 꺾임(1280 = 칸 140) */ }
  #billWeek2 .wk-acts{display:flex;gap:6px;justify-content:flex-end;align-items:center;overflow:visible}
  #billWeek2 .wk-kf{display:flex;gap:6px;flex-wrap:wrap;margin:0 0 12px}
  /* ★ 과제 414c — 옛 `#billWeek2 .wk-kf .on`(파랑 테) 은퇴 → 알약 탭 .ptab(위 「알약 탭」 한 벌) */
  #billWeek2 .wk-empty{margin:0;padding:14px;text-align:center;color:var(--text-3);border:1px dashed var(--line);border-radius:var(--r-ctl)}
  #billWeek2 .wk-bal{margin:10px 0 0;font-size:var(--fs-sm)}
  #billWeek2 .wk-bal.bad{color:var(--bad)}
  #wkPickWrap [data-part="picks"]{display:flex;flex-direction:column;gap:8px;margin:8px 0}
  #wkPickWrap .wk-pick{display:grid;grid-template-columns:20px minmax(0,1fr) auto 120px;align-items:center;gap:8px;font-size:var(--fs-sm)}
  #wkPickWrap .wk-pw{grid-column:2 / -1;font-size:var(--fs-cap)}
  #wkPickWrap .wk-pa{text-align:right}
  /* ★ 과제 190 — 인사 Dashboard : 승인할 것 = 네 칸(이름 · 무엇 · 일수 · 단추 둘) · 아래 대기 · 발급 이력 = List 에만 */
  #hDashView .hr-todo .clrow{grid-template-columns:minmax(0,1fr) minmax(0,1.6fr) 80px 168px;align-items:center}
  #hDashView .hr-todo .clrow > .hr-acts{display:flex;gap:4px;align-items:center;overflow:visible}
  #hr[data-hview="dash"] .hr-pend-card,#hr[data-hview="dash"] #hrCertLogCard{display:none}
  :where(#hrHolidayCard) [data-part~="top"]{margin-bottom:8px}   /* ★ 과제 456 — 옛 .hr-hol-top */
  /* ★ 과제 189 — 결과 보고서 「보고할 것」 = 네 칸(캠페인 · 끝난 지 · 담당 · 단추 둘) · 7일 넘음 = 빨강 */
  #rDashView .rp-wait .clrow{grid-template-columns:minmax(0,1.6fr) 88px minmax(0,.8fr) 168px;align-items:center}   /* 단추 칸 = 고정(max-content 면 빈 머리 칸이 0 이라 머리 · 몸 칸이 어긋났다) */
  #rDashView .rp-wait .clrow > .rp-acts{display:flex;gap:4px;align-items:center;overflow:visible}
  #rDashView .tk-dlist .late{color:var(--bad);font-weight:var(--weight-strong)}
  /* ★ 과제 187 — 판매 매체 도구 줄 한 줄 : CSV 둘 · 불러오기 = 메뉴 단추 하나(옛 셋은 숨김 · id · 핸들러 그대로) */
  #media .tools .m-io-src{display:none}
  /* ★★ 과제 223 — 판매 매체 = 왼쪽 목차(236) + 오른쪽(머리 · 보기) · 시안 v2 조각의 옷을 토큰 그대로(--text-1 은 토큰에 없어 --ink) · 선택 줄 = --bg-active + 왼쪽 2px --accent(DESIGN 174) */
  #mWrap{display:flex;gap:12px;align-items:flex-start}
  @media (max-width:1439px){ #media #mMain h3.toolsonly .tools > .tk-left > .search{flex-basis:160px;width:160px} }   /* 목차 236 만큼 좁아진 학교 표 도구 줄 — 1280 실측 707 > 698 → 검색칸 160(v290 media9 하한) */
  #mNav{width:236px;flex:none;padding:6px 0}
  #mMain{flex:1;min-width:0}
  #mNav button{display:flex;justify-content:space-between;align-items:center;width:100%;height:auto;min-height:0;margin:0;border:0;border-radius:0;box-shadow:none;background:transparent;text-align:left;font:inherit;cursor:pointer}
  #mNav button:hover{background:var(--bg-hover)}
  #mNav button:focus-visible{outline:2px solid var(--accent);outline-offset:-2px;box-shadow:none}
  #mNav .grp{padding:9px 16px;color:var(--text-2);font-weight:var(--weight-medium)}
  #mNav .grp .muted{font-weight:var(--weight-regular)}
  #mNav .grp.on{color:var(--ink)}
  #mNav .it{padding:7px 16px 7px 30px;color:var(--text-2);border-left:2px solid transparent}
  #mNav .it.on,#mNav .it.on:hover{color:var(--accent);background:var(--bg-active);border-left-color:var(--accent)}
  #mNav .it.dim{color:var(--text-3)}
  #mNav .sep{height:1px;background:var(--line);margin:6px 0}
  #mNav .it .muted,#mNav .grp .muted{font-size:var(--fs-sm)}
  #mHead h2{margin:0 0 4px}
  #mHead h2 .muted{font-weight:var(--weight-regular);font-size:var(--fs-sm)}
  #mHead .facts{display:flex;flex-wrap:wrap;gap:6px 18px;color:var(--text-2);margin-top:8px}
  #mHead .facts b{color:var(--ink);font-weight:var(--weight-medium)}
  #mHead .m-hd{display:flex;justify-content:space-between;align-items:flex-start;gap:12px}
  #mItemCard{padding:0;overflow:hidden}
  #mItemCard .m-viewbar{padding:16px 24px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:8px}   /* 도구 줄과 같은 치수(h3.toolsonly) — 클래스만 다르다 */
  #mItemCard.m-bar .m-viewbar{border-bottom:0}   /* 학교 · Dashboard 보기 = 보기 단추 줄만(몸은 아래 학교 표 상자) */
  #mItemHost{padding:16px 24px}
  /* ★★ 과제 224 — 품목 표(시안 v2 조각 그대로) · 묶음 머리줄 = 허용 예외 하나(DESIGN §11) · 둘째 줄 흐리게 · 1280 = 칸 폭만 줄임(한 줄 · 가로 스크롤 0) */
  #mItemList .clrow{grid-template-columns:minmax(200px,1fr) 56px 84px 120px 116px 124px 64px;min-width:0}
  #mItemList .clrow.grp{grid-template-columns:1fr;background:var(--tbl-head-bg);color:var(--text-2);min-height:34px;cursor:default}
  #mItemList .clrow.grp b{color:var(--ink);font-weight:var(--weight-medium)}
  #mItemList .r{text-align:right;font-variant-numeric:tabular-nums;justify-content:flex-end}
  #mItemList .sub{display:block;color:var(--text-3);font-size:var(--fs-sm);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  #mItemList .cl-name{flex-direction:column;align-items:flex-start;justify-content:center;min-width:0}
  #mItemList .clrow.m-off{color:var(--text-3)}
  #mItemList .clrow > .cl-ed{position:relative}
  #mItemList .clrow > .cl-ed > .cl-saved{position:absolute;right:12px;bottom:3px;margin:0}   /* 좁은 숫자 칸 = 「✓ 저장됨」 을 값 아래로(옆에 두면 「✓ 저…」 로 잘림 · 1440 실측) */
  #mItemCard .m-itools{display:flex;align-items:center;gap:8px;flex:1;min-width:0}
  #mItemCard .m-itools .search{flex:1;min-width:120px;max-width:280px}
  #mItemCard .m-itools #mItemNewBtn{margin-left:auto}
  #mItemCard .m-vat{white-space:nowrap}
  #mItemMD .mdside{width:min(560px,96vw)}
  #mItemMD .mdside .tm-foot #mItemSideClose{margin-left:auto}
  .m-tiers{display:flex;flex-direction:column;gap:6px;margin-top:8px}
  .m-tier{display:flex;align-items:center;gap:8px}
  .m-tier input{width:120px}
  @media (max-width:1439px){
    #mItemList .clrow{grid-template-columns:minmax(140px,1fr) 56px 76px 92px 112px 96px 56px}
    #mItemCard .m-itools .m-vat{display:none}
  }
  #mMain #mViewSeg{display:none}
  /* 목차 옆 학교 표(간단) — 가로 스크롤 0(v270 ⓔ) : 칸 = 머리 글자 + 정렬 표시가 한 줄에 드는 만큼(3자 = 88 · 4자 = 104) · 1440 표 812 · 1280 표 652 실측 */
  #mMain #mList:where([data-view="simple"]) .clrow{grid-template-columns:minmax(120px,2fr) 80px 80px 88px 88px 112px 104px minmax(60px,1.4fr);min-width:0}   /* 전역 .clrow min-width 852 를 이 자리만 푼다(마스터는 가로 스크롤 그대로) */
  @media (max-width:1439px){
    #mMain #mList:where([data-view="simple"]) .clrow{grid-template-columns:minmax(100px,2fr) 80px 80px 88px 88px 112px 104px}   /* 합 652 = 1280 표 · 조사일 = 날짜 한 줄(112) */
    #mMain #mList:where([data-view="simple"]) .clrow > :last-child{display:none}   /* 1280 = 비고 칸 뺌(학교 상세에 그대로 · 가정 G-193) */
  }   /* 안쪽 옛 보기 단추(학교 표 [Dashboard | List]) — 위 #mTopSeg 가 대신 · id · 핸들러 그대로 */
  @media (max-width:1439px){ #media h3.toolsonly .tools > .tk-left > .search{flex-basis:190px;width:190px} }   /* 1280 에서 [필터] 가 검색칸 아래로 접혔다 → 지출과 같은 §6-2 하한 190 */
  .tk-dlist .cl-name .nm{font-weight:var(--weight-medium);color:var(--ink)}
  .tk-dlist .cl-name .nm.done{color:var(--text-2);text-decoration:line-through;font-weight:var(--weight-body)}
  .tk-dlist .sub,.tk-dlist .clrow > div > span:first-child{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .tk-dlist .sub{font-size:var(--fs-cap);color:var(--text-2);margin-top:1px}
  .tk-dlist .tk-whos{min-width:0}
  /* ★ 과제 340(10-08 대표 UX 점검) — **반쪽 카드 표(.dl-half)** 한 벌 : 이름 = 두 줄까지(말줄임 없이 꺾음) · 밑 작은 줄 = 한 줄 말줄임(풍선말 = 줄 title) · 담당 = 동그라미만 */
  .tk-dlist .clrow.dl-half > .cl-name{white-space:normal;overflow:visible;text-overflow:clip}
  .tk-dlist .clrow.dl-half > .cl-name > .nm{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;white-space:normal;overflow:hidden;word-break:keep-all;overflow-wrap:anywhere}
  .tk-dlist .clrow.dl-half .dl-who .tk-nms,.tk-dlist .clrow.dl-half .dl-who .uav-nm{display:none}
  .dash-host .tk-dlist .clrow.dl-half{grid-template-columns:minmax(0,1.3fr) minmax(0,1fr) auto}
  .tk-dpeople,.tk-dcamps{display:grid;gap:12px;margin-top:6px}
  .tk-drow{display:grid;grid-template-columns:150px minmax(0,1fr) 128px;align-items:center;gap:12px;cursor:pointer;border-radius:var(--r-ctl);padding:4px 6px;margin:0 -6px}
  .tk-drow:hover{background:var(--row-hover)}
  .tk-drow:focus-visible{outline:none;box-shadow:var(--ring)}
  .tk-dcamp{grid-template-columns:minmax(0,1fr) 150px 96px}
  .tk-dcamp .cn{font-weight:var(--weight-medium);color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .tk-dcamp .sub{display:block;font-size:var(--fs-cap);color:var(--text-2)}
  .tk-hbar{height:10px;background:var(--bg-hover);border-radius:var(--r-ctl);overflow:hidden;display:flex}
  .tk-hbar i{display:block;height:100%}
  .tk-hbar .a{background:var(--accent)} .tk-hbar .b{background:var(--bad)} .tk-hbar .o{background:var(--ok)}
  .tk-dnum{font-size:var(--fs-sm);color:var(--text-2);text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
  .tk-dnum b{color:var(--ink);font-weight:var(--weight-strong)}
  .tk-dnum .late{color:var(--bad);font-weight:var(--weight-strong)}
  .tk-dstack{height:18px;border-radius:var(--r-ctl);overflow:hidden;display:flex;background:var(--bg-hover)}
  .tk-dstack i{display:block;height:100%}
  .tk-dstack .dim{background:var(--bg-fill);border:1px solid var(--line);box-sizing:border-box} .tk-dstack .s1{background:var(--accent)} .tk-dstack .tk-st-warn{background:var(--warn-bg)} .tk-dstack .tk-st-purple{background:var(--purple)}
  .tk-dlg{display:flex;gap:16px;flex-wrap:wrap;margin-top:12px}
  .tk-dlg .st{font-size:var(--fs-sm)}
  .st.tk-st-warn{color:var(--warn)} .st.tk-st-warn i{background:var(--warn)}
  .st.tk-st-purple{color:var(--purple)} .st.tk-st-purple i{background:var(--purple)}
  .tk-dash .hweek .col[data-tkday]{cursor:pointer;border-radius:var(--r-ctl)}
  .tk-dash .hweek .col:focus-visible{outline:none;box-shadow:var(--ring)}
  .tk-dempty{color:var(--text-2);font-size:var(--fs-sm);margin:8px 0 0}
  .tk-empty{padding:0 24px 18px;color:var(--text-2);font-size:var(--fs-sm)}
  /* ── 카드 안의 표 상자 ── */
  .tk-tbl{margin:0 24px 20px;border:1px solid var(--line);border-radius:var(--r-ctl);overflow:auto;background:var(--bg-card)}
  .tk-row{display:grid;grid-template-columns:44px minmax(170px,1fr) minmax(100px,.6fr) minmax(190px,1fr) 210px 184px 140px minmax(210px,2fr) 40px;
      min-width:1288px;gap:0;padding:0;border-bottom:1px solid var(--line-soft);align-items:stretch}
  .tk-tbl .tk-row:last-child{border-bottom:0}
  .tk-row > div{height:44px;padding:0 14px;box-sizing:border-box;display:flex;align-items:center;min-width:0;border-right:1px solid var(--cell-line)}   /* ★ 과제 414a (G-351) — 할 일도 공용 표와 **같은 토큰**(v4 = 세로선 없음 · 대표 10-15 Q-V1 ⓐ) · 옛 = --line-soft 박음 */
  /* ★ v3.08 (과제 181 · 09-25 대표 「고쳐」 · 걷기 148 #9) — **1280 노트북**에서 할 일 List 표가 가로로 넘쳤다(최소 1288 · 표 칸 850).
     ≤1439 에서만 칸 최소를 줄이고(내용 칸도 남긴다 · 칸 빼기 0 · 최소 합 846 < 표 칸 850) · 칸 안여백 14 → 10 · 표 상자 여백 24 는 그대로(다른 화면 표 상자의 잣대 · v270 ⓑ). **1440 모습은 그대로**(할일불변 네 사진).
     「지금 손댈 것」 카드(Dashboard)는 ≤1439 에서 한 줄 전체(짝 카드 「업무 강도」 는 아래로) — 업무 · 광고주 칸이 13px 로 줄었다. 로직 · 순서 · 카드 넷 불변(tasks.js 0줄). */
  @media (max-width:1439px){
    .tk-row{grid-template-columns:36px minmax(128px,1.4fr) minmax(76px,.7fr) minmax(116px,1fr) 130px 150px 88px minmax(90px,.8fr) 32px;min-width:0}
    /* 과제 274 — 칸 안여백 = 다른 화면과 같은 14(옛 10 · 한 겹으로 표 폭 +48) */
    #taskList .tk-dtwo:has(.tk-dlist){grid-template-columns:1fr}
    .tk-search{flex-basis:200px}   /* 과제 274 — 1280 도구 줄 = 한 줄(다른 화면과 같이 · 옛 = 「+ 새 할일」 이 둘째 줄로 꺾여 105) */
  }
  .tk-row > div:last-child{border-right:0}
  .tk-row.tk-head{background:var(--tbl-head-bg);border-bottom:1px solid var(--line)}   /* ★ 과제 414a (G-351) — 머리 = --tbl-head-bg(v4 불투명 흰) · 공용 목록과 한 값 */
  .tk-row.tk-head > div{font-size:var(--fs-sm);font-weight:var(--weight-medium);color:var(--text-2);justify-content:space-between;gap:8px;white-space:nowrap}   /* ★ 과제 321 — 머리 표시(cl-h-ed flex)가 빠지자 1280 「광고주」 가 두 줄로 꺾임 → 한 줄(두 줄 꺾임 금지 G-062) */
  .tk-si{width:14px;height:14px;color:var(--text-3);flex:0 0 auto}
  .tk-gsort{cursor:pointer}
  .tk-gsort:hover{background:var(--bg-hover);color:var(--text)}
  .tk-gsort[data-sort]{color:var(--accent)} .tk-gsort[data-sort] .tk-si{color:var(--accent)}
  .tk-gsort:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
  .tk-row:not(.tk-head):hover{background:color-mix(in srgb, var(--bg-fill) 50%, var(--bg-card))}   /* 줄 호버 = 머리줄보다 옅게(대표 지시 · 토큰 둘의 중간) */
  .tk-row > .tk-ed{cursor:text}
  .tk-row > .tk-ed:hover{background:var(--bg-fill)}
  .tk-row > .tk-ed.tk-on{padding:0 6px;background:var(--bg-card)}
  .tk-row > .tk-ed.tk-on.tk-anch{background:var(--bg-active)}
  .tk-row > .tk-ck,.tk-row > .tk-x{justify-content:center;padding:0}
  .tk-row > .tk-ck input{width:16px;height:16px;margin:0;cursor:pointer;accent-color:var(--fill-brand)}
  .tk-row[draggable]{cursor:grab}
  .tk-row.tk-dragging{opacity:.45}
  .tk-row > div:focus-visible{outline:2px solid var(--accent);outline-offset:-2px;border-radius:var(--r-key)}
  #taskList .tk-row[data-id]:focus-within{background:var(--bg-active);box-shadow:inset 2px 0 0 var(--accent)}   /* ★ 과제 572 (571 걷기 R4 · 디자이너 1) — 초점 줄(등록 · 완료 뒤 새 줄) = 「고른 줄」(.clrow.sel) 꼴 · 1440 · 390 같음 · 새 색 0 */
  .tk-t,.tk-a,.tk-c,.tk-b,.tk-d{font-size:var(--fs-body);   /* 과제 274 — 값 14(DESIGN §11 · 옛 13) */ color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block !important;line-height:44px}
  .tk-t{font-weight:var(--weight-medium);color:var(--ink)}
  .tk-b{color:var(--text-2)}
  .tk-c a{color:var(--text);text-decoration:none} .tk-c a:hover{color:var(--accent);text-decoration:underline}
  .tk-c .ccode{margin-right:6px}
  .tk-a.tk-pend{color:var(--text-2)}
  .tk-ph{color:var(--text-3)}
  .tk-d{font-variant-numeric:tabular-nums}
  .tk-d.over{color:var(--bad);font-weight:var(--weight-strong)}
  .tk-d.today{color:var(--warn);font-weight:var(--weight-strong)}
  .tk-row.tk-done .tk-t{color:var(--text-2);text-decoration:line-through}
  /* ── v2.17 (09-18 · DB v0.57 짝) — 담당자 **여러 명** + 직원 **사진** ──
     사진 = 24 동그라미(없으면 이름 첫 글자) · 여러 명이면 겹쳐 서고 이름은 쉼표 · 칸을 넘으면 말줄임.
     ⚠ 이름은 tk- 접두어 그대로(화면의 .uchip·.av 와 겹치지 않게 — 시안 5판·18판 실측). */
  /* 내 정보 · 내 사진 (v2.17) — 큰 동그라미 하나 + 안내 한 줄 */
  .me-av-row{display:flex;align-items:center;gap:16px}
  .me-av-big{width:64px;height:64px;border-radius:50%;flex:0 0 auto;overflow:hidden;display:inline-flex;align-items:center;justify-content:center;
      background:var(--bg-fill);color:var(--text-2);font-size:var(--fs-title);font-weight:var(--weight-strong)}
  .me-av-big img{width:100%;height:100%;object-fit:cover;display:block}
  .me-av-big.me-av-none{background:var(--accent-soft);color:var(--accent)}
  .tk-av{width:24px;height:24px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
      overflow:hidden;background:var(--bg-fill);color:var(--text-2);font-size:var(--fs-cap);font-weight:var(--weight-strong)}
  .tk-av img{width:100%;height:100%;object-fit:cover;display:block}
  .tk-av.tk-avi{background:var(--accent-soft);color:var(--accent)}
  .tk-whos{display:inline-flex;align-items:center;gap:8px;min-width:0}
  .tk-avs{display:inline-flex;flex:0 0 auto}
  .tk-avs .tk-av{margin-left:-8px;box-shadow:0 0 0 2px var(--bg-card)}
  .tk-avs .tk-av:first-child{margin-left:0}
  .tk-nms{font-size:var(--fs-body);   /* 과제 274 — 값 14 */ color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
  .tk-row:hover .tk-avs .tk-av{box-shadow:0 0 0 2px var(--bg-fill)}         /* 줄 호버 위에서도 겹친 테두리가 보이게 */
  .tk-pop .tk-frow .tk-av{width:20px;height:20px;font-size:var(--fs-cap)}   /* 6단 밖 값 금지(§2) — 12px 토큰 */
  .tk-kbf .tk-whos{min-width:0;overflow:hidden}
  .tk-kbf .tk-nms{font-size:var(--fs-cap)}
  .tk-who{display:inline-flex;align-items:center;min-width:0}
  .tk-in{height:30px;width:100%;box-sizing:border-box;font-size:var(--fs-body);   /* 과제 274 — 고치는 칸 = 값과 같은 14 */ padding:0 8px;border:1px solid var(--accent);border-radius:var(--r-inner);background:var(--bg-card);color:var(--text);box-shadow:var(--ring)}
  .tk-del{width:26px;height:26px;min-height:26px;padding:0;border:0;background:transparent;box-shadow:none;color:var(--text-3);display:inline-flex;align-items:center;justify-content:center;border-radius:var(--r-inner);opacity:0}
  .tk-row:hover .tk-del,.tk-row:focus-within .tk-del{opacity:1}
  .tk-del:hover{background:var(--bad-bg);color:var(--bad)}
  .tk-del svg{width:15px;height:15px}
  /* ── v2.16 (09-17 · 2단계) Kanban · Calendar — 같은 도구 줄 아래 · 카드·칩을 끌면 상태·마감일 ── */
  .tk-kb{display:grid;grid-template-columns:repeat(4,minmax(220px,1fr));gap:12px;align-items:start}   /* 완료 열 없음(대표 결정) */
  .tk-kbcol{background:var(--bg-side);border:1px solid var(--line);border-radius:var(--r-card);padding:10px;min-height:160px;transition:box-shadow var(--duration-fast) var(--ease)}
  .tk-kbcol.tk-drop{box-shadow:var(--ring);background:var(--bg-active)}
  .tk-kbcol h4{margin:0 0 10px;display:flex;align-items:center;gap:8px;font-size:var(--fs-sm);font-weight:var(--weight-strong);color:var(--ink)}
  .tk-kbn{font-weight:var(--weight-body);color:var(--text-2)}
  .tk-kbcard{background:var(--bg-card);border:1px solid var(--line);border-radius:var(--r-ctl);box-shadow:var(--sh-card);padding:10px 12px;margin-bottom:8px;cursor:grab}
  .tk-kbcard:hover{background:var(--bg-hover)}
  .tk-kbcard:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
  .tk-kbcard.tk-dragging{opacity:.45}
  .tk-kbt{font-size:var(--fs-body);font-weight:var(--weight-medium);color:var(--ink);margin-bottom:6px}
  .tk-kbc{font-size:var(--fs-sm);color:var(--text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-bottom:8px}
  .tk-kbc .ccode{margin-right:4px}
  .tk-kbf{display:flex;align-items:center;justify-content:space-between;gap:8px}
  .tk-kdue{font-size:var(--fs-cap);color:var(--text-2);font-variant-numeric:tabular-nums}   /* 칸반 마감일 — v2.68 (과제 130) .tk-kbd([N] 키캡)와 이름 겹침을 풀었다 */
  .tk-kdue.over{color:var(--bad);font-weight:var(--weight-strong)} .tk-kdue.today{color:var(--warn);font-weight:var(--weight-strong)}
  .tk-kbempty{font-size:var(--fs-cap);color:var(--text-3);padding:18px 6px;text-align:center;border:1px dashed var(--line);border-radius:var(--r-ctl)}
  /* 달 = 제 상자 · 위 한 줄(제목 · ‹ › · 오늘 · [이 달|이 주]) · 격자 선 = 바탕(--line) 위 흰 칸 1px 띄우기(끊김 0) · 줄 높이 전부 같게 */
  .tk-calbox{display:flex;flex-direction:column;min-width:0;background:var(--bg-card);border:1px solid var(--line);border-radius:var(--r-card);overflow:hidden;height:clamp(760px, calc(100vh - 300px), 1120px)}
  .tk-calhead{display:flex;align-items:center;gap:6px;padding:12px 16px;border-bottom:1px solid var(--line);flex:0 0 auto}
  .tk-calhead b{font-size:var(--fs-page);font-weight:var(--weight-strong);color:var(--ink);letter-spacing:-.01em;margin-right:6px;white-space:nowrap}
  .tk-calhead b small{font-size:var(--fs-sm);font-weight:var(--weight-body);color:var(--text-2);margin-left:8px}
  .tk-calbox .tk-calhead button.ghost{flex:0 0 auto;width:auto;min-width:0;height:28px;min-height:28px;padding:0 10px;font-size:var(--fs-sm);box-shadow:none;border:1px solid var(--line);border-radius:var(--r-ctl)}
  .tk-calbox .tk-calhead button.ghost.tk-nav{width:28px;padding:0;border-color:transparent;color:var(--text-2);font-size:var(--fs-page)}
  .tk-calbox .tk-calhead button.ghost:hover{background:var(--bg-hover);color:var(--ink)}
  .tk-calseg button{white-space:nowrap}   /* ★ 과제 414c — 높이 = .seg 한 벌(32/26 · 옛 30/24) */
  .tk-cal{flex:1;display:grid;grid-template-columns:repeat(7,minmax(0,1fr));grid-auto-rows:minmax(0,1fr);gap:1px;background:var(--line);min-height:0}
  .tk-day{padding:10px 12px 12px;background:var(--bg-card);display:flex;flex-direction:column;gap:4px;min-height:0;overflow:hidden;transition:background var(--duration-fast) var(--ease)}
  .tk-day.tk-out .tk-dn,.tk-day.tk-out .tk-dw{color:var(--text-3)}
  .tk-day.tk-drop{background:var(--bg-active)}
  .tk-dtop{display:flex;align-items:center;justify-content:space-between;height:28px;margin-bottom:4px;flex:0 0 auto}
  .tk-dw{font-size:var(--fs-sm);font-weight:var(--weight-strong);color:var(--ink)}
  .tk-day.tk-we .tk-dw{color:var(--text-2)}
  .tk-dn{margin-left:auto;font-size:var(--fs-sm);color:var(--text);font-variant-numeric:tabular-nums;display:inline-flex;align-items:center;justify-content:center;min-width:28px;height:28px;border-radius:50%}
  .tk-day.tk-today .tk-dn{background:var(--accent);color:var(--on-fill);font-weight:var(--weight-strong)}
  /* 칩 = 상태 배지 색 꽉 찬 알약 : 대기중 --text-2 · 진행중 --accent · 광고주확인 --warn-bg/--warn · 매체사확인 --purple · 완료 --ok(✓) · 지남 = 왼쪽 빨간 띠 */
  .tk-ev{display:flex;align-items:flex-start;gap:6px;font-size:var(--fs-sm);font-weight:var(--weight-medium);line-height:1.35;padding:6px 10px;border-radius:var(--r-inner);color:var(--on-fill);cursor:grab;position:relative;overflow:hidden;flex:0 0 auto}
  .tk-ev span{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-width:0}
  .cg-bar.cg-faint{opacity:.55}   /* v2.88 (과제 159) — 달력 칩 「흐리게」(지출 낸 건 = 지급일 칸) · 새 색 0 */
  .tk-ev-dim{background:var(--text-2)} .tk-ev-blue{background:var(--accent)} .tk-ev-warn{background:var(--warn-bg);color:var(--warn)} .tk-ev-purple{background:var(--purple)} .tk-ev-ok{background:var(--ok)}
  .tk-ev.over::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--bad)}
  .tk-ev.over{padding-left:13px}
  .tk-ev:hover{filter:brightness(.94)}
  .tk-ev:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
  .tk-ev.tk-dragging{opacity:.45}
  .tk-ev svg{width:14px;height:14px;flex:0 0 auto;margin-top:2px}
  .tk-more{font-size:var(--fs-cap);color:var(--text-2);padding:2px 4px}
  /* ★ v2.75 (과제 135 · DESIGN §11-3-2) — **캠페인 달력**(core.js calGrid) : 옷은 위 할 일 달력 class 를 **그대로** 받는다. 여기는 막대 걸쇠만(새 값 0).
     ① 자리 = 표 상자와 같은 값(도구 줄 아래 20 · 좌우 --card-pad-x · 아래 20 — 위 「목록은 제 상자를 갖는다」 ② 규칙) — 달력은 제 테(.tk-calbox)가 있어 테는 안 준다
     ② [hidden] 되찾기(.tk-ev 의 display:flex · .scrolltbl 이 UA 의 [hidden] 을 이긴다)
     ③ 막대 = 할 일 칩(.tk-ev)과 같은 옷 · 한 줄 말줄임 · 격자 줄 위쪽에 붙는다(세로 자리 · 좌우 안여백은 calGridLayout 이 잰 값으로)
     ④ 주를 넘어 이어지는 쪽은 모서리를 편다(이어짐 표시) · 끌기 없음이라 손 모양 = 누르기 */
  #cCalView{margin:20px var(--card-pad-x) 20px}   /* ★ 과제 490 — 지출 달력 지움(#spCalView) */
  #cCalView[hidden],#campList[hidden],#spListAll[hidden],.cg-bar[hidden]{display:none}
  .cg-bar{align-self:start;cursor:pointer;min-width:0;z-index:1}
  .cg-bar span{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .cg-bar.cg-cont-l{border-top-left-radius:0;border-bottom-left-radius:0}
  .cg-bar.cg-cont-r{border-top-right-radius:0;border-bottom-right-radius:0}
  .cg-more{cursor:pointer}
  /* ★ 09-24 대표 지적 「달력에 휴일 표기」 — 공휴일 · 일요일 날짜 숫자 = --bad(빨강 글자 토큰 하나뿐 · 새 색 0 · G-103) · 오늘(파란 동그라미) · 앞뒤 달 칸(흐림)은 제 색 그대로
     공휴일 이름 = 숫자 바로 옆(한 줄 말줄임 · 작은 글자 --fs-cap) — 할 일 달력에는 안 붙는다(cg- 접두어 · 할 일 CSS 무변경) */
  .cg-cal .tk-day.cg-holi:not(.tk-today):not(.tk-out) .tk-dn{color:var(--bad)}
  .cg-hol{margin-left:auto;min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:var(--fs-cap);color:var(--bad)}
  .cg-hol + .tk-dn{margin-left:0}
  .cg-cal .tk-dtop{gap:4px}   /* 이름과 숫자(오늘 동그라미) 사이 — 칸 안 간격 .tk-day{gap:4px} 과 같은 값(09-24 사진 : 오늘이 공휴일이면 이름이 동그라미에 붙었다) */
  .cg-cal .tk-day.tk-out .cg-hol{color:var(--text-3)}
  .cg-more:hover{color:var(--accent)}
  .cg-note{text-decoration:none}   /* v2.76 (과제 136) — 「예정일 없음 n건」 은 누르면 목록 — 옷은 .tk-cnt 그대로 · 호버만 가리키는 색 */
  .cg-note:hover{color:var(--accent)}
  @media (max-width:1180px){ .tk-calbox{height:auto} .tk-day{min-height:140px} .tk-kb{grid-template-columns:repeat(2,minmax(0,1fr))} }
  @keyframes tkFlash{from{background:var(--bg-active)}to{background:transparent}}
  .tk-row.tk-flash{animation:tkFlash 1.6s var(--ease)}
  #taskList [data-tst]{cursor:pointer}
  #taskList [data-tdue], #taskList [data-tbody]{cursor:pointer;border-radius:var(--r-ctl);padding:2px 6px;margin:-2px -6px}
  #taskList [data-tdue]:hover, #taskList [data-tbody]:hover{background:var(--bg-hover)}
  .tgrp{font-size:var(--fs-cap);font-weight:var(--weight-strong);letter-spacing:.05em;text-transform:uppercase;
      color:var(--text-2);margin:0 0 8px}
  .tgrp .tgrp-n{color:var(--text-2);font-weight:var(--weight-body);margin-left:4px;letter-spacing:0}
  .tgrp .tgrp-over{color:var(--bad);font-weight:var(--weight-body);margin-left:6px;letter-spacing:0}
  .tbox{border:1px solid var(--line);border-radius:var(--r-card);padding:12px 16px 14px;
      margin:0 0 24px;background:var(--bg-fill)}
  .tbox.tb-today{border-left:3px solid var(--accent)}
  /* ★ v1.39 (야간 UX R22 · DESIGN.md §11-6 로드맵 3번) — 사진 증빙 썸네일 그리드.
     학교 이름 줄은 할 일 그룹 머리(.tgrp)와 **같은 옷**을 씁니다(새 규격을 만들지 않으려고).
     색·라운드·굵기는 전부 토큰입니다. 칸 크기(112px)는 격자 목록의 열 폭과 같은 성격의
     레이아웃 숫자입니다 — D-095·D-110 과 같은 판단(결정기록에 적어 두었습니다). */
  .phgrp{font-size:var(--fs-cap);font-weight:var(--weight-strong);letter-spacing:.05em;
      color:var(--text-2);margin:14px 0 8px}
  .phgrp .phgrp-n{color:var(--text-2);font-weight:var(--weight-body);margin-left:6px;letter-spacing:0}
  .phgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(112px,1fr));gap:10px;margin-bottom:6px}
  .phcell{display:block;border:1px solid var(--line);border-radius:var(--r-card);overflow:hidden;
      background:var(--bg-fill);text-decoration:none;color:var(--text-2)}
  .phcell:hover{border-color:var(--accent)}
  .phcell img{display:block;width:100%;aspect-ratio:4/3;object-fit:cover;background:var(--bg-hover)}
  .phcell .phcap{display:block;padding:4px 6px;font-size:var(--fs-cap);color:var(--text-2);
      overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  #btnTaskMine.onme{background:var(--accent-soft);color:var(--accent);border-color:transparent}
  .ttbl{table-layout:fixed;width:100%}
  .ttbl td{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  #taskList a[data-task]{color:inherit}
  #taskList a[data-task]:hover b{text-decoration:underline}
  #taskList a[data-caminfo]{color:var(--text-2)}
  #taskList a[data-caminfo]:hover{text-decoration:underline}
  /* ★ v1.58 (대표 「윤곽선을 「내 할 일」 단추 기준으로 통일」) — 「완료 보기」도 **토글**이다.
     그런데 종전에는 **꺼져 있을 때부터** 초록 틴트 + 투명 테두리라, 같은 줄의 다른 단추들과 윤곽선이 달랐다.
     이제 `#btnTaskMine`(내 할 일)과 **똑같은 문법** : 꺼짐 = 보통 보조 단추 · 켜짐 = 틴트 + 투명 테두리. */
  #btnTaskDoneView.onview{background:var(--ok-bg);color:var(--ok);border-color:transparent}
  #btnTaskDoneView.onview:hover{background:var(--ok-bg)}

  /* ── 견적서 (v0.80~82) ── */
  #qListAll table{table-layout:auto}
  /* v1.15 — 옛 #quoteSide{position:sticky…} 삭제 : id 선택자가 .mdside 팝업 규칙을 이겨 견적 팝업만 위로 붙었다(실측) */
  #quoteSide .card{margin-bottom:0}
  #qMatchBack,#hPayPasteBack{position:fixed;inset:0;z-index:80;background:var(--dim-layer2);display:none;
              align-items:center;justify-content:center;padding:20px}
  #qMatchBack.open,#hPayPasteBack.open{display:flex}
  /* ★ v1.05 — 못 찾은 학교 줄이 「이름 · 검색 · 후보」 세 자리를 쓰므로 폭을 넓혔습니다 (대표 지적) */
  #qMatchPop,#hPayPastePop{background:var(--bg-card);border-radius:var(--r-panel);box-shadow:var(--sh-float);
             width:min(760px,95vw);max-height:86vh;display:flex;flex-direction:column;   /* v2.94 (과제 144) — 2층 = 가운데 760(DESIGN §12-000 · 옛 820) */
             padding:18px 22px 22px;animation:toastIn var(--duration-base) var(--ease)}
  #qMatchPop h3,#hPayPastePop h3{margin:0 0 10px;font-size:var(--fs-card);font-weight:var(--weight-strong);letter-spacing:-.01em;color:var(--ink);display:flex;align-items:center;gap:10px}
  #qMatchBody,#hPayPasteBody{flex:1;overflow-y:auto}
  #qMatchPop .btns,#hPayPastePop .btns{margin-top:12px}
  #qPickBack,#qListBack,#qDocBack{position:fixed;inset:0;z-index:80;background:var(--dim-layer2);display:none;
             align-items:center;justify-content:center;padding:20px}   /* ★ 458 ③ · 기획 허락 — 견적서 미리보기 2층(#qDocBack · #qDocPop · #qDocSlot)을 선택자 목록에 더함 · 값 그대로 */
  #qPickBack.open,#qListBack.open,#qDocBack.open{display:flex}   /* ★ 과제 405b — 리스트에서 담기(#qListBack) = 학교 고르기와 같은 옷(선택자만 더함 · DESIGN §12 「2층 고르기」) */
  #qPickPop,#qListPop,#qDocPop{background:var(--bg-card);border-radius:var(--r-panel);box-shadow:var(--sh-float);
            width:min(1240px,calc(100vw - 48px));max-height:88vh;display:flex;flex-direction:column;   /* v2.94 (과제 144 · 대표 지적 2차 ②ⓑ) — 폭 = 칸이 한 줄로 들어가는 폭(최대 1240 · 창 − 48) · 920 되돌림 */
            padding:18px 22px 22px;animation:toastIn var(--duration-base) var(--ease)}
  #qPickPop h3,#qListPop h3,#qDocPop h3{margin:0 0 10px;font-size:var(--fs-card);font-weight:var(--weight-strong);letter-spacing:-.01em;color:var(--ink);display:flex;align-items:center;gap:10px}
  #qPickBody,#qlBody,#qDocSlot{flex:1;overflow-y:auto;min-height:0}
  #qList th, #qList td{white-space:nowrap}   /* v2.94 (과제 144) — 표 안 두 줄 꺾임 0(학교 이름 · 머리 「승인대행」) */
  #qList td.qp-note{max-width:220px;overflow:hidden;text-overflow:ellipsis}   /* 승인 참고만 한 줄 말줄임 + title(학교 이름은 안 자름) */
  #qPickBody .card{border:0;box-shadow:none;background:transparent;padding:0;margin:0}
  #qPickPop .btns,#qListPop .btns,#qDocPop .btns{margin-top:12px}
  .slideover:not(.modal) .pnl-body{padding-left:var(--pad-pop-x);padding-right:var(--pad-pop-x)}   /* ★ 과제 495(디자이너 9 허락 10-24) — 딤 없는 슬라이드 팝업 몸 좌우 = 다른 팝업과 같은 --pad-pop-x(옛 기본 .pnl-body 20 · 지금 해당 = 견적 작성 하나 · 새 값 0) */
  #qsFootBar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;z-index:5}   /* ★ 458 디자이너 ① — 자리 · 여백 · 칠 · 선 = 표준 발(.slideover .btns.pnl-foot · sticky · 몸 여백과 같은 음수 여백 4629) · 옛 가운데 창 몸 22 · 반투명 유리 은퇴(390 넘침 2px) */
  .slideover:not(.modal) .pnl-body > #qsFootBar{margin-bottom:-36px;bottom:-36px}   /* 딤 없는 넓은 팝업 몸 아래 여백 36(.pnl-body 959) 과 같은 음수 — 표준 발 −22 면 발 밑 14px 로 굴러가는 줄이 비쳤다(굴리는 몸은 견적 작성뿐) */
  #qsFootBar .qsf-sum{font-size:var(--fs-body)}
  #qsFootBar .qsf-sum b{font-size:var(--fs-page)}
  #qsFootBar .qsf-gap{flex:1}
  #qsFootBar #qsMainBtn{height:34px;padding:0 20px;font-weight:var(--weight-strong)}
  #qsFootBar #qsMainBtn:disabled{opacity:.5}
  /* ★ v1.26 (야간 UX 루프 R09 · 발견 801 = 206-b) — 「견적서 보기」 = 같은 작성 팝업의 **읽기 전용** 모드.
     ① 구역 1·2(받는 곳·조건 입력·학교 고르기)와 ② 시트를 고치는 단추·저장 단추를 감춥니다.
     ③ `.qd-noprint`(％·「또는 정액」·할인 신호등처럼 **편집에만 쓰는 글자**)도 감춰 종이와 같은 모습이 됩니다.
     남는 것 = 견적서 문서 + 「PDF 내보내기」. 요소는 하나도 지우지 않았습니다(감추기만 · 규칙 3-2). */
  #qComposeWrap.qs-ro .qgrp[data-step="1"],
  #qComposeWrap.qs-ro .qgrp[data-step="2"],
  #qComposeWrap.qs-ro .qd-noprint,
  #qComposeWrap.qs-ro .qd-edit,
  #qComposeWrap.qs-ro .qd-tier,
  #qComposeWrap.qs-ro .qd-delcol,
  #qComposeWrap.qs-ro #qsAuditOut,
  #qComposeWrap.qs-ro #qsAddRow,
  #qComposeWrap.qs-ro #qsClear,
  #qComposeWrap.qs-ro #qsChips,
  #qComposeWrap.qs-ro #qsfDirty,
  #qComposeWrap.qs-ro #qsMainBtn{display:none}
  /* ★ 458 디자이너 ② — 왼쪽 차례(.qwithnav) 은퇴 뒤 기준 = 발이 든 몸(.pnl-body · boot.js 가 발을 몸 끝으로 옮김) · 확정 · 거절 견적 = 칩 · 「저장 안 된 줄」 · 주 단추 숨김 그대로 */
  /* ★★ v3.34 (과제 241) — 발 `#qsFootBar` 는 과제 52 · 64 부터 `#qComposeWrap` **밖**(팝업 몸통 바로 아래)에 있다(boot.js 「발 한 벌」).
     그래서 위 두 줄(#qsfDirty · #qsMainBtn)은 더는 안 맞았고, 거절 · 만료 견적 「견적서 보기」 발에 「확정하기」 가 살아 있었다(09-30 실측).
     기준을 **팝업 몸통**으로 — 같은 몸통 안에 읽기 전용 시트가 있으면 발의 저장 표시 · 주 단추를 감춘다. 판정 쪽(qsMainState)도 읽기 전용이면 꺼짐(두 겹 · 관문 v344).
     ⚠ 위 두 줄은 지우지 않는다(발이 다시 시트 안으로 돌아와도 맞게). */
  .pnl-body:has(#qComposeWrap.qs-ro) > #qsFootBar #qsfChips,   /* 빈 칸 칩(누르면 그 칸으로) — 읽기 전용이면 갈 칸이 숨어 있어 헛돈다(가정 G-200) */
  .pnl-body:has(#qComposeWrap.qs-ro) > #qsFootBar #qsfDirty,
  .pnl-body:has(#qComposeWrap.qs-ro) > #qsFootBar #qsMainBtn{display:none}
  #qsBody tr td{transition:background .15s var(--ease)}
  #qsBody tr.qsflash td{background:var(--bg-active)}
  /* ★ v1.34 (야간 UX R17 · DESIGN.md §11-6 로드맵 1번) — 상담 목록이 옛 표에서 격자로 왔습니다.
     새 색·새 부품은 없습니다 — `.clrow` 그대로이고, 여기서 정하는 것은 **열 여덟 개의 폭**뿐입니다
     (`#qListAll`·`#odListAll`·`#spListAll` 이 저마다 쓰는 것과 같은 방식). */
  /* ★ 과제 120 (09-22 감사 6회차) — **첫 칸(등록일시) 114 → 132px.**
     `created_at` 은 언제나 `YYYY-MM-DD HH:MM` **16자**라 114px 에서는 **모든 줄이** 「2026-09-19 0…」 로 잘렸다
     (실측 : 보이는 113 · 글 130). 이름·내용의 `…` 와 다르다 — **시각은 줄면 못 읽는다.**
     ★ 132px 은 **견적 목록 첫 칸과 같은 값**(`#qListAll`)이다 — 새 숫자를 발명하지 않았다.
     ★ 자리는 남는다 : 줄 최소폭 888(→906) · 상자 폭 1162. 다른 칸은 그대로다. */
  /* v2.70 (과제 132 · 09-23 대표 지적 「꺾임만 고쳐」) — 머리 글자가 두 줄로 꺾이던 셋(상담상태 · 상담채널 · 캠페인상태)을 한 줄에 필요한 만큼 넓혔다
     (글자 + 간격 8 + 정렬 아이콘 14 + 안여백 28 · 실측 95 · 95 · 107 → 96 · 96 · 108) · 관문 = 통일검사 v270 ⓐ3 */
  #leadList .clrow{grid-template-columns:160px minmax(120px,.9fr) 112px 104px minmax(160px,2.6fr) 96px minmax(110px,.9fr) 108px;   /* ★ 과제 217 (09-28 대표) — 칸 차례 = 상담일시 · 상담명 · 상담자 · 상담채널 · 상담내용 · 상담상태 · 캠페인명 · 캠페인상태 · 상담명 · 캠페인명 줄임(말줄임 + 전문) · 상담자 · 채널 조금 넓힘 · 남는 폭은 전부 상담내용(2.6fr · 가장 넓음) · (앞) v3.08 176 · 203 */
    min-width:906px}
  /* (은퇴 · 과제 319) 과제 250 「첫 연락 전」 칩 · 상담상태 칸 넓히기(li-hasfc) — 칩이 없어져 규칙도 뺌 */
  /* ★★ 과제 250 (09-30 대표 「이대로 진행」 · 시안 v1) — 상담 맨 위 **광고문의 받은 함** · 광고문의 팝업 · 보관함
     카드 = 왼쪽 4px 파란 띠(`--accent` = 가리키는 것) · 표 = 목록 한 벌(.clrow · 머리 · 세로줄 · 줄 키 44 이상 · 두 줄 칸만 제 키만큼)
     경과 색 = ERP 가 준 wait_level 그대로(ok · warn · alert) · 줄 단추 = 흰 보조(검정 = 팝업 안 하나) */
  #leadInbox{margin-bottom:16px}   /* ★ 과제 278 ① — 왼쪽 파란 선 뺌(대표 10-02) */
  #leadInbox .li-head{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:12px}
  #leadInbox .li-n{font-size:var(--fs-num);font-weight:var(--weight-num);color:var(--accent);line-height:1}
  #leadInbox .li-title{font-size:var(--fs-card);font-weight:var(--weight-strong)}
  #leadInbox .li-m{color:var(--text-2);font-size:var(--fs-sm)}
  #leadInbox .li-m b{color:var(--text);font-weight:var(--weight-strong)}
  #leadInbox .li-m b.li-ok{color:var(--ok)} #leadInbox .li-m b.li-bad{color:var(--bad)}
  #leadInbox .li-grow{flex:1}
  #leadInbox .li-list{border:1px solid var(--line);border-radius:var(--r-ctl)}
  #liList .clrow{grid-template-columns:186px 88px minmax(150px,200px) minmax(140px,1fr) 170px 96px 120px 134px;min-width:1104px}   /* ★ 과제 375 — 여덟 열(문의일시 · 문의경로 · 회사명 · 요약 · 매체 · 지역 · 예산 · 처리) · 1440 = 가로 스크롤 0 · 좁으면 상자 안에서 돈다(아래 과제 279 줄과 같은 값) */
  .li-cob{display:flex;align-items:center;gap:8px;min-width:0}   /* ★ 과제 375(시안 3) — 한 줄 : [재문의 · 확인 필요] 알약 + 회사명(말줄임 · 전체 = title) · 문의경로 알약 */
  .li-cob .pill{flex:0 0 auto}
  .li-amt{text-align:right;font-variant-numeric:tabular-nums}   /* 예산 = 돈 칸 오른쪽 · 「1,000,000원」 꼴 */
  .li-rawmark,:where(#liBody) [data-part~="rawmark"]{display:inline-block;margin-left:4px;padding:0 6px;border-radius:var(--r-ctl);background:var(--bg-fill);color:var(--text-3);font-size:var(--fs-cap);line-height:18px;vertical-align:middle}   /* ★ 과제 373 — AI 요약 없음 = 원문 앞줄 표식(목록 · 상세 같은 옷) */
  #liBody [data-part~="rawline"]{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:0}
  .pill.src-k{background:var(--src-kakao);color:var(--src-kakao-ink)}   /* 문의경로 카카오(노랑) */
  .pill.src-w{background:var(--src-web);color:var(--src-web-ink)}       /* 문의경로 홈페이지(로고 남색) */
  .umenu.li-menu .umenu-it{font-size:var(--text-sm)} .umenu.li-menu .uchk{display:none}   /* ★ 과제 375 ⑧ ⑨ — ⋯ 메뉴 = 글만(글자 아이콘 · ✓ 자리 없음) · 글자 크기 = 할 일 「필터」 팝업(h3.toolsonly .tk-fpop = --text-sm) */
  #liList .clrow > div{white-space:nowrap}
  #liList .clrow.clhead{min-height:40px}
  .li-s,:where(#liBody) [data-part~="s"]{color:var(--text-3);font-size:var(--fs-sm)}   /* ★ 과제 456 — 팝업 안 = data-part(보관함 줄 .li-s 는 그대로) */
  .li-co{font-weight:var(--weight-strong)}
  :where(aside[data-panel="linbox"]) [data-part~="age"]{font-size:var(--fs-sm)}   /* ★ 과제 456 — 옛 .li-age(-ok · -warn · -alert) = 팝업 세부정보 줄 · 정도 = data-st */
  :where(aside[data-panel="linbox"]) [data-part~="age"][data-st="ok"]{color:var(--ok)}                                      /* ⚠ 이름에 .warn · .ok 를 그대로 쓰면 전역 .warn(노란 상자 · 규칙 90)이 씌워진다(실측) */
  :where(aside[data-panel="linbox"]) [data-part~="age"][data-st="warn"]{color:var(--warn);font-weight:var(--weight-strong)}
  :where(aside[data-panel="linbox"]) [data-part~="age"][data-st="alert"]{color:var(--bad);font-weight:var(--weight-strong)}
  #liList .li-acts,#liArchList .li-acts{display:flex;gap:6px;justify-content:flex-start;align-items:center}   /* ★ 과제 280 — 처리 칸 = 왼쪽 정렬(머리 「처리」 = 첫 단추 자리) · 세로 가운데 · 차례 고정 [보관] [배정 ▾] [가져가기] */
  #leadInbox .li-empty{margin:0;padding:14px;text-align:center;color:var(--text-3);border:1px dashed var(--line);border-radius:var(--r-ctl)}
  /* 팝업(오른쪽 560) — 발 = [보관] … [배정 ▾] [내가 가져가기] · 몸 = AI 요약 · 문의한 사람 · 이어짐 · 원문(접힘) */
  aside[data-panel="linbox"] #liArchive{margin-right:auto}
  #liBody:focus{outline:none}
  #liBody [data-part~="ai"]{border:1px solid var(--line);border-radius:var(--r-ctl);padding:12px 14px;line-height:1.7}
  #liBody [data-part~="ai"] ol{margin:0;padding-left:18px}
  #liBody [data-part~="ai"] [data-part~="s"]{margin:6px 0 0}
  #liBody [data-part~="link"]{border-radius:var(--r-ctl);padding:10px 14px;font-size:var(--fs-sm);line-height:1.6}
  #liBody [data-part~="link"] a,#liBody a[data-lilead]{color:var(--accent)}
  #liBody [data-part~="raw"] summary{cursor:pointer;color:var(--accent);font-size:var(--fs-sm)}
  #liBody [data-part~="rawtxt"]{margin-top:8px;border:1px dashed var(--line-input);border-radius:var(--r-ctl);padding:10px 14px;color:var(--text-2);
    font-size:var(--fs-sm);white-space:pre-wrap;max-height:40vh;overflow:auto}
  /* 배정 목록 — 휴가 · 휴직 중 = 흐림 + 까닭(고를 수는 있다 · DB 가 경고 문구) */
  .li-as{display:flex;align-items:center;gap:8px;flex:1;min-width:0}
  .li-as-t{margin-left:auto;color:var(--text-3);font-size:var(--fs-cap);white-space:nowrap}
  .li-as.off{opacity:.55}
  .li-as-cap{padding:4px 8px 6px;color:var(--text-3);font-size:var(--fs-cap)}
  /* 보관함 */
  #liArchList{border:1px solid var(--line);border-radius:var(--r-ctl);margin-top:8px}
  #liArchList .clrow{grid-template-columns:minmax(160px,1.4fr) minmax(120px,1fr) 96px;min-width:0}
  /* ★ 검토 375 4차(10-13) — 보관함 줄 = 이름 위 · 날짜 아래 두 줄(각 줄 말줄임). 375 1차가 받은 함에서 .li-two 를 안 쓰게 되며 지운 규칙 둘을 보관함에만 되살림(받은 함 표는 한 줄 그대로) */
  #liArchList .li-two{display:flex;flex-direction:column;justify-content:center;line-height:1.35;min-width:0}
  #liArchList .li-two > *{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  /* ★ 과제 244 (시안 v4) — 열한 칸 : # · 회사명(최대 220) · 업종 · 지역 · 서비스(남는 폭 · 말줄임) · 담당 AE · 집행 · 총매출 · 총마진 · 마진율 · 최근 집행일 · (앞) 과제 147 여섯 칸 */
  #advList .clrow{grid-template-columns:60px minmax(110px,1.2fr) 76px 76px minmax(100px,1fr) 104px 76px 120px 168px 88px 126px;   /* 1440 = 상자 1108 안 · 칸마다 머리(글 + 정렬 표시)와 값이 한 줄로 드는 폭(max-content 실측) · 회사명 · 서비스가 남는 폭을 나눔 */
    min-width:1104px}
  /* ★ 과제 203 (09-26 대표 「고쳐」 · 걷기 2차 #4 · #5) — 1400 아래(1280 등)에서 **핵심 칸이 먼저 줄던 것** : 상담명 · 광고주 담당자명(「외 N명」)
     → 덜 중요한 칸(등록일시 160 → 150(「2026-09-20 00:48」 이 다 들어가는 폭 · v280 ⓞ9) · 상담내용(긴 글 · 늘 말줄임) 최소 108 → 92(머리 글자 「상담내용」 + 정렬 아이콘이 한 줄 · v270 ⓐ3) · 담당자 번호 134 → 120 · 메일 최소 150 → 130)을 줄여 핵심 칸에 준다 · 1440 모습은 그대로
     · 그래도 좁으면 … + 마우스 올리면 전문(title · leads.js · advertisers.js) */
  @media (max-width:1399px){
    #leadList .clrow{grid-template-columns:150px minmax(110px,.8fr) 108px 100px minmax(108px,2fr) 96px minmax(100px,.8fr) 108px}   /* ★ 과제 217 — 1400 아래 : 같은 차례 · 최소 합 880 = 1280 가로 스크롤 0 · 상담내용 최소 108(머리 글자 + 정렬 아이콘 한 줄 · v270 ⓐ3) · (앞) 203 · 검토자 수정요청 92 → 108 */
    #advList .clrow{grid-template-columns:56px minmax(96px,1fr) 74px 74px 100px 76px 120px 134px 88px 124px;min-width:0}
    #advList .clrow > :nth-child(5){display:none}   /* ★ 과제 244 — 1400 아래 = 서비스 칸 감춤(29px 로 줄어 머리 글이 겹쳤다 · 실측) · 서비스는 필터 · 상세 「산 서비스」 에 그대로 */   /* ★ 과제 244 — 1400 아래 : 서비스가 줄고(0 까지) 요일 · 「집계 전」 글이 빠진다(숫자 칩만) · 1280 가로 스크롤 0 */
    #advList .adv-dw,#advList .adv-pl{display:none}
  }
  /* 거래처는 **기준정보**라 줄 높이가 촘촘합니다(§11-3 — 거래처·판매 매체만 8px · 옛 표의 td 와 같은 값)
     ★ v3.4 (과제 90 · 사양 §3-3) — 촘촘 예외는 **제 구역에서 `--row-h` 를 다시 적는다**(전역 값은 안 건드린다). */
  /* v2.70 (과제 132 · G-084) — 촘촘한 36 줄 은퇴 : 할 일과 같은 44(--row-h) */
  /* ★ 과제 122 (09-23 감사 9회차) — **게시대 표의 줄 키를 한 벌로.**
     칸 스물 중 `nowrap` 이 붙은 것은 셋뿐이라(학교·조사일·전화번호) 나머지가 **두 줄로 감겨**
     줄 키가 38 과 59 로 갈렸다(눈에 보인다 · 실제 406개교의 건물명·방법에는 더 긴 값이 많다).
     이 표는 **이미 가로로 스크롤**(`overflow-x:auto`)이라 넓어져도 잃는 것이 없다.
     ⚠ **「비고」 칸만 예외** — 코드가 40자까지 담으므로(`media.js:585`) `nowrap` 만 주면 표가 크게 넓어진다.
        그 칸은 **폭을 묶고 말줄임**으로 둔다(값은 상세에서 다 보인다). */
  /* v2.70 (과제 132 · G-084) — 촘촘한 36 줄 은퇴 : 할 일과 같은 44(--row-h) */
  /* ★ 과제 122 ② — **게시대 표도 제 상자를 갖는다**(과제 119 가 「대상 밖」으로 이름을 적어 남긴 자리).
     판매 매체는 도구 줄 카드가 아니라 119 의 한 자리가 못 닿는다 — 여기서 같은 값을 준다.
     ⚠ 이 표는 `max-height` + `overflow:auto` + **붙박이 머리줄**(`position:sticky`)이라
        라운드와 머리줄이 겹쳐 보일 수 있다 → **머리줄에 바탕을 줘서** 스크롤해도 모서리로 새지 않게 한다
        (`--tbl-head-bg` 는 이미 머리줄이 쓰는 토큰이다 · 새 색 발명 0). 스크롤해서 눈으로 확인했다. */
  /* ★ v2.78 (과제 137 · DESIGN §11-3) — 판매 매체도 **표 한 벌(.clrow)** — 옛 <table> 규칙 셋(상자 · td nowrap · 비고 말줄임)은 은퇴 :
       상자는 도구 줄 카드의 한 자리(위 「목록은 제 상자를 갖는다」)가 주고 · 한 줄 + 말줄임은 공용 뼈대(과제 147)가 준다.
       칸 = 간단 8칸 · (내부) 마스터 19칸 — 머리 글자가 정렬 표시와 한 줄에 들어가는 폭(세 글자 92 · 네 글자 108 — 132 「옛 폭 + 16」 문법)
       마스터는 칸이 많아 **표 상자 안 가로 스크롤**(종전 표도 그랬다 · min-width = 칸 최소 합) · 간단은 1280 에서도 스크롤 0(최소 합 904) */
  #mList:where([data-view="simple"]) .clrow{grid-template-columns:minmax(176px,2fr) 80px 80px 92px 92px 112px 128px minmax(120px,1.4fr)}   /* v2.92 (과제 162) — 학교 칸 최소 200 → 176 : 대표 · 재무 화면의 체크 칸(왼쪽 +24)이 1280 에서 가로 스크롤을 냈다 */
  #mList:where([data-view="master"]) .clrow{grid-template-columns:minmax(180px,1.6fr) 80px 80px 128px 92px 92px 92px 92px 92px 92px 92px 92px 92px 92px 92px 92px 112px 124px minmax(140px,1.4fr);
    min-width:1948px}   /* 판매상태 128 : 「상업광고 불가」 알약이 안 잘린다(108 이면 잘렸다 — 사진) */
  #mMasterNote{margin-top:0}
  #vendList .clrow{grid-template-columns:minmax(140px,1.4fr) minmax(136px,.9fr) minmax(110px,1.1fr) 140px 88px 132px minmax(80px,.8fr);
    min-width:906px}   /* ★ v3.08 (과제 176) — 유형(알약 「매체사」 + 「개인사업자」) 최소 96 → 136 : 1280 에서 「인쇄 …」 로 개인 · 법인이 가려졌다 · 최소 866 → 906(1280 표 948 안) */   /* v2.70 (과제 132 · G-084) — 옛 촘촘 줄 위아래 여백 8 은퇴(줄 키는 칸 44 가 정한다) */
  /* ★ 과제 465c — 탭마다 칸 차례(465c 구현 전 점검 · 디자이너 5 값) : 매체사 여덟 · 전체 = 앞에 유형 · 인쇄소 · 기타 다섯 · 이어짐 점검 넷 */
  /*   ⚠ :where() = 선택자 무게 = #vendList .clrow 와 같게(열 끄기 · 폭 조절 <style>(core.js _colApply · #vendList > .clrow)이 나중에 붙어 이긴다 — 무게가 크면 끈 열 자리가 빈 트랙으로 남음 · v238)
       ⚠ 칸 최소 합 = 1280 안(옛 906 이하 · v270 「1280 가로 스크롤 새로 0」) : 매체사 924 · 전체 942(1280 상자 948 안 · 기획 A = 전체 탭엔 「공식」 칸 없음 · 디자이너 7 ② = 거래처 최소 124(「(주)포커스미디어」 실측) · 말줄임 0 · 유형 108(「● 지정게시대」 105) · 수수료 104 · 담당자 88 · 연락처 136(「010-4444-5555」) · 자료 134 · 최근 집행 96 · 취급 매체 152 · 칩 = 칩 경계 자르기) · 인쇄소 · 기타 616 · 「대행수수료」 112 · 「최근 집행」 104 · 「유형」 84 · 「공식」 92(「● 비공식」 실측 90) · 연락처 136(「010-0000-0000」) · 자료 136(「● 오래됨 25-02」 실측 134) 아래로 줄이지 말 것(머리 한 줄 · v270 ⓐ3 · 디자이너 5) */
  #vendList:where([data-st="med"]) .clrow{grid-template-columns:minmax(120px,1.2fr) minmax(144px,1.1fr) 112px minmax(80px,.8fr) 136px 136px 92px 116px;min-width:936px}   /* ★ 과제 534 — 「최근 집행」 104→116(523 날짜 꼴 「12월 31일 (수)」 글 83 + 안여백 28 = 111 · 디자이너 10-27 18:14) */
  #vendList:where([data-st="all"]) .clrow{grid-template-columns:96px minmax(160px,1.4fr) minmax(114px,1fr) 104px minmax(88px,.8fr) 136px 134px 116px;min-width:948px}   /* ★ 과제 565 ③ 값 C(10-30 기획 · 디자이너 (나) 948 은 v270 ⓐ3 「대행수수료」 꺾임 · v471 ⓖ④ 「오래됨 25-02」 잘림 → A · B 도 v471 빨강) — 상자 948(v270 ⓖ · 1280 가로 굴림 0) · 유형 96 · 이름 160 · 1.4fr · 취급 114 · 1fr · 수수료 104 · 자료 134 · 옛 ② 2차 = 994(1280 에서 46 굴림) */
  #vendList .clrow > .cl-name:has(> .pill){display:flex;align-items:center;gap:var(--gap-tool)} #vendList .clrow > .cl-name:has(> .pill) > .pill{flex:none} #vendList .clrow > .cl-name:has(> .pill) .nm{min-width:0;overflow:hidden;text-overflow:ellipsis}   /* ★ 과제 565 ② — 「확인 필요」 칩 = 이름 왼쪽 같은 줄(칩열 v441 「vend › 거래처」 · 3953 코드 칩 꼴) */
  #vendList:where([data-st="print"]) .clrow,#vendList:where([data-st="etc"]) .clrow{grid-template-columns:minmax(180px,1.4fr) minmax(110px,.8fr) 128px minmax(110px,.8fr) 88px;min-width:616px}
  #vendList:where([data-st="link"]) .clrow{grid-template-columns:minmax(180px,1.2fr) minmax(180px,1.2fr) minmax(160px,1fr) 200px;min-width:720px}
  #vendList [data-part~="cats"]{display:flex;align-items:center;gap:var(--gap-tool);min-width:0}   /* ★ 465c 디자이너 7 ③ — 취급 매체 칩 = 칩 경계에서 자름(넘친 칩은 둘째 줄로 가 숨음 · 수는 남김) */
  #vendList [data-part~="chips"]{display:flex;flex-wrap:wrap;align-items:center;column-gap:var(--gap-tool);row-gap:0;min-width:0;height:var(--h-chip);overflow:hidden}
  #vendList [data-part~="cats"] > .muted,#vendList [data-part~="chips"] > .pill{flex:none}
  #vendList [data-part~="chips"] > .pill:first-child{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;line-height:var(--h-chip)}   /* 디자이너 9 [4] — 첫 칩 = 늘 보임 · 칸보다 길면 칩 안 말줄임(옛 0폭 ::before = 통째 숨김 → 수만 남았음) · 둘째부터 = 통째 아니면 숨김 · block = 알약 inline-flex 엔 text-overflow 가 안 먹음(「…」 없이 글자 중간 잘림) · 점 = ::before 절대 위치 그대로 */
  #vTypeTabs{margin-top:var(--gap-tool-body);margin-bottom:var(--gap-tool)}   /* 도구 줄 → 탭 = 도구 줄→몸 한 값(v354) · 좌우 = 카드 공용 24(위 .card:has(> h3.toolsonly) > * · 표 · 검색과 같은 선 — 디자이너 7 ①) */
  #vLinkLine{margin-top:0;margin-bottom:var(--gap-tool)}
  #vendOps{--pnl-cols:minmax(0,1.2fr) minmax(0,1.2fr) 110px 136px 96px}
  #vendSpend{--pnl-cols:56px 64px minmax(0,1.5fr) 84px 124px 156px}
  #vendSpend:not(:has(.num)){--pnl-cols:56px 64px minmax(0,1.5fr) 84px}
  /* ★ v1.36 (야간 UX R19 · R17 총평) — 「계산서 · 입금」이 열면 목록부터 시작합니다.
     새 색 · 새 부품은 없습니다 — `.clrow` 그대로이고 여기서 정하는 것은 **열 넷의 폭**뿐입니다
     (위 세 줄 · `#qListAll`·`#odListAll`·`#spListAll` 과 같은 방식 — D-095 와 같은 판단). */
  #billList .clrow{grid-template-columns:minmax(170px,1.7fr) minmax(120px,1.2fr) 104px minmax(136px,.9fr) minmax(136px,.9fr);
    min-width:702px}   /* ★ 과제 519 2차 — 다섯째 열 「미수(부가세 포함)」(요약과 같은 돈) · 머리 글이 늘어 돈 열 136 */
  #reportList .clrow{grid-template-columns:minmax(190px,2fr) minmax(130px,1.3fr) 104px;min-width:476px}
  /* v1.65 (과제 17) — 「담당」 열 하나가 캠페인과 합계 사이에 늘었다(84px = 캠페인 목록의 담당 열과 같은 몫) */
  #qListAll .clrow{grid-template-columns:148px 100px minmax(96px,.9fr) minmax(150px,1.5fr) 136px 128px 116px}   /* v2.77 (과제 147 ①) — 만든 날 100 → 116(132 의 「옛 폭 + 16」) : 날짜 10자가 한 줄에 다 들어간다 · 담당 100 → 136 : 사진 동그라미 + 이름 + 「나」 가 한 줄(필요 124.x — 100 이면 「김」 · 124 면 「김태…」 로 잘렸다 — main 에도 · 사진에서 잡음) */
  /* ★★ 과제 107 (09-22 감사 2회차 ① · 검토자 실측 54·44·44) — 담당 칸(다섯째)에 「나」 배지가 더 붙으면
     84px 에 안 들어가 **그 줄만 54px** 이 됐다. 줄 키는 44 한 벌이어야 한다(§0 · R3).
     ★ **과제 105(캠페인)와 같은 원인 · 같은 방법**이다 — 담당 칸을 **한 줄로 못 박는다.**
       두 화면이 어긋나면 다음 사람이 헷갈리므로 **일부러 같은 모양으로** 적는다.
     ⚠ **열 폭은 안 넓힌다** — 검토자가 105 에서 폭만 되돌려 보고 「폭은 원인이 아니다」를 실측했다.
       (105 에서 폭을 `minmax` 로 둔 것은 **넓은 창에서 이름을 살리려는 것**이지 줄 키 때문이 아니다.)
     되돌리려면 : 아래 한 줄만 지운다. */
  #qListAll .clrow > *:nth-child(5){display:flex;align-items:center;min-width:0;white-space:nowrap;overflow:hidden}
  #qListAll{overflow:hidden}   /* ★ 상자(테·라운드·여백)는 위 한 자리로 옮겼다(과제 119). 여기 남은 것은 **이 목록만의 것** — clrow 는 모서리를 넘으므로 잘라 준다 */
  #qListAll>p.muted,#qListAll>.hint{margin:0 24px 16px}

  /* ── 발주 (v0.83~85) ── */
  /* ★ v1.56 (R6) — 발주번호(C26-0042-0001 · 13자)가 96px 칸에서 **두 줄로 깨지던** 자리다(실측).
     가장 긴 번호가 한 줄에 들어가는 폭으로 잡고, 줄바꿈을 막는다(.cnum). */
  #odListAll .clrow{grid-template-columns:142px 68px minmax(118px,1.4fr) minmax(76px,.8fr) 116px 108px minmax(64px,.6fr)}
  /* ⚠⚠ **발주 옛 목록만 예외로 제 상자를 그대로 갖는다** — `#odListWrap.od-v2-hidden` **안**에 있어
     위 한 자리(`.card:has(> h3.toolsonly) > …`)가 **직계 자식이 아니라 못 닿는다.**
     지금은 과제 79 가 감춰 놔 안 보이지만, **되살리는 날 맨몸으로 나온다**(검토자 09-22 이 자리를 잡아냈다).
     ★ **관문이 못 본다** — 감춰진 것은 재지지 않으니, 이 줄을 지우면 아무도 안 운다. 그래서 여기 적어 둔다. */
  #odListAll{margin:20px var(--card-pad-x) 20px;border:1px solid var(--line);border-radius:var(--r-ctl);overflow:hidden}
  #odListAll>p.muted,#odListAll>.hint{margin:0 24px 16px}
  #odSchools{max-height:340px;overflow:auto;border:1px solid var(--line-soft);border-radius:var(--r-ctl)}
  /* ★ v1.13 — 발주 대기·완료 묶음 머리 · 학교 선택 팝업(2층 딤 · #qMatchBack 과 같은 규격) · 달력 뷰 유형 점 · 기간 밖 날짜 */
  .odgrp{display:flex;align-items:center;gap:8px;margin:12px 0 6px;font-size:var(--fs-sm);font-weight:var(--weight-strong);color:var(--text-2)}
  /* ★★ v2.17 (09-17 · 과제 72 · 발주 v3-a) — 마스터-디테일 두 칸 · 학교 리스트 · 작업자 지정 팝업.
     토큰만(색·라운드·굵기) · 새 색 0 · 그림자 0. 감추는 것은 CSS(규칙 112) : 옛 목록 = .od-v2-hidden · 달력 뷰일 때 = #orderMD.odv3-cal */
  .od-v2-hidden{display:none}
  #rFileMake{display:none}   /* ★ 과제 455 — 공유 링크 팝업 안 옛 [보고서 파일 만들기](은퇴 · id 보존) = 옛 .od-v2-hidden 대신 이 id 한 줄(팝업 안 접두어 0) */
  #orderMD.odv3-cal #odV3Wrap{display:none}
  /* ★ v3.5 (과제 93) — 지급 완료 팝업 : 요약 띠 · 줄마다 금액 칸 (새 색·새 크기 0 · 토큰만) */
  /* ★ 과제 455 (팝업 흡수 B) — 지급 완료 팝업 안 = 옛 .spp- 접두어 0 : 옛 자체 요약(#spPaySum)은 머리 띠로 옮긴 뒤 늘 숨김(hidden) · 낼 것 줄 = #spPayLines id 규칙 + data-part(값 그대로) */
  #spPaySum[hidden]{display:none}
  #spPayLines{display:flex;flex-direction:column;gap:6px;margin:12px 0;max-height:46vh;overflow:auto}
  #spPayLines > [data-part="line"]{display:grid;grid-template-columns:minmax(0,1fr) 150px;gap:10px;align-items:center;
      padding:8px 12px;border:1px solid var(--line);border-radius:var(--r-ctl)}
  #spPayLines [data-part="who"]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  #spPayLines [data-spleft]{font-size:var(--fs-cap);margin-top:4px;text-align:right}   /* v2.94 (과제 165 #13) — 줄 밑 흐린 「남음 N원」 */
  #spPayLines [data-part="who"] .muted{font-size:var(--fs-cap)}
  #spPayLines > [data-part="line"] input{text-align:right;font-variant-numeric:tabular-nums}
  /* ★★ v3.6 (과제 94 · 사양 §4·§8) — 지출 등록 팝업(캠페인 지출) · AE 가 못 보는 칸.
     ⚠ 규칙 112 — 감추는 규칙은 전부 **JS 가 붙이는 표시**에 묶여 있다(화면 #spend = class .sp-ae · .sp-nov60 · ★ 과제 455 뒤 팝업 그릇 = data-st 낱말 ae · nov60 · nocamp · nopick).
       JS 가 한 번 걸리면 아무것도 안 감춰진다 = 빈 상자가 되지 않는 안전한 쪽. 새 색·새 크기 0 · 토큰만. */
  #spend.sp-ae #spSum,
  #spend.sp-ae #spDueAct,
  #spend.sp-ae #spInboxBtn,
  #spend.sp-ae #spSeg button[data-spseg="due"],
  #spend.sp-ae #spSeg button[data-spseg="ov"]{display:none}
  #spComposeWrap[data-st~="ae"] #spKindSeg button[data-spkind="ov"],
  #spComposeWrap[data-st~="ae"] #spKindSeg button[data-spkind="mc"]{display:none}   /* ★ 과제 455 — 팝업 그릇 표시 = data-st(규칙 112 그대로) */
  #spComposeWrap[data-st~="nov60"] [data-part~="v60only"]{display:none}
  /* ★ v3.7 (과제 95) — 증빙 격자 : 사진 화면의 격자(.phgrid·.phcell)를 그대로 쓴다(새 부품 0) */
  #spend.sp-ae #spFStatus option[value="__noev"]{display:none}
  /* 승인번호 = **가리키는 것**이므로 파랑(`--accent`) · 주 행동 단추(검정)와 섞지 않는다(DESIGN §1) */
  #spEvCard #spEvRefBtn{color:var(--accent);cursor:pointer}
  .spev-grid{margin-top:8px}
  .spev-cell{position:relative}
  .spev-cell .spev-del{position:absolute;top:4px;right:4px;padding:0 6px;line-height:18px}
  .spev-pdf{display:flex;align-items:center;justify-content:center;height:88px;
      background:var(--bg-fill);border-radius:var(--r-ctl);font-size:var(--fs-sm);color:var(--text-2)}
  #spComposeWrap:not([data-st~="nov60"]) [data-part~="v60hint"]{display:none}
  #spCpForm[data-st~="nocamp"] [data-part~="needcamp"]{display:none}
  #spCpForm:not([data-st~="nocamp"]) [data-part~="onlyok"]{display:none}   /* v2.94 (과제 144) — 캠페인을 고른 뒤엔 「확정 견적 있는 캠페인만」 한 줄 숨김 */
  #spCpForm[data-st~="nopick"] [data-part~="nopickhide"]{display:none}
  #spCpForm[data-st~="attach"] [data-part~="newonly"]{display:none}
  :where(#spComposeWrap) [data-part~="sec"]{padding:12px 0;border-top:1px solid var(--line)}
  /* ★★ v2.88 (과제 159 · 대표 컨펌 · 시안 다섯 장) — 지출 팝업 = 구역 제목(.pnl-sect · 상자 위 줄)이 가른다 → 토막 사이 선은 뗀다 */
  #spCpForm [data-part~="sec"]{border-top:0;padding:0 0 14px}
  :where(#spComposeWrap) [data-part~="kindbar"]{margin:0 0 18px}
  #spComposeWrap[data-st~="edit"] [data-part~="noedit"]{display:none}   /* v2.94 (과제 165 #3) — 지출 수정 = 종류 고르개 · 발주 고르기 없음(그 줄 하나를 고친다) */
  :where(#spComposeWrap) [data-part~="kindbar"] #spKindSeg{display:flex;width:100%}
  :where(#spComposeWrap) [data-part~="kindbar"] #spKindSeg > button{flex:1 1 0;justify-content:center}
  #spCpForm [data-part~="poline"]{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
  #spCpForm [data-part~="poline"] > #cpPoList{flex:1 1 auto;min-width:0}
  #spCpForm [data-part~="poline"]:has(#cpPoList .clrow) > #cpPoList{flex-basis:100%}
  #spCpForm [data-part~="poline"] > #cpNewPo{margin-left:auto}
  #spCpForm [data-part~="poempty"]{color:var(--text-2);font-size:var(--fs-sm)}
  #spCpForm [data-part~="poline"] > #cpPoList:not(:has(.clrow)){border:0;margin-top:0;overflow:visible}   /* 발주 없음 = 테 없는 한 줄 */
  /* 팝업 몸 안 고르개(.seg)는 158 의 「몸 안 단추 = 흰 보조 옷」 에서 뺀다 — 고른 칸만 흰 면(화면 도구 줄 .seg 와 같은 옷) */
  aside.slideover .pnl-body .seg > button:not(.on){background:transparent !important;border:1px solid transparent !important;color:var(--text-2) !important}   /* 158 의 몸 안 단추 규칙(:not 여럿 · 무게가 크다)을 이긴다 · ★ 414c v4 = 투명 1px 테(고른 것과 폭 같음) */
  aside.slideover .pnl-body .seg > button:not(.on):hover{background:var(--bg-hover) !important;color:var(--text) !important}
  aside.slideover .pnl-body .seg > button.on{border:1px solid var(--line) !important;background:var(--bg-card) !important;color:var(--accent) !important;font-weight:var(--weight-medium)}   /* ★ 414c v4 = 흰 + 1px --line + 인디고(옛 = 테 0 · ink 500) */
  aside.slideover .pnl-body button[data-part~="linkbtn"]{background:none;border:0;box-shadow:none;padding:0;height:auto;color:var(--accent);align-self:flex-start}   /* ★ 과제 455 — 지출 쪽 = data-part · ★ 과제 456 — 광고주 등록 팝업도 data-part(옛 .cp-linkbtn 뺌) */
  #spCpForm [data-part~="vnew"]{display:none}
  #spCpForm[data-st~="vnewopen"]:not([data-st~="attach"]) [data-part~="vnew"]{display:flex}
  :where(aside[data-panel="adv"]) [data-part~="linkbtn"],:where(#spComposeWrap) [data-part~="linkbtn"]{background:none;border:0;box-shadow:none;padding:0;height:auto;color:var(--accent);font-size:var(--fs-sm);cursor:pointer;justify-content:flex-start}
  :where(aside[data-panel="adv"]) [data-part~="linkbtn"]:hover,:where(#spComposeWrap) [data-part~="linkbtn"]:hover{background:none;text-decoration:underline}
  #spCpForm .cdprops.asform > [data-part~="vnewtog"]{margin-top:-8px}
  label[data-part~="ck"]{display:flex;align-items:center;gap:8px;min-height:32px;cursor:pointer}   /* ★ 과제 455 — 체크 한 줄(지출 판관비 · 계산서 면세) · 옛 label.sp-ck 와 같은 무게 */
  :where(#spInboxWrap) [data-part="top"]{display:flex;align-items:center;gap:10px;margin:0 0 12px}   /* ★ 과제 455 — 받은편지함 머리 한 줄(옛 .ib-top · 같은 무게) */
  :where(#spInboxWrap) [data-part="top"] > button{margin-left:auto}
  /* 돈 칸 = 오른쪽 정렬 — 적는 칸 폼에서 돈 표시(data-money)가 달린 칸은 모두(지출 · 발주 · 다른 팝업도 같은 한 자리) */
  .cdprops.asform .cdprop:has(> .pv[data-money]) > input{text-align:right;font-variant-numeric:tabular-nums}
  :where(#spComposeWrap) [data-part~="sec"]:first-child{border-top:0;padding-top:0}
  :where(#spComposeWrap) [data-part~="list"]{border:1px solid var(--line);border-radius:var(--r-ctl);overflow:hidden;margin-top:8px;max-height:34vh;overflow-y:auto}
  /* ⚠ 전역 `.clrow` 는 가로 스크롤 표를 위해 `min-width:852px` 다 — 팝업 안(폭 약 510)에서는 칸이 잘린다.
     발주 v3 목록(.odv3-list)이 쓴 방법 그대로 **이 팝업 안에서만** 0 으로 풀고 칸을 다시 나눈다. */
  :where(#spComposeWrap) [data-part~="list"] .clrow{padding-left:16px;padding-right:16px;min-width:0;gap:8px;
      grid-template-columns:minmax(0,104px) minmax(0,1fr) minmax(0,84px) minmax(0,86px) minmax(0,64px)}
  /* ★ v2.94 (과제 165 · 규칙 128) — 발주에 붙이기 표 : 지출번호 · 합계 · 상태 알약은 안 자른다(「1,100,00…」 사진 06) · 줄어드는 것은 발주항목 · 거래처 */
  #cpPoList .clrow{grid-template-columns:124px minmax(0,1fr) minmax(0,54px) 127px}   /* ★ 과제 593(대표 11-02 10:41 ★가 · 시안 화면그리기/그림_261102/과제593_*) — 네 칸 · 지출번호 124(굵은 코드 118~120 안 자름) · 상태 칸 숨김 → 발주항목 152(「● 배송비 포스터 1,000장」 온전) · 금액 127 · 거래처 54 그대로 */
  #cpPoList .clrow > :nth-child(5){display:none}   /* 상태(고를 수 있음 · 돈 나감 · 일부 냄) = 잠긴 줄 이름 앞 자물쇠 + title 로 */
  #cpPoList .clrow[data-st~="locked"] > :nth-child(2)::before{content:"";display:inline-block;width:var(--fs-sm);height:var(--fs-sm);margin-right:calc(var(--gap-tool) / 2);vertical-align:-0.125em;background:currentColor;-webkit-mask:var(--ic-lock) center/contain no-repeat;mask:var(--ic-lock) center/contain no-repeat}
  @media (max-width:600px){   /* ★ 과제 593 ㉠ 한 줄(대표 고름) — 폰 = 발주항목 + 합계 두 칸 · 지출번호 · 거래처는 고른 뒤 폼에 보임 */
    #cpPoList .clrow{grid-template-columns:minmax(0,1fr) 127px}
    #cpPoList .clrow > :nth-child(1),#cpPoList .clrow > :nth-child(3){display:none}
  }
  #cpCampList .clrow{min-width:0;grid-template-columns:minmax(0,104px) minmax(0,1fr) minmax(0,120px)}
  :where(#spComposeWrap) [data-part~="list"] .clrow > *{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  :where(#spComposeWrap) [data-part~="list"] .clrow[data-st~="locked"]{color:var(--text-3)}
  :where(#spComposeWrap) [data-part~="picked"]{margin-top:8px;font-size:var(--fs-sm)}
  :where(#spComposeWrap) [data-part~="evs"]{display:flex;flex-wrap:wrap;gap:8px 14px;font-size:var(--fs-sm)}
  :where(#spComposeWrap) [data-part~="evs"] label{display:flex;align-items:center;gap:6px;white-space:nowrap}
  /* ⚠ 전역 `input{width:100%}` 이 체크박스까지 늘려 글자를 밀어낸다 — 이 팝업 안에서만 제 크기로.
     (전역 규칙은 건드리지 않는다 · 과제 96 이 체크를 직접 그리는 방식으로 정리한다) */
  :where(#spComposeWrap) [data-part~="evs"] input[type=checkbox]{width:auto;flex:0 0 auto;margin:0}
  [data-part~="drop"]{margin-top:10px;padding:14px 16px;border:1px dashed var(--line);border-radius:var(--r-ctl);
      font-size:var(--fs-sm);color:var(--text-2);text-align:center}
  [data-part~="drop"].on{border-color:var(--accent);color:var(--ink)}   /* ★ 과제 579 (디자이너) — 끌어 놓기 칸 = 공용 부품 하나 [data-part~="drop"](옛 = 지출 작성 · 세무사 PDF 2층 선택자 목록 · 566 ② 공용화 후보 · 값 그대로) */
  :where(#spComposeWrap) [data-part~="files"]{margin-top:8px;font-size:var(--fs-sm)}
  :where(#spComposeWrap) [data-part~="files"] .pill{cursor:pointer}
  .odv3-wrap{display:grid;grid-template-columns:minmax(280px,1fr) minmax(0,2.4fr);gap:20px;align-items:start;margin-top:4px}
  @media (max-width:1100px){ .odv3-wrap{grid-template-columns:1fr} }
  .odv3-left,.odv3-right{min-width:0}
  .odgrp-sub{font-weight:var(--weight-regular)}
  /* ★★ 과제 116 ② (09-22 감사) — **표가 제 상자를 갖는다**(DESIGN §11-3 v3.4).
     과제 90 이 옷을 입힌 것은 `.clrow`/`.clhead`/`.scrolltbl` 인데 발주는 **제 클래스 `.odv3-list`** 라
     머리줄·세로줄·줄 키 토큰만 받고 **상자를 못 받았다**(그래서 `디자인v34검사 v238` 이 초록 — 그 관문은 상자를 안 본다).
     ⚠ `#odSchoolList` 는 **가로로 스크롤되는 표**다 — `overflow:hidden` 없이 상자만 주면 선이 끊긴다.
       라운드 + `overflow-x:auto` 로 **스크롤이 상자 안에서 돌게** 한다. */
  .odv3-list{border:1px solid var(--line);border-radius:var(--r-ctl);overflow:hidden}
  .odv3-list > p.muted,.odv3-list > .hint{margin:0;padding:16px}
  .odv3-list .clrow{min-width:0}   /* v2.70 (과제 132) — 줄 여백 16 은 칸 안여백 14 가 맡는다 */
  #odCampList .clrow{grid-template-columns:minmax(0,1fr) 72px 128px}
  #odCampList .clrow .odv3-adv{display:block;font-size:var(--fs-cap);color:var(--text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  #odSchoolList{overflow-x:auto}
  #odSchoolList .clrow{grid-template-columns:38px 72px minmax(84px,1fr) minmax(72px,1fr) 56px 56px 108px 134px minmax(172px,1.3fr) minmax(60px,.5fr)}   /* v2.21 — 진행 열이 ✓·사진 n·배지·📷 를 한 줄에 담게 넓힘 · ★ 과제 116 : 권역 44→56(「수도권」이 한 줄로) · 비고 최소 40→60 */
  /* ★★ 과제 116 ① (09-22 감사 · 검토자 실측 44·48·87) — **줄 키를 44 한 벌로**(R3).
     「수도권」 줄은 권역이 두 줄로 꺾여 48 · 비고가 긴 줄은 네 줄로 터져 87 이었다.
     권역(2번 칸) = 한 줄로 못 박고 폭을 「수도권」이 들어가게 · 비고(10번 칸) = 한 줄 말줄임(전문은 `title` 과 상세에서).
     ⚠ 폭만 넓히는 것으로는 안 된다 — 글자가 길면 또 꺾인다. **꺾임을 막는 것은 `nowrap` 쪽**이다(과제 105 와 같은 결).
     ★ 진행 칸(9번)은 150 → **172px** : ✓시각·사진 n·위치 배지· 네이 한 줄에 **137px** 인데
       칸 안여백·세로줄을 빼면 쓸 수 있는 폭이 **딱 137** 이라 한 픽셀 차로 꺾였다(09-22 실측 · main 도 같았다). */
  #odSchoolList .clrow > *:nth-child(2){white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
  #odSchoolList .clrow > *:nth-child(10){white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
  #odSchoolList .clrow > div:nth-child(9){display:flex;flex-wrap:wrap;align-items:center;gap:4px 6px;min-width:0}
  #odSchoolList .clrow.odv3-on{background:var(--bg-active)}
  .odv3-list .clrow .odv3-ck{width:auto;padding:0;margin:0;cursor:pointer}   /* 전역 input{width:100%} 을 되돌린다 */
  .odv3-list .clrow .r{text-align:right;font-variant-numeric:tabular-nums}
  .odv3-date{height:28px;padding:0 6px;font-size:var(--fs-sm);border:1px solid var(--line);border-radius:var(--r-ctl);background:var(--bg-card);color:var(--ink);width:100%;min-width:0}
  .odv3-date:focus{outline:none;border-color:var(--accent)}
  .odv3-tools{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:0 0 8px}
  .odv3-spacer{flex:1}
  /* ★★ v2.87 (과제 157 · 09-24 대표 「발주 페이지는 화면을 대학교, 지정게시대, 아파트게시판 나눠」) — **대학교 = 확정 학교 한 표** · 작업요청서 = 작업자별 한 줄
     옛 두 칸(#odV3Wrap)은 숨김만(id 보존 · 규칙 112) — ↩ 되살리기 = 아래 첫 줄을 지운다. 「+ 새 발주」 도 숨김만(가정 G-123 · ↩ 둘째 줄).
     값은 전부 토큰 · 칸 폭은 옛 학교 리스트(#odSchoolList)의 폭을 그대로 쓴다(고르기 38 · 권역 72 · 작업일정 134 · 상태 172) · 게시기간 128 = 「10/14 ~ 10/27」 한 줄(1440 실측). */
  #odV3Wrap{display:none}
  /* ★ 과제 407b — #odNewBtn = 「+ 새 현장」(이 화면 주 단추 · 옛 「+ 새 발주」 숨김 줄 은퇴 · ↩ 되살리기 = 이 자리에 #odNewBtn{display:none}) */
  .odu-list{overflow-x:auto}
  /* ★★ 과제 447b (대표 10-19 · 시안 A G-662) — 줄 하나 = 현장 · 주소 · (코드) 광고주_캠페인 · 작업자 · 포스터 · 현수막 · 마감 · 학교 승인 · 진행(묶기 셋 다 같은 꼴)
     옛 = 학교 · 권역 · 게시기간 · 작업자 · 작업일정 · 상태(기획 지적 ① 캠페인 열 없앰 → 대표 10-19 「어떤 프로젝트인지 구분 안 됨」 으로 되살림) · 작업일정 = 현장 상세 · 선택 띠 「작업일정 바꾸기」 */
  #odUnivList .clrow{grid-template-columns:minmax(0,1.25fr) minmax(0,1.05fr) minmax(0,1.25fr) 104px 104px 76px 84px 120px}
  #odUnivList .clrow.clhead > div{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  #odUnivList .clrow > div{min-width:0}
  #odUnivList .clrow > [data-k="name"]{display:flex;align-items:center;gap:6px}
  #odUnivList .clrow > [data-k="name"] .pill{flex:0 0 auto}
  #odUnivList .clrow > [data-k="name"] a.nm{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text);text-decoration:none}
  #odUnivList .clrow > [data-k="name"] a.nm:hover{color:var(--accent);text-decoration:underline}
  #odUnivList .clrow > :is([data-k="addr"],[data-k="camp"]){overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  #odUnivList .clrow > [data-k="camp"] b{font-weight:var(--weight-medium)}
  #odUnivList .clrow > [data-k="qty"]{font-variant-numeric:tabular-nums;white-space:nowrap}
  #odUnivList .clrow [data-lg]{display:none}
  #odUnivList .odu-grp[data-ureq]{border-top:0;padding-top:0;background:var(--tbl-head-bg)}
  #odUnivList .odu-grp[data-ureq] b{font-weight:var(--weight-medium);color:var(--text)}
  #odAxisRow{display:flex;align-items:center;gap:var(--gap-tool);margin:0 0 var(--gap-tool)}
  #odAxisRow[hidden]{display:none}
  /* 현장 상세 — 걸린 캠페인 · 발송 줄 칸(공용 .pnl-rows · 칸 차례만 이 화면 id 로) */
  #odSiteCamps{--pnl-cols:minmax(0,1.6fr) 52px 52px minmax(0,1fr) 112px 52px 72px 132px}
  #odSiteShip{--pnl-cols:minmax(0,1fr) 92px minmax(0,1fr) 132px 56px}
  :is(#odSiteCamps,#odSiteShip) .pnl-row > div{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--fs-sm)}
  #odSiteCamps .pnl-row b{font-weight:var(--weight-medium)}
  @media (max-width:600px){   /* 폰 390 = 넉 줄 카드([권역] 현장 · 마감 / 주소 / 코드 광고주_캠페인 / 포스터 · 현수막 · 진행) · 머리줄 · 작업자 · 승인 = 묶음 머리 · 상세에서 */
    #odUnivList:not(.odu-fld) .clrow{grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"n d" "a a" "c c" "q s";row-gap:2px;height:auto;min-height:0;padding-top:8px;padding-bottom:8px}
    #odUnivList:not(.odu-fld) .clrow.clhead{display:none}
    #odUnivList:not(.odu-fld) .clrow > *{min-height:0;border-right:0}   /* 공용 칸 높이(--row-h) · 세로줄을 폰 카드에선 뺌 */
    #odUnivList:not(.odu-fld) .clrow > [data-k="name"]{grid-area:n} #odUnivList:not(.odu-fld) .clrow > [data-k="due"]{grid-area:d;justify-self:end}
    #odUnivList:not(.odu-fld) .clrow > [data-k="addr"]{grid-area:a} #odUnivList:not(.odu-fld) .clrow > [data-k="camp"]{grid-area:c}
    #odUnivList:not(.odu-fld) .clrow > [data-k="qty"]{grid-area:q} #odUnivList:not(.odu-fld) .clrow > [data-k="step"]{grid-area:s;justify-self:end}
    #odUnivList:not(.odu-fld) .clrow > :is([data-k="who"],[data-k="to"]){display:none}
    #odUnivList:not(.odu-fld) .clrow [data-lg]{display:inline}
    #odSiteCamps,#odSiteShip{--pnl-cols:minmax(0,1fr) minmax(0,1fr)}
  }
  #odUnivList .clrow > .cl-name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
  /* ★ 과제 263 — TO 칸(권역 다음 · v0.79 뒤에만 · .odu-to-on) · 구인 줄(묶음 머리 아래 · 권역 알약) */
  #odUnivList .clrow button.odu-to{background:none;border:0;box-shadow:none;padding:0;height:auto;font-size:var(--fs-sm);font-weight:var(--weight-regular);cursor:pointer;white-space:nowrap;text-align:left}
  #odUnivList .clrow button.odu-to:disabled{cursor:default}
  #odUnivList .clrow button.odu-to:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--radius-sm)}
  .odu-rec{display:flex;flex-wrap:wrap;align-items:center;gap:6px 8px;padding:6px var(--card-pad-x) 8px;border-top:1px solid var(--line);font-size:var(--fs-sm)}
  #odUnivList.clsel .odu-rec{padding-left:calc(var(--card-pad-x) * 2)}
  .odu-rec-l{color:var(--text-3);margin-right:2px}
  .odu-rec .odu-recb{padding:0;border:0;background:none;height:auto}
  .odu-rec .odu-recb:disabled{opacity:1;cursor:default}
  .odu-tosum{white-space:nowrap}
  #odUnivList.clsel .odu-grp{position:relative;padding-left:calc(var(--card-pad-x) * 2)}
  #odUnivList.clsel .odu-grp > .odu-gsel{position:absolute;left:var(--card-pad-x);top:0;bottom:0;margin:0;display:flex;align-items:center;cursor:pointer}
  .selbar[data-selfor]:not([hidden]){display:inline-flex;align-items:center;gap:8px}
  #odUnivList .clrow button.odu-dflt{background:none;border:0;box-shadow:none;padding:0;height:auto;font-size:var(--fs-sm);font-weight:var(--weight-regular);color:var(--text-3);cursor:pointer;white-space:nowrap}
  #odUnivList .clrow button.odu-dflt:hover{color:var(--accent);background:none}
  .odu-phico{display:inline-flex;align-items:center;color:var(--text-2)}
  .odu-phico:hover{color:var(--accent)}
  #odUnivList .clrow > .odu-stcell{display:flex;flex-wrap:nowrap;align-items:center;gap:4px 6px;min-width:0}
  #odUnivList .clrow.odv3-on{background:var(--bg-active)}
  .odu-grp{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:8px 14px;border-top:1px solid var(--line);background:var(--tbl-head-bg);font-size:var(--fs-sm)}
  .odu-grp .odu-gname{font-weight:var(--weight-strong);color:var(--text)}
  .odu-tools{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:0 0 8px}
  .odu-req{border:1px solid var(--line);border-radius:var(--r-ctl);padding:4px 14px 8px;margin:0 0 12px;background:var(--bg-card)}
  .odu-req .odgrp{margin:6px 0 4px;flex-wrap:wrap}   /* 과제 573 ③-b — 머리 [작업요청서 | 급여] · 안내 · 인사 링크가 좁으면 접힘 */
  .odu-reqrow{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:6px 0;border-top:1px solid var(--line);font-size:var(--fs-sm)}
  .odu-reqrow .odu-reqwho{display:inline-flex;align-items:center;gap:8px;min-width:0}
  .odu-pills{display:inline-flex;gap:6px;flex-wrap:wrap}
  .odu-cpill .st{pointer-events:none}
  #mBroAdd, #mBroLink{color:var(--accent);text-decoration:none}   /* ★ 과제 268 실행 — 판매 매체 「소개서 넣기 · 열기 ↗」 = 브라우저 기본 파랑(#0000EE) · 밑줄 → 가리킴 파랑(--accent) · 밑줄 없음(「List 에서 전부 보기 →」 · 「확정 견적 보기 →」 와 같음) */
  .odu-empty{padding:var(--gap-tool-body) 16px}   /* ★ 과제 268 실행 — 도구 줄 → 몸 = 20(표 화면과 같음 · 옛 24) */
  #order .odu-wrap{padding-top:var(--gap-tool-body)}   /* ★ 과제 268 실행 — 대학교 보기 : 작업요청서 카드 · 표가 도구 줄 선에 붙어 있었다(0) → 20 */
  #odCalView{padding-top:calc(var(--gap-tool-body) - var(--gap-title))}   /* ★ 과제 268 실행 — Calendar : 첫 줄 여백 12(묶음 제목) + 8 = 20 */
  /* ★ v2.23 (과제 77) — 「실시간보고서 생성」은 **줄 오른쪽 끝**(사양 §2-5 · 주 행동 하나). 줄이 넘치면 제 줄로 내려가되 오른쪽에 붙는다. */
  #odReportGate{margin-left:auto;display:inline-flex;align-items:center;gap:6px}
  #odReportGate:empty{display:none}
  .odv3-gatehint{font-size:var(--text-sm)}
  .odv3-chips{display:inline-flex;gap:6px;flex-wrap:wrap}
  /* ★ 과제 116 ⑤ (09-22 감사) — 토글 켜짐에 **바탕**이 없어 눌러도 안 눌린 것처럼 보였다.
     캠페인의 「내 캠페인」(`button#cFMine.on` · app.css 위쪽)과 **같은 꼴**로 맞춘다 — `--accent-soft` 바탕. */
  .odv3-chips button.on{background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}
  .odv3-cards{display:flex;flex-wrap:wrap;gap:12px;margin-bottom:10px}
  .odv3-cards:empty{display:none}
  /* ★ v2.18 (과제 73) — 작업자 카드 = 카드 안 묶음(DESIGN §6-3 · 1px 선 · 그림자 0) · 옛 인력 단추 감춤 · 인력 단가 격자 */
  .odv3-wcard{flex:1 1 300px;max-width:420px;min-width:0;border:1px solid var(--line);border-radius:var(--r-card);padding:12px 14px;background:var(--bg-card)}
  .odv3-wcard.odv3-issued{border-color:var(--accent)}
  .odv3-wcard .odv3-wc-head{display:flex;align-items:center;gap:8px;margin-bottom:6px;min-width:0}
  .odv3-wcard .odv3-wc-head .muted{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .odv3-wcard .odv3-wc-head .st{margin-left:auto;white-space:nowrap}
  .odv3-wcard .odv3-wc-sum{display:flex;gap:12px;flex-wrap:wrap;font-size:var(--fs-sm);color:var(--text-2);margin-bottom:8px}
  .odv3-wcard .odv3-wc-sum b{color:var(--ink);font-variant-numeric:tabular-nums}
  .odv3-wcard .odv3-wc-pay{font-size:var(--fs-body);color:var(--ink);font-weight:var(--weight-medium);font-variant-numeric:tabular-nums}
  .odv3-wcard .odv3-wc-btns{display:flex;gap:6px;flex-wrap:wrap;align-items:center}
  .odv3-wcard .odv3-wc-btns .odv3-wc-more{margin-left:auto;display:inline-flex;gap:6px;flex-wrap:wrap}
  .odv3-datehint{flex-basis:100%;font-size:var(--fs-cap)}
  /* ★ v2.21 (과제 76) — 진행 열 : 사진 n(가리키는 것 = 파랑) · 📷 · 드롭존 · 진행 막대 */
  .odv3-ph{cursor:pointer;color:var(--accent);font-size:var(--fs-sm);white-space:nowrap}
  .odv3-ph:hover{text-decoration:underline}
  .odv3-phup{text-decoration:none !important;opacity:.7}
  #odSchoolList .clrow.odv3-drop{outline:2px dashed var(--accent);outline-offset:-2px;background:var(--bg-active)}
  .odv3-upbar{display:block;height:4px;border-radius:2px;background:var(--line);overflow:hidden;margin-top:4px}
  .odv3-upbar[hidden]{display:none}
  .odv3-upbar i{display:block;height:100%;width:0;background:var(--accent);transition:width var(--duration-fast) var(--ease)}
  /* ★ v2.25 (과제 79 · 사양 §2-8) — 발주 v3 로 입구를 모으며 **감추는 것들**. 지우는 것이 아니라 감춘다(id 보존 · 규칙 112).
     DB 뷰·표·함수(v_po_todo · po_todo_overrides · 트리거)는 그대로 둔다 — 화면만 안 보일 뿐이다.
     ⚠ display:none 이라 **키보드(Tab)로도 닿지 않는다**(관문이 그것을 잰다). */
  #odKindSeg{display:none}                       /* 유형 세그먼트 — 인력은 학교 리스트에서, 나머지는 지출 화면에서 */
  #odKindSeg [data-kind=인력]{display:none}      /* (v2.18 · 과제 73) 인력 단추 — 세그먼트째 감춘 뒤에도 남겨 둔다(관문 v218 ⑩ 이 이 줄을 잰다) */
  .odv3-fold{margin-top:10px}
  .odv3-fold .odgrp{margin-top:6px}
  /* 작업자 지정 팝업 — 제 이름만(규칙 110) */
  /* ★ 과제 455 (팝업 흡수 B) — 작업자 지정 팝업 안 = 옛 .odv3a- 접두어 0 : 고르기 줄 = #odV3AssignWrap [data-part~="pick"] · 값 그대로 */
  #odV3AssignList{max-height:280px;overflow:auto;border:1px solid var(--line);border-radius:var(--r-ctl);margin-bottom:10px}
  #odV3AssignWrap [data-part~="pick"]{display:flex;align-items:center;gap:10px;padding:8px 12px;margin:0;border-bottom:1px solid var(--line-soft);cursor:pointer;min-height:40px;font-size:var(--fs-body);color:var(--ink);font-weight:var(--weight-regular)}
  #odV3AssignWrap [data-part~="pick"] .muted{white-space:nowrap}
  #odV3AssignWrap [data-part~="pick"]:last-child{border-bottom:0}
  #odV3AssignWrap [data-part~="pick"]:hover{background:var(--bg-hover)}
  #odV3AssignWrap [data-part~="pick"].on{background:var(--bg-active)}
  #odV3AssignWrap [data-part~="pick"] input[type=radio]{width:auto;height:auto;padding:0;margin:0;flex:0 0 auto}   /* 전역 input{width:100%} 을 되돌린다 */
  #odV3AssignWrap [data-part~="pick"] [data-part="nm"]{font-weight:var(--weight-medium);color:var(--ink);min-width:72px;flex:0 0 auto}
  #odV3AssignWrap [data-part~="pick"] [data-part="last"]{margin-left:auto;font-size:var(--fs-cap);color:var(--text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:46%}
  #odV3AssignWrap [data-part="new"]{border:1px solid var(--line);border-radius:var(--r-ctl);padding:0 12px 10px}
  #odV3AssignWrap [data-part~="newhead"]{padding-left:0;padding-right:0}
  #odV3AssignWrap [data-part="newrow"]{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin:4px 0 8px}
  .odgrp .odgrp-sub{font-weight:var(--weight-medium)}
  .odgrp button.mini{height:26px;min-height:26px;width:26px;padding:0;display:inline-flex;align-items:center;justify-content:center}
  .odgrp[data-dchip]{flex-wrap:wrap;gap:var(--gap-tool)}   /* ★ 과제 449 — 「요약에서 거름」 칩(core.js dashChipPut 한 벌) : 목록 상자 앞 한 줄 · 좁으면 단추째 다음 줄 */
  .odgrp[data-dchip] button.mini{width:auto;padding:0 var(--gap-tool);white-space:nowrap}   /* 위 26 정사각(아이콘 단추)이 「✕ 풀기」 를 두 줄로 꺾었다 */
  #odTodoList .clrow.overdue{box-shadow:inset 2px 0 0 var(--bad)}
  #odPickBack{position:fixed;inset:0;z-index:80;background:var(--dim-layer2);display:none;align-items:center;justify-content:center;padding:20px}
  #odPickBack.open{display:flex}
  /* ★ v2.80 (과제 142 · DESIGN §12-00) — 2층 학교 선택 = 공용 틀 옷 : 760(크기 셋) · 네 토막(pnl-head · pnl-sum · pnl-body · pnl-foot) · 발 회색 면 */
  #odPickPop{background:var(--bg-card);border-radius:var(--r-panel);box-shadow:var(--sh-float);width:min(760px,95vw);max-height:86vh;display:flex;flex-direction:column;padding:0;overflow:hidden;animation:toastIn var(--duration-base) var(--ease)}
  #odPickPop h3{margin:0;font-size:var(--fs-card);font-weight:var(--weight-strong);letter-spacing:-.01em;color:var(--ink);display:flex;align-items:center;gap:10px}
  #odPickPop h3 .tools{margin-left:auto;display:flex;gap:6px;align-items:center}
  #odPickBody{flex:1;overflow-y:auto;min-height:0;padding:18px 22px}
  /* ★ v2.80 (과제 142 수정 · 기획 지적 ①④⑤) — 새 발주 : 즉석 등록 단추 = 제 칸 바로 밑 · 구역 사이 18(pnl-sect 와 같은 값) ·
     집행학교 = [학교 선택] 칸 자리 + 안내 한 줄 · 남은 칸 = 누르는 알약 하나 · 빈 칸 밑 빨간 도움말(.fldmsg) */
  .cdprops.asform .cdprop > .btns{margin:0;justify-content:flex-start}
  :where(#hrIncForm) .cdprops.asform .cdprop[data-part~="calc"]{justify-content:flex-end}   /* ★ 과제 456 — 옛 .hi-calc */
  .cdprops.asform .pk .muted{font-weight:var(--weight-regular);color:var(--text-3)}   /* ★ 과제 145 — 라벨 뒤 흐린 안내(「비우면 재직」 따위) = 보통 굵기 · 흐린 글자(라벨과 갈린다) */   /* ★ 과제 145 — 인센티브 「계산」 단추 = 옆 칸(귀속 월) 바닥에 맞춘다 */
  #odComposeWrap > .card + .card{margin-top:18px}
  #odLaborCard [data-part="schoolcol"]{display:flex;flex-direction:column;gap:5px;align-items:flex-start}
  #odLaborCard [data-part="schoolcol"] > label{margin:0}
  #odSchoolSum{font-size:var(--fs-cap);color:var(--text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
  button.pill[data-act="gatego"]{cursor:pointer;border:0}   /* ★ 과제 455 — 옛 .od-gatego(같은 무게) */
  .fldmsg{font-size:var(--fs-cap);color:var(--bad);line-height:1.5}
  #odPickPop .btns.pnl-foot{margin:0;padding:13px 22px;background:var(--bg-app);border-top:1px solid var(--line)}
  .qcal .qcal-d[disabled]{opacity:.35;cursor:not-allowed}
  #odCalGrid .cal-g .d.mark.k인력::after{background:var(--ok)}
  #odCalGrid .cal-g .d.mark.k인쇄::after{background:var(--accent)}
  #odCalGrid .cal-g .d.mark.k디자인::after{background:var(--warn)}
  #odCalGrid .cal-g .d.mark.kwd::after{background:var(--text-2)}
  .odsch{display:flex;align-items:center;gap:10px;padding:7px 12px;cursor:pointer;
    border-top:1px solid var(--line-soft);font-size:var(--text-sm)}
  .odsch:first-child{border-top:0}
  .odsch:hover{background:var(--bg-hover)}
  .odsch.on{background:var(--bg-active)}
  .odsch input[type=checkbox]{flex:0 0 auto;width:auto;accent-color:var(--accent)}   /* v1.13 — 팝업(#odPickBack)으로 나오면 전역 input{width:100%} 이 체크박스를 750px 로 늘려 학교명이 세로로 섰다(실측 · 규칙 70) */
  .odsch .nm{font-weight:var(--weight-strong)}
  .odsch .rg{color:var(--text-2);font-size:var(--text-xs)}
  .odsch .who{margin-left:auto}
  /* ★ 과제 414c — 옛 `#odRgChips button.on` 은퇴 → 알약 탭 .ptab(한 벌) */

  /* ── 지출 (v0.86~87) ── */
  #spListAll{overflow:hidden}   /* ★ 상자(테·라운드·여백)는 위 한 자리로 옮겼다(과제 119). 여기 남은 것은 **이 목록만의 것** — clrow 는 모서리를 넘으므로 잘라 준다 */
  #spListAll>p.muted,#spListAll>.hint{margin:0 22px 16px}
  /* ★ 과제 121 (09-23 감사) — **인사 목록의 격자를 인라인에서 여기로 옮겼다.**
     `hr.js` 가 줄마다 `style="grid-template-columns:…"` 를 박고 있어 **「열」 기능이 인라인에 졌다**
     (인라인은 선택자 무게로는 못 이긴다). **다른 목록 열둘이 이미 CSS 로** 적으므로 그 방식에 맞췄다.
     ⚠ 값은 **인라인에 있던 것 그대로**다 — 겉모습이 바뀌면 안 된다(머리줄·줄 같은 값). */
  #hrList .clrow{grid-template-columns:94px 1fr 92px 78px 116px 132px 90px}
  /* ★ 과제 121 — 지출도 같은 병이었다(`[data-seg]` 도 무게 1 을 더한다 · 검토자 목록에 없던 자리를 관문이 찾았다). */
  /* v2.70 (과제 132 · G-093) — 머리 칸에 정렬 아이콘(14)+간격(8)이 들어와 +16 으로도 머리 글자가 감기는 칸(지출예정일 · 발생일 · 예정일 · 고정비)은
     새 px 를 만들지 않고 max-content(글자·아이콘에 맞춘 폭) — 남는 폭은 fr 칸이 낸다(가로 스크롤 0).
     ★ v2.71 (과제 133 · 대표 지적 2차 ⑧) — max-content 는 **줄마다 따로 격자**라 줄마다 칸 경계가 어긋났다 → 머리줄 실측(107 · 85)의 고정값 108 · 86 으로(모든 줄 같은 경계). */
  #spListAll .clrow.clhead > *{white-space:nowrap}   /* v2.94 (과제 165) — 머리 글자 한 줄(맨 글자가 flex 이름 없는 칸이라 한글이 글자마다 꺾였다 · 1280 「발주항목」) · 칸 최소 = 한 줄 머리 폭(관문 v304 ⓑ 가 넘침도 본다) */
  #spListAll:where([data-seg="po"]) .clrow{grid-template-columns:140px minmax(83px,1.2fr) minmax(95px,1fr) minmax(83px,.7fr) 142px 100px 108px 89px;
    min-width:840px}   /* ★ v3.08 (과제 176) — 지출번호 122 → 140 : 지금 번호는 넷째 토막이 네 자리(「C26-0042-0002」 굵게 138)라 1440 에서도 「C26-0042-…」 로 셋이 같아 보였다 · 상태 86 → 100(「증빙누락」 알약 96) · 최소 808 → 840(+ 체크 여백 48 = 888 < 1280 표 948) */   /* v2.96 (과제 169) — 돈 칸 = 「지급액」 한 칸 142(굵게 · 옛 합계 142 + 실지급액 140 → 142) · 최소 948 → 808(1280 표 948 에 체크 칸 여백 48 을 더해도 가로 스크롤 0) */   /* v2.94 (과제 165 #2 · #24) — 돈 · 코드 칸은 안 자른다 : 지출번호 122(가장 넓은 「C26-9988-88」 굵게 121) · 합계 142(「9,999,999,999원」 굵게) · 실지급액 140(보통 글자) ·
                          최소 = 머리 글자 한 줄(캠페인 · 거래처 · 지급일 83 · 발주항목 95 · 지출예정일 107 — 1280 사진에서 「발주항목」 이 세로로 꺾였다) · 상태 86(「증빙누락」) · 지급일 89(「09-30 외 1」 · 159 사양) · 합 948 = 1280 표 폭 948(여유 0 — 칸을 더하려면 먼저 잴 것) · 긴 이름은 말줄임(규칙) */
  #spend.sp-ae #spListAll:where([data-seg="po"]) .clrow{grid-template-columns:140px minmax(83px,1.2fr) minmax(95px,1fr) minmax(83px,.7fr) 142px 100px 108px;min-width:751px}   /* v2.96 (과제 169) — 지급액 한 칸 */
  #spend.sp-ae #spListAll:where([data-seg="po"]) .clrow > :nth-child(8){display:none}   /* v2.94 (과제 165 #23) — AE 는 지급일을 못 읽는다(늘 빈 칸) → 칸째 숨김 · 실지급액은 그대로(대표 결정 #22) */   /* v2.88 (과제 159) — 지급일 열 108(지출예정일과 같은 폭 · 「09-19 외 1」 한 줄) · 거래처 최소 56 → 88 : 지급일 열이 자리를 먹어 1280 에서 「거래처」 머리 글자가 꺾였다(칸 80 · 자체시험 (99) 가 잡음) */
  #spListAll:where([data-seg="ov"]) .clrow{grid-template-columns:88px minmax(100px,1.6fr) minmax(64px,.9fr) 142px 148px 86px 108px 86px 82px;
    min-width:914px}   /* v2.94 (과제 165 #2) — 합계 124 → 142(돈 칸 말줄임 0) · 내용 최소 110 → 100 */   /* v2.88 (과제 159) — 지급일 열 108 · v2.91 (과제 163) — 발생일 86 → 등록일시 148(상담 등록일시와 같은 폭 · 「YYYY-MM-DD HH:mm」 한 줄) · 합계 108 → 124(「1,650,000원」 굵게가 잘렸다 · 사진이 잡음 · 지급 대기 실지급액과 같은 폭) */
  /* ★ v2.77 (과제 147 ④ · 09-24 기획 지적) — **지급 대기(9칸)는 격자 규칙이 없었다**(과제 93 부터 · git 기록 전체에 0) → 기본 7칸 격자를 받아
       증빙 · 올린 사람이 줄마다 둘째 줄로 떨어지고 머리줄도 두 줄이었다. 관문이 못 본 까닭 = 통일검사 SEED 가 지출을 「캠페인 지출」 보기로만 심었다.
       칸 = ☐ 44(할 일 체크 칸) · 예정일 88 · 캠페인 · 내용 · 거래처(머리 글자 한 줄 88~) · 은행·예금주·계좌 · 실지급액 124(옛 108 + 16) · 증빙 · 올린 사람(112~) — 1280 표 상자(948)에 가로 스크롤 없이 들어가는 최소 합 936 */
  #spListAll:where([data-seg="due"]) .clrow{grid-template-columns:88px minmax(132px,1.5fr) minmax(100px,1.1fr) minmax(88px,.8fr) minmax(140px,1.4fr) 142px minmax(80px,.8fr) minmax(112px,.9fr)}   /* v2.94 (과제 165 #2) — 실지급액 124 → 142 · 캠페인 150 → 132 · 은행 150 → 140(1280 · 체크 칸 여백 48 포함 가로 스크롤 0) */
  /* ☐ 칸 = 할 일 체크 칸처럼 안여백 0 · 가운데(44 안 안여백 14 면 16 만 남아 말줄임 「.」 이 붙었다 — 사진에서 잡음) · 올린 사람 = 머리 글자 + 정렬 표시 한 줄(96 이면 1280 에서 「올린 사/람」) */
  /* v2.92 (과제 162) — 옛 ☐ 칸(44 · 첫 칸 가운데)은 은퇴 : 고르기 칸 = 공용 .clsel > .clrow > .selbox(맨 왼쪽 · 체크 칸 두 벌 금지) */
  .sel-host{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:0 0 8px}   /* v2.92 (과제 162) — 공용 선택 띠 자리(표 바로 위 한 줄 · 발주 .odu-tools 와 같은 값 · G-127) */
  .sel-host:not(:has(> .selbar:not([hidden]))){display:none}                         /* 띠가 숨으면 자리도 0(빈 줄 8px 을 남기지 않는다) */
  /* ★ v2.94 (과제 165 #7 · Q-055 ⓐ) — 지출 : 표 바로 위 한 줄 = [선택 띠 …] ⟨채움⟩ [받은편지함 →] · 도구 줄 = 한 줄(1280 : 옛 1,066 / 950px) */
  .sp-listhead{display:flex;align-items:center;gap:8px;margin:var(--gap-tool-body) var(--card-pad-x) 8px}   /* ★ 268 뒤따름 — 옛 위 0(도구 줄 선에 붙음 · 정산 표 사진 01) */
  .sp-listhead > .sel-host{margin:0;flex:1 1 auto}
  .sp-listhead > #spInboxBtn{margin-left:auto}
  #spend.sp-ae .sp-listhead{display:none}                                           /* AE = 받은편지함 · 선택 띠 둘 다 없다 → 빈 줄 0 */
  #spend h3.toolsonly #spDueAct:empty{display:none}                                  /* 옛 자리(id 보존) — 늘 비어 사이 8 만 먹었다 */
  @media (max-width:1439px){ #spend h3.toolsonly .search, #spend h3.toolsonly .tools > .tk-left > .search{flex-basis:190px;width:190px} }   /* §6-2 하한 */
  @media (min-width:1440px) and (max-width:1599px){ #spend h3.toolsonly .search, #spend h3.toolsonly .tools > .tk-left > .search{flex-basis:240px;width:240px} }   /* ★ v3.08 (과제 176) — 1440 에서 도구줄이 23 모자라 「내가 만든 것」 이 아래 줄로 꺾였다 → 검색 240 */
  #spend[data-spseg="dash"] .sp-listhead{display:none}   /* ★ 과제 184 ④ (대표 「탭 밑에 혼자 떠 있음」 → 넘침 실측 사진 02 · 03 뒤 기획 ⓒ) — 받은편지함 = 옛 자리(표 바로 위 오른쪽) 그대로 · **Dashboard 보기에서만** 숨김 · 도구 줄 한 줄 유지 */
  /* ★ 과제 268 정산 — 요약 칩 = 공용 칩 그대로(할 일 20 · 좌우 8 · 12px) · 옛 줄 = #spSum .pill{font-size:var(--fs-sm);padding:0 10px;height:22px} */
  #spSum.btns{margin-top:0}   /* ★ 과제 268 정산 — 제목 → 요약 칩 = h2 기본 12(할 일 · 모든 페이지) · .btns 의 위 14 가 h2 의 12 를 이겼다 */
  #spSum[hidden]{display:none}   /* ★ 과제 154 — Dashboard 보기에서는 타일이 같은 값을 보인다(두 번 적지 않는다 · 사진 : display 규칙이 hidden 을 이겼다) */
  #spFMonth{width:132px;flex:0 0 auto}
  #ibList .clrow{grid-template-columns:104px minmax(140px,1.6fr) 80px 126px minmax(90px,.9fr)}
  #ibList{max-height:380px;overflow:auto}

  /* ── 반응형 ── */
  @media (max-width:1080px){
    .split{grid-template-columns:minmax(0,1fr)}
    .split>.side{position:static}
  }
  @media (max-width:1024px){
    nav{position:static;width:auto;height:auto;flex-direction:column;border-right:0;
        border-bottom:1px solid var(--line);padding:8px 12px;overflow:visible}
    #sideBrand,#sideUser,#sideFoot,nav #gSearch{display:none}
    #sideNavScroll{flex-direction:row;overflow-x:auto;overflow-y:visible;gap:2px;padding:0}
    #sideNavScroll[data-more]{-webkit-mask-image:linear-gradient(to right,var(--ink) calc(100% - 32px),transparent);mask-image:linear-gradient(to right,var(--ink) calc(100% - 32px),transparent)}   /* ★ 과제 509 (걷기 줄 8) — 옆으로 더 있으면 오른쪽 흐림(굴림 표시 · data-more = boot.js · 끝까지 굴리면 걷힘) */
    nav a{white-space:nowrap;flex-shrink:0}
    nav .grp{display:none}
    nav a .nkey{display:none}   /* v2.36 — 단축키는 데스크톱 것 · 가로 띠에서는 감춘다 */
    .tk-dtwo,.tk-dtwo.even{grid-template-columns:1fr} .tk-dstats{grid-template-columns:repeat(2,minmax(0,1fr))}   /* v2.40 — 대시보드는 한 줄로 */
    .tk-dstats[data-dn]:not([data-dn="0"]){grid-template-columns:repeat(2,minmax(0,1fr))} .tk-dstats[data-dn] > [data-dcard="dnow"]{grid-column:1/-1}   /* ★ 과제 430c — 좁은 폭 = 「지금 할 일」 한 줄 · 타일 둘씩 */
    .wrap{margin-left:0}
    #home .grid2{grid-template-columns:1fr}
  }
  @media (max-width:880px){
    .slideover{width:100vw;border-radius:0}
    .pnl-head{border-radius:0}
    #toasts{right:10px;bottom:10px}
    .split>.side{position:static}
  }
  @media (prefers-reduced-motion:reduce){
    section.appear,.toast,.slideover,.pnl-backdrop,.stat,.board .cardlet,.flow .st{
      animation:none !important;transition:none !important}
  }

  /* ══ v1.15 (09-10 대표 결정) — 상세 = 가운데 팝업 ══ ★ v2.84(과제 158) : 자리는 오른쪽 넓음 820 · 창 높이 전부로 옮김(아래 「v2.84」 줄 · DESIGN §12-000) ══
     08-21 「자기 개체 = 우측 396px 제자리 패널」을 뒤집었습니다. 목록은 언제나 전폭 · 줄을 고르면 상세가
     화면 가운데 딤 위에 뜹니다(DESIGN.md §5 P1). 구조는 그대로 — 래퍼(#campMD·.mdwrap)의 nosel 이 여전히
     「선택 있음/없음」의 단일 스위치이고, 상세 칸(#campSide·.mdside)에 위치·폭·딤만 입혔습니다.
     id·저장 로직·딥링크 관찰자 무변경. 닫는 길(✕·딤 클릭·Esc) = boot.js mdModal.
     v0.93~1.00 의 ⤢ 전체 보기·← 목록은 은퇴 — 팝업이 920px 라 이유가 없어졌습니다. 캠페인 2단(.campcol)·
     광고주 2단(.advcol) 배치는 그때 규칙을 팝업 안으로 옮긴 것입니다.
     층(z) : 딤 26 → 상세 팝업 28 → (그 위) 팝업 딤 30 → makePanel 팝업 40 — §12-2 표. */
  #campMD:not(.nosel)::before,.mdwrap:not(.nosel)::before{content:"";position:fixed;inset:0;
      background:var(--dim-sheet);z-index:26}   /* v2.84 (과제 158) — 오른쪽 팝업 = 옅은 딤 */
  /* ★★ v2.84 (과제 158) — 상세도 **오른쪽 넓음 820 · 창 높이 전부**(옛 = 가운데 920 · 88vh — DESIGN §10 은퇴 표) · 딤 = 옅게(뒤 목록이 보인다) */
  #campSide,.mdside{position:fixed;top:0;right:0;bottom:0;left:auto;transform:none;z-index:28;
      width:min(820px,96vw);height:100vh;max-height:none;box-sizing:border-box}
  /* 한 카드 상세(상담·광고주·할 일·견적·발주·지출·인사) = 카드가 곧 팝업 · 카드 안에서 스크롤 */
  .mdside>.card{min-height:0;height:100%;overflow-y:auto;box-shadow:var(--sh-float);border:0;border-radius:var(--r-panel) 0 0 var(--r-panel)}   /* v4 지침 P — 오른쪽 팝업 = 왼쪽 모서리만 16 · 선 = --sh-float 의 1px 하나 */
  /* 캠페인 = 카드 여럿(상세 · 견적서 · 할 일·발주) → 앱 바탕색 틀 안에 카드가 놓이고 틀이 스크롤 */
  #campSide{background:var(--bg-app);border:0;border-radius:var(--r-panel) 0 0 var(--r-panel);
      box-shadow:var(--sh-float);padding:14px;overflow-y:auto}
  /* ★★ 과제 457 (팝업 흡수 C2 · 시안 ⓕ A) — 표준 옷을 입으면 그릇 = 흰 바탕 · 패딩 0 · 몸(.pnl-body)이 굴러감(머리 · 큰 제목 · 세부정보 · 발 = 고정) · 상자(.card) = 구역(테두리 · 그림자 · 면 0 · 구역 제목 .pnl-sect 가 나눔) */
  #campSide.pstd{background:var(--bg-card);padding:0;gap:0;overflow:hidden}
  #campSide.pstd > .pnl-body .card{background:none;border:0;box-shadow:none;padding:0;border-radius:0;overflow:visible}
  #campSide.pstd .campcol > .card:not([style*="display:none"]):not([style*="display: none"]):not([hidden]) + .boxttl.pnl-sect{margin-top:calc(var(--gap-group) - var(--gap-card))}   /* ★ 과제 568 — 보이는 상자 다음 머리 = 단 gap 16 + 16 = 32(숨은 은퇴 상자 다음 = 단 맨 위 그대로) */
  #campSide.pstd .campcol > .boxttl.pnl-sect{margin:0 0 -8px;padding-right:0;font-size:var(--fs-body);letter-spacing:normal;color:var(--text)}
  #campSide.pstd > .pnl-foot > #btnCampClose{margin-left:auto}
  /* 팝업이 떠 있으면 뒤 화면은 안 굴러간다 */
  body:has(section.on #campMD:not(.nosel)),body:has(section.on .mdwrap:not(.nosel)){overflow:hidden}
  /* ⚠ 실측(09-10) — 섹션 진입 애니메이션(secIn · translateY 3px)이 도는 동안은 섹션이 transform 을 가져
     position:fixed 의 기준이 뷰포트 → 섹션으로 바뀌고, 팝업이 위로 붙는다(딥링크·빠른 클릭에서 보임).
     상세가 열린 섹션은 진입 애니메이션을 두지 않는다 — 팝업은 언제나 뷰포트 기준(규칙 89). */
  section.on:has(#campMD:not(.nosel)),section.on:has(.mdwrap:not(.nosel)){animation:none}
  /* 상세 위에 등록·수정 팝업(makePanel)이 서면 상세는 잠시 숨고, 그 팝업의 딤은 2층 값(누적 방지 · §12-2) */
  body:has(.slideover.open) #campSide,body:has(.slideover.open) .mdside{visibility:hidden}
  body:has(section.on #campMD:not(.nosel)) .pnl-backdrop.open,
  body:has(section.on .mdwrap:not(.nosel)) .pnl-backdrop.open{background:var(--dim-layer2)}
  /* ✕ — 팝업 오른쪽 위 한 곳(§12-2 · 28px 사각 = button.xclose). 높이 0 sticky 띠에 얹어 카드 자리를 안 먹고
     스크롤해도 따라옵니다. 그 아래 첫 카드 제목의 도구 칸이 ✕ 에 안 가리게 오른쪽을 비웁니다. */
  .mdx-bar{position:sticky;top:0;height:0;margin-bottom:-14px;z-index:3;align-self:stretch;flex:0 0 auto}
  #campSide.pstd > .mdx-bar{margin-bottom:0}   /* ★ 과제 457 2차(디자이너 5) — 표준 옷 = 패딩 0 · 옛 -14(패딩 14 를 먹던 값)가 머리 띠를 창 위로 14 끌어올림 → 0(머리 top 0 · 높이 52 전부) */
  .mdx-bar button.xclose{position:absolute;right:8px;top:8px}
  .mdside>.card>h3:first-of-type,#campSide .grid2>.campcol:last-child>.card:first-child>h3,#ciBody .grid2>.campcol:last-child>.card:first-child>h3{padding-right:34px}
  /* ★ v2.82 (과제 150) — 캠페인 상세의 구역 제목 = 상자 바로 위 밖(boot.js 가 상자 앞으로 옮긴 제목 · .boxttl).
     글자 = 카드 제목과 같은 --fs-card/600(페이지 머리 한 단계 아래 · §2) · 상자와의 사이 = 칸 사이 16 에서 8 을 당겨 8(새 값 0 — 이미 쓰는 8).
     오른쪽 34 = ✕ 자리(위 줄과 같은 값). */
  #campSide .boxttl,#ciBody .boxttl{margin:0 0 -8px 2px;padding-right:34px;font-size:var(--fs-card);font-weight:var(--weight-strong);
      letter-spacing:-.01em;color:var(--ink);display:flex;align-items:center;gap:8px;flex-wrap:wrap}
  #campSide .boxttl.cd-ovl,#ciBody .boxttl.cd-ovl{font-size:var(--fs-cap);color:var(--text-2);letter-spacing:.05em}
  /* 상자가 감춰지면(은퇴한 계약서 · 정산 흐름 껍데기 · 숨은 발주 따위) 옮긴 제목도 함께 감춘다 — 상자가 나중에 보이면 제목도 따라 보인다 */
  #campSide .boxttl:has(+ .card[style*="display:none"]),#campSide .boxttl:has(+ .card[style*="display: none"]),#ciBody .boxttl:has(+ .card[style*="display:none"]),#ciBody .boxttl:has(+ .card[style*="display: none"]),
  #campSide .boxttl:has(+ .card[hidden]),#ciBody .boxttl:has(+ .card[hidden]){display:none}
  #taskViewCard #tmClose{display:none}          /* 할 일 = 옛 팝업 ✕ 가 같이 딸려 오므로 팝업 안에서는 감춤 */
  /* 캠페인 2단 : 왼쪽 = 상세 / 오른쪽 = 견적서·할 일·발주 (v0.96 전체 보기 배치 그대로 · 좁으면 한 줄) */
  #campSide .grid2,#ciBody .grid2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;align-items:start;margin-bottom:0}
  #campSide .grid2>.campcol,#ciBody .grid2>.campcol{display:flex;flex-direction:column;gap:16px;min-width:0}
  @media (max-width:1100px){
    #campSide .grid2,#ciBody .grid2{grid-template-columns:minmax(0,1fr)}
    #campSide .grid2>.campcol,#ciBody .grid2>.campcol{display:contents}
    #campSide.pstd .campcol > .boxttl.pnl-sect{margin-top:calc(var(--gap-group) - var(--gap-card))}   /* ★ 과제 568 — 한 단(≤1100)이면 견적서 머리도 왼 단 아래 경계 */
  }
  /* 광고주 2단 : 왼쪽 = 기업·담당자 / 오른쪽 = 메모·캠페인·관리 (v0.95 배치 그대로 · 좁으면 한 줄) */
  /* ★ 과제 195 (09-25 대표 「고쳐. 다음」 · 144 「광고주 폭 더 줄이도록」) — 광고주 상세 = 상담 상세와 같은 폭(560) · **한 단**(기업 → 담당자 → 메모 → 캠페인 · 적은 순서 = 탭 순서 그대로) */
  #advMD .mdside{width:min(560px,96vw)}
  #taskMD .mdside{width:min(560px,96vw)}   /* ★ 과제 453 — 할 일 화면에서 연 할 일 상세도 560(홈 · 다른 화면 위 #taskModal 과 같은 폭 · 시안 ⓔ · 옛 = 기본 820) */
  #vendMD .mdside{width:min(820px,96vw)}   /* ★ 과제 411b(10-17 대표 「거래처 상세 넓힘」) — 560 한 단 → 820 두 단(상세 표준 · 캠페인 상세와 같은 폭 · 운영매체 · 집행내역 표 둘) */
  /* ★★ 과제 219 — 알바 화면(시안 OK) : 목록 7칸(이름 · 전화 · 은행 · 계좌 · 예금주 · 폰 계정 · 맡은 발주 · 최근 지급일 · 메모) · 상세 560(거래처 상세와 같은 한 단) */
  #albaMD .mdside{width:min(820px,96vw)}   /* ★ 과제 498 2차(디자이너 [1] · §12-000 표 있는 상세 = 820 · 시안 1 · 옛 560) */
  #albaMD .mdside #btnAlbaClose{margin-left:auto}
  /* ★ 과제 491 디자인수정 2 [2](디자이너 10 · §12 발 「왼쪽 위험 하나 ··· 오른쪽 보조 · 주」) — [쉼으로] · [다시 작업자로] = 오른쪽 [닫기] 바로 앞 : 미는 자리(margin-left:auto)를 보이는 그 단추로(숨김 = style display none) */
  #albaMD .mdside .pnl-foot > :is(#alAccRest,#alAccBack):not([style*="none"]){margin-left:auto}   /* ★ 과제 498 — 발 = .pnl-foot(옛 .tm-foot) · 자리 규칙 그대로 */
  #albaMD .mdside .pnl-foot:has(> :is(#alAccRest,#alAccBack):not([style*="none"])) > #btnAlbaClose{margin-left:0}
  #campSide .pnl-foot > #cPONew:not([style*="none"]){margin-left:auto}   /* ★ 과제 511 디자인수정 1(디자이너 7 · 알바 발 본보기) — [삭제] 왼쪽 홀로 · 오른쪽 묶음 [＋ 발주 등록][닫기] : 미는 자리 = 보이는 발주 단추 */
  #campSide .pnl-foot:has(> #cPONew:not([style*="none"])) > #btnCampClose{margin-left:0}
  #albaList .clrow{grid-template-columns:minmax(140px,1.2fr) 144px minmax(180px,1.9fr) 112px 152px 132px 124px minmax(110px,1fr);min-width:0}   /* ★ 과제 469b — 「폰 계정」 칸 뺌(여섯 칸) */
  @media (max-width:1439px){ #albaList .clrow{grid-template-columns:minmax(100px,1fr) 132px minmax(150px,1.6fr) 108px 142px 113px 120px minmax(80px,.7fr)} }   /* ★ 과제 219 — 고정 칸 = 머리 글 + 정렬 꺾쇠 + 안쪽 여백이 한 줄(「최근 지급일」 120 · 「맡은 발주」 108) · 전화 13자리 140(사진 05 실측 : 머리 세 줄 · 번호 잘림) */
  #alViewBody .al-line{display:flex;gap:12px;align-items:baseline;padding:8px 0;border-bottom:1px solid var(--line)}
  #alViewBody .al-line .al-t{flex:1;min-width:0}
  #alViewBody .al-rrn-in{display:flex;gap:8px;align-items:center}
  #alWorkRows{--pnl-cols:96px minmax(0,1fr) minmax(0,1.2fr) auto}   /* ★ 과제 498 (G-b) — 작업 이력 = 공용 되풀이 줄(날짜 · 캠페인 · 근무일 · 리스트 · 급여 · 지급) · 폰 = 공용 두 칸 */
  #alWorkRows .pnl-row > .r{text-align:right;white-space:nowrap}
  #alWorkRows .pnl-row,#alViewSum > .dt-band{word-break:keep-all}   /* ★ 498 2차(디자이너 [3] · DESIGN 324) — 날짜 · 낱말 중간에서 안 꺾임 */
  #alWorkRows[data-rounds]{--pnl-cols:minmax(0,1.6fr) minmax(0,.9fr) minmax(0,1fr) 160px}   /* ★ 디자이너 4 2차 [1] — 끝 칸 고정(가장 긴 「240,000원 ☑ 지급 완료」 실측 146 + 백만 단위) · auto 면 줄마다 칸 x 어긋남 */   /* ★ 과제 574 ③ — 근무 이력 회차 줄(캠페인 · 현장 · 장수 │ 발송 │ 근무일 │ 급여 · 지급) · 날짜 줄(접힘)도 같은 칸 */
  #alWorkRows .pnl-row label{display:inline-flex;align-items:center;gap:var(--gap-tool);white-space:nowrap}
  #alWorkRows .pnl-row label > input[type=checkbox]{height:auto;padding:0}   /* 공용 .pnl-row input(높이 · 안여백) 을 체크에선 뺌 */
  #alWorkRows .al-t{display:flex;align-items:center;gap:var(--gap-tool);min-width:0;white-space:nowrap}   /* ★ 574 검토 8 [1] — pill · 코드 · 메모 = 늘 보임 · 줄이는 건 캠페인 이름만 */
  #alWorkRows .al-t > *{flex:none}
  #alWorkRows .al-t > b,#alWorkRows .al-t > s{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis}
  #alWorkRows > .pnl-row[data-cancel]{color:var(--text-3)}   /* ★ 디자이너 4 2차 [2] — 취소 · 노쇼 줄 글 흐림 */
  @media (max-width:600px){   /* ★ 디자이너 4 2차 [3] — 390 회차 줄 = 첫 줄 [pill] 코드 이름 … 금액 / 둘째 줄 발송 ☑ … 근무 ☐ … ☐ 지급(넘치면 접힘) / 덧글 */
    #alWorkRows > .pnl-row[data-wa]{display:flex;flex-wrap:wrap;align-items:center;gap:var(--gap-tool) var(--gap-field-x)}
    #alWorkRows > .pnl-row[data-wa] > .al-t{flex:1 1 0;order:0}
    #alWorkRows > .pnl-row[data-wa] > .r{display:contents}
    #alWorkRows > .pnl-row[data-wa] > .r > b{order:1}
    #alWorkRows > .pnl-row[data-wa]::after{content:'';flex-basis:100%;height:0;order:2}
    #alWorkRows > .pnl-row[data-wa] > div:not(.al-t),#alWorkRows > .pnl-row[data-wa] > .r > label{order:3}
    #alWorkRows > .pnl-row[data-wa] > .pnl-row-msg{order:4;flex-basis:100%}
    #alWorkSec .pnl-sect .cnt{white-space:normal;overflow:visible}   /* ★ 574 검토 9 [3] — 근무 이력 머리 요약 = 폰에서 줄바꿈(미지급 · 확인 필요 · 취소 수까지 보임) */
    #alWorkRows > .pnl-row[data-wa] > [data-k]::before{content:attr(data-k);margin-right:var(--gap-tool);color:var(--text-2)}
  }
  #alWorkRows > details > summary{cursor:pointer;width:fit-content;padding:4px 0;font-size:var(--fs-sm);color:var(--text-2);border-radius:var(--r-ctl)}
  #alWorkRows > details > summary:focus-visible{outline:none;box-shadow:var(--ring)}
  #alWorkRows > details > .btns{margin:4px 0 8px}
  #alWorkRows > details > .pnl-row > .r{grid-column:-2}   /* 날짜 줄 장수 = 맨 오른쪽 칸(폰 두 칸에서도 오른쪽) */
  #alViewBody .al-rrn-in input{flex:1;min-width:0}
  #alRrnBox > .cdprop{grid-column:1 / -1}   /* ★ 과제 219 — 주민등록번호 = 한 줄 전체(가린 번호 · 「전체 보기 · 고치기」 · 넣기 칸 + 단추가 반 칸에서 접히지 않게 · 사진 02 실측) */
  #alDashView .tk-dlist .clrow > div > .pill{display:inline-flex}   /* ★ 과제 219 — 대시보드 표 칸의 첫 span 을 block 으로 펴는 공용 줄(.tk-dlist .clrow > div > span:first-child)이 폰 계정 알약을 칸 너비 막대로 늘였다(사진 04 실측) → 알약은 알약 모양 그대로 */
  /* ★ 과제 197 — 캠페인 상세 : 이름 = 제목(cDetTitle) 한 곳 · 본문 큰 이름은 숨김(글은 남김 — 딥링크 관문이 읽는다) · 머리 띠 = 한 줄(넘치면 말줄임 · 마우스에 전체) */
  #cDetail .cdhead{display:none}
  #cDetail .pk [data-part~="aqlink"]{margin-left:8px;font-size:var(--fs-cap);font-weight:var(--weight-body);color:var(--accent);text-decoration:none}   /* 확정 견적 보기 → = 칸 이름 옆(가리키는 것 = 파랑) */
  #cDetail .dt-band{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}   /* ★ 과제 196 — 거래처 상세도 같은 폭 */
  /* ★ 과제 196 — 상세 값 상자 안 링크(메일 · 전화 …)가 칸을 8px 높였다(.cdprop .pv a 의 위아래 4px) → 새 옷(.dtform) 값 상자 안에서는 위아래 0 · 옆 여백(누르는 자리)은 그대로 */
  .cdprops.dtform .pv > a{padding-top:0;padding-bottom:0}
  #advViewBody{display:grid;grid-template-columns:minmax(0,1fr);column-gap:26px;align-items:start}
  #advViewBody>.advcol{display:contents}
  /* 메일 = 한 줄 전체 · 긴 값은 줄바꿈(말줄임 금지 — 「yj.jung@hanbitedu.co.kr」 끝이 가려졌다) */
  #advViewBody .cdprops.dtform .cdprop:has(> .pv[data-f*="email"]){grid-column:1 / -1}
  #advViewBody .pv[data-f*="email"],#advViewBody .pv[data-f*="email"] *{white-space:normal;overflow-wrap:anywhere;text-overflow:clip}
  @media (max-width:1100px){
    #advViewBody{grid-template-columns:minmax(0,1fr)}
    #advViewBody>.advcol{display:contents}
  }

  /* 캠페인 요약 카드 — 타 페이지 상세 안에 핵심 4칸 상주 · 클릭 = 읽기 전용 팝업(openCampInfo) */
  .refcard{border:1px solid var(--line);border-radius:var(--r-card);padding:10px 12px;margin:0 0 10px;
      cursor:pointer;transition:background .12s var(--ease)}
  .refcard:hover{background:var(--bg-hover)}
  .refcard:focus-visible{outline:none;box-shadow:var(--ring)}   /* ★ 과제 215 (K2) — Tab 으로 닿는 카드 · 초점 테 = 공용 --ring */
  .clrow.clhead > .gsort:focus-visible,th.sortable:focus-visible{outline:none;box-shadow:var(--ring);color:var(--text-2)}   /* ★ 과제 215 (B1) — 머리 칸에 초점 */
  .refcard .rt{display:flex;align-items:center;gap:8px;margin-bottom:6px}
  .refcard .rt b{font-size:var(--fs-body);font-weight:var(--weight-strong);color:var(--ink);flex:1;min-width:0;
      white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .refcard .more{font-size:var(--fs-cap);color:var(--accent);font-weight:var(--weight-medium);white-space:nowrap}
  .refcard .rr{display:flex;gap:6px 14px;flex-wrap:wrap;font-size:var(--fs-sm);color:var(--text-2);align-items:center}
  .refcard .rr b{font-weight:var(--weight-medium);color:var(--ink);font-variant-numeric:tabular-nums}

  /* ══════════════════════════════════════════════════════════════════
     ★ v1.04 (08-26 대표 지시) — 견적서 문서(.qsdoc) : 첨부 「대학교광고 견적서 리디자인」
     틀을 그대로 옮긴 문서 전용 스타일. ERP UI 토큰이 아니라 **브랜드 문서 토큰**(--qd-*)을
     이 범위 안에서만 씁니다 — 화면에 보이는 그대로 PDF(인쇄)로 나가는 영역이라
     대표 지시로 문서의 색·서체를 고정합니다 (다른 화면 부품에 쓰지 말 것).
     ══════════════════════════════════════════════════════════════════ */
  /* ★ 과제 414a — **문서 서식(견적서 · 재직증명서)은 v4 토큰 밖**(DESIGN §13 · 바깥 문서 색 = 과제 415).
     문서 안 규칙이 앱 토큰(--line · --text-2 · --ink · --weight-strong …)을 읽고 있어, :root 를 v4 로 갈면 종이 글색 · 선 · b 굵기가 따라 바뀐다(27곳 실측).
     그래서 문서 범위 안에서만 v3 값을 그대로 묶어 둔다 — 종이 · PDF 는 한 글자도 안 바뀐다(관문 v114 · 인쇄검사 · 문서 계산 옷 맞대기 0). */
  .qsdoc,.certdoc,#qsPrintHost{
    --line:#E3E3E3; --line-soft:#EBEBEB; --line-input:#8A8A8A; --bg-hover:#EBEBEB;
    --ink:#303030; --text:#303030; --text-2:#616161; --text-3:#8A8A8A;
    --r-ctl:8px; --weight-strong:600; --weight-bold:600; --weight-semibold:600; --weight-num:600; --weight-medium:500;
  }
  .qsdoc{
    --qd-ink:#2A3373; --qd-ink-soft:#48484A; --qd-ink-mute:#6E6E73;
    --qd-line:#E8E8ED; --qd-line-soft:#F1F1F4; --qd-line-mid:#D2D2D7;
    --qd-gold:#4351AC; --qd-gold-soft:#EEEDFB; --qd-sky:#D9D4F5;
    --qd-danger:#B42318;
    font-family:var(--font-sans);
    color:var(--qd-ink); background:#fff;
    /* ★★ v1.80 (과제 33 · 대표 결정 D4) — **A4 세로 → 1920×1080.**
       까닭 = 「모니터 가독성 1순위 · 인쇄 2순위」(대표). 종이보다 **화면에서 읽는 문서**가 됐다.
       ⚠ 1080px 은 A4(≈1123px)보다 **짧다.** 그냥 눕히면 품목 줄이 오히려 줄어든다.
         그래서 **머리(제목·견적번호)와 수신/공급자를 나란히** 놓아 위쪽 띠를 반으로 줄이고,
         그 자리를 전부 품목 표에 준다. 재배치는 **격자(CSS grid)로만** 한다 —
         HTML·id·로직은 한 줄도 안 바뀐다(대표 결정 「로직·id 보존, 껍데기만」). */
    /* ★★ 과제 198 (09-26 대표 「견적서는 지금 가로형인데 세로형으로 수정해」 · 시안 OK · 09-12 D4 를 다시 뒤집음) — **1920×1080 → A4 세로 210 × 297 mm = 794 × 1123 px**
       (재직증명서 .certdoc 과 같은 판) · 격자 = 머리(제목 왼쪽 · 번호 오른쪽) → 수신 · 공급자 나란히 → 품목 표 → 결제 · 비고(왼쪽) | 한글 금액 · 합계(오른쪽) → 꼬리
       · HTML · id · 로직 0 줄(대표 결정 「로직 · id 보존, 껍데기만」 그대로 · 장 넘김은 QD_W · QD_H 두 상수만) */
    width:794px; margin:0 auto;
    padding:34px 44px 26px; position:relative;
    border:1px solid var(--line); border-radius:2px;
    font-size:12.5px; line-height:1.5;
    min-height:1123px; box-sizing:border-box;
    display:grid; align-content:start;
    grid-template-columns:minmax(0,1fr) 292px;
    grid-template-areas:
      "head    head"
      "parties parties"
      "cap     cap"
      "tbl     tbl"
      "audit   audit"
      "notes   sum"
      "foot    foot";
    column-gap:28px;
  }
  .qsdoc > .qd-head{grid-area:head}
  .qsdoc > .qd-parties{grid-area:parties}
  .qsdoc > .qd-cap{grid-area:cap}
  .qsdoc > .scrolltbl{grid-area:tbl}
  .qsdoc > #qsAuditOut{grid-area:audit}
  .qsdoc > .qd-totals-zone{grid-area:sum}
  .qsdoc > .qd-notes{grid-area:notes}
  .qsdoc > .qd-foot{grid-area:foot}
  /* ★ 과제 198 — 머리 = 한 줄(제목 왼쪽 · 견적번호 · 작성일 · 유효기간 오른쪽) */
  .qsdoc > .qd-head{flex-direction:row;align-items:flex-end;justify-content:space-between;padding:6px 0 12px}
  .qsdoc > .qd-head .qd-meta{text-align:right;width:auto}
  .qsdoc > .qd-head .qd-mrow{justify-content:flex-end}
  .qsdoc > .qd-head .qd-mrow>:last-child{text-align:right;min-width:120px}
  .qsdoc > .qd-parties{margin-top:12px;gap:0 24px;align-content:start}
  .qsdoc .qd-party th{width:62px}
  .qsdoc .qd-party th,.qsdoc .qd-party td{padding-top:5px;padding-bottom:5px}
  .qsdoc > .qd-cap{margin-top:14px}
  /* 아래 띠 = 결제 · 비고(왼쪽 · 위아래로 쌓음) · 한글 금액 · 합계(오른쪽 292) 나란히 */
  .qsdoc > .qd-totals-zone{margin-top:12px;display:block}
  .qsdoc > .qd-totals-zone > .qd-words{margin-bottom:6px;padding:0 0 8px}
  .qsdoc .qd-totals{width:100%}
  .qsdoc .qd-line{padding:6px 4px}
  .qsdoc > .qd-notes{margin-top:12px;grid-template-columns:minmax(0,1fr);gap:14px;align-content:start}
  .qsdoc > .qd-foot{margin-top:14px}
  /* 표 줄 높이 = 글 + 여백(목록 표의 줄 높이 44 = .scrolltbl td 를 문서에서는 푼다 · 09-26 시안에서 찾음) */
  .qsdoc table#qdTable tbody td,.qsdoc table.qd-t2 tbody td,.qsdoc table.qd-ax-t tbody td{height:auto}
  /* ★ 과제 198 의 qd-measure(잴 때만 입력칸 높이를 빼던 꼼수)는 ★ 과제 324 에서 은퇴 — 문서에 입력칸이 없어 화면 문서 = 인쇄 모양 그대로 잰다 · 옛 설명 :
     인쇄에 안 나가는 것(할인 신호등 · 고치는 칸 · 점검 줄) 숨김 · 표 입력칸 = 글 높이. 화면에 할인 신호등 · 고치는 칸이 있어 띠가 인쇄보다 206px 커서
     8줄 견적이 2장으로 갈렸다(09-26 실측). 재고 나면 떼므로 화면 모양은 그대로다 */
  /* ★ 과제 198 B — 인쇄처럼 ✕ 칸(9번째)을 머리 · 몸 **둘 다** 뺀다(인쇄 v1.08 의 그 함정) : 읽기 전용(qs-ro)은 머리만 숨어 몸 9번째가 「정의 안 된 열」이 되어 147px 를 먹고
     내용 칸이 두 줄로 꺾여 줄 키가 44 로 재어졌다 → 30줄이 16 + 14 로 갈렸다(09-28 상세 사진 실측 · 인쇄는 한 줄 26) */
  #qComposeWrap.qs-ro table#qdTable td:nth-child(9){display:none}

  /* ★★ v1.80 (과제 33 · 대표 결정 D4) — **밀도 세 단계뿐** : 넉넉 → 보통 → 촘촘.
     ⚠ 그 밖으로 더 줄이지 않는다(무한 축소 금지 · 과제의 금지) · 표 글자는 **12px 밑으로 안 간다**.
     ⚠ 품목을 묶어서 줄이지도 않는다 — 학교별 상세는 그대로 남는다(대표가 ⓐ 를 골랐다). */
  .qsdoc.qd-d1 table#qdTable tbody td{padding-top:8px;padding-bottom:8px;font-size:12.5px}   /* ★ 과제 198 — A4 세로 : 넉넉 8 · 보통 6 · 촘촘 4(글자 12 밑으로 안 감) */
  .qsdoc.qd-d2 table#qdTable tbody td{padding-top:6px;padding-bottom:6px;font-size:12px}
  .qsdoc.qd-d3 table#qdTable tbody td{padding-top:4px;padding-bottom:4px;font-size:12px}
  .qsdoc.qd-d1 table#qdTable thead th{padding-top:9px;padding-bottom:9px}
  .qsdoc.qd-d2 table#qdTable thead th{padding-top:7px;padding-bottom:7px}
  .qsdoc.qd-d3 table#qdTable thead th{padding-top:5px;padding-bottom:5px}

  /* 2장째로 넘어간 줄은 1장에서 감춘다 — **지우지 않는다**(같은 표가 편집 시트다) */
  .qsdoc table#qdTable tbody tr.qd-off{display:none}
  /* 2장째 = 복제본. 1장과 같은 서식에 **가벼운 머리**만 다르다 */
  .qsdoc.qd-p2{margin-top:24px}
  .qsdoc.qd-p2 > .qd-head2{grid-area:head;flex-direction:row;align-items:flex-end;
    grid-column:1 / -1;justify-content:space-between;padding:2px 0 12px;border-bottom:2px solid var(--qd-ink)}
  .qsdoc.qd-p2 > .qd-head2 .qd-title h1{font-size:22px}
  .qsdoc.qd-p2 > .qd-head2 .qd-meta{text-align:right;width:auto}
  .qsdoc.qd-p2 > .qd-head2 .qd-mrow{justify-content:flex-end}
  .qsdoc.qd-p2 > .qd-cap{grid-area:cap}
  .qsdoc.qd-p2 > .scrolltbl{grid-area:tbl}
  .qsdoc.qd-p2 > .qd-totals-zone{grid-area:sum}
  .qsdoc.qd-p2 > .qd-notes{grid-area:notes}
  .qsdoc.qd-p2 > .qd-foot{grid-area:foot}
  /* ★ v1.80 (과제 33) — 뒷장은 **화면에도 뜨는 복제본**이다. 복제본의 입력칸은 글자(.qd-pv)로 바꿨는데
     `.qd-pv` 는 원래 **인쇄 전용**이라 `display:none` 이다 → 뒷장에서는 보이게 한다.
     ⚠ 이걸 빼면 마지막 장의 **결제 조건·비고가 통째로 빈 칸**으로 보인다(09-12 실측 · DOM 에는 글자가 있다). */
  .qsdoc .qd-pv{display:block;width:100%;white-space:normal;word-break:break-word;
    font-size:12px;line-height:1.4;color:var(--qd-ink)}
  .qsdoc .qd-note .qd-pv{font-size:12px;line-height:1.75;color:var(--qd-ink-soft);white-space:pre-line}
  .qsdoc .qd-payv .qd-pv{display:inline;width:auto;white-space:normal}
  .qsdoc .qd-meta .qd-pv,.qsdoc .qd-totals .qd-pv{display:inline-block;width:auto}
  /* ★★ 과제 198 B — 견적 상세 = 견적서 그대로 : 작성 팝업 문서를 베낀 장들(.qdet-docwrap) · 입력칸은 글자로 바꿔 두었으므로 뒷장과 같이 보이게 */
  .qdet-docwrap .qsdoc .qd-pv{display:block;width:100%;white-space:normal;word-break:break-word;font-size:12px;line-height:1.4;color:var(--qd-ink)}
  .qdet-docwrap .qsdoc .qd-note .qd-pv{font-size:12px;line-height:1.75;color:var(--qd-ink-soft);white-space:pre-line}
  .qdet-docwrap .qsdoc .qd-payv .qd-pv{display:inline;width:auto;white-space:normal}
  .qdet-docwrap .qsdoc .qd-meta .qd-pv,.qdet-docwrap .qsdoc .qd-totals .qd-pv{display:inline-block;width:auto}
  .qdet-doc{margin-top:14px}
  /* ★★ 과제 229 (09-28 대표 시안 v3) — 견적 상세 = 문서만 · 단추 위 : 머리 · 띠 · 행동 줄 = 카드 위에 붙음(sticky · 스크롤은 문서만) · 토큰만 */
  #quoteSide .qdet-top{position:sticky;top:calc(-1 * var(--card-pad-y));z-index:2;background:var(--bg-card);
      margin:calc(-1 * var(--card-pad-y)) calc(-1 * var(--card-pad-x)) 0;padding:var(--card-pad-y) var(--card-pad-x) var(--gap-tile);border-bottom:1px solid var(--line-soft)}
  #quoteSide .qdet-top>h3{padding-right:34px}   /* 닫기 ✕ 자리 — 옛 「.mdside>.card>h3:first-of-type」 규칙과 같은 값(h3 가 .qdet-top 안으로 들어가 그 규칙이 안 닿음) */
  #quoteSide .qdet-top h3 #qDetTitle{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  #quoteSide .qdet-top h3 .tools{align-items:center;gap:var(--gap-tool)}
  #qDetStat{display:inline-flex;gap:var(--gap-tool);flex-wrap:wrap;margin:0}
  #quoteSide .qdet-top .dt-band{margin:0 0 var(--gap-tile)}
  #qDetBtns{display:flex;align-items:center;flex-wrap:wrap;gap:var(--gap-tool);margin:0}
  #qDetBtns .qdet-sum{margin-left:auto;font-size:var(--fs-sm);color:var(--text-2)}
  #qDetBtns .qdet-sum b{color:var(--text)}
  #quoteMD .mdside{width:min(880px,96vw)}   /* 문서 794 + 카드 · 바탕 여백 — 줄이지 않고 1:1 로(더 좁으면 줄여 보임) */
  /* 2장째 표는 1장 표와 **같은 옷**을 입는다(복제본이라 id 가 없으므로 클래스로 건다) */
  .qsdoc table.qd-t2,.qsdoc table.qd-ax-t{border-collapse:collapse;table-layout:fixed;width:100%}
  .qsdoc table.qd-t2 thead th,.qsdoc table.qd-ax-t thead th{background:var(--qd-ink);color:#fff;font-size:10.5px;font-weight:600;
    letter-spacing:.04em;padding:6px 4px;text-align:center;white-space:nowrap}
  .qsdoc table.qd-t2 tbody td,.qsdoc table.qd-ax-t tbody td{border-bottom:1px solid var(--qd-line-soft);padding:6px 3px;
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .qsdoc.qd-d1 table.qd-t2 tbody td,.qsdoc.qd-d1 table.qd-ax-t tbody td{padding-top:8px;padding-bottom:8px;font-size:12.5px}
  .qsdoc.qd-d2 table.qd-t2 tbody td,.qsdoc.qd-d2 table.qd-ax-t tbody td{padding-top:6px;padding-bottom:6px;font-size:12px}
  .qsdoc.qd-d3 table.qd-t2 tbody td,.qsdoc.qd-d3 table.qd-ax-t tbody td{padding-top:4px;padding-bottom:4px;font-size:12px}
  /* 1장은 합계·결제·비고·푸터를 2장째에 넘겼으므로 그 자리를 비운다 */
  .qsdoc.qd-split > .qd-totals-zone,.qsdoc.qd-split > .qd-notes,.qsdoc.qd-split > .qd-foot{display:none}
  /* ★ v1.80 — 문서는 **언제나 진짜 1920×1080** 이다. 화면에서는 자리에 맞게 **줄여 보이기만** 한다
     (`--qd-scale` · `qsDocFit()` 이 잰다). 줄여 보이는 것이라 인쇄·PDF 는 원래 크기 그대로 나간다.
     ⚠ 옛 `max-width:100%` 로 폭을 줄이면 **문서 자체가 좁아져** 16:9 가 깨진다(09-12 실측 : 1156px). */
  .qd-wrap{background:var(--bg-fill); padding:18px 10px; border-radius:var(--r-card); overflow:hidden}
  .qd-wrap > .qsdoc{transform:scale(var(--qd-scale,1));transform-origin:top left}
  .qsdoc::before{content:"";position:absolute;top:0;left:0;right:0;height:5px;
    background:linear-gradient(90deg,var(--qd-ink) 0%,var(--qd-ink) 62%,var(--qd-gold) 62%,var(--qd-gold) 88%,var(--qd-sky) 88%,var(--qd-sky) 100%)}
  /* 문서 헤더 */
  .qd-head{display:flex;justify-content:space-between;align-items:flex-end;
    padding:12px 0 16px;border-bottom:2px solid var(--qd-ink)}
  .qd-title h1{font-size:30px;font-weight:600;letter-spacing:.3em;line-height:1.15;color:var(--qd-ink);text-indent:.1em;margin:0}
  .qd-title .qd-en{font-size:10.5px;letter-spacing:.24em;color:var(--qd-gold);text-transform:uppercase;margin-top:7px;font-weight:600}
  .qd-meta{text-align:right;font-size:12px;color:var(--qd-ink-soft)}
  .qd-mrow{display:flex;justify-content:flex-end;align-items:baseline;gap:10px;margin-top:4px}
  .qd-mlbl{font-size:10px;letter-spacing:.12em;color:var(--qd-ink-mute);font-weight:600;width:52px;text-align:left;flex:none}
  /* ★ 값 칸 : 쪼개지면 안 된다(날짜가 「2026-10-」/「10」 로 갈렸다 — 실측 · DESIGN.md §13-2).
     nowrap 만 주면 넘칠 수 있으므로 **최소 폭 + 필요하면 왼쪽으로 늘어나게** 한다(행이 우측 정렬이라 안전) */
  .qd-mrow>:last-child{min-width:150px;flex:0 0 auto;text-align:right;white-space:nowrap}
  .qd-no{font-variant-numeric:tabular-nums;font-weight:500}
  /* 수신/공급자 */
  .qd-parties{display:grid;grid-template-columns:1fr 1fr;gap:0 32px;margin-top:18px}
  .qd-party h2{font-size:11px;letter-spacing:.16em;font-weight:700;color:var(--qd-ink);
    padding-bottom:8px;border-bottom:1.5px solid var(--qd-ink);display:flex;align-items:baseline;gap:8px;margin:0}
  .qd-party .qd-en2{font-size:9.5px;letter-spacing:.16em;color:var(--qd-gold);font-weight:600}
  .qd-party table{width:100%;border-collapse:collapse;margin-top:2px}
  .qd-party th{width:74px;text-align:left;font-size:11px;font-weight:600;color:var(--qd-ink-mute);
    letter-spacing:.02em;padding:7px 0;border-bottom:1px solid var(--qd-line-soft);vertical-align:middle;background:transparent}
  .qd-party td{padding:7px 0 7px 6px;border-bottom:1px solid var(--qd-line-soft);font-size:12.5px;color:var(--qd-ink);font-weight:500}
  .qd-party tr:last-child th,.qd-party tr:last-child td{border-bottom:none}
  .qd-seal-line{position:relative}
  .qd-seal{position:absolute;right:0;top:50%;transform:translateY(-50%);width:52px;height:52px;pointer-events:none}
  .qd-seal img{width:100%;height:100%;object-fit:contain;display:block}
  /* 캡션 */
  .qd-cap{margin-top:22px;display:flex;justify-content:space-between;align-items:baseline}
  .qd-cap .t{font-size:13px;font-weight:600}
  .qd-cap .t::before{content:"";display:inline-block;width:14px;height:2px;background:var(--qd-gold);
    vertical-align:middle;margin-right:8px}
  .qd-cap .u{font-size:11px;color:var(--qd-ink-mute)}
  /* 품목 표 — 기존 #qsTable 을 문서 모양으로 덮어쓴다 (id·로직 불변) */
  .qsdoc .scrolltbl{margin-top:8px;border:none;border-radius:0}
  /* ★ 열 폭을 문서(A4 내용폭 186mm)에 맞춰 고정합니다.
     인라인 min-width 가 걸려 있어 !important 로만 이깁니다 — 안 그러면 표가 968px 로 벌어져
     단가·금액 열이 종이 밖으로 나가 PDF 에서 사라집니다(08-26 실측). */
  /* ★ v1.05 — 9열 : # · 매체 · 품목 · 내용 · 수량 · 단위 · 단가 · 금액 · ✕
     (권역·포스터·현수막이 「내용」 안으로 들어가 열이 셋 줄었습니다 — 내용이 그만큼 넓어집니다)
     ⚠ v1.80 (과제 33) — 여기 있던 **A4 고정 px 폭 여덟 줄을 뺐습니다.** 1920 폭에서는 단가·금액이
       70px·82px 로 남아 오른쪽 끝에 몰리고, **뒷장 복제본(.qd-t2)과 열이 어긋나** 보였습니다(09-12 실측).
       지금 폭은 위쪽 **비율 규칙** 한 벌이 정합니다. */
  .qsdoc table#qdTable{border-collapse:collapse;table-layout:fixed;width:100%}
  .qsdoc table#qdTable th,.qsdoc table#qdTable td{min-width:0 !important}
  /* ★ v1.80 (과제 33) — 1920 폭에 맞춘 **비율** 열 폭. 옛 A4 고정 px(아래 줄들)를 덮는다 —
     안 덮으면 남는 폭이 전부 「내용」으로 몰려 단가·금액이 오른쪽 끝에 몰린다(09-12 실측). */
  .qsdoc table#qdTable th:nth-child(1),.qsdoc table.qd-t2 th:nth-child(1){width:30px !important}   /* ★ 과제 198 — 794 폭에 맞춘 비율(내용 칸이 가장 넓게) · # 는 두 자리(30줄)가 안 잘리게 30px */
  .qsdoc table#qdTable th:nth-child(2),.qsdoc table.qd-t2 th:nth-child(2){width:10%}
  .qsdoc table#qdTable th:nth-child(3),.qsdoc table.qd-t2 th:nth-child(3){width:9%}
  .qsdoc table#qdTable th:nth-child(4),.qsdoc table.qd-t2 th:nth-child(4){width:auto}
  .qsdoc table#qdTable th:nth-child(5),.qsdoc table.qd-t2 th:nth-child(5){width:6%}
  .qsdoc table#qdTable th:nth-child(6),.qsdoc table.qd-t2 th:nth-child(6){width:5%}
  .qsdoc table#qdTable th:nth-child(7),.qsdoc table.qd-t2 th:nth-child(7){width:10%}
  .qsdoc table#qdTable th:nth-child(8),.qsdoc table.qd-t2 th:nth-child(8){width:13%}
  .qsdoc table#qdTable th:nth-child(9),.qsdoc table.qd-t2 th:nth-child(9){width:28px}   /* ✕ 줄 지우기(작성 화면) — 인쇄 · PDF 에서는 qd-delcol 이 숨는다 */
  /* ★ 과제 198 — 뒷장 복제 표(qd-t2)에는 지우기 칸이 필요 없다 : 머리줄만 숨고 몸통 9번째 칸이 남아 내용 칸 폭을 반으로 나눠 가졌다(30줄 사진 실측) → 둘 다 숨김 */
  .qsdoc table.qd-t2 th:nth-child(9),.qsdoc table.qd-t2 td:nth-child(9){display:none}
  /* 좁은 칸의 글자 겹침 방지 — 셀 안쪽 여백을 줄이고 삭제 단추도 칸에 맞춥니다 */
  .qsdoc table#qdTable tbody td{padding-left:3px;padding-right:3px}
  .qsdoc table#qdTable td:last-child button{min-width:0;padding:0 4px;width:22px}
  /* 좁아진 칸에서 글자가 겹치지 않게 — 값만 보이는 셀은 말줄임 */
  .qsdoc table#qdTable tbody td{overflow:hidden;text-overflow:ellipsis}
  .qsdoc table#qdTable thead th{background:var(--qd-ink);color:#fff;font-size:10.5px;font-weight:600;
    letter-spacing:.04em;padding:8px 4px;text-align:center;white-space:nowrap;border:none;position:static}
  .qsdoc table#qdTable thead th:first-child{border-radius:2px 0 0 0}
  .qsdoc table#qdTable thead th:last-child{border-radius:0 2px 0 0}
  .qsdoc table#qdTable tbody td{border:none;border-bottom:1px solid var(--qd-line);padding:5px 4px;font-size:12px;vertical-align:middle;background:transparent}
  .qsdoc table#qdTable tbody tr:hover td{background:#FBFBFD}
  .qsdoc table#qdTable input{border:none;border-bottom:1px solid transparent;background:transparent;
    border-radius:0;padding:3px 2px;font-size:12px;color:var(--qd-ink);width:100%;min-height:0;box-shadow:none}
  .qsdoc table#qdTable input:hover{border-bottom-color:var(--qd-line-mid);background:#FBFBFD}
  .qsdoc table#qdTable input:focus{outline:none;border-bottom:1px solid var(--qd-gold);background:var(--qd-gold-soft);box-shadow:none}
  /* 합계 */
  .qd-totals-zone{display:flex;justify-content:space-between;gap:28px;margin-top:16px;align-items:flex-start}
  .qd-words{flex:1;font-size:12.5px;color:var(--qd-ink-soft);padding:12px 0;line-height:1.7}
  .qd-words .lbl{font-size:10px;letter-spacing:.14em;color:var(--qd-gold);font-weight:600;display:block;margin-bottom:3px}
  .qd-totals{width:320px;flex:none}
  .qd-line{display:flex;justify-content:space-between;align-items:baseline;padding:7px 4px;font-size:12.5px;border-bottom:1px solid var(--qd-line)}
  .qd-line .k{color:var(--qd-ink-mute);font-size:11.5px}
  .qd-line .v{font-variant-numeric:tabular-nums;font-weight:500}
  .qd-line.qd-disc .v{color:var(--qd-danger)}
  .qd-line.qd-final .k{color:var(--qd-ink);font-weight:600}
  .qd-line.qd-final .v{font-weight:700}
  .qd-edit{display:flex;align-items:center;justify-content:space-between;gap:6px;padding:6px 4px;
    font-size:11.5px;color:var(--qd-ink-mute);border-bottom:1px solid var(--qd-line)}
  .qd-edit input{width:76px;text-align:right;font-variant-numeric:tabular-nums;border:1px solid var(--qd-line-mid);
    border-radius:6px;padding:3px 8px;font-size:12px;background:#fff;min-height:0}
  .qd-edit input:focus{outline:none;border-color:var(--qd-gold);background:var(--qd-gold-soft);box-shadow:none}
  .qd-tier{padding:4px;font-size:11.5px}
  .qd-grand{margin-top:8px;background:var(--qd-ink);color:#fff;border-radius:10px;
    padding:12px 16px;display:flex;justify-content:space-between;align-items:center}
  .qd-grand .k{font-size:11px;letter-spacing:.1em;font-weight:600;color:var(--qd-sky)}
  .qd-grand .v,.qd-grand .v b{font-size:18px;font-weight:700;font-variant-numeric:tabular-nums;color:#fff}
  /* 하단 안내 */
  .qd-notes{display:grid;grid-template-columns:1.15fr 1fr;gap:22px;margin-top:24px}
  .qd-note h3{font-size:10.5px;letter-spacing:.14em;font-weight:700;color:var(--qd-ink);
    padding-bottom:7px;border-bottom:1px solid var(--qd-ink);margin:0 0 4px}
  .qd-paytext{font-size:12px;color:var(--qd-ink-soft);padding:6px 0;line-height:1.75}
  /* ★★ v1.08 — 결제 조건을 **문서 안에서** 고칩니다 (대표 지시).
     어법은 합계 상자의 `.qd-edit input` 과 같게 : 흰 바탕 + 옅은 테두리 + 초점에 골드.
     ⚠ `.qd-edit` 클래스는 인쇄에서 통째로 감춰지므로(1411줄) 여기서는 쓰지 않습니다 —
       결제 조건은 **종이에 나가야 하는 값**입니다. 편집에만 쓰는 글자만 `.qd-noprint` 입니다. */
  .qd-payrow{display:flex;align-items:baseline;gap:6px;padding:2px 0}
  .qd-payk{flex:0 0 58px;color:var(--qd-ink-mute)}
  .qd-payv{flex:1 1 auto;min-width:0;display:flex;flex-wrap:wrap;align-items:center;gap:5px}
  .qd-payin{display:inline-flex;align-items:center;gap:4px}
  .qd-payin em,.qd-payin b{font-style:normal;font-weight:400;font-size:11px;color:var(--qd-ink-mute)}
  .qd-payor{padding-left:4px}
  .qd-paytext input,.qd-paytext select{border:1px solid var(--qd-line-mid);border-radius:6px;
    padding:3px 8px;font-size:12px;background:#fff;min-height:0;color:var(--qd-ink);box-shadow:none}
  .qd-paytext input:focus,.qd-paytext select:focus{outline:none;border-color:var(--qd-gold);
    background:var(--qd-gold-soft);box-shadow:none}
  #qsDpRate,#qsDpAmtIn{text-align:right;font-variant-numeric:tabular-nums}   /* ★ 458 디자이너 ⑤ — 폭 46 · 88 지움 = 표준 칸(.cdprops.asform) 상자가 줄 끝까지(v426 ⓒ1) · 숫자 맞춤만 */
  .qd-paytext .qd-payw{width:100%;max-width:246px}
  .qd-paycalc{font-weight:600;color:var(--qd-ink);font-variant-numeric:tabular-nums}
  .qd-payhint{flex:0 0 100%;font-size:11px;color:var(--qd-ink-mute)}
  .qd-note textarea{font-size:12px;color:var(--qd-ink-soft);padding:6px 0;line-height:1.75;border:none;
    background:transparent;width:100%;resize:none;border-radius:0;min-height:64px;box-shadow:none}
  .qd-note textarea:focus{outline:none;background:var(--qd-gold-soft);box-shadow:none}
  /* 푸터 */
  .qd-foot{margin-top:26px;padding-top:13px;border-top:2px solid var(--qd-ink);
    display:flex;justify-content:space-between;align-items:flex-end;gap:20px}
  .qd-contact{font-size:11px;color:var(--qd-ink-soft);line-height:1.8}
  .qd-contact .name{font-weight:600;color:var(--qd-ink);font-size:12px}
  .qd-brand{text-align:right}
  .qd-logo{height:20px;width:auto;display:block;margin-left:auto}
  .qd-logo-fb{font-size:16px;letter-spacing:.22em;font-weight:600;color:var(--qd-ink)}
  .qd-brand .sub{font-size:9.5px;color:var(--qd-ink-mute);letter-spacing:.06em;margin-top:5px}
  .qd-goldbar{width:44px;height:2px;background:var(--qd-gold);margin:8px 0 0 auto}
  /* 인쇄용 값 한 벌 — 화면에서는 감춥니다 (인쇄에서만 입력칸 대신 이것이 보입니다) */
  .qd-pv{display:none}

  /* 조건 입력 밑 안내 한 줄 */
  .hint-inline{font-size:var(--text-xs);margin-top:3px;min-height:15px}

  /* ══════════════════════════════════════════════════════════════════
     ★ v1.05 — 견적 작성 팝업의 구역 ①②③ (대표 재요청 3회 · 규격 = DESIGN.md §13-5)
     ⚠ 왜 안 갈라져 보였나 : 팝업 안에서는 `.slideover.modal .pnl-body .card` 가
       카드의 보더·바탕·패딩을 전부 지운다(위 규칙). 그래서 「가르는 선」 하나로는
       카드 제목과 구역 머리가 같은 층으로 보였다. → 구역을 `<section class="qgrp">` 로
       **감싸서 묶음 자체를 보이게** 한다.
     ★ 과제 501 — 옛 세 안(.qopt-a 단계 머리 · .qopt-c 좌측 레일)과 번호 원(.qsec · 458 에서 .pnl-sect 로 은퇴) 규칙은 쓰는 곳이 없어 지움 · 남은 것 = 안 B(.qopt-b)
     ══════════════════════════════════════════════════════════════════ */
  /* 구역 안의 카드 제목은 한 단 낮춘다 — 두 제목이 같은 층으로 보이던 것을 없앤다 */
  .qgrp .card>h3{font-size:var(--fs-body);color:var(--text-2);font-weight:var(--weight-medium)}
  .qgrp .card>h3 .muted{font-size:var(--fs-sm)}

  /* ── 안 B · 묶음 카드 : 구역 하나가 한 장의 카드다 (가장 확실한 「여기까지가 한 묶음」) ── */
  .qopt-b .qgrp{margin-bottom:var(--gap-tool-body)}   /* ★ 458 디자이너 ③ — 표준 팝업 = 구역은 상자 없이 머리 한 줄(.qsec 밑줄)로 가름 · 옛 카드 상자(흰 · 선 · 16 · 안여백) 걷음 */
  .qopt-b .qgrp:last-of-type{margin-bottom:4px}
  .qopt-b .qgrp .card{margin-bottom:0}
  .slideover[data-panel="qcompose"] .pnl-body .card{border:0;box-shadow:none;background:transparent;padding:0}   /* ★ 458 디자이너 ⑦ — 오른쪽 820(딤 없음 · .modal 아님)이라 .slideover.modal 의 「몸 안 카드 = 상자 없음」 이 안 닿았다 → 같은 값 · 구역 안 카드 상자 0 · 칸 상자 왼쪽 한 세로선(v426 ⓒ1 756 · 781) */
  /* 문서 회색 판이 카드 안에서 한 겹 더 쌓이면 배경 톤이 셋이 된다(§7) — 흰 바탕으로 눕힌다 */
  .qopt-b .qd-wrap{background:transparent;padding:0}
  .qopt-b .qsdoc{border-color:var(--line)}

  /* ── 담당자 자동 저장 알림 한 줄 (버튼 은퇴 자리) ── */
  .qc-autonote{font-size:var(--fs-sm);color:var(--text-2);margin-top:8px;
    display:flex;align-items:center;gap:8px;flex-wrap:wrap;min-height:22px}
  .qc-autonote b{color:var(--text);font-weight:var(--weight-strong)}
  .qc-autonote.ok b{color:var(--ok)}
  .qc-autonote.bad{color:var(--bad)}
  .qc-autonote button{height:24px;padding:0 9px;font-size:var(--fs-sm)}

  /* ── ★★ v1.08 작성완료 = **가운데 다운로드 팝업** (대표 지시 · v1.05 의 「확인 띠」를 옮긴 것)
     딤·가운데 정렬은 붙여넣기 팝업(#qMatchBack)과 **같은 어법**을 씁니다 — 새 모양을 만들지 않습니다. */
  #qsDoneBack{position:fixed;inset:0;z-index:90;background:var(--dim-layer2);display:none;
    align-items:center;justify-content:center;padding:20px}
  #qsDoneBack.open{display:flex}
  .qsdone{display:flex;align-items:flex-start;gap:14px;margin:0;padding:22px 24px;
    width:min(460px,94vw);border:1px solid var(--ok);border-radius:var(--r-panel);   /* v2.94 (과제 144) — 460(확인 창과 같은 좁은 틀 · 옛 480) */
    background:var(--bg-card);box-shadow:var(--sh-float);flex-wrap:wrap;
    animation:toastIn var(--duration-base) var(--ease)}
  .qsdone-ic{flex:0 0 auto;width:34px;height:34px;border-radius:50%;background:var(--ok);color:var(--on-fill);
    display:inline-flex;align-items:center;justify-content:center}
  .qsdone-body{flex:1 1 220px;min-width:0;display:flex;flex-direction:column;gap:5px}
  .qsdone-body b{font-size:var(--fs-page);font-weight:var(--weight-strong);color:var(--ink);letter-spacing:-.01em}
  .qsdone-sub{font-size:var(--fs-sm);color:var(--text-2);line-height:1.6}
  /* 다음 할 일 한 줄 — 안내이므로 배경 없는 `.hint` 어법(DESIGN §5 · 노란 상자는 막는 것만) */
  .qsdone-next{font-size:var(--fs-sm);color:var(--text-2);border-left:2px solid var(--ok);
    padding:1px 0 1px 9px;margin-top:2px}
  .qsdone-btns{flex:1 1 100%;display:flex;align-items:center;justify-content:flex-end;gap:8px;
    margin-top:4px;padding-top:14px;border-top:1px solid var(--line-soft)}
  .qsdone-btns>button:first-child{margin-right:auto}

  /* ══ ★ v1.05 — 시트 「내용」 칸 : 권역·규격·포스터·현수막을 여기 하나로 합쳤다 ══ */
  .qsdoc table#qdTable td.qs-desc{padding-left:4px;padding-right:4px;overflow:visible;text-overflow:clip}
  .qs-desc-free input{width:100%}
  .qs-desc-fix{font-size:12px;color:var(--qd-ink)}
  /* 요약 한 줄 = 종이에 나가는 글. 단추처럼 보이지 않게, 밑줄만 살짝 (표 안 입력칸과 같은 어법) */
  .qs-desc-sum{display:flex;align-items:center;gap:6px;width:100%;height:auto;min-height:24px;
    padding:3px 2px;background:transparent;border:none;border-bottom:1px solid transparent;
    border-radius:0;box-shadow:none;color:var(--qd-ink);font-size:12px;
    font-weight:var(--weight-body);text-align:left;letter-spacing:0;line-height:1.35}
  .qs-desc-sum:hover{background:#FBFBFD;border-bottom-color:var(--qd-line-mid);color:var(--qd-ink)}
  .qs-desc-sum:active{transform:none}
  .qs-desc-sum .muted{font-size:12px}
  .qs-desc-chev{flex:0 0 auto;margin-left:auto;color:var(--qd-ink-mute);
    transition:transform var(--duration-fast) var(--ease)}
  .qs-desc-sum[aria-expanded="true"] .qs-desc-chev{transform:rotate(180deg)}
  .qs-desc-edit{display:flex;flex-wrap:wrap;gap:4px 8px;padding:6px 2px 3px;
    border-top:1px dashed var(--qd-line-mid);margin-top:3px}
  /* ★★ author 의 display 는 UA 의 [hidden]{display:none} 을 이깁니다 — 되찾지 않으면
     접힌 칸이 계속 「보이는 칸」으로 재어져 PDF 에 쓸모없는 텍스트가 깔립니다(v1.05 실측 · 규칙 53 짝) */
  .qs-desc-edit[hidden]{display:none}
  .qs-sub{display:flex;align-items:center;gap:4px;font-size:10.5px;color:var(--qd-ink-mute);
    letter-spacing:.02em;white-space:nowrap;flex:0 0 auto}
  .qs-sub>span{flex:0 0 auto;font-weight:var(--weight-strong)}
  /* ⚠ 폭은 `.qsdoc table#qdTable` 선택자(id 포함)와 **같은 자리에서** 지정해야 이깁니다 —
     `.qs-sub input` 만으로는 위의 `width:100%` 에 집니다(v1.05 실측) */
  /* 속칸은 「고치는 칸」임이 보여야 합니다 — 합계 상자의 입력칸(.qd-edit input)과 같은 어법 */
  .qsdoc table#qdTable .qs-sub input{width:58px;min-width:0;padding:2px 6px;
    border:1px solid var(--qd-line-mid);border-radius:5px;background:#fff}
  .qsdoc table#qdTable .qs-sub input:focus{border-color:var(--qd-gold);background:var(--qd-gold-soft)}
  .qsdoc table#qdTable .qs-sub input:disabled{background:var(--qd-line-soft);border-color:var(--qd-line)}
  .qsdoc table#qdTable .qs-sub-n input{width:40px;text-align:right}
  .qsdoc table#qdTable .qs-sub-w input{width:100%}
  .qs-sub-w{flex:1 1 100%;min-width:0}

  /* ══ ★ v1.05 — 붙여넣은 학교 선택 팝업 (대표 「보기 불편하다」) ══ */
  .qmatch-sum{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:2px 0 12px;
    align-items:stretch}
  /* ★★ v1.08 (대표 「박스 크기를 맞춰 달라」) — 가운데 칸만 작아 보이던 원인은 **전역 `.warn`** 이다.
     `.warn{margin:12px 0}`(349줄)이 격자 칸에 그대로 걸려 그 칸만 위아래 12px 씩 줄어들고
     세로 가운데로 밀린다(실측 85 / **61** / 85px). 다른 두 칸에는 걸리는 전역 규칙이 없어
     혼자만 작아 보였다. 여기서 margin 을 되돌려 세 칸을 같은 크기로 맞춘다.
     ⚠ 전역 `.warn` 은 padding·글자 크기도 함께 주므로 그 셋도 이 자리에서 못박는다
        (`.qmatch-tile` 이 뒤에 오므로 같은 특이도에서 이긴다 — 화면규칙 61 과 같은 결) */
  .qmatch-tile{border:1px solid var(--line);border-radius:var(--r-ctl);padding:9px 12px;
    margin:0;font-size:var(--fs-sm);line-height:1.45;min-height:58px;
    display:flex;flex-direction:column;gap:2px;background:var(--bg-card)}
  .qmatch-tile b{font-size:var(--fs-num);font-weight:var(--weight-strong);color:var(--ink);
    font-variant-numeric:tabular-nums;line-height:1.1}
  .qmatch-tile span{font-size:var(--fs-cap);color:var(--text-2)}
  .qmatch-tile.ok{background:var(--ok-bg);border-color:var(--ok)}
  .qmatch-tile.ok b{color:var(--ok)}
  .qmatch-tile.warn{background:var(--warn-bg);border-color:var(--warn)}
  .qmatch-tile.warn b{color:var(--warn)}
  .qmatch-tile.done b{color:var(--text-2)}
  .qmatch-body{max-height:min(52vh,440px);overflow-y:auto;padding-right:4px}
  .qmatch-hit{border:1px solid var(--line-soft);border-radius:var(--r-ctl);
    padding:8px 10px;margin-bottom:12px;background:var(--bg-fill)}
  .qmatch-hit>summary{cursor:pointer;font-size:var(--fs-sm);color:var(--text-2);list-style:none}
  .qmatch-hit>summary::-webkit-details-marker{display:none}
  .qmatch-hit>summary::before{content:"▸";display:inline-block;width:12px;color:var(--text-3)}
  .qmatch-hit[open]>summary::before{content:"▾"}
  .qmatch-hit>summary b{color:var(--ink)}
  .qmatch-chips{display:flex;flex-wrap:wrap;gap:5px;margin-top:8px}
  .qmatch-chip{display:inline-flex;align-items:baseline;gap:5px;padding:3px 8px;border-radius:var(--r-ctl);
    background:var(--bg-hover);border:1px solid var(--line-soft);font-size:var(--fs-sm);color:var(--text)}
  .qmatch-chip i{font-style:normal;font-size:var(--fs-cap);color:var(--text-2)}
  .qmatch-chip.fuzzy{border-style:dashed;border-color:var(--warn)}
  .qmatch-chip.on{background:var(--ok-bg);border-color:var(--ok);color:var(--ok);font-weight:var(--weight-strong)}
  .qmatch-chip.on i{color:var(--ok)}
  .qmatch-misshead{font-size:var(--fs-sm);color:var(--text-2);margin:0 0 8px}
  .qmatch-misshead b{color:var(--warn);font-variant-numeric:tabular-nums}
  .qmatch-allgood{font-size:var(--fs-sm);color:var(--ok);background:var(--ok-bg);
    border:1px solid var(--ok);border-radius:var(--r-ctl);padding:10px 12px}
  .qmatch-row{display:grid;grid-template-columns:168px minmax(0,1fr);gap:10px;align-items:start;
    padding:9px 0;border-top:1px solid var(--line-soft)}
  .qmatch-row.picked{opacity:.72}
  .qmatch-name{font-size:var(--fs-sm);font-weight:var(--weight-strong);color:var(--ink);
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding-top:6px}
  .qmatch-pick{display:flex;flex-direction:column;gap:8px;min-width:0}
  .qmatch-pick>span,.qmatch-pick>button{align-self:flex-start}
  /* ★★ v1.08 (대표 「고를 학교가 검색창과 구분이 안 된다」)
     종전엔 검색 입력칸과 후보 단추가 **둘 다 흰 바탕 + 회색 테두리**여서, 아래 것도 입력칸처럼 보였다.
     → 검색칸 = 「치는 곳」(회색 바탕 · 돋보기) / 후보 = 「누르는 곳」(강조 바탕 · ＋ 표) 으로 갈랐다.
     새 색은 만들지 않는다 — 있는 토큰(--bg-app · --accent-soft · --accent)만 쓴다(DESIGN §7). */
  .qmatch-search{position:relative;display:block;width:100%}
  .qmatch-search::before{content:"⌕";position:absolute;left:9px;top:50%;transform:translateY(-52%);
    font-size:var(--fs-page);line-height:1;color:var(--text-3);pointer-events:none}
  .qmatch-search input{width:100%;height:30px;padding:0 10px 0 26px;font-size:var(--fs-sm);
    background:var(--bg-fill);border:1px solid var(--line);border-radius:var(--r-ctl);color:var(--text)}
  .qmatch-search input::placeholder{color:var(--text-3)}
  .qmatch-cands{display:flex;flex-wrap:wrap;gap:6px;align-items:center}
  .qmatch-cands .muted{font-size:var(--fs-sm)}
  /* 후보 묶음 머리 — 한 줄 통째로 차지해 단추들 위에 놓인다(다시 그려도 함께 그려진다) */
  .qmatch-candlab{flex:0 0 100%;font-size:var(--fs-cap);color:var(--text-2);letter-spacing:.02em}
  /* ★ v1.08 (대표 「단추 글자가 가운데가 아니다」) — 종전 `align-items:baseline` 이 원인이었다.
     높이가 못박힌(30px) flex 단추에서 baseline 정렬은 글자 묶음을 **줄 위쪽에 붙인다**
     (실측 : 위 1px / 아래 14px). 기본 button 규칙의 `center` 를 되살려 세로 가운데로 둔다.
     가로도 `justify-content:center` 로 못박는다 — 규칙 30(달력 숫자)과 같은 결. */
  .qmatch-cand{height:30px;padding:0 11px 0 8px;font-size:var(--fs-sm);font-weight:var(--weight-strong);
    background:var(--accent-soft);color:var(--accent);border:1px solid var(--accent);border-radius:999px;
    display:inline-flex;align-items:center;justify-content:center;gap:5px;box-shadow:none;line-height:1}
  .qmatch-cand::before{content:"＋";font-size:var(--fs-cap);font-weight:var(--weight-strong);line-height:1}
  .qmatch-cand:hover{background:var(--accent);border-color:var(--accent);color:var(--on-fill)}
  .qmatch-cand:active{background:var(--accent-active);border-color:var(--accent-active)}
  .qmatch-cand i{font-style:normal;font-size:var(--fs-cap);color:var(--accent);opacity:.75}
  .qmatch-cand:hover i{color:var(--on-fill);opacity:.85}
  /* ★ v1.09 — 명부 밖 학교 등록 줄 (매칭 팝업 후보 자리 · 직접 선택 팝업 0곳 자리 공용)
     붙여넣은 이름 칸(168px)과 나눠 쓰면 학교명·주소 입력칸이 좁아 글자가 잘린다(실측) —
     등록 줄이 뜬 그 줄만 통째로 한 칸으로 넓혀 준다(다른 줄은 그대로 168px 라벨 + 본문). */
  .qmatch-row:has(.qmatch-add){grid-template-columns:1fr}
  .qmatch-add{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,2fr) 92px 150px auto auto;
    gap:6px 8px;align-items:end;width:100%}
  .qmatch-add label{display:flex;flex-direction:column;gap:3px;min-width:0}
  .qmatch-add label span{font-size:var(--fs-cap);color:var(--text-2);letter-spacing:.02em}
  .qmatch-add label span b{color:var(--warn);font-weight:var(--weight-strong)}
  .qmatch-add input,.qmatch-add select{width:100%;min-width:0;height:30px;font-size:var(--fs-sm)}
  .qmatch-add button{height:30px;white-space:nowrap}
  .qmatch-add-msg{grid-column:1/-1;margin:0;padding:6px 10px;font-size:var(--fs-sm)}   /* 전역 .warn 의 margin 을 여기서 못박는다 — 규칙 71 */
  .qmatch-chip.added{border-style:dashed;border-color:var(--ok);color:var(--ok)}
  #qList .qmatch-add{margin:8px 0 2px}
  .qmatch-foot{align-items:center;gap:10px;flex-wrap:wrap}
  .qmatch-foot .muted{font-size:var(--fs-sm)}

  /* ══ ── 게시일정 달력 팝오버 (v1.04 · ★ v1.05 재작업) ── ══
     ★ 대표 지적 「숫자가 요일과 안 맞는다」의 원인 : 기본 button 규칙이 display:inline-flex 라
       justify-content 가 flex-start → 숫자가 칸 **왼쪽**에 붙었다. 요일 머리(text-align:center)와
       한 칸씩 어긋나 보인 것이 이것이다. → 날짜 칸을 격자 정렬(place-items:center)로 고정한다.
     ★ 요일은 일·월·화·수·목·금·토 (일요일 시작 — 대표 지시 · JS 의 lead 계산과 짝) */
  .qcal{position:absolute;z-index:1200;background:var(--bg-card);border-radius:var(--r-panel);
    box-shadow:var(--sh-pop);padding:12px 12px 10px;width:296px}
  .qcal .qcal-head{display:flex;align-items:center;justify-content:space-between;
    margin:0 2px 10px;gap:6px}
  .qcal .qcal-head b{font-size:var(--fs-body);font-weight:var(--weight-strong);color:var(--ink);
    font-variant-numeric:tabular-nums}
  .qcal .qcal-head button{height:26px;min-height:26px;width:26px;padding:0;
    display:inline-flex;align-items:center;justify-content:center;font-size:var(--fs-card);line-height:1}
  .qcal .qcal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;justify-items:stretch}
  /* 요일 머리 — 날짜 칸과 같은 격자 정렬을 쓴다(두 줄이 같은 규칙이어야 어긋나지 않는다) */
  .qcal .qcal-dow{display:grid;place-items:center;height:22px;font-size:var(--fs-cap);font-weight:var(--weight-medium);
    color:var(--text-2);letter-spacing:0}
  .qcal .qcal-dow.sun,.qcal .qcal-dow.sat{color:var(--text-2)}
  /* ★ 날짜 칸 : 정사각 + 가운데 정렬. button 기본 규칙(inline-flex·height 32·padding 0 14)을 전부 되찾는다 */
  .qcal .qcal-d{appearance:none;display:grid;place-items:center;box-sizing:border-box;
    width:100%;height:34px;min-height:0;padding:0;margin:0;border:1px solid transparent;
    background:transparent;border-radius:8px;box-shadow:none;cursor:pointer;
    font-family:var(--font-sans);font-size:var(--fs-sm);font-weight:var(--weight-medium);
    font-variant-numeric:tabular-nums;letter-spacing:0;color:var(--text);text-align:center;
    transition:background var(--duration-fast) var(--ease),color var(--duration-fast) var(--ease),
      border-color var(--duration-fast) var(--ease)}
  .qcal .qcal-d:hover{background:var(--bg-hover);border-color:transparent}
  .qcal .qcal-d:active{transform:none}
  .qcal .qcal-d:focus-visible{outline:none;box-shadow:var(--ring)}
  .qcal .qcal-d.we{color:var(--text-2)}
  .qcal .qcal-d.today{border-color:var(--accent);color:var(--accent);font-weight:var(--weight-strong)}
  .qcal .qcal-d.on{background:var(--accent);border-color:var(--accent);color:var(--on-fill);
    font-weight:var(--weight-strong)}
  .qcal .qcal-d.on:hover{background:var(--accent-hover);border-color:var(--accent-hover);color:var(--on-fill)}
  /* 지난달·다음달 자리는 빈 칸 — 눌리지 않고 격자만 채운다 */
  .qcal .qcal-d.qcal-pad{visibility:hidden;pointer-events:none}
  .qcal .qcal-foot{display:flex;justify-content:space-between;align-items:center;
    margin-top:10px;padding-top:9px;border-top:1px solid var(--line-soft);gap:6px}
  .qcal .qcal-foot .muted{font-size:var(--fs-cap)}
  .qcal .qcal-foot button{height:26px;padding:0 9px;font-size:var(--fs-sm)}

  /* ── 인쇄 : PDF 내보내기(qsPdf)가 #qsDoc 을 body 직속(#qsPrintHost)으로 옮긴 뒤 인쇄합니다 ── */
  #qsPrintHost{display:none}
  /* ★ v1.14 (과제 12) — 아래 「#qsPrintHost …」 서식 규칙은 종이(인쇄)와 **PDF 자동 저장(html2pdf 캡처)** 이 함께 씁니다.
     그래서 @media print 밖에 둡니다 — 문서는 인쇄·캡처 때만 #qsPrintHost 안에 있으므로 평소 화면에는 영향이 없습니다.
     인쇄 전용은 @media print 안의 세 줄(나머지 감추기 · 호스트 보이기 · @page)뿐입니다. 서식을 두 벌로 만들지 마십시오(규칙 53·54·55 · DESIGN §13-3-5c). */
  body.qs-capturing #qsPrintHost{display:block}
  /* 캡처 중 원본 문서를 담는 자리 — 화면 밖(왼쪽 -100000px). html2pdf 는 이 원본을 복제해 그리므로 원본은 보이지 않아도 됩니다 */
  #qsCaptureWrap{position:fixed;left:-100000px;top:0;width:794px}   /* ★ 과제 198 — A4 세로 */
  @media print{
    body.qs-printing > *:not(#qsPrintHost){display:none !important}
    #qsPrintHost{display:block !important}
    @page{size:210mm 297mm;margin:0}   /* ★ 과제 198 — A4 세로(794 × 1123 px @96dpi) · 옛 = 508mm 285.75mm 1920×1080 가로 */
  }
  /* ── 문서 서식 (인쇄 + PDF 캡처 공용) ── */
    /* ★★ v1.05 (대표 지적 「PDF 디자인이 원래 견적서와 다르다」) — 원인 둘을 여기서 고칩니다.
       ① 배경·색을 인쇄에서 브라우저가 **버립니다**(기본값 economy). 그래서 표 머리의 잉크 띠,
          합계 상자, 상단 브랜드 띠, 골드 선이 종이에서 흰색이 됐습니다 → print-color-adjust:exact.
       ② 인쇄 전용으로 글자 크기·여백을 따로 조여 놓아 **화면과 다른 서식**이 나왔습니다
          → 화면 규격(13px 본문 · 12mm 여백 · 12px 표)을 그대로 씁니다.
             줄이 많아 한 장을 넘으면 자연히 2장으로 나가고, 표는 장 사이에서 끊기지 않게 합니다. */
    #qsPrintHost,#qsPrintHost *{-webkit-print-color-adjust:exact !important;print-color-adjust:exact !important}
    /* 여백·글자 크기는 **화면과 같은 값**(12mm · 13px). 아래쪽만 8mm — 푸터 밑 빈 자리라
       눈에 보이는 서식은 그대로이고, 이 2mm 로 기본 서식이 A4 한 장에 들어갑니다(관문) */
    #qsPrintHost .qsdoc{width:794px;border:none;border-radius:0;padding:34px 44px 26px;font-size:12.5px;   /* ★ 과제 198 — 화면과 같은 A4 세로 */
      box-shadow:none;margin:0;transform:none}
    #qsPrintHost .qd-wrap{background:#fff;padding:0;border-radius:0;overflow:visible}
    #qsPrintHost .qd-noprint,#qsPrintHost .qd-edit,#qsPrintHost .qd-tier,
    #qsPrintHost .qd-delcol,#qsPrintHost td:last-child button,#qsPrintHost #qsAuditOut{display:none !important}
    /* ★ 입력칸은 폭 고정이라 글자가 잘립니다 — 인쇄에서는 흐르는 텍스트(.qd-pv)로 바꿉니다(함정 55).
       크기·색은 **화면의 입력칸과 같게** 맞춥니다 — 그래야 같은 서식으로 보입니다 */
    /* ★ v1.08 — `select`(결제방식)도 문서 안 값이 됐으므로 같이 감추고 값만 텍스트로 나갑니다 */
    #qsPrintHost input,#qsPrintHost textarea,#qsPrintHost select{display:none !important}
    #qsPrintHost .qd-pv{display:block;width:100%;white-space:normal;word-break:break-word;
      font-size:12px;line-height:1.4;color:var(--qd-ink)}
    #qsPrintHost .qd-note .qd-pv{font-size:12px;line-height:1.75;color:var(--qd-ink-soft);white-space:pre-line}
    /* ★ v1.08 — 결제 조건 줄은 「· 라벨  값」 한 줄로 나가야 합니다.
       위의 `.qd-note .qd-pv{display:block;width:100%}`(공통 규칙) 을 이 자리에서만 되돌립니다 */
    #qsPrintHost .qd-payv .qd-pv{display:inline;width:auto;white-space:normal}
    #qsPrintHost .qd-payrow{padding:0}
    #qsPrintHost .qd-payv{gap:0}
    #qsPrintHost .qd-meta .qd-pv,#qsPrintHost .qd-totals .qd-pv{display:inline-block;width:auto}
    /* 내용 칸 — 접힌 편집 줄은 인쇄에 없는 것(요약 한 줄만 나갑니다) */
    #qsPrintHost .qs-desc-edit,#qsPrintHost .qs-desc-hidden{display:none !important}
    #qsPrintHost .qs-desc-chev{display:none !important}
    #qsPrintHost .qs-desc-sum{border:none;background:transparent;padding:0;font-size:12px;
      display:block;white-space:normal}
    /* 첫 열·삭제 열은 인라인 width(34px)가 걸려 있어 되찾아야 내용 열이 넓어집니다(함정 54) */
    #qsPrintHost table#qdTable th:nth-child(1){width:30px !important}   /* ★ 과제 198 — 22 → 30 : A4 세로 30줄이면 두 자리 번호(10~)가 「1…」 로 잘렸다 */
    /* ★★ v1.08 (대표 「PDF 표의 금액 우측에 여백이 생겼다」) — 원인은 **머리만 감춘 삭제 열**이다.
       `.qd-delcol`(th 9번째)은 display:none 이 되는데 **몸통 td 9번째는 그대로 남아**,
       머리 8칸 / 몸통 9칸이 되면서 마지막 칸이 남은 폭을 통째로 먹었다(실측 141px — 금액 열 오른쪽 빈 칸).
       th 만 0px 로 줄여서는 안 없어진다 — **몸통 칸도 함께 없애야** 열이 맞는다.
       ⚠ 이 표는 table-layout:fixed 라 열 폭은 첫 줄(thead)이 정한다. 몸통에만 있는 칸은
         「정의되지 않은 열」이 되어 남은 폭을 전부 가져간다(화면규칙 54 와 같은 결). */
    #qsPrintHost table#qdTable th:nth-child(9),
    #qsPrintHost table#qdTable td:nth-child(9){display:none !important}
    #qsPrintHost .scrolltbl{overflow:visible}
    /* 한 장을 넘길 때 표·합계·안내가 어정쩡하게 끊기지 않게 */
    #qsPrintHost table#qdTable tr{break-inside:avoid}
    #qsPrintHost table#qdTable thead{display:table-header-group}
    #qsPrintHost .qd-totals-zone,#qsPrintHost .qd-notes,#qsPrintHost .qd-foot{break-inside:avoid}

  /* ★ 458 디자이너 ④ — 견적서 작성 팝업 왼쪽 차례(.qwithnav · .qnav* · .qnav-on · 과제 52 · 215 · 332) 은퇴 : 마크업 · JS 0 → 규칙 걷음(경위 = git 7dba193 앞) */

/* ══════════════════════════════════════════════════════════════════════════
   ★★ v2.09 (09-16 · 과제 68-C) — 재직증명서 서식 (A4 세로 한 장)
   ⚠ 이것은 **문서 서식**입니다 — 견적서(§13)와 같은 예외로, DESIGN.md 의 화면 규격 밖입니다.
     밖으로 나가는 종이라 글자 크기·여백을 종이 기준으로 못 박습니다(화면 토큰을 쓰면 인쇄가 어긋납니다).
   ⚠ A4 세로 = 210×297mm. 96dpi 기준 **794×1123px** 로 둡니다(견적서가 1920×1080px 로 둔 것과 같은 결).
   ══════════════════════════════════════════════════════════════════════════ */
.certdoc{
  display:none;                      /* 평소에는 안 보입니다 — 미리보기·PDF 때만 켭니다 */
  width:794px; height:1123px; box-sizing:border-box;
  padding:70px 64px; background:#fff; color:#111;
  font-family:'Apple SD Gothic Neo','Malgun Gothic',sans-serif; font-size:15px; line-height:1.7;
}
.certdoc.on{display:block}
.certdoc .cd-no{text-align:right; font-size:13px; color:#555; letter-spacing:.02em}
.certdoc .cd-title{
  margin:28px 0 40px; text-align:center;
  font-size:30px; font-weight:700; letter-spacing:.32em;
}
.certdoc .cd-tbl{width:100%; border-collapse:collapse; margin-bottom:44px}
.certdoc .cd-tbl th, .certdoc .cd-tbl td{
  border:1px solid #888; padding:11px 14px; font-size:15px; vertical-align:middle;
}
.certdoc .cd-tbl th{width:96px; background:#f4f4f4; font-weight:600; text-align:center; white-space:nowrap}
.certdoc .cd-say{margin:56px 0 0; text-align:center; font-size:17px; letter-spacing:.04em}
.certdoc .cd-date{margin:40px 0 0; text-align:center; font-size:16px; letter-spacing:.06em}
.certdoc .cd-issuer{margin-top:56px; display:flex; align-items:flex-end; justify-content:space-between; gap:24px}
.certdoc .cd-co{border-collapse:collapse; font-size:13.5px}
.certdoc .cd-co th{text-align:left; font-weight:600; padding:3px 14px 3px 0; white-space:nowrap; color:#444}
.certdoc .cd-co td{padding:3px 0}
/* ⚠ 09-16 실측(육안) — 대표이사 이름이 **도장에 밀려 두 줄로 깨졌습니다**(「대표이사 김」 / 「태훈」).
   밖으로 나가는 종이라 그대로 두면 안 됩니다. → 서명 줄은 **줄바꿈 금지**하고 도장 자리를 **따로** 비웁니다. */
.certdoc .cd-sign{
  position:relative; flex:0 0 auto; white-space:nowrap;
  padding-right:86px;                /* 도장이 앉을 자리 — 글자와 겹치지 않게 */
}
.certdoc .cd-ceo{font-size:19px; letter-spacing:.04em; white-space:nowrap}
.certdoc .cd-ceo b{font-size:21px; font-weight:700; margin-left:6px}
.certdoc .cd-seal{position:absolute; right:0; top:50%; transform:translateY(-52%)}
.certdoc .cd-seal img{width:74px; height:74px; opacity:.9; display:block}

/* ★ v2.09 수정 (09-17 · 검토자 지적 ①) — 인사 **발급 창(560)** 안에서는 A4(794) 서식을 **줄여서** 보여 줍니다.
   종전에는 줄이는 장치가 없어 오른쪽 280px 이 창 밖으로 나가 **생년월일·직위·고용형태·제출처가 잘리고 발급·반려 단추가 화면 밖**이었습니다.
   transform 이라 PDF(원본 크기 · body 로 옮겨 찍음)에는 영향이 없습니다. 배율은 `hr.js hrCertShow` 가 창 너비로 잽니다(--hc-scale). */
#hcPreview{position:relative;width:100%;aspect-ratio:794/1123;overflow:hidden;--hc-scale:.65;--hc-left:0px;
           max-height:calc(88vh - 200px);min-height:240px;      /* 창(88vh) 안에 머리·발(발급·반려)이 함께 들어가야 한다 — 실측 : 안 자르면 발이 창 밖 */
           border:1px solid var(--line);border-radius:var(--r-ctl);background:var(--bg-app)}
#hcPreview .certdoc{position:absolute;left:var(--hc-left);top:0;transform:scale(var(--hc-scale));transform-origin:top left}

/* 인쇄·PDF — 견적서와 같은 방식(문서를 body 직속 #certPrintHost 로 옮긴 뒤 찍습니다) */
#certPrintHost{display:none}
body.cert-capturing #certPrintHost{display:block}
body.cert-capturing #certPrintHost .certdoc{display:block; margin:0}

/* ★★ 과제 230 (09-28 대표 예외 ② 「초점일 때만」 · 213 v331 ③ 한 뿌리) — **키보드 초점이면 공용 초점 테두리가 이긴다**
   뿌리 = 더 센(또는 뒤에 온) 선택자의 box-shadow:none 이 `button:focus-visible{box-shadow:var(--ring)}` 을 덮었다(보기 단추 · 도구 줄 ghost · 할 일 도구 줄 · 오른쪽 팝업 단추 · ✕).
   평소 · hover · 마우스 누름 모습은 한 픽셀도 안 바뀐다(:focus-visible 만) · 값 = 다른 단추와 같은 --ring · 이 파일 맨 끝(뒤에 온 규칙이 이긴다) */
.seg button:focus-visible,#cSeg button:focus-visible,
h3.toolsonly .tools > button.ghost:focus-visible,h3.toolsonly .tools > .tk-left > button.ghost:focus-visible,h3.toolsonly .tools .tk-fwrap > button.ghost:focus-visible,
#tkTools button.ghost:focus-visible,
aside.slideover button:focus-visible,.pnl-head .x:focus-visible,button.xclose:focus-visible,#advCtLines button[data-ctstar]:focus-visible,
button.ghost:focus-visible,button.danger:focus-visible,aside.slideover .pnl-body button[data-part~="linkbtn"]:focus-visible{outline:none;box-shadow:var(--ring)}   /* ghost · danger 는 제 그림자(--sh-btn)가 뒤에 와서 초점 테두리를 덮었다 */
/* Dashboard 추이 막대(g[data-tb]) — 초점 = 누르는 자리(.ld-hit)에 파란 선(옛 = hover 와 같은 회색 바탕뿐 · 키보드로는 어디 있는지 안 보였다) */
.ld-trend [data-tb]:focus-visible .ld-hit{fill:var(--bg-hover);stroke:var(--accent);stroke-width:2}
/* ★ 과제 414c — 알약 탭 초점 = 공용 고리(투명 outline 함께 = 고대비 모드에서 보임 · 위 「알약 탭」 의 box-shadow:none 을 이긴다) */
.ptabs > button.ptab:focus-visible{outline:2px solid transparent;box-shadow:var(--ring)}
.htask[role="button"]:focus-visible{outline:none;box-shadow:var(--ring)}   /* ★ 과제 230 — 캠페인 상세 할 일 줄 초점 */
#bDashView .bill-cf .clrow:not(.clhead):not(.bill-cf-over){cursor:default}   /* ★ 과제 230 — 현금 흐름 주 줄은 누를 곳이 없다(첫 줄 「예정일 지남」 만 누름) — 손가락 뗌 */
/* ══ ★★ v3.33 (과제 248 · 09-30 대표 「이대로 진행」 · 시안 v1) — 근태 ══════════════════════════════
   색 = §1 토큰만(새 색 0) · 종류 색 이름 = core.js LEAVE_TONE 한 자리 · 알약 = .pill 에 얹는 모양(.pill.lv-*) · 막대 = .lv-blk.lv-*
   오늘 쉬는 사람 한 줄 = 인사 · 홈 · 할 일 위(할 일 = 대표 예외 · 쉬는 사람이 있을 때만) · 담당자 칩 옆 「휴가」 = .uav-lv */
.lv-an{background:var(--accent-soft);color:var(--accent)}
.lv-half{background:var(--bg-active);color:var(--accent)}
.lv-sick{background:var(--warn-bg);color:var(--warn)}
.lv-spc{background:var(--ok-bg);color:var(--ok)}
.lv-par{background:var(--purple-bg);color:var(--purple)}
.lv-abs{background:var(--bad-bg);color:var(--bad)}
.lv-gray{background:var(--bg-fill);color:var(--text-2)}
.uav .uav-lv{flex:0 0 auto;font-size:var(--fs-cap);line-height:18px;padding:0 6px;border-radius:var(--r-ctl);background:var(--accent-soft);color:var(--accent);white-space:nowrap}
.uav .uav-lv.par{background:var(--purple-bg);color:var(--purple)}
.lv-today{display:flex;align-items:center;gap:10px;flex-wrap:wrap;border:1px solid var(--line);border-radius:var(--r-card);background:var(--bg-card);padding:10px 16px;margin:0 0 16px;font-size:var(--fs-body)}
.lv-today[hidden]{display:none}
.lv-today b{font-weight:var(--weight-strong)}
.lv-today .grow,.lv-bar .grow,.lv-legend .grow{flex:1}
.lv-who{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--line);border-radius:var(--radius-pill);padding:2px 10px 2px 3px}
.lv-who .uav-lv{margin-left:0}
/* 보기별 단추 · 카드 : Calendar = 근태 등록 · List = 직원 등록(N 이 보이는 주 단추 하나) · 승인 대기 · 발급 이력 = List 에만 */
#hr:not([data-hview="cal"]) #hrLvNewBtn,#hr[data-hview="cal"] #hrNewBtn,#hr[data-hview="inc"] #hrNewBtn,#hr[data-hview="pay"] #hrNewBtn{display:none!important}   /* ★ 과제 303 — 인센티브 보기도 「+ 직원 등록」 없음 */
#hr[data-hview="cal"] .hr-pend-card,#hr[data-hview="cal"] #hrCertLogCard,#hr[data-hview="inc"] .hr-pend-card,#hr[data-hview="inc"] #hrCertLogCard,#hr[data-hview="pay"] .hr-pend-card,#hr[data-hview="pay"] #hrCertLogCard,#hr:not([data-hview="pay"]) #hPayWhCard{display:none}   /* ★ 과제 493b — 급여 · 신고 보기도 대기 · 이력 카드 없음 · 일용 · 사업소득 대장 카드 = 그 보기에서만 */   /* ★ 과제 303 — 대기 · 이력 카드 = List 에만(인센티브 보기도) */
.lv-bar{display:flex;align-items:center;gap:8px;margin:4px 0 12px}
/* ★ 과제 303 — 인사 「인센티브」 보기 · 근거 팝업 · 내 정보 근거(§11 줄 문법 .clrow · 토큰만) */
#hr:not([data-hview="inc"]) .hinc-tool,#hr:not([data-hview="pay"]) #hPayTool,#hr:not([data-hview="pay"]) #hPayConfirmBtn,#hr:not([data-hview="pay"]) #hPayReopenBtn,#hPayConfirmBtn[hidden],#hPayReopenBtn[hidden]{display:none}
#hr[data-hview="pay"] #hrHolBtn,#hr[data-hview="pay"] .toolsonly .search{display:none}   /* ★ 493b — 급여 · 신고 = 달 · 건수 · 붙여넣기 · 보기 · 주 단추(시안 1 · 검색 · 공휴일 = 목록 보기 것) */   /* ★ 303 2차 — 달 · 셈 · 합계 = 인센티브 보기에서만(도구 줄 안) */
.hinc-tool,#hPayTool{display:inline-flex;align-items:center;gap:var(--gap-tool);flex-wrap:wrap}
.hinc-tool input[type=month],#hPayTool input[type=month]{width:auto;flex:none}
.hinc-tool button,#hPayTool button{white-space:nowrap;flex:none}
#hPayTool button[hidden]{display:none}   /* 규칙 58 — 위 display 가 [hidden] 을 이김 */
#hIncView{padding-top:var(--gap-tool-body)}   /* 도구 줄 → 몸 = 한 값(다른 보기와 같게 · 268) · 첫 자식이 숨은 안내일 때도 */
#hIncWarn{margin-bottom:var(--gap-tile)}
#hIncSum{margin:0 0 var(--gap-tile);font-size:var(--fs-sm)} #hIncSum:empty{display:none}   /* ★ 303 3차 — 합계 한 줄(도구 줄 밖) */
#hIncList .clrow.hinc-row{grid-template-columns:minmax(120px,1.1fr) minmax(130px,1fr) minmax(110px,1fr) minmax(110px,0.9fr) minmax(100px,0.9fr) minmax(170px,1.2fr) 96px}
#hIncList .clrow.hinc-row:not(.clhead){cursor:pointer}
/* ★ 과제 493b — 급여 · 신고(시안 = 화면그리기/그림_261023/과제493b_시안_*) : 대장 = 직원 · 지급 셋 · 공제 여섯 · 차인 · [명세서] · 합계 줄 = 묶음 바탕 · 돈 = 숫자만(머리 「단위 원」) */
#hPayList .clrow{grid-template-columns:minmax(72px,0.8fr) repeat(10,minmax(76px,1fr)) minmax(92px,1.1fr) 72px;column-gap:var(--gap-tool)}   /* ★ 496 ③ 13칸(공제 7) = 1440 안 · 돈 안 자름(7,000,000 = 76) */
#hPayList .clrow > .r{padding-left:0;padding-right:0}   /* ★ 496 ③ 칸 사이 = column-gap 하나(안여백 0 · 숫자 오른쪽 맞춤) */   /* 세무사 대장 꼴 = 칸 안여백 토큰 하나(12칸 · 시안 1) */   /* 12칸이 1440 에서 옆 굴림 · 잘림 없이(G-a ⓐ · 7,000,000 = 칸 안여백 둘 + 숫자 아홉 자리) */
#hPayList .clrow[data-tot]{background:var(--grp-row-bg);font-weight:var(--weight-strong)}
#hPayList .clrow.clhead.grp > :nth-child(2){grid-column:span 3}   /* 묶음 머리(§6-10 ①) = 「지급」 세 칸 · 「공제」 여섯 칸 걸침 */
#hPayList .clrow.clhead.grp > :nth-child(3){grid-column:span 7}   /* ★ 496 ③ 공제 = 그 밖 공제까지 일곱 칸 */
#hPayWhList .clrow[data-tot]{background:var(--grp-row-bg);font-weight:var(--weight-strong)}
#hPayList .clrow > .r,#hPayWhList .clrow > .r,#meSlipList .clrow > .r,:where(#hPayPasteBody) .clrow > .r{text-align:right;justify-content:flex-end}
#hPayList .clrow > :last-child,#meSlipList .clrow > :last-child{overflow:visible}
#hPayWhList .clrow{grid-template-columns:minmax(90px,1.4fr) minmax(90px,1fr) 56px repeat(3,minmax(96px,1fr)) 88px}
:where(#hPayPasteBody) .clrow{grid-template-columns:96px minmax(0,1fr) repeat(4,104px);min-width:0}   /* ★ 496 ② 세무사 차인 · ERP 차인 두 칸 더함 */   /* 2층 760 안 = 공용 .clrow 의 넓은 표 최소 폭(852) 풂 */
#hPayPasteBody .clrow[data-bad]{border-left:2px solid var(--bad)}
/* ★ 과제 579 (디자이너 · 시안 ★A 두 단 줄 · 화면그리기/그림_261030/과제579_시안_*) — 공용 부품 「미리보기 격자」 [data-part~="pv"]
   붙이는 곳 = 붙여넣기 · 세무사 PDF 미리보기 몸(#hPayPasteBody · 급여 · 원천세). 칸 차례 = ① 표지(코드) ② 이름 ③ 지급 ④ 숨길 세부 ⑤ 핵심 값 ⑥ 맞대 볼 값 · 칸 이름 = 칸의 data-l(짧은 글)
   넓은 화면 = 위 :where(#hPayPasteBody) 칸 폭 그대로(1440 변화 0) · 폰 = 1줄 [표지] 이름 … 핵심 / 2줄 지급 … 맞대 볼 값 / 3줄 ④ 세부(★ 586 · 옛 = 숨김) · 머리 줄 숨김 */
@media (max-width:600px){
  [data-part~="pv"] .clrow.clhead{display:none}
  [data-part~="pv"] .clrow{grid-template-columns:max-content minmax(0,1fr) max-content;grid-template-areas:"c1 nm main" "c3 c3 c6" "c4 c4 .";row-gap:0;column-gap:var(--gap-tool);min-width:0;padding-top:var(--gap-tool);padding-bottom:var(--gap-tool);align-items:baseline}
  [data-part~="pv"] .clrow > div{min-height:0;height:auto;line-height:1.5;padding-top:0;padding-bottom:0}
  [data-part~="pv"] .clrow > :nth-child(1){grid-area:c1}
  [data-part~="pv"] .clrow > :nth-child(2){grid-area:nm;font-weight:var(--weight-medium);word-break:keep-all;min-width:0}
  [data-part~="pv"] .clrow > :nth-child(3){grid-area:c3;justify-content:flex-start;text-align:left}
  [data-part~="pv"] .clrow > :nth-child(4){display:block;grid-area:c4;text-align:left}   /* ★ 과제 586 (시안 ★A 셋째 줄 · 지급 밑) — 폰엔 hover 가 없어 숨김 ✗(규칙 134) */
  [data-part~="pv"] .clrow > :nth-child(5){grid-area:main;font-weight:var(--weight-medium)}
  [data-part~="pv"] .clrow > :nth-child(6){grid-area:c6}
  [data-part~="pv"] .clrow > :is(:nth-child(3),:nth-child(4),:nth-child(6)){font-size:var(--fs-sm);color:var(--text-2)}
  [data-part~="pv"] .clrow > [data-l]:is(:nth-child(3),:nth-child(4),:nth-child(5),:nth-child(6))::before{content:attr(data-l) " ";color:var(--text-3)}
}
#hPayPasteSum .st{white-space:normal}   /* ★ 566 ② 디자이너 수정 — 거절 글이 2층 창 밖으로 넘침(.st nowrap) */
#hPayPdfAlt{margin-top:var(--gap-tool)}   /* ★ 566 ② 디자이너 수정 — 대안 줄이 끌어 놓기 칸 아래 선에 붙음 */
#hPayPasteIn{width:100%;box-sizing:border-box;margin:0 0 10px}
#meSlipList .clrow{grid-template-columns:minmax(96px,1.4fr) repeat(3,minmax(96px,1fr)) minmax(96px,1fr) minmax(96px,1fr) 64px}   /* ★ 502 디자인수정 2 [1] — 지급일 · 받은 날 = 제 열 둘 */
#hPayCal{margin-bottom:var(--gap-field)}
#finLabor .clrow{grid-template-columns:minmax(88px,0.8fr) repeat(5,minmax(112px,1fr)) minmax(120px,1fr)}   /* ★ 과제 493d ④ — 재무 현황 인건비 · 뒤 6달(화면 id 줄) */
#finLabor .clrow > .r{text-align:right;justify-content:flex-end}
#finLabor{margin-bottom:var(--gap-card)}   /* ★ 493d 디자인수정 2차 [2] — 인건비 표 ↔ 다음 구역 제목 사이 = 재무 현황 구역 사이 토큰 */
#hPayView{padding-top:var(--gap-tool-body)}   /* 도구 줄 → 몸 = 다른 보기와 같은 한 값(v354 잣대 20) */
#hIncList .clrow.hinc-row > div:last-child{overflow:visible}   /* [지급 찍기] 단추가 말줄임에 잘리지 않게 */
#hiBasisBody .clrow.hinc-bas{grid-template-columns:minmax(200px,2fr) minmax(110px,0.9fr) minmax(150px,1fr) minmax(120px,0.9fr)}
#hiBasisBody .hinc-bas .cl-name,#meIncBasis .me-incbas .cl-name{display:flex;flex-direction:row;align-items:center;gap:var(--gap-tool);min-width:0}   /* 코드 칩 · 이름 = 한 줄(191 캠페인별 진행과 같은 꼴) */
#hiBasisBody .hinc-bas .cl-name .ccode,#meIncBasis .me-incbas .cl-name .ccode{flex:none}
#hiBasisBody .hinc-bas .cl-name .nm,#meIncBasis .me-incbas .cl-name .nm{min-width:0;overflow:hidden;text-overflow:ellipsis}
#hiBasisBody .clrow.hinc-bas.mine{background:var(--surface-subtle)}
#hrDetInc .hinc-mo3{display:inline-flex;align-items:center;gap:var(--gap-tool);margin-right:var(--gap-tile)}
#meIncBasis .clrow.me-incbas{grid-template-columns:minmax(220px,2fr) minmax(120px,1fr) minmax(150px,1fr)}
#me .me-wide{grid-column:1 / -1}   /* ★ 303 2차 — 근거 = 넓은 카드 한 줄(두 칸 격자 줄을 늘리지 않게) */
#me > .grid2{align-items:stretch}   /* ★ 303 2차 — 한 줄 두 카드 = 같은 키(옛 align-items:start 면 짧은 카드 밑이 카드↔카드 사이 빈칸으로 보였다 · v354 = 16) */
#meIncBasis .clrow{gap:0;padding:0;align-items:stretch}   /* 목록 줄 한 벌(§11 · 칸 안여백 14 · 줄 키 = --row-h) — 내 정보는 공용 규칙(:not(#me)) 밖이라 여기서 */
#meIncBasis .clrow > *{padding:0 14px;min-height:var(--row-h);box-sizing:border-box;display:flex;align-items:center}
@media (max-width:600px){   /* ★ 과제 303 — 폰 390 : 내 정보 근거 · 인사 인센티브 줄 = 고정 칸을 풀고 두 단(이름 / 값 · 날짜) · 머리줄 숨김(DESIGN 폰 절) */
  #meIncBasis .clrow.me-incbas{grid-template-columns:minmax(0,1fr) auto}   /* 폰 = 한 줄(캠페인 · 마진 · 발행일은 넓은 화면에서) · 줄 키 = 목록 한 벌 */
  #meIncBasis .clrow.me-incbas > :nth-child(3){display:none}
  #hIncList .clrow.hinc-row{grid-template-columns:minmax(0,1fr) auto auto}
  #finLabor{overflow-x:auto} #finLabor .clrow{min-width:720px}
  main #hPayCal .stat .delta{white-space:normal;overflow:visible;text-overflow:clip}   /* ★ 493d 디자인수정 2차 [1] — 폰 = 타일 셋째 줄(상태 · 할 일) 꺾임 허용 · 말줄임 0 */   /* ★ 493d 디자인수정 [2] — 폰 = 인건비 표 상자 안 옆 굴림(달 · 돈 안 자름) */
  #hPayList .clrow{grid-template-columns:minmax(0,1fr) auto auto;min-width:0}   /* ★ 과제 493b G-e ⓐ — 폰 = 직원 · 차인 · [명세서] 셋(줄 = 명세서 = 항목 전부) · 옆 굴림 없음 */
  #hPayList .clrow > [data-m],#hPayList .clrow.clhead.grp{display:none}
  #hPayCal{grid-template-columns:repeat(2,minmax(0,1fr))}   /* ★ 493b — 폰 = 타일 2칸(시안 4) */
  #hPayTool{flex:1 1 100%;min-width:0}   /* 폰 = 달 · 붙여넣기 · 확정 묶음이 온 폭에서 접힘(한 덩어리로 화면을 밀던 것 막음) */
  #hPayTool input[type=month]{flex:1 1 auto;min-width:0}
  #hPayCal .stat .k .muted{display:none}
  #hPayCal .stat [data-insest]{display:none}   /* ★ 496 디자인수정 2 [2] — 폰 = 4대보험 「납부 추정 n원」 한 줄(근로자 · 사업주 = title) */   /* 폰 = 이름 뒤 「9월분」 숨김(시안 넘김 글) */
  #hPayWhList,#meSlipList{overflow-x:auto;min-width:0}
  #hPayWhCard,#meSlipCard{min-width:0;max-width:100%}   /* 아래 대장 = 상자 안 옆 굴림(시안 5) · 카드가 넓은 표를 따라 늘어 화면이 넘치던 것 막음 */   /* 폰 = 한 줄(직원 · 금액 · 상태) · 마진 · 요율 = 근거 팝업 · [지급 찍기] = 넓은 화면(지급은 책상에서) */
  #hIncList .clrow.hinc-row > :nth-child(2), #hIncList .clrow.hinc-row > :nth-child(3), #hIncList .clrow.hinc-row > :nth-child(4), #hIncList .clrow.hinc-row > :nth-child(7){display:none}
  #hiBasisBody .clrow.hinc-bas{grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"n n" "w m" "d d"}
  #hiBasisBody .clrow.hinc-bas > :nth-child(1){grid-area:n} #hiBasisBody .clrow.hinc-bas > :nth-child(2){grid-area:w} #hiBasisBody .clrow.hinc-bas > :nth-child(3){grid-area:m} #hiBasisBody .clrow.hinc-bas > :nth-child(4){grid-area:d}
  #hiBasisBody .clrow.clhead.hinc-bas{display:none}
}
#hLvView > .lv-bar{margin-top:var(--gap-tool-body)}   /* ★ 268 뒤따름 — 인사 Calendar 도구 줄 → 날짜 줄 4 → 한 겹 값(정산 표 사진 06) */
.lv-cal{border:1px solid var(--line);border-radius:var(--r-card);overflow:auto}
.lv-grid{min-width:1260px}
.lv-row{display:grid;grid-template-columns:160px repeat(42,minmax(26px,1fr))}
.lv-row > div{position:relative;height:var(--row-h);border-top:1px solid var(--line-soft);border-left:1px solid var(--line-soft)}
.lv-row > .lv-p{display:flex;align-items:center;gap:6px;padding:0 12px;border-left:0;white-space:nowrap;overflow:hidden}
.lv-head > div{height:auto;border-top:0;background:var(--tbl-head-bg);color:var(--text-2);font-size:var(--fs-cap);text-align:center;padding:4px 0;line-height:1.3}
.lv-head > .lv-p{font-size:var(--fs-sm)}
.lv-d.we{background:var(--row-hover)}
.lv-d.hol{background:color-mix(in srgb,var(--bad-bg) 40%,var(--bg-card))}
.lv-head .we{color:var(--text-3)} .lv-head .hol{color:var(--bad)}
.lv-d.tod{background-image:linear-gradient(to right,var(--accent) 2px,transparent 2px)}
.lv-head .tod{color:var(--accent);font-weight:var(--weight-strong)}
.lv-blk{position:absolute;left:3px;top:8px;bottom:8px;z-index:1;display:flex;align-items:center;padding:0 6px;border:0;border-radius:var(--r-ctl);font:inherit;font-size:var(--fs-cap);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer;justify-content:flex-start}
.lv-blk:hover{filter:brightness(.97)} .lv-blk:active{filter:brightness(.94)}
.lv-blk:focus-visible{outline:none;box-shadow:var(--ring)}
.lv-legend{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:10px;font-size:var(--fs-sm)}
#hLvView .lv-rech{margin:24px 0 10px}
#hLvRec .clrow > span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 등록 팝업 */
:where(#hrLvForm) [data-part~="types"]{display:flex;flex-wrap:wrap;gap:6px}   /* ★ 과제 456 — 옛 .lv-types · .lv-calc · .hl-* · .is-* = 근태 등록 그릇 id 아래 data-part · 상태 = data-st(무게 그대로) */
:where(#hrLvForm) [data-part~="types"] button[aria-pressed="true"]{background:var(--bg-active);border-color:var(--accent);color:var(--accent)}
#hrLvForm:not([data-st~="long"]) [data-part~="long"],#hrLvForm:not([data-st~="par"]) [data-part~="par"],#hrLvForm:not([data-st~="abs"]) [data-part~="abs"]{display:none}   /* ★ 과제 456 — 그 종류일 때만 보임 · 보일 때 = 제 옷 그대로(표준 칸 = 왼쪽 항목명 · 오른쪽 상자) · 옛 「보일 때 display:flex」 가 표준 칸을 깨뜨려 항목명이 상자 위 가운데로 갔음 */
#hrLvForm #hlFollow:empty{display:none}
:where(#hrLvForm) [data-part~="calc"]{background:var(--bg-fill);border-radius:var(--r-ctl);padding:10px 14px;margin:12px 0;font-size:var(--fs-sm);color:var(--text-2);line-height:1.7}
:where(#hrLvForm) [data-part~="calc"]:empty{display:none}
:where(#hrLvForm) [data-part~="calc"] b{color:var(--text)}
.lv-hand{display:grid;grid-template-columns:minmax(0,1fr) auto 150px;gap:8px;align-items:center;padding:6px 0;border-bottom:1px solid var(--line-soft);font-size:var(--fs-sm)}
.lv-tl{padding:6px 0;font-size:var(--fs-sm);border-bottom:1px solid var(--line-soft)}
/* ★ v3.35 (과제 257) — 남은 연차 음수(내년 것 당겨 씀) = 빨강 글자 한 벌(새 색 0) · 등록 창 경고 = 전역 .warn 상자 */
.lv-neg{color:var(--bad);font-weight:var(--weight-strong)}
#hrLvForm #hlBorrow{margin:8px 0 0}

  /* ★ 과제 262 — 계산서 발행 요청 : 캠페인 상세 구역 · 계산서 · 입금 「발행할 것」 카드(받은 함 카드와 같은 결 · 왼쪽 파란 띠 = 가리키는 것) */
  :where(#cInvReq) [data-part~="list"]{display:flex;flex-direction:column;gap:4px;margin:4px 0}
  :where(#cInvReq) [data-part~="row"]{display:flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:var(--fs-sm);padding:4px 0;border-bottom:1px solid var(--line-soft)}
  :where(#cInvReq) [data-part~="row"] b{font-variant-numeric:tabular-nums}
  :where(#cInvReq) [data-part~="row"] .ghost.mini{margin-left:auto}
  #bInvQueue{border-left:4px solid var(--accent);margin-bottom:16px}
  #bInvQueue .ireq-head{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:12px;font-size:var(--fs-sm)}
  #bInvQueue .ireq-n{font-size:var(--fs-num);font-weight:var(--weight-num);color:var(--accent);line-height:1}
  #bInvQueue .ireq-title{font-size:var(--fs-card);font-weight:var(--weight-strong)}
  #bInvQueue .ireq-q{border:1px solid var(--line);border-radius:var(--r-ctl)}
  #bInvQueueList .clrow{grid-template-columns:72px minmax(140px,1.4fr) minmax(130px,1fr) minmax(90px,.7fr) 56px 112px 104px 116px 104px 112px;min-width:0}
  @media (max-width:1399px){ #bInvQueueList .clrow{grid-template-columns:72px minmax(140px,1.4fr) minmax(130px,1fr) 56px 112px 104px 116px 100px 112px} #bInvQueueList .ireq-mail{display:none} }
  #bInvQueueList .clrow > .r{text-align:right;justify-content:flex-end;font-variant-numeric:tabular-nums}
  #bInvQueueList .clrow > div{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .ireq-two{display:flex;flex-direction:column;line-height:1.35;min-width:0}
  .ireq-two > *{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  #bInvQueue .ireq-empty{margin:0;padding:14px;text-align:center;color:var(--text-2);font-size:var(--fs-sm);border:1px dashed var(--line);border-radius:var(--r-ctl)}   /* ★ 과제 268 정산 — 빈 글 = 13px --text-2(DESIGN §1 「--text-3 은 글자색이 아니다」 · 할 일 빈 글과 같음) · 옛 = --text-3 · 14px */
  #irWrap #irMiss{margin:12px 0 0}
  #cInvReq [data-part~="act"]{margin-top:6px}
  #irCalc b{font-variant-numeric:tabular-nums}
/* ★ 과제 258 — 인사 상세 「연차 근거」(자동 / 손 · 근거 · 지금 다시 셈 · 퇴사 정산) */
#hrLvAuto{margin-top:10px;display:flex;flex-direction:column;gap:6px;font-size:var(--fs-sm)}
#hrLvAuto:empty{display:none}
#hrLvAuto .hr-lvauto-h{display:flex;align-items:center;justify-content:space-between;gap:8px}
#hrLvAuto .hr-lvauto-s{padding:8px 12px;border:1px solid var(--line);border-radius:var(--r-ctl)}

/* ★ 과제 274 (10-01 · 268 제안 4 · 대표 답 G-030 함께) — 폰 390 Dashboard(공용 dashGrid · 할 일 포함 전 화면) · ⚠ 파일 맨 끝(앞 규칙들을 이기려고)
   옛 = 타일 두 칸 · 칩 글 줄바꿈 허용(.dash-host … .delta{white-space:normal}) → 칩이 한 글자씩 꺾여 겹침 · 보기 단추 묶음이 오른쪽에서 잘림(268 사진 06)
   → 타일 한 줄에 하나 · 칩 줄바꿈 금지(넘치면 말줄임) · 보기 단추 묶음 = 제 줄 하나(줄 넘김) · 그래도 넓으면 묶음 안에서 옆으로 굴림(단추가 두 줄로 꺾이지 않게) */
@media (max-width:600px){
  main .tk-dash .tk-dstats, main .dash-host .tk-dstats, main .tk-dstats{grid-template-columns:1fr}
  main .tk-dstats[data-dn]:not([data-dn="0"]):not([data-dn="1"]){grid-template-columns:repeat(2,minmax(0,1fr))}   /* ★ 과제 430c — 폰 = 「지금 할 일」 한 줄 온 폭 · 타일 둘씩(시안 16) */
  main .tk-dstats[data-dn] > [data-dcard="dnow"]{grid-column:1/-1}
  main .tk-dstats > [data-dcard="dnow"] .htask .ht-c{display:none}
  main .tk-dash .stat .delta, main .dash-host .tk-dstats .stat .delta{white-space:nowrap;max-width:100%;overflow:hidden;text-overflow:ellipsis}
  main #spend:not(.sp-ae) #spDashView .tk-dstats{grid-template-columns:1fr} main #spend:not(.sp-ae) #spDashView .tk-dstats .stat .v{font-size:var(--fs-num)}   /* ★ 과제 342 — 지출 Dashboard 다섯 · 셋 칸 규칙(184)이 폰까지 이겨 타일 42 · 73px(알약 한두 글자) → 폰은 위 줄대로 하나씩 */
  main .card h3.toolsonly > .tools{flex-wrap:wrap;min-width:0;width:100%}   /* 안쪽 도구 묶음도 줄을 넘김(옛 = 한 줄에 눌려 검색칸 · 보기 단추가 찌그러짐) */
  main .card h3.toolsonly .tools .seg, main #tkTools .seg{flex:1 1 100%;max-width:100%;overflow-x:auto;flex-wrap:nowrap}
  /* ★ 과제 477 (디자이너 5 · 10-21) — 폰 390 공용 둘(관문 v475)
     ⓐ 요약 타일 큰 숫자 = 한 단계 작은 토큰 --fs-page · 한 줄(둘씩 놓기 = 430c 시안 16 그대로 · 큰 돈이 「원」 에서 꺾이고 칸 밖으로 나가던 것) · 지출 한 칸 타일은 342 규칙(--fs-num)이 그대로 이김
     ⓑ 보기 전환 다섯 이상 = 한 줄을 넘으면 두 줄로 꺾음(옆 굴림은 굴림 표시가 없어 끝 단추가 「잘린 듯」 보였다 · 단추 글은 안 꺾임 = flex:none 그대로) · 넷 이하는 폰 한 줄에 들어가 그대로 */
  main .tk-dstats .stat .v{font-size:var(--fs-page);white-space:nowrap}
  main .seg:has(> button:nth-of-type(5)), main .card h3.toolsonly .tools .seg:has(> button:nth-of-type(5)){flex-wrap:wrap;height:auto;overflow-x:visible;border-radius:var(--r-ctl)}
  /* ★ 과제 298 (10-05 · 191 검사 중 찾음) — 단추가 줄어들며(flex-shrink 기본 1) 글이 세로로 꺾였다(발주 「대학교 · 지정게시대 …」 · 카드 [건수|금액] · 판매 매체 「품목 41」)
     → 단추 = 제 글 폭 그대로 · 한 줄 · 묶음이 넘치면 그 안에서 옆으로 굴림(위 274 규칙과 같은 꼴) · 관문 v363 ⓕ */
  main .seg{max-width:100%;overflow-x:auto;flex-wrap:nowrap}
  main .seg > button{flex:none;white-space:nowrap}
  main .ld-trend-segs{flex-wrap:wrap;justify-content:flex-end;max-width:100%}   /* 추이 [건수|금액] + [주|월|연] 두 묶음 = 좁으면 두 줄(옛 = 단추가 줄어 글이 꺾였다 → 줄지 않으니 카드 밖으로 나감) */
}

/* ★ 과제 279 (10-02 대표 「26년 10월 2일 (금) 12:15」 · 「일시 칸은 안 자름 · 두 줄 꺾임 금지」) — 날짜 · 일시 글이 길어져(16자 → 20자 안팎) 칸을 넓힘 · 관문 = 일시표기검사 v366 ⓕ(꺾임 · 잘림 0)
   글 폭 실측(14px Pretendard) : 「26년 12월 28일 (월) 22:36」 157 · 「26년 12월 28일 (월)」 116 · 칸 = 글 + 안여백 28 + 선 1 */
  #leadList .clrow{grid-template-columns:188px minmax(120px,.9fr) 112px 104px minmax(160px,2.6fr) 96px minmax(110px,.9fr) 108px}   /* 상담일시 160 → 188 */
  #liList .clrow{grid-template-columns:186px 88px minmax(150px,200px) minmax(140px,1fr) 170px 96px 120px 134px;min-width:1104px}   /* ★ 과제 375 — 여덟 열 · 최소 합 1084 + 20 = 1104 ≤ 1440 상자 1108(실측) · 짧은 값 잘림 0(v270 Q-050 · 처리 ⋯가져가기 133 · 홈페이지 85 · 매체 「버스쉘터 · 아파트 게시판」 163 · 회사명 「(회사명 없음)」 + 확인 필요 알약 149) · 가로 스크롤 0 */   /* 받은 함 문의일시 128 → 186 · 최소 = 칸 최소 합 1098(옛 1060 = 합 1040 + 20) → 1440 상자 1105 안 · 가로 스크롤 0 그대로 · 좁으면 상자 안에서 돈다(그대로) */
  #qListAll .clrow{grid-template-columns:148px 100px minmax(96px,.9fr) minmax(150px,1.5fr) 136px 128px 148px}   /* 만든 날 116 → 148 */
  /* ★ 과제 351(Q-049 답 ⓑ · G-255) — 견적 List ≤1399(1280) = **만든 날 칸 숨김**(덜 쓰는 칸 · 견적 상세에 그대로 · 1440 은 그대로) · 옛 = 캠페인 180 이 잘렸다 → 만든 날 148 이 이름 칸으로 */
  @media (max-width:1399px){
    #qListAll .clrow{grid-template-columns:148px 100px minmax(96px,.9fr) minmax(150px,1.5fr) 136px 128px}
    #qListAll .clrow > .col-off-narrow{display:none}
  }
  #hrList .clrow{grid-template-columns:94px 1fr 92px 78px 132px 132px 90px}   /* 입사일 116 → 132 */
  /* ★ 과제 377(10-13 대표 「다른 표 형식과 맞게」 · 기획 시안) — 명부 코드 칸 = <span><span class="ccode"> 작은 코드 배지(칸을 꽉 채우던 회색 덩어리 ✗ · 캠페인 코드와 같은 옷) · 「증명서 발급 이력」(split 안 · margin-bottom 0) ↔ 「주민등록번호 열람 기록」 사이 = 다른 카드와 같은 16 */
  #hrRrnLogCard{margin-top:var(--gap-card)}
  #campList .clrow{grid-template-columns:minmax(100px,2.4fr) minmax(90px,.8fr) minmax(134px,.6fr) 122px 190px minmax(128px,.4fr)}   /* ★ 과제 449b(디자이너 4 시안 A · 기획 10-20) — fr 만 : 캠페인 1.5 → 2.4 · 담당 .9 → .6 · 계약금액 .7 → .4(고정 폭 그대로 · 1440 이름 칸 253 → 304 · 「완료」 배지 + 코드 + 이름 잘림 0 · 같은 fr 여덟 줄 = 위 1345~1367 죽은 블록도 같은 값) · ★ 과제 351(10-08 대표 디자인 점검 · Q-049 답 ⓑ · 대표 10-09) — 캠페인 List = **넓은 화면(1440)에서도 집행기간 칸 숨김**(≤1366 은 G-049 로 이미 숨김 · 상세 · Calendar 에 그대로) · 옛 = 집행기간 206 · 결제 176 이 칸을 차지해 이름 124(남는 폭 24) · 이제 이름이 남는 폭을 가져간다 · 결제 190(「입금 7월 29일 (수)」 158 + 안여백 28 + 선 1) */
  #campList:where(.mg) .clrow{grid-template-columns:minmax(100px,2.4fr) minmax(90px,.8fr) minmax(134px,.6fr) 122px 190px minmax(128px,.4fr) 80px;min-width:894px}
  /* ★ 과제 351 — 목록에서 숨기는 열 = 칸에 `col-off`(항상) · `col-off-narrow`(≤1399 만) 를 단다(순서 번호를 안 센다 · core.js _colApply 가 같은 표시로 저장 너비를 맞춘다) */
  .clrow > .col-off{display:none}
  @media (max-width:1399px){
    #leadList .clrow{grid-template-columns:188px minmax(110px,.8fr) 108px 100px minmax(108px,2fr) 96px minmax(100px,.8fr) 108px;min-width:918px}   /* 상담일시 150 → 188 */
    /* 할 일 List 마감 = 짧은 꼴 「8월 26일 (수) · 지남」(143) → 옛 칸 150 에 그대로 들어감 · 할 일 격자 안 바꿈 */
  }
  /* 캠페인 List ≤1366 — 집행기간(193)과 결제(「입금 7월 29일 (수)」 158)가 1280 상자(948)에 같이 못 들어감 → 집행기간 칸을 숨기고(판매 매체 1280 비고 칸 숨김 G-193 과 같은 길 · 상세 · Calendar 에 그대로) 결제를 넓힘 · 가정 G-049 */
  @media (max-width:1366px){
    #campList .clrow{grid-template-columns:minmax(100px,2.4fr) minmax(90px,.8fr) minmax(134px,.6fr) 100px 160px minmax(128px,.4fr)}   /* ★ 과제 449b(디자이너 4 시안 B 를 실측으로 고침 · 기획 확인 대기) — 결제 190 → 160 : 「입금 7월 29일 (수)」 = 158(.st-d 없는 알약이라 숨김으로 안 짧아짐 · 시안 124 = 결제 글이 잘림) → 160 이면 결제 잘림 0 · 1280 이름 칸 146 → 179 */
    #campList:where(.mg) .clrow{grid-template-columns:minmax(100px,2.4fr) minmax(90px,.8fr) minmax(134px,.6fr) 100px 160px minmax(128px,.4fr) 80px;min-width:872px}
    #campList .clrow > :nth-child(6){display:none}   /* 1 = 고르기 상자(.selbox · 격자 밖) · 6 = 집행기간(.cl-run) · 머리줄도 같은 자리 */
  }
  /* ★ 과제 279 검토 ②③ — 짧은 꼴 날짜(「12월 28일 (월)」 84) · 「외 1」(110) · 기간(「9월 21일 (월) ~ 10월 30일 (금)」 176) · 일시(158) + 안여백 28 + 선 1 = 칸 116 · 140 · 206 · 188 */
  #odListAll .clrow{grid-template-columns:142px 68px minmax(118px,1.4fr) minmax(76px,.8fr) 116px 206px minmax(64px,.6fr)}   /* 발주 List 집행기간 108 → 206 */
  #spListAll:where([data-seg="po"]) .clrow{grid-template-columns:140px minmax(83px,1.2fr) minmax(95px,1fr) minmax(83px,.7fr) 142px 100px 116px 140px;min-width:899px}   /* 예정일 108 → 116 · 지급일 89 → 140 · 1280 = 899 + 고르기 48 = 947 ≤ 948 */
  #spend.sp-ae #spListAll:where([data-seg="po"]) .clrow{grid-template-columns:140px minmax(83px,1.2fr) minmax(95px,1fr) minmax(83px,.7fr) 142px 100px 116px;min-width:759px}
  #spListAll:where([data-seg="ov"]) .clrow{grid-template-columns:88px minmax(100px,1.6fr) minmax(64px,.9fr) 142px 188px 116px 140px 86px 82px;min-width:1006px}   /* 등록일시 148 → 188 · 예정일 86 → 116 · 지급일 108 → 140 */
  #spListAll:where([data-seg="due"]) .clrow{grid-template-columns:116px minmax(122px,1.5fr) minmax(100px,1.1fr) minmax(88px,.8fr) minmax(140px,1.4fr) 142px minmax(80px,.8fr) minmax(112px,.9fr)}   /* 지급 대기 예정일 88 → 116 · 캠페인 최소 132 → 122(1280 = 948) */
  @media (max-width:1366px){
    /* 판관비 List ≤1366 — 칸 아홉이 1280 상자(948)에 다 못 들어감 → 등록일시를 숨김(상세 팝업 · 1440 에는 그대로 · 캠페인 집행기간 G-056 과 같은 길 · G-058) */
    #spListAll:where([data-seg="ov"]) .clrow{grid-template-columns:88px minmax(100px,1.6fr) minmax(64px,.9fr) 142px 116px 140px 86px 82px;min-width:818px}
    #spListAll:where([data-seg="ov"]) .clrow > :nth-child(5){display:none}
  }
/* ★ 과제 288 — 연결 · 점검 「테스트 자료 일괄 삭제」 확인 창(건수 표 = 공용 table · 수 = 오른쪽 · 폴더 목록 = 여백만) */
  :where(#trBody) [data-part~="tbl"] th.r,:where(#trBody) [data-part~="tbl"] td.r{text-align:right}   /* ★ 과제 456 — 옛 .tr-tbl · .tr-fold · .tr-ask */
  #trBody [data-part~="fold"]{margin:0;padding-left:var(--inset-x)}
  #trWrap [data-part~="ask"]{display:grid;gap:calc(var(--gap-tool) / 2);margin-top:var(--gap-tool)}

/* ★★ 과제 286 (10-02 대표 「표에서 어디를 누르면 바로 수정 · 상세가 열리는지 알아보기 힘들어」 · 「전체 페이지 모든 표에」 · 시안 = 시제품/…261002…표누르기시안.html · 「열림 · 평소 검정 · 넣음」)
   ① 열기 = 이름 칸 : 줄에 올리거나 초점 → 이름 파랑 + 밑줄 · 칸 끝 ↗(올렸을 때만) · 읽기 칸도 누르면 상세(지금 동작 그대로 · 줄 커서 = pointer)
   ② 고치는 칸(.cl-ed · 할 일 .tk-ed) : 커서 text · 올림 · 초점 = 흰 바탕 + --line-input 테두리(초점 = --accent 2) + 오른쪽 ✎ · 오른쪽 안여백 = ✎ 자리(값 안 가림)
   ③ 잠긴 칸(.cl-lock) : 커서 not-allowed · 올림 · 초점 = 🔒 · 누르기 · Enter = 까닭 한 줄(그대로)
   ④ (은퇴 · 과제 321 · 10-06 대표) 머리 표시 ✎ · 🔒   ⑤ (은퇴 · 과제 321) 표 아래 안내 한 줄 .cl-foot — 칸 안 표시(①~③)만 남음
   ⚠ 동작 · 저장 · 권한 · id 그대로 · 모습만 · 할 일 표 = 규칙 124 대표 예외(G-050) */
  .clrow:not(.clhead):has(> .cl-ed):hover,.tk-row:not(.tk-head):hover{background:var(--row-hover-soft)}
  .clrow:not(.clhead):hover > .cl-name .nm,.clrow:not(.clhead):hover > .cl-name .nm a,.clrow > .cl-name .nm a:focus-visible,.clrow:not(.clhead):focus-visible > .cl-name .nm{color:var(--accent);text-decoration:underline;text-underline-offset:3px}
  .clrow > .cl-name:not(.cl-ed),.clrow > .cl-open{position:relative}
  .clrow:not(.clhead):hover > .cl-open,.clrow:not(.clhead):focus-visible > .cl-open{color:var(--accent);text-decoration:underline;text-underline-offset:3px}   /* 이름 칸이 없는 표의 여는 칸(clMarkTables 가 붙임) */
  .clrow > .cl-name:not(.cl-ed)::after,.clrow > .cl-open::after,.clrow > .cl-ed::after,.tk-row > .tk-ed::after{content:'';position:absolute;right:var(--gap-tool);top:50%;width:var(--ic-mark);height:var(--ic-mark);transform:translateY(-50%);
      background:var(--text-3);-webkit-mask:var(--ic-open) center / contain no-repeat;mask:var(--ic-open) center / contain no-repeat;opacity:0;pointer-events:none;transition:opacity var(--duration-fast) var(--ease);
      outline:calc(var(--gap-tool) / 2) solid var(--bg-card);outline-offset:0}   /* 흰 받침 = 값 끝 글자 위에 겹쳐도 표시가 읽힘 */
  .clrow:not(.clhead):hover > .cl-name:not(.cl-ed)::after,.clrow > .cl-name:not(.cl-ed):focus-within::after,.clrow:not(.clhead):hover > .cl-open::after{opacity:1}
  .clrow > .cl-ed,.tk-row > .tk-ed{position:relative}
  /* ★ 과제 321 ⑨ — 할 일 업무명 = 여는 칸(286 이름 칸 ① 과 같은 모습 : 평소 검정 · 올리면 · 초점 = 파랑 밑줄 + ↗) */
  .tk-row > .tk-open{position:relative;cursor:pointer}
  .tk-row:not(.tk-head):hover > .tk-open,.tk-row > .tk-open:focus-visible{color:var(--accent);text-decoration:underline;text-underline-offset:3px}
  .tk-row > .tk-open::after{content:'';position:absolute;right:var(--gap-tool);top:50%;width:var(--ic-mark);height:var(--ic-mark);transform:translateY(-50%);background:var(--text-3);-webkit-mask:var(--ic-open) center / contain no-repeat;mask:var(--ic-open) center / contain no-repeat;opacity:0;pointer-events:none;transition:opacity var(--duration-fast) var(--ease);outline:calc(var(--gap-tool) / 2) solid var(--bg-card);outline-offset:0}
  .tk-row:not(.tk-head):hover > .tk-open::after,.tk-row > .tk-open:focus-visible::after{opacity:1}   /* 칸 폭 · 안여백 그대로(날짜 칸 안 자름 · 과제 279) — ✎ 는 올림 · 초점 때만 값 끝 위에 흰 받침과 함께 */
  .clrow > .cl-ed::after,.tk-row > .tk-ed::after{-webkit-mask-image:var(--ic-pen);mask-image:var(--ic-pen)}
  .clrow > .cl-ed:not(.cl-lock):not(.cl-on):hover,.clrow > .cl-ed:not(.cl-lock):not(.cl-on):focus-visible,
  .tk-row > .tk-ed:not(.tk-on):hover,.tk-row > .tk-ed:not(.tk-on):focus-visible{background:var(--bg-card);box-shadow:inset 0 0 0 1px var(--line-input);border-radius:var(--r-inner);outline:none}
  .clrow > .cl-ed:not(.cl-lock):not(.cl-on):focus-visible,.tk-row > .tk-ed:not(.tk-on):focus-visible{box-shadow:inset 0 0 0 2px var(--accent)}
  .clrow > .cl-ed:not(.cl-on):hover::after,.clrow > .cl-ed:not(.cl-on):focus-visible::after,.tk-row > .tk-ed:not(.tk-on):hover::after,.tk-row > .tk-ed:not(.tk-on):focus-visible::after{opacity:1}
  .clrow > .cl-ed.cl-on::after,.tk-row > .tk-ed.tk-on::after{display:none}
  .clrow > .cl-ed.cl-lock{cursor:not-allowed}
  .clrow > .cl-ed.cl-lock::after{-webkit-mask-image:var(--ic-lock);mask-image:var(--ic-lock)}
  .clrow > .cl-ed.cl-lock:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--accent);border-radius:var(--r-inner)}
  /* (은퇴 · 과제 321 · 10-06 대표) 머리 표시 ✎ · 🔒(.cl-hm · cl-h-ed · cl-h-lock) · 표 아래 안내 .cl-foot — 칸 안 표시만 남김 */

/* ★ 과제 275 (10-02 · 검토자가 274 검토 중 찾음) — 폰 390 화면 한 벌 · 가로 넘침 0 · 카드 값 카드 안 · 글 세로 0 · 관문 = 폰390넘침검사 v363 · ⚠ 파일 맨 끝(앞 규칙들을 이기려고) · 데스크톱(>600) 모습 그대로
   ① 할 일 Dashboard 「지금 손댈 것」 머리줄(고정 칸 합 276 > 카드 안 202)이 문서를 432 로 밀었다 → 폰에선 줄 = 세 단(업무 · 상태 / 광고주 · 캠페인 / 담당 · 마감) · 칸 이름 머리줄 숨김
   ② 사람별 · 캠페인별 줄 = 고정 칸(150 · 128 / 150 · 96)이 이름 칸을 0 으로 눌러 광고주 이름이 세로로 · 숫자가 카드 밖 → 두 단(이름 · 숫자 / 막대)
   ③ .grid2 = 칸 최소 430(auto-fit) → 창 390 보다 넓어 내 정보 카드가 오른쪽으로 삐짐 → 폰에선 한 칸 */
@media (max-width:600px){
  main .grid2{grid-template-columns:minmax(0,1fr)}
  #taskList .tk-dlist .clrow.clhead{display:none}
  #taskList .tk-dlist .clrow{grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"n s" "w d";row-gap:calc(var(--gap-tool) / 2);column-gap:var(--gap-tile)}
  #taskList .tk-dlist .clrow > div:nth-child(1){grid-area:n} #taskList .tk-dlist .clrow > div:nth-child(2){grid-area:w}   /* ★ 과제 340 — 넷 칸(이름 · 담당 · 마감 · 상태) */
  #taskList .tk-dlist .clrow > div:nth-child(3){grid-area:d} #taskList .tk-dlist .clrow > div:nth-child(4){grid-area:s}
  #taskList .tk-dlist .clrow > div{border-right:0;padding-right:0}   /* 칸 사이 세로 선 = 한 줄 표의 것 · 쌓으면 엉뚱한 자리에 선이 남는다 */
  #taskList .tk-ddone .clrow{grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"n d" "c w"}
  #taskList .tk-ddone .clrow > div:nth-child(2){grid-area:c} #taskList .tk-ddone .clrow > div:nth-child(3){grid-area:w} #taskList .tk-ddone .clrow > div:nth-child(4){grid-area:d}
  .tk-drow,.tk-dcamp{grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"a c" "b b";row-gap:var(--gap-tool)}
  .tk-drow > :nth-child(1){grid-area:a;min-width:0} .tk-drow > :nth-child(2){grid-area:b} .tk-drow > :nth-child(3){grid-area:c}
  /* ④ 광고주 Dashboard(순번 칸 24 = 바탕 규칙 .adv-rank · .adv-top 의 첫 칸 그대로 · 새 값 아님) — 띠(인사이트 셋)가 한 줄 세 칸 → 한 칸 · 순위 · 다시 연락 · 업종별 · 상위 10 · 박한 곳 줄 = 두 단(이름 · 값 / 막대 · 설명) · 금액 한 줄 */
  .tk-dstrip{grid-template-columns:minmax(0,1fr)}
  .adv-rank{grid-template-columns:24px minmax(0,1fr);grid-template-areas:"k n" "k v" "k b";row-gap:var(--gap-tool)}
  .adv-rank > .adv-rk{grid-area:k} .adv-rank > .adv-rn{grid-area:n;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis} .adv-rank > .adv-rbar{grid-area:b} .adv-rank > .adv-rv{grid-area:v;align-items:flex-start}
  .adv-back{grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"n r" "m m";row-gap:calc(var(--gap-tool) / 4)}
  .adv-back > :nth-child(1){grid-area:n;min-width:0} .adv-back > :nth-child(2){grid-area:m} .adv-back > :nth-child(3){grid-area:r}
  .adv-by{grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"k m" "b b" "s s"}
  .adv-by > .adv-byk{grid-area:k} .adv-by > .tk-hbar{grid-area:b} .adv-by > .adv-bym{grid-area:m;white-space:nowrap} .adv-by > .adv-bys{grid-area:s}
  .adv-top{grid-template-columns:24px minmax(0,1fr) auto;grid-template-areas:"k n r" "k b b";row-gap:calc(var(--gap-tool) / 2)}
  .adv-top > :nth-child(1){grid-area:k} .adv-top > :nth-child(2){grid-area:n;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis} .adv-top > :nth-child(3){grid-area:b} .adv-top > :nth-child(4){grid-area:r;white-space:nowrap}
  .dash-host .tk-dlist .clrow.adv-lowrow{grid-template-columns:repeat(3,minmax(0,1fr));grid-template-areas:"n n n" "v m t"}
  .dash-host .tk-dlist .clrow.adv-lowrow > :nth-child(1){grid-area:n} .dash-host .tk-dlist .clrow.adv-lowrow > :nth-child(2){grid-area:v} .dash-host .tk-dlist .clrow.adv-lowrow > :nth-child(3){grid-area:m} .dash-host .tk-dlist .clrow.adv-lowrow > :nth-child(4){grid-area:t}
  .dash-host .tk-dlist .clrow.clhead.adv-lowrow{display:none}
  /* ⑤ 결과보고 「보고할 것」 = 단추 칸 168 고정이 카드 밖으로 → 세 단(캠페인 / 끝난 지 · 담당 / 단추) · 칸 이름 머리줄 숨김 */
  #rDashView .rp-wait .clrow{grid-template-columns:auto minmax(0,1fr);grid-template-areas:"n n" "g w" "a a";row-gap:var(--gap-tool);column-gap:var(--gap-tile)}
  #rDashView .rp-wait .clrow > :nth-child(1){grid-area:n} #rDashView .rp-wait .clrow > :nth-child(2){grid-area:g} #rDashView .rp-wait .clrow > :nth-child(3){grid-area:w} #rDashView .rp-wait .clrow > :nth-child(4){grid-area:a}
  #rDashView .rp-wait .clrow.clhead{display:none}
  #rDashView .rp-wait .clrow > div{border-right:0;padding-right:0}
  /* ⑧ 추이 차트 범례 = 이름이 낱말마다 꺾임(「집행 / 끝」) → 범례 줄은 넘기되 이름 하나는 한 줄 */
  .ld-legend{flex-wrap:wrap} .ld-legend > span{white-space:nowrap}
  /* ⑥ 판매 매체 — 목차(236) 옆에 본문이 94 로 눌려 제목이 세로로 → 목차 위 · 본문 아래(한 칸) */
  #mWrap{flex-direction:column;align-items:stretch} #mNav{width:auto}
  /* ⑦ 긴 값(연결 · Project URL 등) = 칸 안에서 줄바꿈(옛 = 글이 칸 밖 46) */
  .cdprop .pv{overflow-wrap:anywhere}
  /* ★ 과제 531 (10-29 · 대표 G-688 = A · 옛 = 과제 313 옆 굴림 표 = 금액 18곳이 카드 밖) — 폰 390 계산서 · 입금 「현금 흐름」 = 주마다 두 줄
       위 = 주 이름 · 차액 / 아래 = 들어올 · 나갈(작은 회색) · 머리줄 숨김 · 칸 이름 = JS 글 .bill-cf-lab · 금액 말줄임 0(DESIGN 금액 말줄임 금지) · 디자이너 시안 CSS 를 토큰으로 */
  #bDashView .bill-cf{overflow-x:visible}
  #bDashView .bill-cf .clrow.clhead{display:none}
  #bDashView .bill-cf .clrow{grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"wk net" "in out";min-width:0;min-height:0;row-gap:calc(var(--gap-tool) / 4);padding:var(--gap-tool) 0;align-items:baseline}
  #bDashView .bill-cf .clrow > div{min-height:0;height:auto;padding-top:0;padding-bottom:0;line-height:1.5}
  #bDashView .bill-cf .clrow > div:nth-child(1){grid-area:wk;font-weight:var(--weight-medium);color:var(--ink)}
  #bDashView .bill-cf .clrow > div:nth-child(2){grid-area:in;text-align:left;font-size:var(--fs-sm);color:var(--text-2);font-weight:var(--weight-regular)}
  #bDashView .bill-cf .clrow > div:nth-child(3){grid-area:out;font-size:var(--fs-sm);color:var(--text-2);font-weight:var(--weight-regular)}
  #bDashView .bill-cf .clrow > div:nth-child(4){grid-area:net}
  #bDashView .bill-cf .clrow > div.r{white-space:nowrap;overflow:visible;text-overflow:clip}
  #bDashView .bill-cf .clrow > div:nth-child(1){white-space:normal;overflow:visible;text-overflow:clip;word-break:keep-all}   /* ★ 과제 543 — 주 이름 = 두 줄 허용(9자리 차액 셋이면 「이번 주 · 9월 28일 (월) 주」 7px 말줄임 · DESIGN 324 날짜 안 자름) · 날짜는 붙는 공백(boot.js)으로 한 덩어리 */
  #bDashView .bill-cf .bill-cf-lab{display:inline;font-size:var(--fs-sm);color:var(--text-2);font-weight:var(--weight-regular)}
  /*   ② 지출 Dashboard 「지급할 것」(과제 313 본래) = 세 칸이 202 에 눌려 이름 「8…」 · 예정일 「8월」 반 · 머리 「예」 → 두 단(지출 / 예정일 · 지급액) · 칸 이름 머리줄 숨김(① 할 일 「지금 손댈 것」 과 같은 결) */
  #spDashView .tk-dlist .clrow.clhead{display:none}
  #spDashView .tk-dlist .clrow{grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"n n" "d a";min-height:0;padding:var(--gap-tool) 0;row-gap:calc(var(--gap-tool) / 4);column-gap:var(--gap-tile);align-items:baseline}   /* ★ 과제 543 — 줄 93 → 60 = 현금 흐름(.bill-cf) 과 같은 풀이(칸 min-height 44 가 남아 두 줄 사이 49) */
  #spDashView .tk-dlist .clrow > div:nth-child(1){grid-area:n} #spDashView .tk-dlist .clrow > div:nth-child(2){grid-area:d} #spDashView .tk-dlist .clrow > div:nth-child(3){grid-area:a}
  #spDashView .tk-dlist .clrow > div{border-right:0;padding-right:0;min-height:0;height:auto;padding-top:0;padding-bottom:0;line-height:1.5}
  #spDashView .tk-dlist .clrow > div:nth-child(n+2){white-space:nowrap;overflow:visible;text-overflow:clip}
  /*   ★ 과제 531 ② (10-29 기획 승인 · v363 ⓘ) — 계산서 「입금 늦은 것」 = 세 칸이 300 에 눌려 예정일 「9월 27일 (일) · 지」 · 미수액 · 머리가 잘렸다(title 이 있어도 날짜 · 금액은 잘리면 안 됨)
       → 지출 「지급할 것」(위 ②) 과 같은 두 단 : 위 = 캠페인(말줄임 · title) / 아래 = 예정일 · 미수액(잘림 0) · 머리줄 숨김 */
  #bDashView .bill-late .clrow.clhead{display:none}
  #bDashView .bill-late .clrow{grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"n n" "d a";min-height:0;padding:var(--gap-tool) 0;row-gap:calc(var(--gap-tool) / 4);column-gap:var(--gap-tile);align-items:baseline}   /* ★ 과제 543 — 줄 93 → 60 = 현금 흐름(.bill-cf) 과 같은 풀이(칸 min-height 44 가 남아 두 줄 사이 49) */
  #bDashView .bill-late .clrow > div:nth-child(1){grid-area:n} #bDashView .bill-late .clrow > div:nth-child(2){grid-area:d} #bDashView .bill-late .clrow > div:nth-child(3){grid-area:a}
  #bDashView .bill-late .clrow > div{border-right:0;padding-right:0;min-height:0;height:auto;padding-top:0;padding-bottom:0;line-height:1.5}
  #bDashView .bill-late .clrow > div:nth-child(n+2){white-space:nowrap;overflow:visible;text-overflow:clip}
  /*   ③ 재무 「현금 흐름」(.fin-cf · 다섯 칸) = 주 칸 「9월 28일 (월) 주 ·」 · 「지난 예정(아직 안 된 것」 이 잘렸다 → 계산서 현금 흐름과 같은 결(카드 안 옆 굴림 · 칸 폭 고정 · 주 칸은 접어 두 줄 · 금액 칸은 한 줄) */
  #fin .fin-cf{overflow-x:auto}
  #fin .fin-cf .clrow{grid-template-columns:118px repeat(4,124px);min-width:614px}   /* 위 계산서 현금 흐름과 같은 칸(주 118 · 금액 124) · 최소 614 = 118 + 124 × 4 = 칸 합(맨 수 까닭 = 위) */
  #fin .fin-cf .clrow > div:first-child,#fin .fin-cf .clrow.clhead > div{white-space:normal;overflow:visible;text-overflow:clip}
  #fin .fin-cf .clrow > div.r{white-space:nowrap;overflow:visible;text-overflow:clip}
  /*   ④ Dashboard 공용 세 칸 목록(.dash-host .tk-dlist · 캠페인 「지금 손댈 것」 · 알바 「폰 계정이 없는 알바」 …) = 셋째 칸 45~51 에 안여백 14+14 → 머리 「담당」 · 「거래처」 가 잘렸다
       → 폰에선 칸 안여백 = --gap-tool(8) · 셋째 칸 최소 4.5em(두세 글자 머리가 들어감 · 줄마다 같은 폭이라 열이 맞음) · 이름 칸 말줄임은 그대로(온전한 글 = title · 아래 공용) */
  .dash-host .tk-dlist .clrow{grid-template-columns:minmax(0,1.5fr) minmax(0,1.2fr) minmax(4.5em,.9fr)}
  .dash-host .tk-dlist .clrow > div{padding-left:var(--gap-tool);padding-right:var(--gap-tool)}
  /* ★ 과제 340 — 반쪽 카드 표(.dl-half) 폰 = 이름 한 줄 통째 · 그 밑 「할 일」 · 담당(동그라미) · 머리줄 숨김(할 일 표와 같은 꼴) */
  .dash-host .tk-dlist .clrow.dl-half{grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"n n" "y w";row-gap:calc(var(--gap-tool) / 2)}
  .dash-host .tk-dlist .clrow.dl-half > :nth-child(1){grid-area:n} .dash-host .tk-dlist .clrow.dl-half > :nth-child(2){grid-area:y} .dash-host .tk-dlist .clrow.dl-half > :nth-child(3){grid-area:w}
  .dash-host .tk-dlist .clrow.clhead.dl-half{display:none}
  #cDashView [data-dcard="now"] .clrow.dl-half{grid-template-columns:minmax(0,1fr) auto}   /* 위 캠페인 몫 줄(id)이 이겨 세 칸으로 남았다 → 같은 무게로 두 칸 */
}

/* ══ ★ 과제 306 (10-06) — 재무(#fin) · 부품 = 할 일 Dashboard(dashGrid) · 표(.clrow) · 추이(dashTrendSlot) 그대로 · 열 폭만 ══ */
#fin .clrow{min-width:0}   /* .clrow 기본 min-width 818 를 되찾는다(인사 · 내 정보와 같은 결 · 폰 390 에서 카드가 옆으로 밀렸다) — 달별 표는 아래 폰 규칙이 따로 980 */
#fin .fin-chk .tk-drow.fin-line{grid-template-columns:150px minmax(0,1fr) 128px}
#fin .fin-chk .tk-drow.fin-line:not([data-dgo]){cursor:default}
#fin .fin-chk .tk-drow.fin-line .tk-dn{color:var(--accent);font-size:var(--fs-sm)}
#fin .tk-drow[data-dgo] .tk-dn:last-child{color:var(--accent);font-size:var(--fs-sm)}
#fin .tk-drow:not([data-dgo]){cursor:default}
#fin .fin-miss{margin:var(--gap-tile) 0 0;font-size:var(--fs-sm);color:var(--text-2)}
#fin .fin-cf{margin-top:var(--gap-tile)}
#fin .fin-cf .clrow{grid-template-columns:minmax(0,1.3fr) repeat(4,minmax(0,1fr))}
#fin .fin-cf .clrow:not(.clhead){cursor:default}
#fin .fin-cf .clrow > div.r,#fin .fin-mo-tbl .clrow > div.r,#finList .clrow > div.r{text-align:right;justify-content:flex-end;font-variant-numeric:tabular-nums}
#fin .fin-cf .clrow.clhead > div:not(:first-child),#fin .fin-mo-tbl .clrow.clhead > div:nth-child(n+2):nth-child(-n+8){justify-content:flex-end;text-align:right}
#finMonth .clrow.fin-mo > :first-child .muted{font-size:var(--fs-cap)}
#fin .fin-cf .fin-cf-past{background:var(--surface-subtle)}
#fin .late{color:var(--bad);font-weight:var(--weight-strong)}
#finMonth{padding-top:var(--gap-tool-body)}   /* ★ #finList 는 공용 margin-top 20 만(검토 미리 봄 2 — 둘 다면 도구 줄 → 첫 머리 41) */
#finList .fin-h{margin:0 0 var(--gap-tile);padding:var(--gap-tile) var(--pad-cell-x) 0;font-size:var(--fs-card)}   /* 표 틀 안 머리 = 칸과 같은 안여백 14 */
#finList .fin-h + div + .fin-h{margin-top:var(--gap-card)}
#fin h3.toolsonly .tools{flex-wrap:wrap}   /* ★ 과제 540 ③(539 ④) — 받을 돈 · 줄 돈 도구 줄 끝 요약(건수 · 합계 · 캠페인 지출 …)이 9자리 합계면 넘침 → 모자라면 요약 통째로 둘째 줄(글 줄임 ✗ · 지금처럼 닿기만 할 땐 모양 그대로) */
#finFCount{white-space:nowrap}   /* ★ 과제 540 ③ — 요약 = 한 덩어리(낱말 가운데 꺾임 ✗) */
#finList #finAp, #finList #finAr{margin-bottom:var(--gap-card)}
#finList .clrow.fin-ar{grid-template-columns:minmax(120px,1fr) minmax(146px,1.7fr) minmax(130px,0.8fr) minmax(116px,0.9fr) minmax(116px,0.9fr) 72px minmax(136px,0.9fr) 112px}   /* ★ 과제 452 — 끝 칸 = [입금 확인] · ★ 과제 537 — 1280 칸 최소 합 1002→948(캠페인 200→174 · 계산서 발행 · 입금 예정 130→116 = 534 날짜 칸 값 · 디자이너 10-27 19:08) */   /* ★ 과제 540 — 금액 110→130(9자리 「123,456,789원」 글 98.6 + 안여백 28 = 127 · 돈은 안 자름) · 캠페인 166→146(코드 온전 · 이름만 말줄임) · 합 948 · 디자이너 10-28 09:06 */   /* ★ 과제 537b — 1280 짧은 값 잘림 0 : 상태 128→136(「이번주 입금예정」 알약) · 캠페인 174→166(이름만 말줄임) · 연체 72 그대로(「121일」) · 합 948 · 디자이너 10-27 19:40 */
#finApList .clrow.fin-ap{grid-template-columns:minmax(124px,1fr) 92px minmax(166px,1.7fr) minmax(130px,0.8fr) minmax(116px,0.9fr) 72px minmax(136px,0.9fr) 112px}   /* ★ 과제 452 — 줄 돈 = 거래처 · 종류 · 지출 · 남은 지급액 · 예정 · 지남 · 상태 · [지급 완료] */   /* ★ 과제 537 — 1280 칸 최소 합 968→948(지출 200→194 · 지급 예정 130→116) */   /* ★ 과제 540 — 남은 지급액 110→130(9자리) · 지출 186→166(코드 온전 · 이름만 말줄임) · 합 948 · 디자이너 10-28 09:06 */   /* ★ 과제 537b — 거래처 120→124(「(주)포커스미디어」) · 종류 96→92 · 지출 194→186 · 상태 128→136(「이번주 지급예정」) · 합 948 · 디자이너 10-27 19:40 */
/* ★ 과제 452 — 재무 작업대 : 묶기 줄 · 묶음 머리 줄(--grp-row-bg = #mItemList 와 같은 꼴) · 이번 주 할 것 줄 · 「금요일 = ④ 마감」 한 줄 — 있는 부품(.seg · .clrow · .tk-drow · .st · .pill · button.mini) 그대로 · 칸 폭만 */
#fDashView .tk-dtwo > .card,#finMoDash .tk-dtwo > .card{margin-bottom:0}   /* ★ 과제 452 — 격자 안 카드 = 격자 틈 16 한 번(#bDashView 과제 268 정산과 같음) */
#spLedger.hint.guide{margin-top:0}   /* ★ 과제 452 — 제목 바로 아래 = 제목→첫 카드 12 한 번(제목 아래 여백과 겹쳐 24 가 됐다) */
#fin .clrow.grp{display:block;background:var(--grp-row-bg);color:var(--text-2);cursor:default}
#fin .clrow.grp b{color:var(--ink);font-weight:var(--weight-medium)}
#finApList .clrow > div.r,#finList .clrow > div.r{text-align:right;justify-content:flex-end;font-variant-numeric:tabular-nums}
#fin .fin-desk-list .tk-drow.fin-desk{grid-template-columns:minmax(0,1fr) 120px 128px max-content;cursor:default}   /* ★ 과제 510 디자이너 6 [1] — 단추 칸 = 글 폭(옛 96 = 「통장 엑셀에서 짝 찾기 →」 두 줄로 꺾여 단추 밖 · 글 줄이기 ✗ · DESIGN §12-3-4) */
#fin .fin-desk-list .tk-drow.fin-desk button{white-space:nowrap}
#fin .fin-desk-list .tk-drow.fin-desk > .tk-dn{text-align:right;font-variant-numeric:tabular-nums}
#fin .fin-desk-list .tk-drow.fin-desk > :last-child{text-align:right}
#fin .fin-desk-who{display:flex;flex-direction:column;min-width:0}
#fin .fin-desk-who > *{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#fin .fin-desk-who .muted{font-size:var(--fs-sm)}
#fin .tk-dstrip .tk-drow.fin-fri{grid-template-columns:auto minmax(0,1fr) auto;padding:var(--gap-tile) var(--pad-cell-x);margin:0;background:var(--accent-soft)}
#finMonth .fin-mo-dash{margin-top:var(--gap-card)}
#finList .clrow[data-fin],#finApList .clrow[data-fin]{cursor:pointer}
#finList .clrow > div:last-child,#finApList .clrow > div:last-child{overflow:visible;text-overflow:clip}   /* ★ 과제 452 — 끝 단추 칸 = 말줄임 없음 */
#finList .clrow.clhead.fin-ar > :is(:nth-child(3),:nth-child(6)),#finApList .clrow.clhead.fin-ap > :is(:nth-child(4),:nth-child(6)){justify-content:flex-end;text-align:right}   /* 금액 · 연체(지남) 머리 = 값과 같은 오른쪽 */
#finMonth .clrow.fin-mo{grid-template-columns:minmax(110px,0.9fr) repeat(3,minmax(112px,1fr)) 72px repeat(3,minmax(104px,0.9fr)) 104px}   /* 첫 칸 = 「9월 '26 4곳」(발주 0 = 표 아래 안내 줄 · 검토 미리 봄 1440 잘림) */
#fin .fin-todo{grid-template-columns:minmax(0,1fr) 80px 128px}
#finMonth .clrow.fin-mo:not(.clhead){cursor:default}
@media (max-width:1399px){ #finMonth .fin-mo-tbl{overflow-x:auto} #finMonth .clrow.fin-mo{min-width:1016px} }   /* ★ 과제 563 ③ — 아홉 칸(알바 지급 · 원천세 뺌 · 영업이익 더함) · 1280 = 표 상자 안 옆 굴림 */   /* 1280 = 열 열 개가 안 들어감 → 표 상자 안에서 옆으로(다른 넓은 표와 같은 결 · 화면은 안 넘침) */
#finMonth .fin-mo-now{background:var(--surface-subtle)}
#finMonth .ld-trend [data-tb]:not([data-dgo]){cursor:default}   /* 달별 추이 = 보기만(누를 곳 없음 · 숫자는 위 표) — 손가락 뗌(v331 ①) */
#finMonth .fin-note{margin:var(--gap-tile) 0 var(--gap-card);font-size:var(--fs-sm)}
#finMonth .fin-mo-trend .ld-trend{margin-top:var(--gap-tile)}
#finMonth .fin-h{margin:0;font-size:var(--fs-card)}
@media (max-width:600px){
  /* 폰 = 한 줄(이름 · 금액 · 상태) · 날짜 · 연체 = 넓은 화면 */
  #finList .clrow.fin-ar{grid-template-columns:minmax(0,1fr) 120px 96px}   /* 폰 = 이름 · 금액 · [입금 확인](칸 고정 · 연체 = 금액 빨강) · 날짜 · 상태 = 넓은 화면 */
  #finList .clrow.fin-ar > :nth-child(2), #finList .clrow.fin-ar > :nth-child(4), #finList .clrow.fin-ar > :nth-child(5), #finList .clrow.fin-ar > :nth-child(6), #finList .clrow.fin-ar > :nth-child(7){display:none}
  #finApList .clrow.fin-ap{grid-template-columns:minmax(0,1fr) 120px 96px}   /* ★ 과제 452 — 폰 = 거래처 · 남은 지급액 · [지급 완료] */
  #finApList .clrow.fin-ap > :nth-child(2), #finApList .clrow.fin-ap > :nth-child(3), #finApList .clrow.fin-ap > :nth-child(5), #finApList .clrow.fin-ap > :nth-child(6), #finApList .clrow.fin-ap > :nth-child(7){display:none}
  #fin .fin-desk-list .tk-drow.fin-desk{grid-template-columns:minmax(0,1fr) auto;row-gap:4px}   /* 폰 = 두 줄(거래처 · 코드 / 날짜 · 단추 · 450 시안 12) */
  #fin .fin-desk-list .tk-drow.fin-desk > :nth-child(1){grid-column:1;grid-row:1} #fin .fin-desk-list .tk-drow.fin-desk > :nth-child(2){grid-column:2;grid-row:1}
  #fin .fin-desk-list .tk-drow.fin-desk > :nth-child(3){grid-column:1;grid-row:2} #fin .fin-desk-list .tk-drow.fin-desk > :nth-child(4){grid-column:2;grid-row:2}   /* 칸 넷 = 이름 | 금액 / 날짜 | 단추 */
  #finMonth .fin-mo-tbl{overflow-x:auto}
  #finMonth .clrow.fin-mo{min-width:1016px}
  #fin .fin-cf .clrow{grid-template-columns:minmax(0,1fr) auto}   /* 폰 = 주 · 차액 두 칸(들어올 · 나갈 = 막대 · 넓은 화면) */
  #fin .fin-cf .clrow > :nth-child(2), #fin .fin-cf .clrow > :nth-child(3), #fin .fin-cf .clrow > :nth-child(5){display:none}
  #fin .fin-chk .tk-drow.fin-line{grid-template-columns:110px minmax(0,1fr)}
  #fin .fin-chk .tk-drow.fin-line > :nth-child(3){display:none}
  #fin .fin-todo{grid-template-columns:minmax(0,1fr) auto}
  #fin .fin-todo > :nth-child(3){display:none}   /* 폰 = 항목 · 건수(줄 누르기 = 그 화면 그대로) */
}

/* ══ ★ 과제 311 (10-06) — 계약서 화면 : 캠페인 「계약」 구획 · 광고주 계약 표 · 견적 상세 한 줄 · 부품 = 속성 줄 · 표(.clrow) · 알약 그대로 ══ */
#cContract [data-part~="act"]{margin-top:6px}
#cContract [data-part~="note"]{margin:var(--gap-tile) 0 0}
#cContract [data-part~="hist"]{margin-top:var(--gap-tile);font-size:var(--fs-sm)}
#cContract [data-part~="hist"] summary{cursor:pointer;color:var(--text-2)}
#cContract [data-part~="hrow"]{padding:4px 0}
#cContract [data-part~="nw"]{white-space:nowrap}   /* 금액 · 날짜 한 조각 = 한 줄(조각 사이에서만 꺾임) */
#advContracts .clrow{grid-template-columns:minmax(0,0.9fr) minmax(0,0.9fr) 78px minmax(116px,1fr) minmax(128px,1.1fr);min-width:0}   /* 패널 510 안 = 공급가 잘림 0(캠페인 = 코드 · 이름은 title · 서명일 = 연도 없이) · ★ 과제 523(v384 ⓗ) — 상태 = .st 점 + 글(2차 · 디자이너 ㉠) · 칸 78(점 + 두 글자 + 칸 안 여백 = 77) · 계약번호 · 캠페인 코드 잘림 0 · 옛 72 = 「보냄…」 말줄임) */
#advContracts .clrow:not(.clhead){cursor:pointer}
#advContracts .clrow > .r{text-align:right;justify-content:flex-end;font-variant-numeric:tabular-nums}
.qdet-ct{margin-top:2px}
@media (max-width:600px){
  #advContracts .clrow{grid-template-columns:minmax(0,1fr) auto}
  #advContracts .clrow > :nth-child(1), #advContracts .clrow > :nth-child(4), #advContracts .clrow > :nth-child(5){display:none}
}

  /* ══ ★★ 과제 324 (10-06 대표 「A안」 · G-230 · DESIGN §13-00-A) — 견적서 구역 = 위 입력 시트(표준 칸) + 아래 문서 미리보기(읽기 전용) ══
     시트 = 문서 밖 표준 표(§11) · 칸 36 · 본문 글자 · 문서 = 글만(입력칸 0 · qsDocMirror) · 1장도 뒷장처럼 .qd-pv 글이 보인다(위 규칙 묶음) */
  .qs-input,.qs-preview{min-width:0;max-width:100%}
  .qs-input{overflow-x:auto}   /* 좁은 폭(390 · 팝업 안 내용 칸이 좁음)에서 조건 표 최소 폭이 바깥 칸을 밀지 않게 — 카드 안에서 굴림 */
  .qs-sheet{min-width:0;max-width:100%}
  .qs-sheet .qs-sheet-tbl{overflow-x:auto;max-width:100%}   /* 좁으면 시트만 제 표 안에서 가로 굴림(표 규칙 §11) — 바깥 칸을 넓히지 않게 */
  .qs-sheet table#qsTable{width:100%;border-collapse:collapse;table-layout:auto}
  .qs-sheet table#qsTable thead th{text-align:left;font-size:var(--fs-sm);color:var(--text-2);font-weight:var(--weight-strong)}
  .qs-sheet table#qsTable td{padding:4px 6px;vertical-align:middle;font-size:var(--fs-body)}
  .qs-sheet table#qsTable input,.qs-sheet table#qsTable select{height:36px;font-size:var(--fs-body);padding:0 10px}
  /* ★ 458 디자이너 ⑧ — 견적 줄 시트 = 좁은 칸(820 팝업 · 가로 굴림 0) : 칸 안 여백 = 도구 간격 반(첫 · 끝 칸 24 · 12 표 문법은 시트에선 안 씀 — 「#」 · ✕ 칸이 44 · 37 로 부풀었다)
     · 입력 안 여백 = 도구 간격 반 · 넘치는 글 = 말줄임(매체 · 품목이 두 글자로 잘려 보이던 것) · 칸 폭은 프론트 값 그대로 */
  .qs-sheet table#qsTable :is(th,td),.qs-sheet table#qsTable :is(th,td):first-child,.qs-sheet table#qsTable :is(th,td):last-child{padding-left:calc(var(--gap-tool) / 2);padding-right:calc(var(--gap-tool) / 2)}
  .qs-sheet table#qsTable input,.qs-sheet table#qsTable select{padding-left:calc(var(--gap-tool) / 2);padding-right:calc(var(--gap-tool) / 2)}
  .qs-sheet table#qsTable input{text-overflow:ellipsis}
  .qs-sheet table#qsTable .qs-desc-sum{min-height:36px;font-size:var(--fs-body)}
  .qs-sheet-foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px 16px;padding:8px 2px 0;font-size:var(--fs-cap);color:var(--text-2)}
  .qs-sheet-sum{font-variant-numeric:tabular-nums;color:var(--text);font-weight:var(--weight-strong)}
  /* 시트의 「내용」 칸(요약 단추 · 펼치는 속칸) — 문서 팔레트(--qd-*)는 .qsdoc 안에만 있으므로 시트는 화면 토큰으로 */
  .qs-sheet td.qs-desc{min-width:200px}   /* ★ 과제 405b (기획 시안 8) — 매체 150 · 품목 130 · 수량 80 · 단위 76 · 단가 120 · 금액 100 · 나머지 = 내용(옛 280 이면 1440 에서 시트가 가로로 굴렀다) */
  .qs-sheet .qs-desc-sum{min-height:36px;padding:6px 10px;border:1px solid var(--line-input);border-radius:var(--r-ctl);
    background:var(--bg-card);color:var(--text);font-size:var(--fs-body)}
  .qs-sheet .qs-desc-sum:hover{background:var(--bg-hover);border-color:var(--line-input);color:var(--text)}
  .qs-sheet .qs-desc-sum .muted{font-size:var(--fs-sm)}
  .qs-sheet .qs-desc-chev{color:var(--text-3)}
  .qs-sheet .qs-desc-fix{font-size:var(--fs-body);color:var(--text)}
  .qs-sheet .qs-desc-edit{border-top:1px dashed var(--line);gap:6px 10px}
  .qs-sheet .qs-sub{font-size:var(--fs-cap);color:var(--text-2)}
  .qs-sheet table#qsTable .qs-sub input{width:72px;min-width:0}
  .qs-sheet table#qsTable .qs-sub-n input{width:60px;text-align:right}
  .qs-sheet table#qsTable .qs-sub-w input{width:100%}
  .qs-preview.qs-doc-shut .qd-wrap{display:none}
  /* 읽기 전용(견적서 보기 · 확정본) — 시트 · 조건 칸은 감추고 문서만(시트 줄은 qsRoFill 이 글로 채워 문서가 베낌) */
  #qComposeWrap.qs-ro #qsSheet,#qComposeWrap.qs-ro .qs-input h3 .tools{display:none}
  /* 문서 안 글 — 내용 요약 한 줄 · 결제 줄 값 · 비고(옛 인쇄 글과 같은 옷) */
  .qsdoc .qs-desc-sum{border:none;background:transparent;padding:0;font-size:inherit;display:block;white-space:normal;text-align:left;color:var(--qd-ink)}
  .qsdoc .qd-tx{color:var(--qd-ink)}
  .qsdoc .qd-notetext{font-size:12px;color:var(--qd-ink-soft);padding:6px 0;line-height:1.75;white-space:pre-line;min-height:1.75em}
  .qsdoc table#qdTable th:nth-child(9),.qsdoc table#qdTable td:nth-child(9){display:none}   /* ✕ 칸 = 시트에만 */

/* ★ 과제 350(10-08 대표 UX 점검) — 폰(≤ 768) Dashboard = **카드 한 겹** : 바깥 상자(.card ⊃ .dash-host) 테두리 · 바탕 0 · Dashboard 좌우 안여백 0
   옛 = 바깥 상자 테두리 + .tk-dash 안여백 24 + 카드 → 좌우 여백 두 배 · 카드 244px(390) · 표 칸 「C26-00」 · 「박 .」 · 관문 v398 · 할 일(#taskList)은 잣대라 안 건드림 */
/* ★ 과제 354(10-08 대표 디자인 점검) — **모든 폭**으로(옛 = 폰 ≤ 768 만 · 넓은 화면도 바깥 상자 테두리 안에 타일 · 차트 카드가 또 테두리) */
  main .card:has(> .dash-host:not([hidden])){border:0;background:transparent}   /* Dashboard 보기일 때만(List · Calendar 는 바깥 상자 그대로 · 다른 보기 = .dash-host[hidden]) */
  main .card > .dash-host:not(#_){margin-left:0;margin-right:0}   /* :not(#_) = 도구 줄 카드 공용 좌우 24(.card:has(> h3.toolsonly) > :not(…) · 무거운 고르개)를 이기려고 */
  main .dash-host .tk-dash{padding-left:0;padding-right:0}
  main .card:has(> .dash-host:not([hidden])) > h3.toolsonly{padding-left:0;padding-right:0}   /* 도구 줄도 카드와 같은 왼쪽 줄 */
  /* ★ 과제 354 — 할 일 화면(#taskBox · 잣대)도 같은 한 겹 : Dashboard(.tk-dash)가 보일 때만 · 다른 화면과 같은 자(관문 v361 ⓒ) · TK_WARN = 대표 컨펌 범위 */
  #taskBox:has(> #taskList > .tk-dash){border:0;background:transparent}
  #taskBox:has(> #taskList > .tk-dash) > #taskList{margin-left:0;margin-right:0}
  #taskBox .tk-dash{padding-left:0;padding-right:0}
  #taskBox:has(> #taskList > .tk-dash) > #tkTools:not(#_){padding-left:0;padding-right:0}   /* 할 일 도구 줄(#tkTools) = 다른 화면 h3.toolsonly 와 같은 자 · :not(#_) = 공용 좌우 24 규칙을 이기려고 */

/* ══ ★★ 과제 364 (판매매체 대개편 2단계 · 사양 §5-1~5-3) — 3단 고르기 + 시트 상태 줄 + 매체정보 카드 ══ */
#mWrap.mo > #mNav{display:none}   /* 옛 목차 = DOM 을 남기고 숨김(id 보존) — 자료(상품 줄)가 있을 때만 */
#mWrap.mo-off #mHead, #mWrap.mo-off #mItemCard, #mWrap.mo-off #mDetailWrap, #mWrap.mo-off #mDashView{display:none !important}   /* 상품 있는 매체 = 카드(옛 품목 · 학교 화면은 「품목 보기」) */
.mo-bar{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:12px}
.mo-bar[hidden],.mo-sheet[hidden]{display:none}
.mo-steps{display:flex;align-items:center;gap:6px;flex-wrap:wrap;min-width:0}
.mo-step{display:inline-flex;align-items:center;gap:6px;min-height:32px;padding:0 12px;border:1px solid var(--line);border-radius:var(--r-ctl);background:var(--bg-card);color:var(--text);font-size:var(--fs-body);max-width:320px;overflow:hidden;white-space:nowrap}
.mo-step b{font-weight:var(--weight-medium);overflow:hidden;text-overflow:ellipsis}
.mo-step:hover:not(:disabled){background:var(--bg-hover)}
.mo-step:disabled{color:var(--text-3)}
.mo-caret,.mo-sep{color:var(--text-3)}
.mo-sheet{display:flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:var(--fs-sm);color:var(--text-2)}
.mo-sline{display:inline-flex;align-items:center;gap:6px}
.mo-dot{display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--text-3);flex:none}
.mo-dot.fresh{background:var(--ok)}.mo-dot.aging{background:var(--warn)}.mo-dot.stale{background:var(--bad)}.mo-dot.dead{background:var(--text)}.mo-dot.busy{background:var(--accent)}
.mo-st{display:inline-flex;align-items:center;gap:5px}
#moPanel .mo-hd{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:6px}
#moPanel .mo-hd h3{margin:0}
.mo-meta{display:flex;flex-wrap:wrap;gap:6px 18px;font-size:var(--fs-sm);color:var(--text-2);margin-bottom:12px}
.mo-old{font-size:var(--fs-cap)}
.mo-need{color:var(--bad);font-weight:var(--weight-medium)}   /* 비었는데 채워야 하는 칸 = 「확인 필요」 (Q-2 ⓑ · 저장은 안 막음) */
.mo-links{display:flex;gap:8px;flex-wrap:wrap;margin:12px 0 8px}
.mo-note{font-size:var(--fs-sm);color:var(--text-2)}
a.btnlike{display:inline-flex;align-items:center;min-height:32px;padding:0 12px;border:1px solid var(--line);border-radius:var(--r-ctl);background:var(--bg-card);color:var(--text);text-decoration:none;font-size:var(--fs-sm)}
a.btnlike:hover{background:var(--bg-hover)}
/* ★ 과제 454 (팝업 흡수 A) — 매체정보 수정 팝업 안 = 접두어 0 : 메모 칸 = 공용 .cdprops.asform(이름 왼쪽 · 상자 오른쪽 · 도움말 · 목록은 상자 열) · 메모 줄 · 경로 줄 = 이 팝업 id 규칙(값은 옛 .mo-memo-box · .mo-memo · .moe-row 그대로) */
#moEditWrap [data-part="memo"]{margin-top:16px}
#moEditWrap [data-part="memo"] textarea{width:100%;box-sizing:border-box;margin:0}
#moMemoList [data-part="memo"]{padding:8px 0;border-top:1px solid var(--line-soft);font-size:var(--fs-sm)}
#moMemoList [data-part="memo"] div{white-space:pre-wrap;color:var(--text);margin-top:2px}
#moEditBody [data-part="sep"]{color:var(--text-3)}   /* ★ 과제 467 — 경로 줄(path · sp) 지움 = 「분류」 읽기 상자로(공용 .cdprops.dtform) · 구분 › 색만 남김 */
#moEditBody > .hint[data-part="retired"]{margin:0 0 var(--gap-group)}   /* ★ 과제 557 ② 디자인수정 1(디자이너) — 거래 중단 안내 줄 ↔ 「분류」 줄 32(옛 = .pnl-body .hint 6 0 0 → 3px) */
.pnl-foot > #moDelete:not([hidden]){margin-left:0;margin-right:auto}   /* ★ 과제 576 ② 디자인수정 1(디자이너 4) — [삭제] 는 흐림(aria-disabled · .danger 뗌)일 때도 발 맨 왼쪽 홀로(옛 = .pnl-foot>button.danger 만 밀어 흐리면 오른쪽 묶음으로 튐 · 511 #cPONew 꼴 · 값 없음) */
#odAdjWrap > .hint{margin:0 0 var(--gap-group)}   /* ★ 과제 573 ③-a — 현장 조정 안내 줄 ↔ 「승인 대행」 줄 = 557 ② 와 같은 값(시안 1) */
@media (max-width:600px){ #odUnivList .clrow > [data-k="qty"] .muted{display:none} }   /* ★ 과제 573 ③-a — 좁은 칸 = 현장 값만(견적 값 = 칸 title · 시안 ★A) */
#moEditMore > details,#olMore{margin-top:12px}
#moEditMore > details > summary,#olMore > summary{cursor:pointer;color:var(--accent);font-size:var(--fs-sm)}
@media (max-width:760px){ .mo-bar{align-items:flex-start} .mo-step{max-width:100%} }
/* ★ 과제 370 — 판매 매체 위쪽 = 대표 PPT 1 · 2 · 4장 : 고르기 세 칸(고른 상품 = 옅은 파랑 알약) + [불러오기](검정 주 행동) · 누르기 전 빈 화면 · 매체정보 머리 한 줄 + 상자 한 줄 · 수정 팝업 머리 */
#media.mo-card > p.sub{display:none}
.mo-bar .mo-steps{flex:1 1 auto}
.mo-step b{font-weight:var(--weight-body)}
.mo-bar .mo-step:not(.cur){border-color:transparent;background:none}   /* PPT 1장 = 대분류 · 매체는 글만(▾) · 고른 상품만 알약 */
.mo-step.cur{background:var(--accent-soft);border-color:transparent}   /* 알약 모양 = 앱의 알약과 같은 --r-ctl(새 둥근값 발명 ✗) */
.mo-step.cur:hover:not(:disabled){background:var(--bg-active)}
#moSync{margin-left:8px}
.mo-sp{flex:1 1 auto}
#moPanel .mo-hd{display:flex;align-items:center;justify-content:flex-start;flex-wrap:wrap;gap:6px 12px;margin-bottom:10px}
#moPanel .mo-hd .mo-meta{display:flex;flex-wrap:wrap;gap:4px 18px;margin:0;font-size:var(--fs-sm);color:var(--text)}
.mo-link{color:var(--accent);font-size:var(--fs-sm);text-decoration:none}
.mo-link:hover{text-decoration:underline}
.mo-box{display:flex;flex-wrap:wrap;gap:8px 40px;align-items:center;justify-content:space-between;padding:16px 20px;border:1px solid var(--line);border-radius:var(--r-card)}
.mo-it{white-space:nowrap;font-size:var(--fs-body);color:var(--text)}
.mo-il{color:var(--text)}
/* ★ 과제 454 — 옛 .moe-hd · .moe-t · .moe-name · .moe-row · .moe-meta · .moe-ml · .moe-mv · .moe-fields(매체정보 수정 · 단지 · 열 관리 · 맞추기 팝업 머리 묶음 · 칸 그리드)는 지움 :
   머리 묶음 = 세부정보 한 줄(.pnl-sum · panelSummary) · 칸 그리드 = app.css 「과제 440」 .pstd .cdprops 규칙(같은 값) · .moe-more 도 지움(알바 등록 = 448b 가 #vAlbaMore id 규칙으로 · 쓰는 곳 0) */
@media (max-width:760px){ .mo-box{flex-direction:column;align-items:flex-start;gap:6px} .mo-it{white-space:normal} }
/* ★ 과제 411b — 판매매체 ↔ 거래처 잇기(시안 화면그리기/그림_261016/과제411b_시안_* · DESIGN §12-3-2 끝 줄) · 새 색 0 · 토큰만 · 그림자 0(짧은 목록 = 공용 .umenu)
   상자 = 두 줄(위 = 매체 정보 다섯 그대로 · 아래 = 돈 받을 곳 + 대표 · 재무 단추) · 칩 = 공용 .pill(ok · dim · warn · bad) · 거름 = 고르기 줄 오른쪽 ghost mini 셋 */
.mo-box.mo-vbox{flex-direction:column;align-items:stretch;gap:12px}
.mo-vrow{display:flex;flex-wrap:wrap;gap:8px 40px;align-items:center;justify-content:space-between;min-width:0}
.mo-vrow.mo-money{justify-content:flex-start;gap:8px 28px;border-top:1px solid var(--line-soft);padding-top:12px}
.mo-vrow .pill,.mo-vrow .mo-link{white-space:nowrap}
.mo-mh{font-weight:var(--weight-medium)}
.mo-vbtns{display:inline-flex;flex-wrap:wrap;gap:8px;margin-left:auto}
.mo-vf{display:inline-flex;align-items:center;gap:6px;flex-wrap:wrap}
.mo-vfl{font-size:var(--fs-sm);color:var(--text-2)}
.mo-vf button[aria-expanded="true"]{background:var(--bg-active);border-color:var(--accent);color:var(--accent)}   /* 연 동안 = 켜짐 옷(할 일 토글 · §1 파랑 = 가리키는 것) */
.mo-vit{display:inline-flex;align-items:center;gap:6px;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.umenu .mo-vfoot{border-top:1px solid var(--line-soft);padding:8px 10px 6px;font-size:var(--fs-sm);color:var(--text-2)}
@media (max-width:760px){ .mo-box.mo-vbox{align-items:stretch} .mo-vrow,.mo-vrow.mo-money{flex-direction:column;align-items:flex-start;gap:6px} .mo-vbtns{margin-left:0} .mo-vrow .mo-it{white-space:normal} .mo-vrow .pill,.mo-vrow .mo-link{white-space:nowrap} }
/* 거래처 상세 820 두 단(캠페인 상세 #campSide .grid2 와 같은 꼴) · 운영매체 · 집행내역 표 = 줄 한 줄(꺾임 ✗) */
#vendViewBody .vs-two{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;align-items:start}
#vendViewBody .vs-col{display:flex;flex-direction:column;gap:16px;min-width:0}
#vendViewBody .vs-col > .viewsec{margin-top:0}
#vendViewBody .vs-media,#vendViewBody .vs-spend,#vendViewBody .vs-memo{margin-top:var(--gap-group)}   /* ★ 과제 568 — 옛 16 */
#vendViewBody .viewsec[hidden]{display:none}
#vendViewBody .viewsec{margin-top:var(--gap-group)}   /* ★ 과제 568 — 옛 16 ·  ★ 과제 489 2차(디자이너 10 [1]) — 한 단 구역 사이 = 광고주 · 상담 상세와 같은 값(#advViewBody · #leadViewBody .viewsec) */
#vendViewBody .viewsec:first-child{margin-top:0}
#vendViewBody .viewsec>.pnl-sect{margin-bottom:var(--gap-tool)}   /* ★ 과제 568 — 머리 → 첫 줄(옛 4) */
#vendViewBody .vs-note{font-size:var(--fs-sm);font-weight:var(--weight-body);margin-left:8px}
#vendViewBody .vs-hint{margin:0 0 8px;font-size:var(--fs-sm);color:var(--text-2)}   /* 칸 밑 한 줄 도움말(막대 없음 · 작은 회색 · §12 ⓔ) */
#vendViewBody .vs-tbl{width:100%}
#vendViewBody .vs-tbl th,#vendViewBody .vs-tbl td{white-space:nowrap}
#vendViewBody .vs-tbl .num{text-align:right}
#vendViewBody .vs-tbl .vs-ell{max-width:200px;overflow:hidden;text-overflow:ellipsis}
#vendViewBody .vs-tbl tfoot td{font-weight:var(--weight-medium);border-bottom:0}
#vendViewBody #vendOps tbody tr{cursor:pointer}
#vendViewBody #vendOps tbody tr:hover{background:var(--bg-hover)}
#vendViewBody #vendOps tbody tr:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--accent)}
#vendViewBody .vs-row2{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-top:8px;flex-wrap:wrap}
#vendViewBody .vs-row2 .vs-hint{margin:0}
#vendViewBody #vendOps,#vendViewBody #vendSpend{overflow-x:auto}
@media (max-width:760px){ #vendViewBody .vs-two{grid-template-columns:minmax(0,1fr)} }
/* ★ 과제 360 — 추이 범례의 「속 빈 점」 견본(건수가 적어 참고만) */
.ld-legend .hol{display:inline-block;width:8px;height:8px;border-radius:50%;border:1.5px solid var(--ok);background:var(--bg-card);box-sizing:border-box;margin-right:5px}
/* ★ 과제 359 — 홈 「돈 알림」 작은 카드 : 제목 한 줄 + 알약 · 단추 한 줄(제목 없이 타일과 카드 사이에 떠 있던 줄을 묶음) */
.hmoney h3{margin:0 0 8px}
.hmoney .hm-row{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
/* ★ 과제 352 — 캠페인 상세 안 「발주 · 지출」 표 : 세 칸 · 칸 밖 넘침 0 · 한 칸 두 줄 안(코드 · 거래처 = 항목 밑 작은 줄 · 지급일 = 알약 밑 작은 줄) */
#cPOs table{table-layout:fixed;width:100%}
#cPOs th:nth-child(2), #cPOs td:nth-child(2){width:92px;text-align:right;white-space:nowrap}
#cPOs th:nth-child(3), #cPOs td:nth-child(3){width:108px}
#cPOs td{vertical-align:top;overflow:hidden}
#cPOs [data-part~="t"], #cPOs [data-part~="sub"]{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
#cPOs [data-part~="sub"]{font-size:var(--fs-cap);color:var(--text-2)}
#cQuotes table{table-layout:fixed;width:100%}
#cQuotes th:nth-child(2), #cQuotes td:nth-child(2){width:104px;text-align:right;white-space:nowrap}
#cQuotes th:nth-child(3), #cQuotes td:nth-child(3){width:96px}
#cQuotes td{vertical-align:top;overflow:hidden}
#cQuotes [data-part~="t"], #cQuotes [data-part~="sub"]{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
#cQuotes [data-part~="sub"]{font-size:var(--fs-cap);color:var(--text-2)}
/* ★ 과제 366 — 매체사 리스트(DESIGN §11-3-06 · 10-12 대표 「PPT 그대로」 = PPT 2 · 3장) : 머리(업로드일 · 이전 판) · 노란 띠 · 넓은 필터 칸 + 다운로드 · 진짜 table(열 수가 시트마다 달라 .clrow 못 씀 = §11-5 허용 예외) · 열 제목 메뉴(PPT 3장) */
#moList[hidden]{display:none}
.ml-hd{display:flex;align-items:baseline;flex-wrap:wrap;gap:4px 16px;margin-bottom:10px}
.ml-hd h3{margin:0}
.ml-up{font-size:var(--fs-sm);color:var(--text)}
.ml-sp{flex:1 1 auto}
.ml-count{font-size:var(--fs-sm)}
.ml-link{background:none;border:0;box-shadow:none;padding:0;height:auto;min-height:0;color:var(--accent);font-size:var(--fs-sm);cursor:pointer}
.ml-link:hover{text-decoration:underline;background:none}
.ml-band{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:8px 12px;margin-bottom:8px;border-radius:var(--r-ctl);font-size:var(--fs-sm)}
.ml-band > span:not(.mo-dot):not(.ml-sp){flex:1 1 0;min-width:0}   /* 글이 남는 폭 — 점이 혼자 윗줄로 꺾이지 않게(390) */
.ml-band.warn{background:var(--warn-bg);color:var(--warn)}
.ml-tools{display:flex;align-items:center;gap:8px;margin-bottom:8px}
.ml-qwrap{position:relative;flex:1 1 auto;min-width:0;display:flex;align-items:center}
.ml-qwrap .ml-ico{position:absolute;left:12px;color:var(--text-3);pointer-events:none}
.ml-q{width:100%;min-width:0;padding-left:36px}
.ml-dl{display:inline-flex;align-items:center;gap:6px;flex:0 0 auto;height:32px}
.ml-ico{flex:0 0 auto}
#moList .tablewrap{overflow:auto;max-height:70vh;max-width:100%;border-top:1px solid var(--line)}
.ml-table{margin-top:0;width:100%;border-collapse:separate;border-spacing:0}
.ml-table th{position:sticky;top:0;z-index:1;background:var(--bg-card);padding:0;border-bottom:1px solid var(--line);text-align:left;font-size:var(--fs-cap);color:var(--text-2);font-weight:var(--weight-medium);white-space:nowrap}
.ml-table td{height:36px;padding:0 10px;border-bottom:1px solid var(--line);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:260px;font-size:var(--fs-body);color:var(--text)}
.ml-table td.num, .ml-table th.num{text-align:right}
.ml-table td.ml-name, .ml-table th.ml-name{width:100%;max-width:none;min-width:160px}
.ml-table tbody tr{cursor:pointer}
.ml-table tbody tr:hover{background:var(--bg-hover)}
.ml-table tbody tr:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--accent)}
.cm-th{display:flex;align-items:center;gap:4px;width:100%;min-height:32px;padding:0 8px 0 10px;border:0;background:none;box-shadow:none;border-radius:0;font:inherit;color:inherit;cursor:pointer;white-space:nowrap}
.cm-th:hover{background:var(--bg-hover)}
.cm-th:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--accent)}
.cm-th .cm-tl{overflow:hidden;text-overflow:ellipsis;flex:1 1 auto;text-align:left}
.ml-table th.num .cm-tl{text-align:right}
.cm-th .cm-mk{flex:0 0 auto;display:inline-flex;color:var(--text-3);font-size:var(--fs-cap)}
.cm-th .cm-mk.on{color:var(--accent)}
/* ★ 과제 429 ⑥ (10-18 점검 A7) — 표 머리 아이콘 숲(리스트 담기 · 판매 매체 · 당사 리스트 열마다 깔때기 + ⇅) → **필요할 때만** :
   기본 = 숨김(visibility = 폭 그대로 · 머리 글이 들썩이지 않음) · 머리 hover · 초점(:focus-within · 키보드 Tab) · 정렬된 열(.sorted) · 거르기 걸린 열(.on) = 보임.
   폰 = 칸 전체가 단추라 누르면 메뉴 그대로(아이콘은 안내일 뿐). 관문 = v451 ⓐ⑥. */
.ml-table .cm-th .cm-mk{visibility:hidden}
.ml-table .cm-th:hover .cm-mk,.ml-table th:focus-within .cm-mk,.ml-table .cm-th.sorted .cm-mk,.ml-table .cm-th.on .cm-mk,.ml-table .cm-th .cm-mk.on{visibility:visible}
.cm-th.on, .cm-th.sorted{color:var(--accent)}
.ml-foot{padding-top:8px}
/* 열 제목 메뉴 = PPT 3장 : 왼쪽 열 고르기 목록 · 오른쪽 정렬 · 조건 넷 · 값 · 취소 · 확인 */
.umenu.colmenu{display:flex;gap:8px;max-height:none;overflow:visible;padding:8px}
.colmenu .cm-left{flex:0 0 150px;min-width:0;display:flex;flex-direction:column;gap:4px}
.colmenu .cm-cur{display:flex;align-items:center;justify-content:space-between;height:28px;padding:0 8px;border:1px solid var(--line);border-radius:var(--r-inner);font-size:var(--fs-cap)}
.colmenu .cm-cur span:first-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.colmenu .cm-car{color:var(--text-3)}
.colmenu .cm-cols{max-height:220px;overflow-y:auto;border-radius:var(--r-inner);outline:none}
.colmenu .cm-cols:focus-visible{box-shadow:var(--ring)}
.colmenu .cm-col{min-height:26px;display:flex;align-items:center;padding:0 8px;border-radius:var(--r-inner);font-size:var(--fs-cap);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.colmenu .cm-col:hover{background:var(--bg-hover)}
.colmenu .cm-col.sel{background:var(--bg-active);color:var(--accent)}
.colmenu .cm-col.on::after{content:"·";margin-left:4px;color:var(--accent)}
.colmenu .cm-side{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:8px}
.colmenu .cm-sort{display:flex;gap:6px}
.colmenu .cm-sort .on{color:var(--accent);border-color:var(--accent)}
.colmenu .cm-ops{display:grid;grid-template-columns:1fr 1fr;gap:4px 8px}
.colmenu .cm-op{display:inline-flex;align-items:center;justify-content:flex-start;gap:6px;font-size:var(--fs-cap);cursor:pointer;white-space:nowrap}
.colmenu .cm-op input{margin:0;padding:0;width:auto;height:auto;flex:0 0 auto;accent-color:var(--accent)}
.colmenu .cm-v{width:100%;box-sizing:border-box}
.colmenu .cm-ex{border-top:1px solid var(--line-soft);padding-top:6px}
.colmenu .cm-foot{display:flex;gap:6px;justify-content:flex-end}
/* ★ 과제 454 (팝업 흡수 A) — 판 기록 팝업 안 = 접두어 0 : 표 · 「+n −n」 글 단추 = 이 팝업 id 규칙(값은 옛 .ml-hist · .ml-link 그대로) */
#mlHistBody [data-part="hist"]{width:100%;font-size:var(--fs-sm)}
#mlHistBody [data-part="hist"] td,#mlHistBody [data-part="hist"] th{padding:6px 4px;border-bottom:1px solid var(--line-soft);text-align:left}
#mlHistBody [data-part="hist"] .num{text-align:right}
#mlHistBody [data-part="hist"] button{white-space:nowrap}
#mlHistBody button[data-act="diff"]{background:none;border:0;box-shadow:none;padding:0;height:auto;min-height:0;color:var(--accent);font-size:var(--fs-sm);cursor:pointer}
#mlHistBody button[data-act="diff"]:hover{text-decoration:underline;background:none}
.ml-dl-list{margin:4px 0 12px;padding-left:18px;font-size:var(--fs-sm)}
.ml-dl-list li{padding:2px 0}
@media (max-width:760px){ .ml-table td.ml-name, .ml-table th.ml-name{width:auto} .colmenu .cm-left{flex-basis:120px} }
/* ══ ★ 과제 367b — 당사 관리 리스트(PPT 5 · 6 · 7장) : 366 옷(.ml-table · .cm-th · .ml-tools)을 그대로 쓰고 다른 것만 여기 ══ */
#olList[hidden]{display:none}
#olList .tablewrap{overflow:auto;max-height:70vh;max-width:100%;border-top:1px solid var(--line)}
.ol-hd .ol-meta{display:flex;flex-wrap:wrap;gap:4px 18px;font-size:var(--fs-sm);color:var(--text)}   /* 매체코드 · 업데이트일 · 최종수정자 = 매체정보 머리와 같은 글 */
.ol-hd .ol-mode{font-size:var(--fs-cap)}                                                                /* PPT 6 — 수정중일 때 「리스트」 옆 작은 「수정」 알약(경고색 토큰) */
.ol-hd .ol-mode[hidden]{display:none}
.ol-edit{flex:0 0 auto;height:32px;min-width:72px}
.ol-edit.on{background:var(--fill-editing);color:var(--fill-editing-ink);border-color:var(--fill-editing);font-weight:var(--weight-medium)}   /* [수정중] = PPT 그대로 주황 채움(10-13 대표 결정 ① · 토큰 --fill-editing 이 단추에만) */
.ol-edit.on:hover{background:var(--fill-editing-hover);border-color:var(--fill-editing-hover)}
/* ★ 과제 454 (팝업 흡수 A) — 단지 팝업 안 = 접두어 0 : 칸 + 단위 = 이 팝업 id 규칙(값은 옛 .ol-fv · .ol-unit 그대로) · 칸 그리드 · 읽기 값(회색 상자 §12) = 「과제 440」 .pstd 규칙 */
#olRowBody [data-part="fv"]{display:flex;align-items:center;gap:8px;min-width:0}            /* ④ 칸 + 단위 */
#olRowBody [data-part="fv"] > input,#olRowBody [data-part="fv"] > select{flex:1 1 auto;min-width:0}
#olRowBody [data-part="unit"]{flex:0 0 auto;color:var(--text-3);font-size:var(--fs-sm)}         /* 세대 · 장 · 일(칸 뒤 회색 글 · 값은 숫자 그대로) */
.ol-name{font-size:inherit;text-align:left}                                                            /* 수정중 = 단지명이 파란 링크(가리키는 것 = --accent · G-268) */
.ol-table tr.ol-miss td{color:var(--text-3)}                                                            /* 「시트에 없음」 줄 = 회색 글 + 작은 알약 */
.ol-miss-pill{margin-left:6px;font-size:var(--fs-cap)}
#olConf > [data-part="band"]{margin-top:12px}   /* ★ 과제 454 — 충돌 띠(옛 .ol-conf · .ol-conf-btns) */
#olConf > .btns{justify-content:flex-start}
/* 팝업 안 노란 띠(시트에서 사라진 줄 · 은퇴 · 충돌 — 옛 .ml-band.warn + .mo-dot 를 이 팝업 id 규칙으로 · 값 그대로 · 본문 띠 .ml-band 는 그대로) */
#olRowBody [data-part="band"]{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:8px 12px;margin:0 0 12px;border-radius:var(--r-ctl);font-size:var(--fs-sm);background:var(--warn-bg);color:var(--warn)}
#olRowBody [data-part="band"] > span:not([data-dot]){flex:1 1 0;min-width:0}
#olRowBody [data-dot]{display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--text-3);flex:none}
#olRowBody [data-dot="aging"]{background:var(--warn)}
#olRowBody [data-dot="stale"]{background:var(--bad)}
#olRowWrap > .btns{margin-top:16px}
/* ══ ★ 과제 367c — 안 그려진 자리(기획 시안 1 ~ 7 · 토큰만 · 새 값 0) ══ */
#olRowRetire[hidden],#olNewBtn[hidden],#olRetTgl[hidden]{display:none}                                   /* 발 · 도구 줄 단추 옷이 display 를 정해 hidden 이 안 먹던 것 */
.ml-band > .ol-band-btn{flex:0 0 auto;margin-left:auto;background:var(--bg-card)}                         /* 띠 안 오른쪽 단추([열 관리] · [확인하고 맞추기]) */
.ol-table tr.ol-off td{color:var(--text-3)}                                                              /* 지정게시대 미운영 · 상업광고불가 = 줄 흐리게(알약은 그대로) */
.ol-ret.on{background:var(--bg-hover);color:var(--ink)}                                                  /* 「은퇴만」 보기 켬 */
/* ★ 과제 454 — 팝업 안 묶음 머리(옛 .ol-grp) = 공용 구역 제목 .pnl-sect(+ 덧말 .cnt) · 신청 사이트 값 줄 · 열 관리 줄 · 맞추기 표 = 그 팝업 id 규칙(값은 옛 .ol-site · .ol-colrow · .ol-many 그대로) */
#olRowBody [data-part="site"]{display:flex;flex-wrap:nowrap;align-items:center;gap:8px;min-width:0}   /* 390 에서도 값 · [보기] · [복사] 한 줄 */
#olRowBody [data-part="site"] > [data-part="site-v"],#olRowBody [data-part="site"] > [data-part="mask"]{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#olRowBody [data-part="site"] > button,#olRowBody [data-part="site"] > a{flex:0 0 auto}
#olRowBody [data-part="mask"]{letter-spacing:.1em}
#olColsBody [data-part="colrow"]{display:flex;align-items:center;flex-wrap:wrap;gap:8px;min-width:0}
#olColsBody [data-part="colrow"] > .seg{flex:0 0 auto}
#olColsBody [data-part="colrow"] > select{flex:1 1 160px;min-width:0}
#olManyBody [data-part="many"]{margin-top:0;width:100%;border-collapse:separate;border-spacing:0}
#olManyBody [data-part="many"] th{position:sticky;top:0;z-index:1;background:var(--bg-card);padding:0 10px;height:32px;border-bottom:1px solid var(--line);text-align:left;font-size:var(--fs-cap);color:var(--text-2);font-weight:var(--weight-medium);white-space:nowrap}
#olManyBody [data-part="many"] td{height:36px;padding:0 10px;border-bottom:1px solid var(--line);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:260px;font-size:var(--fs-body);color:var(--text)}
#olManyBody [data-part="miss"]{font-size:var(--fs-sm);color:var(--text-2);line-height:1.6}

/* ══ ★★ 과제 378a (10-13 대표 「나머지 페이지 팝업창도 이 기준으로 모두 — 제목 크게 · 그 아래 세부정보 · 그 아래 좌측 항목명 우측 내용 박스로」
      → 기획 시안 「좋아 · 전부 적용」 · 정본 = 화면그리기/그림_261013/팝업표준_시안_전후.png) — **팝업 표준 한 벌** · DESIGN §12-0000
   켜는 길 = core.js panelTitle(name, 큰 제목, 머리 글) 하나 → 그 팝업 aside 에 .pstd (378a = 영업 · 378b = 나머지 · 안 부른 팝업 = 옛 옷 그대로)
   위에서 아래로 : 머리 띠(팝업 종류 · 그대로) → ⓐ 큰 제목 .pnl-title(--fs-title) → ⓑ 세부정보 한 줄 .pnl-sum(회색 면 없이 글줄) → 가는 선 →
   ⓒ 칸 = **한 줄에 하나 · 왼쪽 항목명(--pk-w · 보통 굵기 · 본문색) · 오른쪽 내용 상자** · 여러 줄 글 = 항목명 위 맞춤 · 도움말 = 상자 아래(이름 열 비움)
   ⓓ **읽기만 하는 값 = 옅은 회색 상자**(--bg-hover 면 · --line 테두리 · 32) — 과제 353 「읽기 값 = 상자 없음」(§11-3-04)을 **팝업에서** 뒤집음(대표 10-13)
   ⚠ 팝업 아닌 오른쪽 상세(P4 · #leadMD · #advMD · #campSide)는 범위 밖 — 규칙은 전부 aside.slideover.pstd 안에서만 · 새 색 0(토큰만) */
.slideover .pnl-title{flex-shrink:0;padding:var(--gap-tool-body) var(--pad-pop-x) 4px;font-size:var(--fs-title);font-weight:var(--weight-strong);
    line-height:1.3;letter-spacing:-.01em;color:var(--ink);overflow-wrap:anywhere;background:var(--bg-card)}
.slideover .pnl-title[hidden]{display:none}
.slideover .pnl-title .pill{vertical-align:middle;margin-left:4px}
.slideover.pstd .pnl-title:not(:has(+ .pnl-sum:not([hidden]))){padding-bottom:var(--gap-field);border-bottom:1px solid var(--line)}   /* 세부정보가 없으면 선은 제목 밑 */
.slideover.pstd .pnl-sum{background:var(--bg-card);padding:2px var(--pad-pop-x) var(--gap-field);border-bottom:1px solid var(--line)}
/* ⓒ 칸 = 한 줄에 하나 · 왼쪽 이름 · 오른쪽 상자 (적는 칸 asform · 읽는 칸 dtform 같은 옷) */
.slideover.pstd .cdprops.asform,.slideover.pstd .cdprops.dtform{grid-template-columns:minmax(0,1fr);gap:10px}
.slideover.pstd .cdprops.asform .cdprop,.slideover.pstd .cdprops.dtform .cdprop{display:grid;grid-template-columns:var(--pk-w) minmax(0,1fr);
    align-items:center;column-gap:12px;row-gap:4px}
.slideover.pstd .cdprops.asform .cdprop > .pk,.slideover.pstd .cdprops.dtform .cdprop > .pk{grid-column:1;font-weight:var(--weight-body);color:var(--text);overflow-wrap:anywhere}
.slideover.pstd .cdprops.asform .cdprop > :not(.pk),.slideover.pstd .cdprops.dtform .cdprop > :not(.pk){grid-column:2}
.slideover.pstd .cdprops.asform .cdprop:has(> textarea),.slideover.pstd .cdprops.dtform .cdprop:has(> .pv[data-t="multiline"]){align-items:start}
.slideover.pstd .cdprops.asform .cdprop:has(> textarea) > .pk,.slideover.pstd .cdprops.dtform .cdprop:has(> .pv[data-t="multiline"]) > .pk{padding-top:8px}
.slideover.pstd .cdprops.asform > .pfhelp,.slideover.pstd .cdprops.asform > .hint{padding-left:calc(var(--pk-w) + 12px)}   /* 칸 밖 도움말 줄도 상자 밑에 맞춤 */
/* ⓓ 읽기 값 = 옅은 회색 상자 */
.slideover.pstd .cdprops.dtform .cdprop > .pv:not(.editable),
.slideover.pstd .cdprops.asform .cdprop > .pv:not(.pf-v):not(.editable){min-height:32px;display:flex;align-items:center;gap:6px;box-sizing:border-box;
    padding:4px 10px;border:1px solid var(--line);border-radius:var(--r-ctl);background-color:var(--bg-hover);color:var(--ink);font-size:var(--fs-body)}
/* ⑤ 광고주 「담당자 내용」 되풀이 칸 = ★ 378b(10-14 14:5x 대표 「B 로 해」 · 그림 과제378b_광고주담당자_B_두칸.png) **두 칸** : 한 사람 = 「담당자명 | 담당자 번호」 / 「담당자 메일 | 직책」 두 줄 ·
   칸마다 왼쪽 이름(--pk-w2 76) · 오른쪽 상자 · 줄 단추(등록 · 대표로 · 삭제)는 그대로 · 390 = 한 칸으로 */
.slideover.pstd #advFormCard .contact-row{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:10px var(--gap-field-x)}
.slideover.pstd #advFormCard .contact-row > div:not(.acts){display:grid;grid-template-columns:var(--pk-w2) minmax(0,1fr);align-items:center;column-gap:12px}
.slideover.pstd #advFormCard .contact-row > div:not(.acts) > label{margin:0;font-size:var(--fs-sm);font-weight:var(--weight-body);color:var(--text)}
.slideover.pstd #advFormCard .contact-row > .acts{grid-column:1 / -1}
@media (max-width:600px){ .slideover.pstd #advFormCard .contact-row{grid-template-columns:minmax(0,1fr)} }
/* ★ 과제 378b — 나머지 팝업의 폼 꼴 셋도 같은 옷(마크업 · id 그대로) :
   ⓐ 맨몸 .asform(label + 칸 짝 — 새 품목 · 새 매체 · 급여 수정) ⓑ .row > div(label 위 — 공휴일 관리) ⓒ 이름 열 96 이던 둘(매체정보 수정 .moe-fields · 당사 리스트 줄 .ol-fields) = --pk-w
   ⓓ 몸 안에 제 큰 이름(.moe-name)을 그리던 둘(매체정보 수정 · 단지 팝업)은 큰 제목이 그 자리를 맡으니 몸 안 이름은 숨김
   ★ 과제 454 — ⓒ ⓓ 의 두 줄은 지움 : 그 팝업들이 공용 .cdprops(「과제 440」 .pstd 규칙 = --pk-w)를 입고 몸 안 큰 이름을 더 그리지 않는다(접두어 0 · v460) */
.slideover.pstd .pnl-body .asform:not(.cdprops){display:grid;grid-template-columns:var(--pk-w) minmax(0,1fr);align-items:center;column-gap:12px;row-gap:10px}
.slideover.pstd .pnl-body .asform:not(.cdprops) > label{margin:0;font-size:var(--fs-sm);font-weight:var(--weight-body);color:var(--text)}
.slideover.pstd .pnl-body .asform:not(.cdprops) > .hint,.slideover.pstd .pnl-body .asform:not(.cdprops) > .pfhelp{grid-column:2;margin:0}
.slideover.pstd.modal:not([data-panel="qcompose"]) .pnl-body .row{display:grid;grid-template-columns:minmax(0,1fr);gap:10px}
.slideover.pstd.modal:not([data-panel="qcompose"]) .pnl-body .row > div{display:grid;grid-template-columns:var(--pk-w) minmax(0,1fr);align-items:center;column-gap:12px}
.slideover.pstd.modal:not([data-panel="qcompose"]) .pnl-body .row > div > label{margin:0;font-size:var(--fs-sm);font-weight:var(--weight-body);color:var(--text)}
.slideover.pstd .cdprops.dtform .cdprop > select{width:100%;max-width:none;min-width:0;box-sizing:border-box}
.slideover:not(.modal) .pnl-body > .btns.pnl-foot{margin-left:-20px;margin-right:-20px}   /* 딤 없는 좁은 팝업(핵심 칸 짝 narrow)의 발 = 몸 안여백 20 과 같은 음수 여백(옛 −22 = 2px 넘침 · main 에도 있던 것 · 390 ⓖ) */   /* 핵심 칸 짝(select 가 바로 상자) = 줄 끝까지 */
.slideover.pstd .cdprops.asform .cdprop > label[data-part~="ck"]{grid-column:1 / -1;font-size:var(--fs-sm);font-weight:var(--weight-body);color:var(--text)}   /* 체크 한 줄(판관비 고정비 · 비밀) = 이름 · 상자 짝이 아니라 줄 전체 */

/* 견적서 작성(qcompose · 예외 큰 창) = 머리 칸들(받는 곳 · 기본 정보)만 같은 꼴 — 학교 · 줄 표는 그대로(과제 378 ④)
   값이 들어도 상자(과제 345 「빈 칸만 입력칸 · 값이 들면 글」 을 표준으로 넓힘 · v396 ⓑ 기대 고쳐 씀) · 줄 사이 선 없음 · 이름 열 = --pk-w */
.slideover.pstd .qgrp[data-step="1"] .cdprops[data-pf]{display:grid;grid-template-columns:minmax(0,1fr);gap:10px}
.slideover.pstd .qgrp[data-step="1"] .cdprops[data-pf] > .cdprop{display:grid;grid-template-columns:var(--pk-w) minmax(0,1fr);align-items:center;column-gap:12px;padding:0;border-bottom:0}
.slideover.pstd .qgrp[data-step="1"] .cdprops[data-pf] > .cdprop[style*="display:none"]{display:none}
.slideover.pstd .qgrp[data-step="1"] .cdprops[data-pf] > .cdprop > .pk{font-weight:var(--weight-body);color:var(--text)}
.slideover.pstd .qgrp[data-step="1"] .cdprops[data-pf] > .cdprop > :not(.pk){grid-column:2}
.slideover.pstd .qgrp[data-step="1"] .cdprops[data-pf] > .pfhelp{padding-left:calc(var(--pk-w) + 12px)}
.slideover.pstd .qgrp[data-step="1"] .cdprops[data-pf] .cdprop > .pv.pf-v.editable{border:1px solid var(--line-input);min-height:32px;margin-left:0;padding:5px 11px;background:var(--bg-card)}
.slideover.pstd .qgrp[data-step="1"] .cdprops[data-pf] .cdprop > .pv.pf-v.editable:hover{border-color:var(--accent);background:var(--bg-card)}

/* ════════════════════════════════════════════════════════════════════════════════════════════════
   ★★ 과제 414b — 디자인 v4 3단계 : 표 · 칩 · 증감 · KPI · 그래프 · 숫자 배지 · 빈 상태 · 이니셜 · 스크롤바 · 모션
   정본 = DESIGN.md §6-10 · 사양 `루프/사양/…261015…디자인v4_밝은옷.md` 5-5 ~ 5-8 · 5-14 · 5-15 · 5-19 ~ 5-21 · `디자인시스템v4/지침.md` §C · §K · §L · §V · §M
   값 = 토큰만 · 클래스 · id · 로직 그대로(더함 = .tag · .dsub · .dash-cmpt · .tbl-wide · .v4-empty · .ld-tip · .tk-av-more · .v4-*) · 관문 = 검증도구/…v4표칩검사_v441.js
   ⚠ 이 묶음은 파일 맨 끝 — 앞 규칙과 무게가 같으면 이 묶음이 이긴다(앞 줄을 지우지 않고 덮음 · 되돌리기 = 이 묶음 통째로)
   ════════════════════════════════════════════════════════════════════════════════════════════════ */
/* ① 표(L-1 ~ L-4) — 머리 12 · 450 · --text-2 · 불투명 흰 / 이름 · 돈 500 / 세로선 = 넓은 표만 / 묶음 줄 = --grp-row-bg */
th,.scrolltbl th{font-weight:var(--weight-medium)}
.clrow.clhead:where(:not(:is(#me, #photo) *)),.clrow.clhead:where(:not(:is(#me, #photo) *)):hover{font-size:var(--fs-cap)}   /* 내 정보 · 사진 = 대상 밖(DESIGN §11-5 · 규칙 123 · v270 ⓐ4) */
.tk-row.tk-head > div{font-size:var(--fs-cap)}                                   /* 할 일 머리도 같은 값(할일불변 「뜻대로」 · DESIGN §6-10 ①) */
#hBoard .clrow.clhead,#hBoard .clrow.clhead:hover{background:var(--tbl-head-bg)}  /* 홈 보드 머리 = 불투명 흰(옛 = 투명) */
.cl-name .nm,.cl-name .nm a,table a,.tk-dlist .cl-name .nm:not(.done){font-weight:var(--weight-name)}
.clrow:not(.clhead) > .r,.clrow:not(.clhead) > .li-amt,td.r,td.num,.numcell{font-weight:var(--weight-num);font-variant-numeric:tabular-nums}
.tbl-wide,#mList[data-view="master"]{--cell-line:var(--line-soft)}               /* 넓은 표(칸 12 넘음) = 세로선 --line-soft · 좁은 표 = 없음(Q-V1 ⓐ) */
#mItemList .clrow.grp{background:var(--grp-row-bg)}
tr.sel > td:first-child,.scrolltbl tr.sel > td:first-child{box-shadow:inset 2px 0 0 var(--accent)}
.clrow,.tk-row,tbody tr > td{transition:background-color var(--duration-fast) var(--ease)}
/* 칩 모양 글자(+13) 로 고정 폭 칩 칸이 잘리는 자리 = 「옛 폭 + 16」(§11-3 · 132 문법) */
#wkRows .clrow{grid-template-columns:112px minmax(140px,1.3fr) 140px 36px minmax(150px,1.8fr) 128px 232px}   /* ★ 과제 562 ② — 점수 칸 칩(◐ 비용 짝 남음) 112 → 128 */
#finMonth .clrow.fin-mo{grid-template-columns:minmax(110px,0.9fr) repeat(3,minmax(112px,1fr)) 72px repeat(3,minmax(104px,0.9fr)) 124px}   /* 재무 달별 「계산서」 칩(◐ 1장 안 붙음) 104 → 124 */
#leadList .clrow{grid-template-columns:188px minmax(120px,.9fr) 112px 104px minmax(160px,2.6fr) 112px minmax(110px,.9fr) 108px}   /* 상담상태 칩(○ 상담종료) 96 → 112 */
@media (max-width:1399px){ #leadList .clrow{grid-template-columns:188px minmax(110px,.8fr) 108px 100px minmax(108px,2fr) 112px minmax(100px,.8fr) 108px;min-width:934px} }
#cPOs td:nth-child(2),#cQuotes td:nth-child(2),#hIncList .clrow:not(.clhead) > .r{font-weight:var(--weight-num);font-variant-numeric:tabular-nums}   /* 상세 팝업 안 돈 칸 · 인센티브 돈 칸 */

/* ② 칩 .pill(C-1 · 사양 2-3) — 칠 + 안쪽 1px 테 + 모양 글자 + 글 · 20 · 6 · 12 · 500 · 칩은 상태 열 · 증감에만(종류 = .tag 점 + 글) */
.pill{position:relative;height:var(--h-chip);border-radius:var(--r-chip);column-gap:4px;padding-left:calc(8px + var(--fs-cap));background:var(--nt-bg);color:var(--nt);box-shadow:inset 0 0 0 1px var(--nt-line)}
.pill::before{content:"○";position:absolute;left:8px;top:50%;transform:translateY(-50%);font-size:calc(var(--fs-cap) * .75);line-height:1}   /* 모양 글자 = 겹쳐 놓음(흐름 밖 — 칩 글의 기준선 · 줄 높이 그대로) · 자리 = 왼쪽 안 여백 */
.pill.ok,.pill.stg6{background:var(--ok-bg);color:var(--ok);box-shadow:inset 0 0 0 1px var(--ok-line)}
.pill.ok::before,.pill.stg6::before{content:"●"}
.pill.warn{background:var(--warn-bg);color:var(--warn);box-shadow:inset 0 0 0 1px var(--warn-line)}
.pill.warn::before{content:"◐"}
.pill.bad{background:var(--bad-bg);color:var(--bad);box-shadow:inset 0 0 0 1px var(--bad-line)}
.pill.bad::before{content:"◆"}
.pill:is(.blue,.stg1,.stg2,.stg3,.stg4,.stg5){background:var(--info-bg);color:var(--info);box-shadow:inset 0 0 0 1px var(--info-line)}
.pill:is(.blue,.stg1,.stg2,.stg3,.stg4,.stg5)::before{content:"◔"}
.pill.dim{background:var(--nt-bg);color:var(--nt);box-shadow:inset 0 0 0 1px var(--nt-line)}
.pill.dim::before{content:"○"}
.pill.purple{background:var(--purple-bg);color:var(--purple);box-shadow:inset 0 0 0 1px var(--purple-line)}
.pill.purple::before{content:"■"}
button.pill,button.pill:is(.ok,.warn,.bad,.dim,.blue,.purple){box-shadow:none;border:1px solid var(--nt-line)} button.pill.warn{border-color:var(--warn-line)} button.pill.bad{border-color:var(--bad-line)} button.pill.ok{border-color:var(--ok-line)}   /* 단추 칩(현장 「남은 칸 N」 od-gatego) = 테두리(팝업 안 단추 그림자 0 · v280 ⓗ5) */
/* 옷 밖 : 문의경로(375 대표 허락 색) · 근태 범례(달력 막대 색) · 할 일 카드 머리 건수(잣대) — 모양 글자 · 테 없음 */
.pill:is(.src-k,.src-w,[class*="lv-"])::before,#taskList .tk-h .pill::before{content:none}
.pill:is(.src-k,.src-w,[class*="lv-"]){box-shadow:none;padding-left:8px}
#taskList .tk-h .pill{padding-left:8px}
.umenu-it .pill:not(.tag),.tk-pop .tk-frow .pill:not(.tag){padding-left:calc(8px + var(--fs-cap))}   /* 팝 안 칩도 모양 글자 자리 */
/* ★ 종류 · 분류 = 점 + 글(.pill.tag) · 돈 알림 줄(홈 #hMoney · 지출 #spSum — 지침 C 「✗ 돈 알림 칩 셋」) */
.pill.tag,#spSum .pill,#hMoney .hm-row .pill{background:transparent;box-shadow:none;padding:0 0 0 13px;height:auto;min-height:var(--h-chip);border-radius:0;font-weight:var(--weight-medium)}
#hMoney .hm-row .pill.jump:focus-visible{box-shadow:var(--ring)}   /* ★ 과제 521 2차(디자이너) — 누르는 알약 둘(받을 돈 연체 · 잔고) = 키보드 초점 고리(위 줄이 그림자를 지움) */
.hg-none b{white-space:nowrap}   /* ★ 과제 521 2차(디자이너) — 빈 목표 평균 금액 = 한 덩어리(390 「27,833,333 / 원」 꺾임 0) */
.pill.tag::before,#spSum .pill::before,#hMoney .hm-row .pill::before{content:"";left:0;width:7px;height:7px;border-radius:50%;background:currentColor;font-size:0}
.pill.tag.dim,#spSum .pill.dim,#hMoney .hm-row .pill.dim{color:var(--text-2)}
#spSum .pill b,#hMoney .hm-row .pill b{color:inherit}
/* ★ 견적 작성 팝업 = 옛 칩 그대로(과제 144 계획 「견적 작성 팝업은 안 건드림」 · v280 ⓝ 같은 사진 · 견적서 서식 = 과제 415) */
.slideover[data-panel="qcompose"] .pill{padding:0 8px;border-radius:var(--r-ctl);column-gap:normal;box-shadow:none}
.slideover[data-panel="qcompose"] .pill::before{content:none}
.slideover[data-panel="qcompose"] .pill.dim{background:var(--bg-hover);color:var(--text-2)}
.slideover[data-panel="qcompose"] .pill:is(.blue,.stg1,.stg2,.stg3,.stg4,.stg5){background:var(--accent-soft);color:var(--accent)}
/* 코드(C-5) = --bg-fill · 회색 450 · 6 · tabular(테 = 투명 — 폭 그대로) */
.ccode{background:var(--bg-fill);border-color:transparent;border-radius:var(--r-chip);font-variant-numeric:tabular-nums}
/* 사람 알약 · 이니셜(5-20 · L-5) = 한 색 */
.uchip{background:var(--accent-soft);color:var(--accent);border-radius:var(--r-pill)}
.tk-av{background:var(--accent-soft);color:var(--accent);font-weight:var(--weight-strong)}
.tk-av.tk-av-more{background:var(--bg-fill);color:var(--text-2)}

/* ③ 증감 .delta(C-2 · 5-8) — 칩(화살 있음) · 보조글 .dsub(칩 아님) · 비교 글 .dash-cmpt(칩 밖 회색) */
.delta:not(.dsub){background:var(--nt-bg);color:var(--nt);box-shadow:inset 0 0 0 1px var(--nt-line)}
.delta:not(.dsub),.dash-host .tk-dstats .stat .delta:not(.dsub){display:inline-flex;align-items:center;gap:3px;height:var(--h-chip);padding:0 7px;margin:0;border:0;border-radius:var(--r-chip);
  font-size:var(--fs-cap);font-weight:var(--weight-strong);line-height:var(--h-chip);white-space:nowrap}   /* 색은 아래 뜻마다(이 줄 = 꼴만 — Dashboard 타일 안 무거운 선택자가 뜻 색을 덮지 않게) */
.delta.ok:not(.dsub){background:var(--ok-bg);color:var(--ok);box-shadow:inset 0 0 0 1px var(--ok-line)}
.delta.warn:not(.dsub){background:var(--warn-bg);color:var(--warn);box-shadow:inset 0 0 0 1px var(--warn-line)}
.delta.bad:not(.dsub){background:var(--bad-bg);color:var(--bad);box-shadow:inset 0 0 0 1px var(--bad-line)}
.delta.dim:not(.dsub){background:var(--nt-bg);color:var(--nt);box-shadow:inset 0 0 0 1px var(--nt-line)}
.delta.dsub{color:var(--text-2)}
.delta.dsub,.dash-host .tk-dstats .stat .delta.dsub{display:block;height:auto;padding:0;margin:0;border:0;border-radius:0;background:transparent;box-shadow:none;
  font-size:var(--fs-sm);font-weight:var(--weight-body);line-height:1.45;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}   /* 색 = 아래 뜻마다(이 줄 = 꼴만) */
/* ★ 과제 510 ⑤ (걷기2 줄 11 · 재무 「연체 1건 · 5,500,0…」) — 폰 = 타일 보조글(.dsub · 칩 아님 · 배경 없음)은 넘치면 **띄어쓰기에서만** 둘째 줄로(keep-all = 274 의 한 글자씩 꺾임 없음 · 금액 말줄임 0) · 칩(:not(.dsub))은 그대로 한 줄 */
@media (max-width:600px){ main .dash-host .tk-dstats .stat .delta.dsub{white-space:normal;word-break:keep-all;overflow:visible} }
/* ★ 과제 510 ③ — 대표 · 재무 = 머리 글(p.sub) 숨김 → 장부 띠가 제목 바로 밑 : 띠 위 여백(12)이 제목 아래 여백에 더해져 24 가 됨(v354 「제목→첫 카드」 기준 12) → 그때만 띠 위 0 */
#bill:has(> p.sub[hidden]) > #billLedger{margin-top:0}
.delta.dsub:is(.ok,.warn,.bad)::before{content:"";display:inline-block;width:7px;height:7px;border-radius:50%;background:currentColor;margin-right:6px;vertical-align:1px}
.delta.dsub.ok{color:var(--ok)} .delta.dsub.warn{color:var(--warn)} .delta.dsub.bad{color:var(--bad)}
.dash-cmpt{display:block;font-size:var(--fs-sm);color:var(--text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}

/* ④ KPI .stat(K-3 · 5-5) — 위 = 이름 + 오른쪽 위 증감 칩 · 숫자 28 · 500 · 잉크 · 아래 = 숫자 밑 한 줄 · 보조글 · 비교 글 · 아이콘 상자 숨김(Q-D3 ⓐ) */
.stat .tile,.dash-host .tk-dstats .stat > .tile{display:none}
.stat .body{display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:8px;align-content:start}
.stat .body > *{grid-column:1 / -1}
.stat .body > .k{grid-column:1;grid-row:1;align-self:center}
.stat .delta-slot,.stat .delta-slot:has(.dash-cmp){display:contents}
.stat .delta-slot > .delta:not(.dsub){grid-column:2;grid-row:1;justify-self:end;align-self:center}
.stat .delta-slot > .dsub,.stat .delta-slot > .dash-cmpt{grid-column:1 / -1;margin-top:6px}
.stat .delta-slot > .dash-cmpt + .dsub,.stat .delta-slot > .dsub + .dash-cmpt{margin-top:2px}
.stat .k,#home .stat .k{font-size:var(--fs-body);font-weight:var(--weight-medium);color:var(--text)}
.stat .v{font-size:var(--fs-num);font-weight:var(--weight-num);letter-spacing:var(--ls-title);margin-top:10px}
.stats .stat:nth-child(4) .v{color:var(--ink)}
.dash-host .tk-dstats .stat > .body > :not(.delta-slot){padding-right:0}

/* ⑤ 그래프(V-1 · 5-14) — 막대 · 선 색 = core.js dashTrendSvg · 진도 막대 = --accent 단색 + 바닥 --bg-fill(Q-V2 ⓐ) · 풍선 .ld-tip */
.cl-stg2 .tr{background:var(--bg-fill);border-radius:var(--r-pill)}
.cl-stg2 .tr i{border-radius:var(--r-pill)}
.tk-hbar,.hbar .hb-track{background:var(--bg-fill)}
.ld-legend i{border-radius:50%;width:8px;height:8px}
.ld-legend i.ln{width:12px;height:2px;border-radius:var(--r-pill)}
.ld-tip{position:fixed;z-index:60;pointer-events:none;display:flex;flex-direction:column;gap:2px;max-width:280px;padding:8px 10px;border-radius:var(--r-ctl);
  background:var(--bg-card);box-shadow:var(--sh-pop);font-size:var(--fs-sm);color:var(--text);line-height:1.4}
.ld-tip[hidden]{display:none}
.ld-tip .k{color:var(--text-2)}
.ld-tip .v{font-weight:var(--weight-num);font-variant-numeric:tabular-nums}

/* ⑥ 숫자 배지(5-15) · 빈 상태(5-19) · 뼈대 · 스크롤바(5-21) */
nav a .nbdg{box-sizing:border-box;min-width:var(--h-chip);height:var(--h-chip);line-height:var(--h-chip);padding:0 6px;border-radius:var(--r-pill)}
.v4-empty{display:flex;flex-direction:column;align-items:center;gap:10px;margin:0;padding:32px 16px;text-align:center;color:var(--text-2)}
.v4-empty::before{content:"";width:28px;height:28px;background:var(--deco);-webkit-mask:var(--ic-search) center / 28px no-repeat;mask:var(--ic-search) center / 28px no-repeat}
.tk-dempty{text-align:center;color:var(--text-2)}
.skb{border-radius:var(--r-chip)}
::-webkit-scrollbar{width:6px;height:6px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--line);border-radius:var(--r-pill)}
::-webkit-scrollbar-thumb:hover{background:var(--deco)}

/* ⑦ 모션(지침 §M · 디자인시스템v4/css/motion.css 옮김) — 첫 진입에만 · 300ms 안(그래프 560 예외) · backwards(끝 값 안 붙잡음) · 줄이기 = 1ms */
@keyframes v4-rise{from{opacity:0;transform:translateY(var(--rise))}}
@keyframes v4-fade{from{opacity:0}}
@keyframes v4-grow-y{from{transform:scaleY(0)}}
@keyframes v4-grow-x{from{transform:scaleX(0)}}
@keyframes v4-pop{from{opacity:0;transform:translateY(-4px) scale(.98)}}
@keyframes v4-sheet{from{opacity:0;transform:translateX(24px)}}
@keyframes v4-flash{from{opacity:1}to{opacity:0}}
.v4-enter > *{animation:v4-rise var(--duration-base) var(--ease) backwards}
.v4-enter > *:nth-child(2){animation-delay:calc(var(--stagger) * 1)}
.v4-enter > *:nth-child(3){animation-delay:calc(var(--stagger) * 2)}
.v4-enter > *:nth-child(n+4){animation-delay:calc(var(--stagger) * 3)}
.v4-enter .ld-tsvg rect:not(.ld-hit),.v4-bars > *{transform-box:fill-box;transform-origin:bottom;animation:v4-grow-y var(--duration-chart) var(--ease-out) backwards;animation-delay:120ms}
.v4-enter .cl-stg2 .tr i,.v4-enter .tk-hbar > i,.v4-meter > i{transform-origin:left;animation:v4-grow-x var(--duration-chart) var(--ease-out) backwards;animation-delay:120ms}
.v4-swap{animation:v4-fade var(--duration-base) var(--ease) backwards}
.v4-acts{opacity:0;transition:opacity var(--duration-fast) var(--ease)}
:is(tbody tr,.clrow,.tk-row):is(:hover,:focus-within) .v4-acts{opacity:1}
@media (hover:none){ .v4-acts{opacity:1} }
.v4-new{animation:v4-rise var(--duration-base) var(--ease) backwards}
.v4-flash{position:relative}
.v4-flash::after{content:"";position:absolute;inset:0;background:var(--accent-soft);pointer-events:none;border-radius:inherit;animation:v4-flash 1200ms var(--ease) forwards}
.v4-popin{animation:v4-pop var(--duration-fast) var(--ease) backwards}
.v4-sheetin{animation:v4-sheet var(--duration-slow) var(--ease) backwards}
.v4-out{transition:opacity var(--duration-fast) var(--ease-in),transform var(--duration-fast) var(--ease-in);opacity:0;transform:translateY(4px)}
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:1ms !important;animation-delay:0ms !important;animation-iteration-count:1 !important;transition-duration:1ms !important}
}

/* ── ★ 과제 413 (10-17 · 대표 안 B · 시안 3판) — 현장 화면 탭 둘 [현장 작업 | 결과 보고서] · 결과 보고서 = 왼쪽 광고주 목록 · 오른쪽 광고주가 받을 화면 그대로(iframe)
     탭 = .ptabs 부품 그대로(DESIGN §6-9 ①) · 목록 = .clrow(§11 · 한 줄) · 칩 = .pill 그대로 · 감춤 = CSS(규칙 112) · 색 · 라운드 · 굵기 = 토큰만 · 그림자 0 ── */
#order.od-tab-report #orderMD{display:none}
#order:not(.od-tab-report) #odRpPane{display:none}
.od-rp{display:flex;gap:16px;align-items:flex-start}
.od-rp-l{flex:0 0 460px;min-width:0;margin:0;padding:0;overflow:hidden}
.od-rp-h{display:flex;align-items:center;gap:8px;padding:14px 16px 10px}
.od-rp-h h3{margin:0;flex:none;font-size:var(--fs-card);font-weight:var(--weight-medium)}
.od-rp-h .search{flex:1;min-width:0}
.od-rp-h .search input{width:100%}
#odRpList .clrow{grid-template-columns:minmax(0,1fr) 64px minmax(64px,auto);min-width:0}   /* 옛 .clrow 최소 852(일곱 칸 표) 풂 — 안 풀면 진행 · 사진 칸이 카드 밖으로 밀려 잘림(v442 ⓒ3b) */
#odRpList .rp-c1{display:flex;align-items:center;gap:6px;min-width:0;white-space:nowrap;overflow:hidden}
#odRpList .rp-c1 .pill{flex:none}
#odRpList .rp-c1 .nm{flex:none;font-weight:var(--weight-name)}
#odRpList .rp-c1 .cp{min-width:0;overflow:hidden;text-overflow:ellipsis;color:var(--text-2)}
#odRpList .rp-c1 .cp::before{content:'· '}
#odRpList .rp-prog,#odRpList .rp-ph{text-align:right;white-space:nowrap;font-variant-numeric:tabular-nums}
#odRpList .clhead > div:not(:first-child){text-align:right}
.rp-nph{margin-left:6px;color:var(--warn);font-size:var(--fs-sm)}
.rp-nph::before{content:'';display:inline-block;width:7px;height:7px;margin-right:5px;vertical-align:1px;border-radius:var(--r-pill);background:var(--warn)}
.od-rp-f{margin:0;padding:10px 16px 14px}
.od-rp-f .rp-f-m{display:none}
.od-rp-r{flex:1;min-width:0}
.od-rp-back{display:none}
.rp-bar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:0 0 10px}
.rp-bar .rp-tt{font-size:var(--fs-card);font-weight:var(--weight-medium)}
.rp-bar .rp-when{font-size:var(--fs-sm)}
.rp-bar .sp,.rp-slot .sp{flex:1}
.rp-same{margin:0 0 10px}
.rp-np{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin:0 0 10px}
.rp-np button.on{border-color:var(--accent-line);color:var(--accent)}
.rp-slot{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:0 0 10px;padding:12px 14px;border:1px dashed var(--line-input);border-radius:var(--r-ctl);background:var(--bg-card);color:var(--text-2);font-size:var(--fs-sm)}
.rp-slot b{color:var(--text);font-weight:var(--weight-medium)}
.rp-slot.odv3-drop{border-color:var(--accent);background:var(--bg-active)}
.rp-slot-why{flex-basis:100%;margin:0}
.rp-slot-urls{display:flex;align-items:flex-start;gap:8px;flex-basis:100%}
.rp-slot-urls textarea{flex:1;min-width:0;font-size:var(--fs-sm)}
.rp-pv{position:relative;min-height:240px;overflow:hidden;border:1px solid var(--line);border-radius:var(--r-card);background:var(--bg-card)}
.rp-pv > .hint.guide{margin:16px}
.rp-pv > .rp-pvnote{margin:16px}
.rp-pv iframe{display:block;border:0;transform-origin:0 0}
@media (max-width:1100px){ .od-rp-l{flex-basis:380px} }
@media (max-width:760px){
  .od-rp{display:block}
  .od-rp-l{width:auto}
  .od-rp.rp-mob-pv .od-rp-l{display:none}
  .od-rp:not(.rp-mob-pv) .od-rp-r{display:none}
  .od-rp-back{display:inline-flex;margin:0 0 10px}
  #odRpList .clrow{grid-template-columns:minmax(0,1fr) auto auto;min-width:0;padding-top:6px;padding-bottom:6px}
  #odRpList .rp-c1{flex-wrap:wrap;row-gap:2px;white-space:normal}   /* 폰 = 시안 3판 6번 그대로 : 캠페인 · 사진 없는 곳 = 밑 작은 줄 */
  #odRpList .rp-c1 .cp{flex-basis:100%;font-size:var(--fs-sm)}
  #odRpList .rp-c1 .cp::before{content:none}
  #odRpList .rp-nph{display:block;margin:2px 0 0}
  .rp-bar .rp-when{display:none}
  .od-rp-f .rp-f-d{display:none}
  .od-rp-f .rp-f-m{display:inline}
}
/* ── 과제 413 끝 ── */

/* ══ ★ 과제 405b (10-17) — 견적 [리스트에서 담기] · 둘째 층 몸(옷 = #qPickBack 한 덩어리 · DESIGN §12 「2층 고르기」) · 꼭 채울 빈 칸 .in-need(§6-2) · 시트 리스트 줄 · 별지 쪽(§13-9) ══ */
#qListPop .ptabs{margin:0 0 var(--gap-field)}
#qListPop .ql-filt{margin:0}
#qListPop .ql-hint{margin:6px 0 var(--gap-field);font-size:var(--fs-sm)}
#qListPop .ql-paste{margin:0}
#qListPop .ql-paste textarea{min-height:0}
#qListPop .ql-pasteout{margin:6px 0 var(--gap-field);font-size:var(--fs-sm)}
#qListPop .ql-pasteout:empty{display:none}
#qListPop .ql-misses{list-style:none;margin:6px 0 0;padding:0;display:flex;flex-direction:column;gap:6px}
#qListPop .ql-miss{display:flex;align-items:center;flex-wrap:wrap;gap:6px}
#qListPop .ql-miss-n{font-weight:var(--weight-strong);color:var(--text);margin-right:4px}
#qListPop table.ol-checks th.ol-ck,#qListPop table.ol-checks td.ol-ck{width:40px;text-align:center;padding:0}
#qListPop table.ol-checks tr.ql-in td{color:var(--text-2)}
#qListPop .ql-cups{width:96px;height:28px;text-align:right}
#qListPop .ql-bn{display:grid;grid-template-columns:minmax(220px,1fr) minmax(0,2.4fr);gap:var(--gap-card);align-items:start}
#qListPop .ql-bn-h,#qListPop .ql-bn-r{display:grid;grid-template-columns:88px minmax(170px,1fr) 104px 44px 84px 92px minmax(112px,auto);align-items:center;column-gap:10px;min-height:44px;border-bottom:1px solid var(--line-soft);padding:0 var(--pad-cell-x)}
#qListPop .ql-bn-h{min-height:36px;font-size:var(--fs-sm);color:var(--text-2);background:var(--tbl-head-bg)}
#qListPop .ql-bn-h .num,#qListPop .ql-bn-r .num{text-align:right;font-variant-numeric:tabular-nums}
#qListPop .ql-bn-p{display:flex;align-items:center;gap:6px;min-width:0}
#qListPop .ql-bn-q{width:72px;text-align:right}
#qListPop .ql-bn-empty{margin:var(--gap-field) 0}
#qListPop .ql-need{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin:var(--gap-field) 0 0}
#qListPop .ql-need:empty{display:none}
#qListPop .ql-need input{width:140px;text-align:right}
#qListPop .ql-foot{display:flex;align-items:center;gap:var(--gap-tool);flex-wrap:wrap}
#qListPop .ql-gap{flex:1}
#qListPop .ql-sum{font-size:var(--fs-body);color:var(--text)}
/* ★ 과제 431 ② (디자인 점검 B4) — 몸줄 = 표 줄 44(--row-h · 414b 표 규칙 · 옛 36) · 머리 오른쪽 고른 수(#qlHeadSum · 본문 굵기 · 둘째 글색) */
#qListPop table.ol-table tbody tr[data-i]{height:var(--row-h)}
#qListPop .ql-hsum{margin-left:auto;font-size:var(--fs-sm);font-weight:var(--weight-body);color:var(--text-2);white-space:nowrap;font-variant-numeric:tabular-nums}
#qListPop .ql-hsum:empty{display:none}
#qListPop h3:has(.ql-hsum:not(:empty)) > button.xclose{margin-left:0}   /* 머리 수가 오른쪽 끝 자리를 잡고 ✕ 는 그 옆 */
#qListPop .ql-keys{font-size:var(--fs-sm)}
#qListPop .ql-why{display:inline-flex;align-items:center;gap:var(--gap-tool);margin:0}   /* ★ 과제 424 — [담기] 꺼진 까닭 한 줄(.hint · 배경 없음) + [그 탭으로] */
#qListPop .ql-why:empty{display:none}
#leadViewBody .lv-next[hidden],#leadViewBody .lv-make[hidden]{display:none}   /* ★ 과제 424 2차 — 발 주 단추가 있으면 몸 안 [캠페인 만들기 →] 숨김(id 그대로) */
/* DESIGN §6-2 — 꼭 채울 빈 칸(새 색 0 · 테 = --bad · 곁에 .pill.bad 글 한 짝) */
input.in-need,select.in-need,textarea.in-need{border-color:var(--bad) !important}   /* ★ 과제 480 — 꼭 채울 빈 칸 = 상태라 어느 자리 칸 규칙(팝업 679 · 681 · 0,6,2 까지)보다 이긴다 · 초점 고리(--ring)는 box-shadow 라 그대로 · 옛 #qListPop · #qsBody 특례 흡수 */
.cdprop > .pill[data-need]{justify-self:start}   /* ★ 과제 481 모양 검토 [1] — 곁 글 = 칩 폭(격자 둘째 열 기본 stretch 로 상자 폭 전부 띠가 되던 것) · 481 [3] · 기획 허락 · hint 곁 글도 칩 폭 */
/* 시트 리스트 줄 — 펼침(담은 곳 · 빼기 · 수량 · 단가 · 매수) · 고친 단가 표시(.qs-inote = 문서 거울이 뗌) */
#qsBody .qs-desc-sum.ql-dsum{display:flex;align-items:center;gap:6px;width:100%;white-space:nowrap;text-align:left}   /* 표 줄은 한 줄 — 긴 요약 = 말줄임 + title */
#qsBody .ql-dsum .ql-dsum-t{flex:1 1 auto;width:0;min-width:0;overflow:hidden;text-overflow:ellipsis}   /* width 0 = 칸 최소 폭에 안 듦(1차 검토 · 1440 리스트 줄 넷 = 시트 가로 굴림 0) · 전문 = title */
#qsBody .ql-picks{display:flex;flex-direction:column;gap:6px;max-height:260px;overflow:auto;margin-top:6px}
#qsBody .ql-picks[hidden]{display:none}   /* 화면규칙 5d — display 를 준 칸의 hidden 짝 */
#qsBody .ql-pk{display:flex;align-items:center;gap:6px;flex-wrap:wrap;padding-bottom:6px;border-bottom:1px solid var(--line-soft)}
#qsBody .ql-pk-n{flex:1 1 100%;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#qsBody .ql-pk-f{display:inline-flex;align-items:center;gap:4px;font-size:var(--fs-sm);color:var(--text-2)}
#qsBody .ql-pk-f input{width:76px;height:28px;text-align:right}
.qsdoc table#qdTable tr.qd-ql td,.qdet-docwrap .qsdoc table tr.qd-ql td{word-break:keep-all}   /* 리스트 줄 = 낱말 중간 안 꺾음(「아파트게시판」) · 대학교 줄 = 그대로 */
.qsdoc table#qdTable tr.qd-ql td:nth-child(5),.qsdoc table#qdTable tr.qd-ql td:nth-child(5) .qd-pv,.qdet-docwrap .qsdoc table tr.qd-ql td:nth-child(5) .qd-pv{white-space:nowrap;word-break:keep-all;overflow:visible}   /* 리스트 줄 수량(컵홀더 20,000매) = 숫자를 가르지 않음(화면규칙 128) · 대학교 줄 = 그대로 */
#qsBody .ql-inote{display:flex;align-items:center;justify-content:flex-end;gap:6px;flex-wrap:wrap;color:var(--warn);font-size:var(--fs-sm);margin-top:4px}
#qsBody .ql-dot{width:6px;height:6px;border-radius:var(--r-pill);background:var(--warn);display:inline-block}
/* 별지 「상세 리스트」 쪽(DESIGN §13-9) — 본문 장과 같은 판 · 묶음 · 표(머리 · 몸 옷 = 뒷장 표 .qd-t2 한 벌에 선택자만 더함) */
.qsdoc.qd-annex > *{grid-column:1 / -1}
.qsdoc.qd-annex .qd-ax-sec{margin-top:14px}
.qsdoc.qd-annex .qd-ax-sec .qd-cap{margin-top:8px}
.qsdoc table.qd-ax-t{margin-top:8px}
.qsdoc table.qd-ax-t th:nth-child(1){width:30px}
.qsdoc table.qd-ax-t th:nth-child(4){width:10%}
.qsdoc table.qd-ax-t th:nth-child(5){width:13%}
.qsdoc table.qd-ax-t th:nth-child(6){width:15%}
.qsdoc table.qd-ax-t td.num{text-align:right;font-variant-numeric:tabular-nums}
.qsdoc table.qd-ax-t tr.qd-ax-tot td{border-top:1.5px solid var(--qd-ink);font-weight:var(--weight-strong)}
/* ★ 과제 462c (디자이너 10 · 시안 = 디자이너 5 「과제462_시안_4_별지상세판_A4_*_v4」 · DESIGN_문서서식 §13-9) — 별지 상세판 옷
   ⓐ 매체별 칸 = 표에 판 이름 하나(.qd-ax-ap = 아파트 AP-BD 10칸 · .qd-ax-bn = 지정게시대 BN-DB 9칸 · 없으면 옛 6칸 = 위 넷 그대로 · 옛 별지 바이트 불변)
      폭 = 짧은 값 칸만 정함 · 이름 · 주소 · 규약 = 남는 폭(auto) · A4 판(.qsdoc 폭) 잘림 0
   ⓑ 지역 묶음 줄 tr.qd-ax-grp(첫 칸 빈 td + 나머지 colspan 한 칸 = 「서울 강동구 · 2곳」) ⓒ 머리 요약 한 줄 .qd-ax-sum(캡션 바로 아래) ⓓ 끝 「안내」 블록 .qd-ax-note(h4 + ul · 글 = 프론트) */
.qsdoc table.qd-ax-t:is(.qd-ax-ap,.qd-ax-bn) th{width:auto}
.qsdoc table.qd-ax-t:is(.qd-ax-ap,.qd-ax-bn) th:nth-child(1){width:30px}
.qsdoc table.qd-ax-t.qd-ax-ap th:nth-child(4){width:8%}    /* 세대수 */
.qsdoc table.qd-ax-t.qd-ax-ap th:nth-child(5){width:8.5%}  /* 단지구분 */
.qsdoc table.qd-ax-t.qd-ax-ap th:nth-child(6){width:8%}    /* 게시수량 */
.qsdoc table.qd-ax-t.qd-ax-ap th:nth-child(7){width:8%}    /* 게시기간 */
.qsdoc table.qd-ax-t.qd-ax-ap th:nth-child(8){width:9.5%}  /* 게시방법 */
.qsdoc table.qd-ax-t.qd-ax-ap th:nth-child(9){width:9%}    /* 단가 */
.qsdoc table.qd-ax-t.qd-ax-ap th:nth-child(10){width:11%}  /* 금액 */
.qsdoc table.qd-ax-t.qd-ax-bn th:nth-child(3){width:10%}   /* 구분 */
.qsdoc table.qd-ax-t.qd-ax-bn th:nth-child(4){width:13%}   /* 사이즈 */
.qsdoc table.qd-ax-t.qd-ax-bn th:nth-child(5){width:10%}   /* 게시기간 */
.qsdoc table.qd-ax-t.qd-ax-bn th:nth-child(7){width:7%}    /* 수량 */
.qsdoc table.qd-ax-t.qd-ax-bn th:nth-child(8){width:10%}   /* 단가 */
.qsdoc table.qd-ax-t.qd-ax-bn th:nth-child(9){width:12%}   /* 금액 */
.qsdoc table.qd-ax-t:is(.qd-ax-ap,.qd-ax-bn) td.num{white-space:nowrap}
.qsdoc table.qd-ax-t tr.qd-ax-grp td{font-weight:var(--weight-strong);color:var(--qd-ink);padding-top:10px}
.qsdoc.qd-annex .qd-ax-sum{margin:6px 0 0;font-size:12px;color:var(--qd-ink-soft)}
.qsdoc.qd-annex .qd-ax-note{margin-top:18px;width:55%}
.qsdoc.qd-annex .qd-ax-note h4{margin:0;padding-bottom:6px;border-bottom:1px solid var(--qd-ink);font-size:12px;font-weight:var(--weight-strong);color:var(--qd-ink)}
.qsdoc.qd-annex .qd-ax-note ul{margin:6px 0 0;padding:0;list-style:none;font-size:12px;line-height:1.7;color:var(--qd-ink-soft)}
.qsdoc.qd-annex .qd-ax-note li::before{content:"· "}
/* ★ 과제 493c (디자이너 10 · DESIGN_문서서식 §13-10 · 11 · 12) — 급여 서류 셋 = 별지 판(.qsdoc.qd-p2.qd-annex · 머리 .qd-head2 · 표 .qd-ax-t · 띠 .qd-grand)에 판 이름 하나
   .qd-pay = 급여명세서(A4 세로 · 받는 사람 칸 · 지급 | 공제 두 표 · 차인지급액 띠 · 발 = 회사 + 직인 + 「ERP 에서 발급」)
   .qd-land = A4 가로 판(1123 × 794) · 표 판 이름 .qd-ax-wh = 사업소득지급대장 8칸 · .qd-ax-dy = 일용 임금명세서 7칸 · tr.qd-ax-off = 원천세 확정 전 줄(흐리게 · 합계 밖) */
.qsdoc.qd-land{width:1123px;min-height:794px}
.qsdoc.qd-pay .qd-pay-who{display:grid;grid-template-columns:auto 1fr auto 1fr;gap:6px 16px;margin:16px 0 0;padding:12px 0;border-bottom:1px solid var(--qd-line);font-size:12.5px}
.qsdoc.qd-pay .qd-pay-who dt{color:var(--qd-ink-mute)}
.qsdoc.qd-pay .qd-pay-who dd{margin:0;font-weight:var(--weight-strong);white-space:nowrap}
.qsdoc.qd-pay .qd-pay-two{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:16px;align-items:start}
.qsdoc.qd-pay table.qd-ax-t th{width:auto}
.qsdoc.qd-pay table.qd-ax-t th:nth-child(2){width:46%}
.qsdoc.qd-pay .qd-grand{margin-top:16px}
.qsdoc.qd-pay .qd-pay-foot{margin-top:32px;display:flex;justify-content:space-between;align-items:flex-end;gap:24px;font-size:12px;color:var(--qd-ink-soft)}
.qsdoc.qd-pay .qd-pay-co{display:flex;align-items:center;gap:10px;font-size:13px;color:var(--qd-ink);font-weight:var(--weight-strong)}
.qsdoc.qd-pay .qd-pay-co{white-space:nowrap;flex:none}   /* ★ 502 디자인수정 2 [2] — 회사명 안 꺾임(디자이너 10 허락) */
.qsdoc.qd-pay .qd-pay-co img{width:52px;height:52px;opacity:.9}
.qsdoc table.qd-ax-t:is(.qd-ax-wh,.qd-ax-dy) th{width:auto}
.qsdoc table.qd-ax-t:is(.qd-ax-wh,.qd-ax-dy) th:nth-child(1){width:30px}
.qsdoc table.qd-ax-t.qd-ax-wh th:nth-child(3),.qsdoc table.qd-ax-t.qd-ax-dy th:nth-child(3){width:10%}   /* 사원코드 */
.qsdoc table.qd-ax-t.qd-ax-wh th:nth-child(4){width:12%}   /* 소득 구분 */
.qsdoc table.qd-ax-t.qd-ax-wh th:nth-child(5){width:13%}   /* 지급일 */
.qsdoc table.qd-ax-t.qd-ax-dy th:nth-child(4){width:12%}   /* 근로 건수 */
.qsdoc table.qd-ax-t:is(.qd-ax-wh,.qd-ax-dy) th:nth-last-child(-n+3){width:14%}   /* 세전 · 원천세 · 실지급 */
.qsdoc table.qd-ax-t:is(.qd-ax-wh,.qd-ax-dy,.qd-pay-t) td.num{white-space:nowrap}
.qsdoc table.qd-ax-t tr.qd-ax-off td{color:var(--qd-ink-mute)}
@media (max-width:600px){
  #qListPop .ql-sub,#qListPop .ql-keys,#qListPop .ql-hint{display:none}
  #qListPop .ql-bn{grid-template-columns:1fr}
  #qListPop .ql-bn-h{display:none}
  #qListPop .ql-bn-r{grid-template-columns:1fr 1fr;row-gap:4px;padding:6px 0}
}

/* ── ★ 과제 407b ── */
/* ══ ★ 과제 407b (10-17 · 시안 `화면그리기/그림_261016/과제407b_시안_*`) — 「+ 새 현장」 팝업 · 「새 현장」 표 · 폰 두 칸 + 펼침 · 발주 등록 「집행학교」 표준 칸
   토큰만(새 색 0 · 틀린 칸 = --bad · --bad-bg = 받은편지함 「안 고르면」 선례) · 그림자 0 · 표 줄 = 한 줄(칸 말줄임 · title 전문) */
/* ★ 과제 455 (팝업 흡수 B · 시안 ⓒ) — 새 현장 줄 표 = 공용 되풀이 줄(.pnl-rows · 「과제 440」) · 머리 = .pnl-sect + .pnl-sect-act · 옛 .odf- 13 이름 0
   칸 차례 = 이 표 id 한 줄(--pnl-cols · 값 = 옛 .odf-row 그대로) · 돈 칸 오른쪽(.r) · 붙여넣기 알림 ✓ 색 = 옛 .odf-ok 값 · 나머지 모양 = 공용 부품 */
#odfGrid{--pnl-cols:14px minmax(110px,1.15fr) minmax(160px,1.6fr) 80px 52px 40px 124px minmax(56px,.8fr) 72px 28px}
#odfGrid .pnl-row input.r{text-align:right}
#odfGrid .pnl-row > [data-c]{min-width:0}
#odfPasteMsg[data-ok]{color:var(--ok)}
#odFieldWrap [data-part="note"]{margin-top:6px}
#odfErr{margin-top:6px}
/* 「새 현장」 표 = 같은 상자(#odUnivList) · 열 열 · 한 줄 */
#odUnivList.odu-fld .clrow{grid-template-columns:minmax(116px,1.2fr) minmax(86px,1.4fr) 76px 76px 140px minmax(104px,.8fr) 96px 64px minmax(86px,1fr) 56px}   /* ★ 과제 542 — 1280 칸 최소 합 1010→900 + 왼 안여백 48(고르기 자리 · 대학교 표와 같은 꼴) = 상자 948 · 이름 132→116 · 주소 150→86 · 부착 위치 132→86(셋 말줄임 + title) · 더보기 40→56(단추 28 + 안여백 28) · 디자이너 10-28 10:03 */
#odUnivList.odu-fld .clrow > div{min-width:0}
#odUnivList.odu-fld .clrow .odf-noloc{color:var(--text-3)}
#odUnivList .clrow .odf-exp{display:none}
#odUnivList.odu-fld .clrow .odf-more button{width:28px;padding:0}
#odUnivWrap.odu-fldmode #odToBtn{display:none}   /* 새 현장 = [TO 확인] 없음(시안 4) */
@media (max-width:600px){
  #odUnivList.odu-fld .clrow{grid-template-columns:minmax(0,1fr) auto;row-gap:2px}
  #odUnivList.odu-fld .clrow.clhead > div:not(:first-of-type):not(:nth-of-type(7)){display:none}
  #odUnivList.odu-fld .clrow > div{order:2}
  #odUnivList.odu-fld .clrow > .cl-name{order:0;display:flex;align-items:center;gap:6px}
  #odUnivList.odu-fld .clrow > .odu-stcell:not([data-k]){order:1}
  #odUnivList.odu-fld .clrow:not(.clhead) > [data-k]{display:none}
  #odUnivList.odu-fld .clrow.odf-open > [data-k]{display:flex;align-items:center;justify-content:flex-start;text-align:left;gap:8px;grid-column:1 / -1;white-space:normal;font-size:var(--fs-sm)}
  #odUnivList.odu-fld .clrow.odf-open > [data-k]::before{content:attr(data-k);flex:0 0 64px;color:var(--text-3);font-size:var(--fs-cap)}
  #odUnivList.odu-fld .clrow .odf-exp{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;background:none;border:0;color:var(--text-3);cursor:pointer}
  #odUnivList.odu-fld .clrow.odf-open .odf-exp{transform:rotate(180deg)}
  #odfGrid .pnl-row > [data-c="name"],#odfGrid .pnl-row > [data-c="address"],#odfGrid .pnl-row > [data-c="memo"]{grid-column:1 / -1}   /* ★ 과제 455 — 폰 두 칸 격자 = 공용 .pnl-row 600 규칙 + 이 표 통째 칸 셋 */
  #odfGrid .pnl-row > .pnl-row-x{justify-self:end}
}
/* ★ 과제 407b(422 멈춤 · v426 ⓒ1 ⓒ2) — 발주 등록(인력) 「집행학교」 = 팝업 표준 칸 꼴(왼쪽 이름 --pk-w · 오른쪽 상자) — 과제 142 의 #odLaborCard .od-schoolcol(세로)이 표준을 이기던 자리 · 팝업 밖(옛 옷)은 그대로 */
.slideover.pstd #odLaborCard .row > [data-part="schoolcol"]{display:grid;grid-template-columns:var(--pk-w) minmax(0,1fr);align-items:center;column-gap:12px;row-gap:4px}
.slideover.pstd #odLaborCard .row > [data-part="schoolcol"] > :not(label){grid-column:2}
.slideover.pstd #odLaborCard #odSchoolPickBtn{width:100%;height:var(--h-ctl);justify-content:flex-start;text-align:left;border:1px solid var(--line-input);background:var(--bg-card);color:var(--text);border-radius:var(--r-ctl)}
#odDashChip [data-dashv].on{border-color:var(--accent);color:var(--accent)}   /* ★ 3차 — 거름 띠 보기 단추 = 지금 보기(가리킴 색) */
/* ── 과제 407b 끝 ── */
/* ★ 과제 426b — 견적 링크(광고주 열람 · 동의 = 자동 계약) : 단추 · 한 줄 · 주소 글 · 숨김(`button{display:inline-flex}` 가 [hidden] 을 이김 = 같은 함정 · 1255) · 새 색 0 · 토큰만 */
#qDetBtns > button[hidden],.qsdone-btns > button[hidden],.qsh-url[hidden],#qDetShare[hidden],.qsh-nodel[hidden]{display:none}
.qsh-appr[hidden]{display:none}   /* ★ 과제 431 ⑤ — 승인 요청 한 줄(#qDetAppr · #qsDoneAppr) · 글 = 본문 · 단추 = 보조 작은 단추 */
.qsh-appr{font-size:var(--fs-sm);color:var(--text)}
#qsFootBar > .qsf-appr{flex:1 0 100%}
.qsh-chips{display:contents}
.qsh-line{display:flex;align-items:center;flex-wrap:wrap;gap:4px 8px}
.qsh-line .sp{flex:1}
.qsh-url{font-size:var(--fs-sm);color:var(--text);word-break:break-all;user-select:all;-webkit-user-select:all}
.qsh-err{font-size:var(--fs-cap);color:var(--text-2)}
.qsh-nodel{font-size:var(--fs-sm);margin-right:auto}
/* ── 과제 426b 끝 ── */

/* ── ★ 과제 428 (10-17 대표 답 A) — 로그인 카드 · 홈 로그인 길잡이 · 「미연결」 단추 초점(화면 전용 cn-* · 새 색 0 · 그림자 0)
   칸 = 적는 칸(asform) 그대로 · 한 줄에 하나 · 폭 460(오른쪽 팝업 작은 폭과 같은 값) · 「고급」 = details(기본 닫힘 · 주소 · 키 · 연결 시험) ── */
/* ★ 과제 431 ③ (디자인 점검 B5) — 로그인 카드 = 가운데 · 최대 폭 520(DESIGN §12 팝업 폭 460 · 560 사이 · 폭 토큰 없음 = 자리 값 · G-591) · 점검 카드 둘 = 대표 · 재무만(.cn-boss · core.js cnBossPaint) */
#conn .cn-login{max-width:520px;margin-left:auto;margin-right:auto}
#conn .cn-boss[hidden]{display:none}
/* ★ 과제 431 ① — 견적 발 [PDF 내보내기] 저장 전 숨김(작성자 display 가 [hidden] 을 이김 · 규칙 58) · 그 자리 한 줄 · ⓘ 풍선 = 도움말 줄 기준(칸 상자 밑에서 시작) */
#qsFootBar > button[hidden],#qsFootBar > .qsf-pdfwait[hidden]{display:none}
#qsFootBar .qsf-pdfwait{font-size:var(--fs-sm);white-space:nowrap}
/* ★ 458 디자이너 ⑥ — 1440 발 = 한 줄(합계 · 칩 · 안내 글 · 단추 넷) : 단추는 줄지 않고 오른쪽 · 남는 폭이 모자라면 「저장하면 PDF…」 만 말줄임 · 합계 · 공급가 · 할인 = 안 자르고 합계 칸 안에서 두 줄 · 칩은 그대로
   승인 줄(.qsf-appr)이 보일 때만 두 줄 · 폰(≤600) = 옛 두 줄 꼴 그대로 */
@media (min-width:601px){
  #qsFootBar{flex-wrap:wrap;row-gap:var(--gap-tool);justify-content:flex-start}   /* ★ 과제 517(디자이너 10 시안 ccdcfca · 기획 판단 ⓐ) — 1440 발 = 늘 두 줄 : 위 = 합계(안 줄어듦) · 알약 · 남은 것 / 아래 = PDF 안내 ··· 단추 넷 · 옛 = 한 줄(큰 금액 + 알약 셋 = 합계 칸 폭 0 · 돈 안 보임) · 승인 줄 보이면 세 줄 */
  #qsFootBar > button{flex:none}
  #qsFootBar > .qsf-pdfwait{flex:0 4 auto;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}   /* 안내 글 = 먼저 말줄임 */
  #qsFootBar > .qsf-sum{flex:none;white-space:nowrap}   /* ★ 517 — 돈 = 줄지 않음 · 안 꺾임(§11-3 · 옛 flex:0 1 auto = 눌려 폭 0) */
  #qsFootBar > .qsf-gap{flex:1 0 100%;height:0}   /* ★ 517 — 줄 나눔 자리(마크업 그대로) */
  #qsFootBar > .qsf-gap,#qsFootBar > .qsf-pdfwait,#qsFootBar > button{order:1}   /* ★ 517 — 「남은 것」(#qsfLeft · 마크업 = 안내 글 뒤)은 위 줄에 남김 · 마크업을 옮기면 폰(≤600) 차례까지 바뀜 → 1440 만 차례로 */
  #qsFootBar > .qsf-pdfwait:not([hidden]){margin-right:auto}
  #qsFootBar > .qsf-pdfwait[hidden] ~ #qsPdf{margin-left:auto}   /* 시안 「+」 → 「~」 : 사이에 #qsfLeft 가 낌 */
  #qsFootBar > .qsf-pdfwait[hidden] ~ #qsPdf[hidden] ~ #qsPreviewBtn{margin-left:auto}
  #qsFootBar > #qsfChips{flex:none;white-space:nowrap}
}
#qsCampHelp{position:relative}
#qsCampHelp .tk-dinfo[data-tip]:hover::after,#qsCampHelp .tk-dinfo[data-tip]:focus::after{left:calc(var(--pk-w) + 12px);max-width:min(280px, calc(100% - var(--pk-w) - 24px))}
#conn .cn-login .cn-form,#conn .cn-login #connMsg{max-width:460px}
#conn .cn-login .cn-form .cdprops.asform{grid-template-columns:minmax(0,1fr)}
#conn .cn-login .cn-raw{margin:8px 0 0;font-size:var(--fs-cap);color:var(--text-3);word-break:break-word}
#conn .cn-login .cn-adv{margin-top:16px;padding-top:12px;border-top:1px solid var(--line)}
#conn .cn-login .cn-adv>summary{cursor:pointer;width:fit-content;font-size:var(--fs-sm);color:var(--text-2);border-radius:var(--r-ctl)}
#conn .cn-login .cn-adv>summary:hover{color:var(--text)}
#conn .cn-login .cn-adv>summary:focus-visible{outline:none;box-shadow:var(--ring)}
#conn .cn-login .cn-adv[open]>summary{margin-bottom:8px}
#home #hLogin .cn-guidebtns{margin-top:10px}
#sideUser:focus-visible{outline:none;box-shadow:var(--ring)}
/* ★ 과제 428 검토 권고 ① — 같은 말 둘 ✗ : 홈(미연결) = 길잡이 #hLogin 하나 · 로그인 카드(#conn) 위 = 띠가 「「연결과 점검」에서」 로 지금 자리를 가리킴 → 둘 다 띠 숨김(다른 화면 = 띠 그대로) */
body:has(#home.on) #connBar,body:has(#conn.on) #connBar{display:none !important}
/* ── ★ 과제 433 (10-19 대표 「로그인 박스만 가운데 · 나머지 화면은 비워져 있게」) — 미연결 + 로그인 화면 = 한 장(body.cn-gate = core.js setConnBar · #conn.on 일 때만)
   셸(머리 · 왼쪽 메뉴 · 맨 위 띠) · 큰 제목 · 부제 · 점검 카드 = 숨김 · 위 = 상표 두 줄(.cn-brand) → 카드(최대 폭 400 · [로그인] 온 폭) → 한 줄(.cn-foot)
   PC = 세로 · 가로 가운데 · 폰(≤ 600) = 위에서 48 · 좌우 16(키보드가 올라와도 카드 보임) · 상표 · 한 줄은 한 장에서만(로그인한 사람의 「연결 · 점검」 = 옛 모양)
   미연결로 다른 화면에 가면(주소를 손으로 바꿈 등) 옛 셸 · 띠 · 홈 길잡이 그대로(G-610) · 새 색 0 · 그림자 0 */
#conn .cn-brand,#conn .cn-foot{display:none}
body.cn-gate:has(#conn.on) header,
body.cn-gate:has(#conn.on) .wrap > nav,
body.cn-gate:has(#conn.on) #connBar,
body.cn-gate:has(#conn.on) #conn > h2,
body.cn-gate:has(#conn.on) #conn > p.sub,
body.cn-gate:has(#conn.on) #conn .cn-boss{display:none !important}
body.cn-gate:has(#conn.on) .wrap{margin-left:0;min-height:0}
body.cn-gate:has(#conn.on) main{padding:0}
body.cn-gate:has(#conn.on) #conn{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;
  box-sizing:border-box;min-height:100vh;padding:24px 16px;background:var(--bg-app)}
body.cn-gate:has(#conn.on) #conn .cn-brand{display:block;text-align:center}
#conn .cn-brand .cn-b1{font-size:var(--fs-card);font-weight:var(--weight-strong);color:var(--ink);line-height:1.3}
#conn .cn-brand .cn-b2{margin-top:4px;font-size:var(--fs-cap);color:var(--text-3)}
body.cn-gate:has(#conn.on) #conn .cn-login{box-sizing:border-box;width:100%;max-width:400px;margin:0}
body.cn-gate:has(#conn.on) #conn .cn-login .cn-form,body.cn-gate:has(#conn.on) #conn .cn-login #connMsg{max-width:none}
body.cn-gate:has(#conn.on) #conn .cn-login #btnLogin{flex:1 1 100%;width:100%}
body.cn-gate:has(#conn.on) #conn .cn-adv .cdprop > .pv{min-width:0;overflow-wrap:anywhere}   /* 「고급」 을 펼치면 주소 · 키 값이 400 카드 안에서 줄을 넘김(잘림 0 · 글자크기 v148 ④) */
body.cn-gate:has(#conn.on) #conn .cn-foot{display:block;margin:0;text-align:center;font-size:var(--fs-cap);color:var(--text-3)}
@media (max-width:600px){
  body.cn-gate:has(#conn.on) #conn{justify-content:flex-start;padding:48px 16px 24px}
}
/* ── 과제 433 끝 ── */

/* ════════════════════════════════════════════════════════════════════════════════════════════════
   ★★ 과제 440 (10-19 대표 「모든 팝업의 기준 = 좌측 항목명 · 우측 데이터 박스로 통일」) — **팝업 공용 부품 한 벌**(주인 = `pnl-`)
   정본 = DESIGN.md §12 「지금 기준」 · 시안 = 화면그리기/그림_261019/과제팝업_시안_ⓐ~ⓕ · 관문 = 검증도구/…팝업옷검사_v460.js
   ⚠ 이 묶음은 **더하기만** 한다 — 앞의 `.slideover.pstd` 규칙 값은 한 글자도 안 바꿈(같은 값을 `.pstd` 로 넓힌 줄 + 새 부품 셋).
     그래서 지금 화면 · 팝업 모습은 그대로이고, 화면이 마크업을 옮길 때(프론트 흡수 카드) 이 부품을 입는다.
   ⓐ 그릇 — 슬라이드 팝업 밖(오른쪽 상세 `.mdside` · 자체 모달)도 `.pstd` 하나만 붙이면 같은 뼈대 :
      `.pnl-head`(종류 · ✕) → `.pnl-title`(큰 제목) → `.pnl-sum`(세부정보 흰 한 줄) → `.pnl-body`(몸 · 스크롤) → `.pnl-foot`(발 · 바닥)
   ⓑ 칸 · 읽기 상자 = 앞 378a 값 그대로를 `.pstd` 로 · 고치는 값(`.pv.editable` · `.pv.pf-v.editable`) = 흰 상자(적는 칸과 같은 옷)
   ⓒ 새 부품 셋 : `.pnl-rows`(되풀이 줄 표 · 옛 `.odf-grid` 꼴) · `.pnl-checks`(고르기 여러 개 묶음) · `.pnl-indent`(상자 열에 맞춤) + `.pnl-sect-act`(구역 머리 오른쪽 단추)
   값 = 토큰 · 간격 숫자는 앞 규칙에 이미 있는 값만(새 값 0) · 색 · 모서리 · 굵기 = 토큰
   ════════════════════════════════════════════════════════════════════════════════════════════════ */
/* ⓐ 그릇(슬라이드 팝업 밖) */
.pstd:not(.slideover){display:flex;flex-direction:column;gap:0;padding:0;overflow:hidden;background:var(--bg-card)}
.pstd:not(.slideover) > .pnl-body{flex:1;min-height:0;overflow-y:auto;padding:18px var(--pad-pop-x) 22px}
.pstd:not(.slideover) > .pnl-foot{flex-shrink:0;margin:0;display:flex;align-items:center;gap:8px;padding:12px var(--pad-pop-x);border-top:1px solid var(--line);background:var(--bg-card)}
.pstd .pnl-title{flex-shrink:0;padding:var(--gap-tool-body) var(--pad-pop-x) 4px;font-size:var(--fs-title);font-weight:var(--weight-strong);
    line-height:1.3;letter-spacing:-.01em;color:var(--ink);overflow-wrap:anywhere;background:var(--bg-card)}
.pstd .pnl-title[hidden]{display:none}
.pstd .pnl-title .pill{vertical-align:middle;margin-left:4px}
.pstd .pnl-title:not(:has(+ .pnl-sum:not([hidden]))){padding-bottom:var(--gap-field);border-bottom:1px solid var(--line)}
.pstd .pnl-sum{background:var(--bg-card);padding:2px var(--pad-pop-x) var(--gap-field);border-bottom:1px solid var(--line)}
.pstd > .hint{margin:var(--gap-field) var(--pad-pop-x) 0}   /* ★ 과제 432 모양 검토 [1](디자이너 9) — 머리 아래 안내 한 줄(그릇 바로 아래 .hint · 첫 자리 = 할 일 #tmAppr) = 제목 · 세부정보 · 몸과 같은 좌우 선 */
/* ⓐ′ 구역 제목 = 슬라이드 팝업과 같은 옷(앞 `aside.slideover .pnl-sect` 값 그대로 · 그릇 밖에도) */
.pstd .pnl-sect{font-size:var(--fs-body);font-weight:var(--weight-strong);color:var(--text)}
/* ⓑ 칸 = 한 줄에 하나 · 왼쪽 이름(--pk-w) · 오른쪽 상자 */
.pstd .cdprops.asform,.pstd .cdprops.dtform{grid-template-columns:minmax(0,1fr);gap:10px}
.pstd .cdprops.asform .cdprop,.pstd .cdprops.dtform .cdprop{display:grid;grid-template-columns:var(--pk-w) minmax(0,1fr);align-items:center;column-gap:12px;row-gap:4px}
.pstd .cdprops.asform .cdprop > .pk,.pstd .cdprops.dtform .cdprop > .pk{grid-column:1;font-weight:var(--weight-body);color:var(--text);overflow-wrap:anywhere}
.pstd .cdprops.asform .cdprop > :not(.pk),.pstd .cdprops.dtform .cdprop > :not(.pk){grid-column:2}
.pstd .cdprops.asform .cdprop:has(> textarea),.pstd .cdprops.dtform .cdprop:has(> .pv[data-t="multiline"]){align-items:start}
.pstd .cdprops.asform .cdprop:has(> textarea) > .pk,.pstd .cdprops.dtform .cdprop:has(> .pv[data-t="multiline"]) > .pk{padding-top:8px}
.pstd .cdprops.asform > .pfhelp,.pstd .cdprops.asform > .hint{padding-left:calc(var(--pk-w) + 12px)}
.pstd .cdprops.dtform .cdprop > .pv:not(.editable),
.pstd .cdprops.asform .cdprop > .pv:not(.pf-v):not(.editable){min-height:32px;display:flex;align-items:center;gap:6px;box-sizing:border-box;
    padding:4px 10px;border:1px solid var(--line);border-radius:var(--r-ctl);background-color:var(--bg-hover);color:var(--ink);font-size:var(--fs-body)}
/* ⓑ′ 고치는 값 = 흰 상자(누르면 고치는 줄 · 고르는 칸) — 적는 칸(input)과 같은 옷 · 슬라이드 팝업 밖 그릇(오른쪽 상세 · 자체 모달)만
   (슬라이드 팝업 안 고치는 값은 화면마다 옷이 이미 있음 — 매체정보 수정 · 미리보기 따위 · 흡수 카드에서 하나로) */
.pstd:not(.slideover) .cdprops .cdprop > .pv.editable{min-height:32px;display:flex;align-items:center;gap:6px;box-sizing:border-box;margin:0;
    padding:4px 10px;border:1px solid var(--line-input);border-radius:var(--r-ctl);background:var(--bg-card);color:var(--ink);font-size:var(--fs-body)}
.pstd:not(.slideover) .cdprops .cdprop > .pv.editable:hover{border-color:var(--accent);background:var(--bg-card)}
/* ⓑ″ ★ 과제 463 (디자이너 4 · 10-20 · 453 모양 검토 참고 ④) — 고치는 상자를 **연 동안 = 선 하나** :
   안에 들어온 input · select · textarea(core.js startInput 이 .pv 안에 넣는다)는 제 테두리 · 초점 고리 · 바탕 · 모서리 0 · 높이 = 상자 안(--h-ctl − 선 2) ·
   초점 고리는 **상자**(:focus-within)에 하나(--accent + --ring · 적는 칸과 같은 그림) · 읽기 상자(--bg-hover) · 슬라이드 팝업 안 입력칸은 그대로(범위 = .pstd:not(.slideover) 만) */
.pstd:not(.slideover) .cdprops .cdprop > .pv.editable:has(> input,> select,> textarea){padding:0 10px;cursor:text}
.pstd:not(.slideover) .cdprops .cdprop > .pv.editable:focus-within{border-color:var(--accent);box-shadow:var(--ring);background:var(--bg-card)}
.pstd:not(.slideover) .cdprops .cdprop > .pv.editable > input,.pstd:not(.slideover) .cdprops .cdprop > .pv.editable > select,.pstd:not(.slideover) .cdprops .cdprop > .pv.editable > textarea{
    border:0;box-shadow:none;outline:0;background-color:transparent;margin:0;padding:0;width:100%;max-width:none;flex:1;min-width:0;font-size:var(--fs-body);color:var(--ink)}
.pstd:not(.slideover) .cdprops .cdprop > .pv.editable > input,.pstd:not(.slideover) .cdprops .cdprop > .pv.editable > select{height:calc(var(--h-ctl) - 2px);min-height:0}
.pstd:not(.slideover) .cdprops .cdprop > .pv.editable > textarea{padding:6px 0;height:auto}
.pstd:not(.slideover) .cdprops .cdprop > .pv.editable:has(> textarea){flex-wrap:wrap}   /* ★ 과제 453 (디자이너 5 답 ① · 10-20) — 여러 줄 칸 = 상자 폭 전부 · 키 안내(⌘Enter 저장 · Esc 취소)는 상자 안 다음 줄(gap = 위 상자의 6 · 새 숫자 0) · 범위 = ⓑ″ 와 같은 선택자 */
.pstd:not(.slideover) .cdprops .cdprop > .pv.editable:has(> textarea) > textarea{flex-basis:100%}
.pstd:not(.slideover) .cdprops .cdprop > .pv.editable > input:focus,.pstd:not(.slideover) .cdprops .cdprop > .pv.editable > select:focus,.pstd:not(.slideover) .cdprops .cdprop > .pv.editable > textarea:focus{border:0;box-shadow:none;outline:0}
/* ⓒ 되풀이 줄 표 — 칸 차례는 그 표의 그릇에 `--pnl-cols`(화면 id 한 줄)로 준다 · 없으면 한 칸 */
.pnl-rows{display:grid;gap:0;margin:0 0 4px}
.pnl-row{display:grid;grid-template-columns:var(--pnl-cols,minmax(0,1fr));gap:4px;align-items:center;padding:6px 0;border-bottom:1px solid var(--line-soft)}
.pnl-row.pnl-rows-hd{padding:0 0 6px;border-bottom:1px solid var(--line);font-size:var(--fs-cap);font-weight:var(--weight-medium);color:var(--text-2)}
.pnl-row .pnl-row-no{font-size:var(--fs-cap);color:var(--text-3);text-align:right}
.pnl-row input,.pnl-row select{width:100%;min-width:0;box-sizing:border-box;height:var(--h-ctl);font-size:var(--fs-sm);padding-left:8px;padding-right:8px;border-color:var(--line-input)}   /* ★ 과제 479 2차(검토 5 [2]) — 되풀이 줄 적는 칸도 --line-input(옛 --line = 광고주 담당자 줄만 옅었음) */
.pnl-row input:focus,.pnl-row select:focus{border-color:var(--accent)}
.pnl-row .pnl-row-x button{width:28px;padding:0}
.pnl-row input.pnl-row-fixed{color:var(--text-3);background:var(--bg-fill);text-align:center}   /* 잠긴 칸(고정 단위 「장」) */
.pnl-row .pnl-row-bad,.pnl-row input.pnl-row-bad:not([type="checkbox"]):not([type="radio"]){border-color:var(--bad);background:var(--bad-bg)}   /* 틀린 칸 · ★ 과제 471 — input 줄(0,4,1) = 슬라이드 팝업 입력칸 규칙(0,3,2)을 이기고 · 누름(:focus 0,4,2)엔 짐 = 초점 고리 그대로 */
.pnl-row .pnl-row-msg{grid-column:2 / -1;margin:0}
@media (max-width:600px){
  .pnl-row{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
  .pnl-row.pnl-rows-hd,.pnl-row .pnl-row-no{display:none}
  .pnl-row .pnl-row-wide,.pnl-row .pnl-row-msg{grid-column:1 / -1}
}
/* ⓒ 구역 머리 오른쪽 단추([+ 줄] 따위) — 선 뒤 오른쪽 끝 */
.pnl-sect:has(> .pnl-sect-act)::after{order:1}
.pnl-sect > .pnl-sect-act{order:2;margin-left:0;display:inline-flex;gap:var(--gap-tool)}   /* ★ 492 2차(디자이너 10 허락) — 머리 단추 둘 사이 = 토큰 하나(단추 하나뿐인 자리 변화 0) */
/* ⓒ 고르기 여러 개(체크 · 칩) = 상자 열 안에서 줄바꿈 묶음 · 상자 열에 맞춤 */
.pnl-checks{display:flex;flex-wrap:wrap;align-items:center;gap:6px var(--gap-field-x)}
.pnl-checks > label{display:inline-flex;align-items:center;gap:6px;margin:0;font-size:var(--fs-sm);font-weight:var(--weight-body);color:var(--text)}
.pstd .pnl-indent{margin-left:calc(var(--pk-w) + 12px)}
/* ★ 과제 473 (디자이너 5 · 10-21) — 공용 부품 둘 더함(값 = 지금 쓰는 값 그대로 · 새 값 0)
   ⓓ 두 단 `.pnl-two` = 820 상세(캠페인 · 거래처)의 두 칸 · 칸(바로 아래 자식)마다 구역을 세로로 쌓음 · 760 아래 = 한 칸(값 = #vendViewBody .vs-two/.vs-col 그대로)
   ⓔ 줄 표 숫자 칸 `.pnl-row .num` = 오른쪽 맞춤 · 고정폭 숫자(금액 · 수량 · 합계 · 날짜 아님) */
.pnl-two{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;align-items:start}
.pnl-two > *{display:flex;flex-direction:column;gap:16px;min-width:0}
.pnl-two > * > .viewsec{margin-top:0}
@media (max-width:760px){ .pnl-two{grid-template-columns:minmax(0,1fr)} }
.pnl-row .num{text-align:right;font-variant-numeric:tabular-nums}
/* ── 과제 440 끝 ── */

/* ════════════════════════════════════════════════════════════════════════════════════════════════
   ★ 과제 479b (디자이너 8 · 10-22 · 대표 A 확정 G-674) — **공용 부품 둘 : 진도 띠 `.stepbar` · 「지금 할 일」 번호 목록 `.nextlist`** + 요약 타일 넷 `.stats.cols4`
   정본 = DESIGN.md §6-12 · 본보기 마크업 = 루프/UX/479b_부품_마크업.html(프론트는 그대로 복사) · 관문 = 검증도구/…v4표칩검사_v441.js ⓘ
   첫 자리 = 캠페인 정보 팝업(#campInfoModal · §12 예외) · 화면 접두어 ✗ — 단계 · 다음 행동을 보여 줄 자리면 어디서나 같은 옷
   색의 역할 : 진도(끝난 칸 · 지금 글) = 인디고 --accent(가리킴) / 1번 숫자 동그라미 = 보라 --fill-brand(숫자 배지 = 채움) · 그라데이션 0 · 그림자 0
   ════════════════════════════════════════════════════════════════════════════════════════════════ */
/* ⓐ 진도 띠 — 칸 수 = li 수(캠페인 = CAMP_STAGES 7) · 끝난 칸 .done = --accent 막대 · 지금 칸 .now(aria-current="step") = --accent-line 막대 + --accent 글 · 남은 칸 = --line-soft */
.stepbar{min-width:0}
.stepbar > ol{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);gap:4px;margin:0;padding:0;list-style:none}
.stepbar > ol > li{display:flex;flex-direction:column;gap:6px;min-width:0;margin:0;padding:0;font-size:var(--fs-cap);font-weight:var(--weight-body);color:var(--text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.stepbar > ol > li::before{content:"";display:block;height:4px;border-radius:var(--r-pill);background:var(--line-soft)}
.stepbar > ol > li.done{color:var(--text-2)}
.stepbar > ol > li.done::before{background:var(--accent)}
.stepbar > ol > li.now{color:var(--accent);font-weight:var(--weight-medium)}
.stepbar > ol > li.now::before{background:var(--accent-line)}
.stepbar > .stepbar-now{display:none;margin:6px 0 0;font-size:var(--fs-sm);color:var(--text-2)}
.stepbar > .stepbar-now b{font-weight:var(--weight-medium);color:var(--accent)}
/* ⓑ 「지금 할 일」 번호 목록 — 줄 = 번호 · 제목 + 한 줄 설명 · 갈 곳 단추(.ghost.mini) · 첫 줄 = 지금 먼저 할 것(--accent-soft 칠 + 번호 --fill-brand) */
.nextlist{margin:0;padding:0;list-style:none;border:1px solid var(--line);border-radius:var(--r-card);overflow:hidden;background:var(--bg-card)}
.nextlist > li{display:grid;grid-template-columns:var(--sz-avatar) minmax(0,1fr) auto;align-items:center;gap:var(--gap-tile);margin:0;padding:var(--gap-tile) var(--pad-cell-x)}
.nextlist > li + li{border-top:1px solid var(--line-soft)}
.nextlist > li:first-child{background:var(--accent-soft)}
.nextlist .nextlist-no{display:inline-flex;align-items:center;justify-content:center;width:var(--sz-avatar);height:var(--sz-avatar);border-radius:var(--r-pill);
    background:var(--bg-fill);color:var(--text-2);font-size:var(--fs-cap);font-weight:var(--weight-medium);font-variant-numeric:tabular-nums}
.nextlist > li:first-child .nextlist-no{background:var(--fill-brand);color:var(--on-fill)}
.nextlist .nextlist-tx{display:flex;flex-direction:column;gap:2px;min-width:0}
.nextlist .nextlist-t{font-size:var(--fs-body);font-weight:var(--weight-medium);color:var(--ink);overflow-wrap:anywhere}
.nextlist .nextlist-d{font-size:var(--fs-sm);color:var(--text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.nextlist .nextlist-go{white-space:nowrap}
/* ⓒ 요약 타일 넷 — 기존 `.stat` 그대로 · 줄만 넷(폰 = 둘) · 값이 글(매체 · 담당)이라 숫자 단 대신 큰 값 단 --fs-page */
.stats.cols4{grid-template-columns:repeat(4,minmax(0,1fr));margin-bottom:0}
.stats.cols4 .stat,.stats.cols4 .stat:hover{cursor:default;border-color:var(--line);background:var(--bg-card)}   /* 보기 타일 = 누르는 것 아님(hover 옷 0) */
.stats.cols4 .stat .v{font-size:var(--fs-page);overflow-wrap:anywhere}
.stepbar + .stats.cols4{margin-top:var(--gap-field)}   /* ★ 479c 모양 검토 [1] — 진도 띠 바로 아래 타일 = 칸 이름이 타일 테에 붙지 않게(시안 3_A) */
@media (max-width:600px){
  .stepbar > ol > li{font-size:0;gap:0}                         /* 폰 390 = 막대만 + 「4/7 끝 · 지금 = 결과보고」 한 줄(수 = 끝난 칸) */
  .stepbar > .stepbar-now{display:block}
  .nextlist > li{grid-template-columns:var(--sz-avatar) minmax(0,1fr);align-items:start}
  .nextlist .nextlist-d{white-space:normal}
  .nextlist .nextlist-go{grid-column:2;justify-self:start}      /* 갈 곳 단추 = 줄 아래 */
  .stats.cols4{grid-template-columns:repeat(2,minmax(0,1fr))}
}
/* ★ 과제 483 (디자이너 9 · 10-22 · 479c 모양 검토 거리 셋) — 갈래 줄 · 세부정보 구분점 · 끝난 진도 띠 · 토큰만 · DESIGN §12-0000 · §6-12
   ⓓ 큰 제목 위 갈래 줄 `.pnl-crumb` = 「광고주 › 캠페인」(누구 것) · 머리 띠와 큰 제목 사이 · 값 없으면 hidden · 구분 = span.sep(aria-hidden) */
.pstd .pnl-crumb{flex-shrink:0;margin:0;padding:var(--gap-tool-body) var(--pad-pop-x) 0;font-size:var(--fs-cap);font-weight:var(--weight-body);color:var(--text-2);background:var(--bg-card);overflow-wrap:anywhere}
.pstd .pnl-crumb[hidden]{display:none}
.pstd .pnl-crumb .sep{color:var(--text-3)}
.pstd .pnl-crumb:not([hidden]) + .pnl-title{padding-top:calc(var(--gap-tool) / 2)}
/* ⓔ 세부정보 줄 구분점 — 줄바꿈 때 줄 끝에 「·」 가 매달리지 않게(마크업 = popSummary 그대로) : span.sep 는 숨기고 점 = 다음 항목 앞 그림(::after · 흐름 밖)
     · 앞 항목 오른쪽 여백 --gap-tile + 틈 --gap-tool = 점 자리 · 줄 첫머리로 내려간 항목의 점 = 내용 상자 밖 → overflow:clip 이 자름(3 = 초점 고리 --ring 바깥 폭은 남김) */
.pnl-sum:has(> .sep){overflow:clip;overflow-clip-margin:content-box 3px}   /* 두 축 clip 일 때만 margin 이 먹음(한 축 = 안여백 상자에서 잘려 점이 남음 · 실측) · 범위 = popSummary 줄(span.sep 있음)만 — dtBand 띠 + 「마지막 수정」 이력 상자(.dt-hist · 위 여백 −10)는 clip 밖(483 검토 6 [1]) */
.pnl-sum > .sep{display:none}
.pnl-sum .pair{display:inline-flex;align-items:center;gap:inherit;white-space:nowrap}   /* ★ 과제 499 ① (디자이너 10 허락) — 이름 · 값 한 묶음 = 안 꺾임 · 묶음 안 틈 = 줄 틈 그대로(gap:inherit · 새 값 0) · 줄은 묶음 사이에서만 꺾임(옆 굴림 ✗) */
/* ★ 과제 499 ② (디자이너 10 허락 · 10-24) — 폰(≤600) 구역 머리 = 한 줄 : 제목(글자 노드) 안 꺾임 · 덧말 .cnt = 말줄임(+ title · openPanel 이 붙임) · 머리 단추 .pnl-sect-act = 안 줄어듦 · 선(::after) = 0 까지 줄어듦 */
@media (max-width:600px){
  .pnl-sect{white-space:nowrap}
  .pnl-sect .cnt{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}   /* flex 0 1 = 948 의 flex:0 0 auto 를 폰에서만 풀어 줄어들게 */
  .pnl-sect > .pnl-sect-act{flex:none;white-space:nowrap}
  .pnl-sect::after{min-width:0}
}
.pnl-sum > :has(+ .sep){margin-right:var(--gap-tile)}
.pnl-sum > .sep + *{position:relative}
.pnl-sum > .sep + *::after{content:"·";position:absolute;top:0;bottom:0;right:100%;width:calc(var(--gap-tool) + var(--gap-tile));display:flex;align-items:center;justify-content:center;
    font-size:var(--fs-cap);font-weight:var(--weight-body);color:var(--text-3);pointer-events:none}
/* ⓕ 끝난 진도 띠(지금 칸 없음 = 끝난 캠페인 · 모두 끝) = 1440 에서도 띠 아래 한 줄(폰과 같은 말) · 굵은 글 = 잉크(가리킬 지금 칸이 없음) */
.stepbar:not(:has(> ol > li.now)) > .stepbar-now{display:block}
.stepbar:not(:has(> ol > li.now)) > .stepbar-now b{color:var(--ink)}
/* ── 과제 479b 끝 ── */
/* ★ 과제 509 (걷기 줄 9) — 「본문으로」 건너뛰기 = 평소 화면 밖 · 초점이면 왼쪽 위에 뜸(공용 a.btnlike 옷 · 토큰만) */
#skipMain{position:fixed;top:var(--gap-field);left:var(--gap-field);z-index:10000;transform:translateY(-200%)}
#skipMain:focus{transform:none;outline:none;box-shadow:var(--ring)}

/* ★ 과제 563 ③ — 재무 「판관비」 보기(#finOh) = 있는 부품만(타일 · 카드 = dashGrid · 표 = .clrow · .fin-mo-tbl · 칸 고치기 = .cl-ed · 상태 = .st · 알약 = .pill) — 여기는 칸 폭 · 정렬만(새 부품 0) */
#finOh .clrow.fin-oh{grid-template-columns:minmax(120px,1.1fr) repeat(6,minmax(104px,1fr)) minmax(96px,0.9fr)}   /* 분류 · 6달 · 전월 비 */
#finOh .clrow.fin-oh:not(.clhead){cursor:default}
#finOh .clrow.fin-oh [data-ohc]{cursor:pointer}
#finOh .clrow.fin-oh-sum{font-weight:var(--weight-strong);background:var(--surface-subtle)}
#finOh .clrow.fin-ohl{grid-template-columns:112px 128px minmax(0,2fr) 72px 120px 128px 88px}   /* 날짜 · 분류 · 내용 · 출처 · 금액 · 증빙 · 확인 */
#finOhRows{overflow-x:auto}
#finOh .clrow.fin-ohl{min-width:808px}   /* 칸 합 + 내용 최소 160 — 오른쪽 창이 밀어 좁아져도 내용 칸이 0 으로 겹치지 않게(상자 안 옆 굴림) */
#finOh .clrow.fin-ohl > .r,#finOh .clrow.fin-ohc > .r{text-align:right;justify-content:flex-end;font-variant-numeric:tabular-nums}
#finOh .clrow.clhead.fin-ohl > :is(:nth-child(5),:nth-child(7)),#finOh .clrow.clhead.fin-ohc > :nth-child(n+2){justify-content:flex-end;text-align:right}
#finOh .clrow.fin-ohc{grid-template-columns:minmax(0,1fr) 96px 140px}
#finOh .clrow.fin-ohc:not(.clhead){cursor:default}
#finOh .fin-note{margin:0 0 var(--gap-tile);font-size:var(--fs-sm)}
@media (max-width:1399px){ #finOh .fin-mo-tbl{overflow-x:auto} #finOh .clrow.fin-oh{min-width:880px} }
@media (max-width:600px){
  #finOh .clrow.fin-ohl{grid-template-columns:minmax(0,1fr) 104px 88px;min-width:0}   /* 폰 = 내용 · 금액 · [확인] — 날짜 · 분류 · 출처 · 증빙 = 넓은 화면 */
  #finOh .clrow.fin-ohl > :is(:nth-child(1),:nth-child(2),:nth-child(4),:nth-child(6)){display:none}
  #finOh .clrow.fin-oh{grid-template-columns:minmax(0,1fr) max-content max-content;min-width:0}   /* ★ 디자이너 563 ③ — 폰 월별 표 = 분류 · 이번 달 · 전월 비만(옛 = 옆 굴림 첫 칸이 가장 옛 달) · 넓은 화면 그대로 */
  #finOh .clrow.fin-oh > :nth-child(n+2):nth-child(-n+6){display:none}
}

/* ★ 과제 587 (디자이너 4 시안 ★B 두 칸 장부 · ea805a6 · 화면그리기/그림_261031/과제587_시안_*) — 폰 390 현장 › 급여 표(#odPayTbl[data-mob]) 오른 칸 잘림 · 「미확인 n일」 알약
   마크업 · id · 로직 그대로(폰 마크업 = 작업자 칸 넷 · 급여 · 지급 칸 셋) · 1줄 이름 … 급여 / 2줄 현장 · 캠페인 … 지급(+ 미확인) / 3줄 근무일 / 4줄 발송 … 행동 단추 · 1440 = @media 밖이라 변화 0
   ★ 검토 9 [1] — 규칙은 폰 마크업([data-mob] · orders.js odPayRender 가 폰일 때만 붙임)에만 : 넓은 마크업(td 8)이 그려진 채 창을 좁히면 옛 표 옆 굴림 그대로(겹침 0) · 간격 = 토큰(옛 6 · 2 → --gap-tool · 0) */
@media (max-width:600px){
 #odPayTbl[data-mob]{overflow-x:visible}
 #odPayTbl[data-mob] table,#odPayTbl[data-mob] tbody{display:block;width:100%}
 #odPayTbl[data-mob] thead{display:none}
 #odPayTbl[data-mob] tbody tr{display:grid;grid-template-columns:minmax(0,1fr) max-content;column-gap:var(--gap-tool);row-gap:0;align-items:baseline;padding:var(--gap-tool) 0;border-bottom:1px solid var(--line-soft)}
 #odPayTbl[data-mob] tbody td{display:contents}
 #odPayTbl[data-mob] tbody td:first-child > :nth-child(1){grid-column:1;grid-row:1}
 #odPayTbl[data-mob] tbody td:first-child > :nth-child(2){grid-column:1;grid-row:2}
 #odPayTbl[data-mob] tbody td:first-child > :nth-child(3){grid-column:1;grid-row:3}
 #odPayTbl[data-mob] tbody td:first-child > :nth-child(4){grid-column:1;grid-row:4}
 #odPayTbl[data-mob] tbody td + td > .numcell{display:flex;justify-content:flex-end;align-items:center;gap:var(--gap-tool);text-align:right;grid-column:2}
 #odPayTbl[data-mob] tbody td + td > :nth-child(1){grid-row:1}
 #odPayTbl[data-mob] tbody td + td > :nth-child(2){grid-row:2 / span 2;flex-direction:column;align-items:flex-end;align-self:start}
 #odPayTbl[data-mob] tbody td + td > :nth-child(3){grid-row:4}
 #odPayTbl[data-mob] [data-k="unc"]{white-space:nowrap}
}
/* ★ 과제 595 (587 미룸) — PC 1440 현장 › 급여 표(#odPayTbl · 폰 마크업 아님) 옆 굴림 49 → 0 : 칸 8 · 글 · 꼴 그대로 · 안 칸 안여백만 12 → --gap-tool(양 끝 24 = 목록 표준 그대로) · 칸 최소 합 1129 → 1073 ≤ 상자 1080 */
#odPayTbl:not([data-mob]) :is(th,td):not(:first-child){padding-left:var(--gap-tool)}
#odPayTbl:not([data-mob]) :is(th,td):not(:last-child){padding-right:var(--gap-tool)}
