/* JIYOU 공통 부품 계층(2026-10-14 대표 요청: 휴대폰·태블릿·컴퓨터 모두 틀어짐 없이, 앞으로 더하는 화면도 같은 부품으로).
   새 화면은 이 부품과 design-tokens.css 토큰만으로 만든다(DESIGN-SYSTEM.md ‘부품 계층’). tests/test_design_contract.py가 지킨다:
   - 반경은 --radius-* 토큰, 굵기는 400·500·600·700, 색은 var(--…) 토큰(그림자·배경막만 투명 검정 허용), !important 금지.
   - 화면 폭 기준은 둘뿐: 휴대폰 ≤760px · 태블릿 761–1180px · 컴퓨터 ≥1181px((max-width:760px)·(max-width:1180px)).
   - 누르는 곳은 터치 44px(--height-touch) 이상. tests/component_layout_browser.py가 세 화면 폭에서 넘침·잘림·크기를 잰다.
   포털의 기본 단추 규칙(materials.css: 모든 button에 알약 반경·48px·그라데이션)은 단추 모양 부품에만 맞다.
   사진·카드 제목처럼 단추 모양이 아닌 누르는 곳은 .ui-plain으로 끊는다(2026-10-14 휴대폰에서 사진 자리가 알약 모양으로 커졌던 원인). */

/* ---------------- 맨 단추: 모양 없이 누르는 곳 ---------------- */
:is(.workspace,.entry) .ui-plain,.ui-plain{appearance:none;-webkit-appearance:none;margin:0;padding:0;border:0;border-radius:0;background:none;box-shadow:none;
  min-width:0;min-height:0;font:inherit;color:inherit;text-align:inherit;letter-spacing:inherit;cursor:pointer;transform:none;transition:none}
:is(.workspace,.entry) .ui-plain:not(:where(:disabled,[aria-disabled="true"],[aria-busy="true"])):active{transform:none;box-shadow:var(--ui-control-shadow-active,none)}
.ui-plain:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}

/* ---------------- 명시적 배치 계약(2026-10-19): 폭·좌우 여백은 공통 부모의 변수와 이 열 하나가 소유한다.
   --ui-content-width는 화면의 공통 부모에서만 정한다(읽기 열과 넓은 업무 목록의 폭은 다를 수 있다).
   맞춰야 하는 형제 열은 같은 값을 상속한다. 자식마다 max-width/padding-inline을 되풀이하지 않는다.
   gap은 묶음이 소유하며 자식의 기본 세로 margin은 지운다. 자세한 API: docs/design-system/layout-contract-20261019.md. */
.ui-stack{display:grid;gap:var(--ui-stack-gap,calc(var(--space-unit) * 3));min-width:0}
.ui-cluster{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ui-cluster-gap,var(--gap-control));min-width:0}
.ui-fieldgroup{display:grid;gap:var(--gap-control);min-width:0;margin:0;padding:0}
:is(.ui-content-column,.ui-stack,.ui-cluster,.ui-fieldgroup),:is(.ui-content-column,.ui-stack,.ui-cluster,.ui-fieldgroup)>*{box-sizing:border-box;min-width:0;max-width:100%}
:is(.ui-stack,.ui-fieldgroup)>*{margin-block:0}
.ui-fieldgroup>.ui-field{display:block;width:100%;min-width:0;max-width:100%;box-sizing:border-box;margin:0}
:is(.ui-content-column,.ui-stack,.ui-cluster,.ui-fieldgroup)[hidden]{display:none}
/* A column may also be a stack: its inherited maximum wins over the generic 100% guard. */
.ui-content-column{box-sizing:border-box;width:100%;max-width:var(--ui-content-width,100%);min-width:0;margin-inline:auto;
  padding-inline:var(--ui-content-inset,var(--inset-content))}

/* 타이포는 클래스가 붙은 요소만 정한다. 전역 h1/h2/p나 문서 출력에는 적용하지 않는다. */
:is(.workspace,.entry) :is(.ui-title-page,.ui-title-section,.ui-copy,.ui-help,.ui-field-label,.ui-field-help){margin:0;overflow-wrap:anywhere}
:is(.workspace,.entry) .ui-title-page{font-size:var(--t-title1);font-weight:600;line-height:var(--lh-title);color:var(--ink)}
:is(.workspace,.entry) .ui-title-section{font-size:var(--t-title2);font-weight:600;line-height:var(--lh-title);color:var(--ink)}
:is(.workspace,.entry) .ui-copy{font-size:var(--t-body);font-weight:400;line-height:var(--lh-body);color:var(--ink)}
:is(.workspace,.entry) .ui-field-label{font-size:var(--t-subhead);font-weight:500;line-height:var(--lh-ui);color:var(--ink-2)}
:is(.workspace,.entry) :is(.ui-help,.ui-field-help){font-size:var(--t-footnote);font-weight:400;line-height:var(--lh-body);color:var(--ink-3)}

/* ---------------- 카드와 카드 격자 ---------------- */
.ui-cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,var(--ui-card-min,260px)),1fr));gap:12px;margin:0;padding:0;list-style:none}
/* 격자 칸 사이는 gap만: 예전 전역 규칙(portal.css `article+article`의 위 여백·윗줄·위 안쪽 여백)이 두 번째 카드부터 밀어 내려
   같은 줄 카드의 위쪽이 어긋났다(2026-10-14 운영 단가표 목록). :where로 예전 규칙과 같은 우선순위를 두어 화면별 클래스 스타일은 그대로 이긴다. */
.ui-cards>*{margin:0}
:where(.ui-cards)>article+article{margin-top:0;padding-top:0;border-top:0}
.ui-card{position:relative;display:flex;flex-direction:column;min-width:0;border:1px solid var(--rule);border-radius:var(--radius-card);background:var(--surface);overflow:hidden;
  transition:border-color var(--dur-state,220ms) var(--ease-standard,ease),box-shadow var(--dur-state,220ms) var(--ease-standard,ease)}
.ui-card.is-selected{border-color:var(--accent);box-shadow:inset 0 0 0 1px var(--accent)}
.ui-card.is-marked{border-color:var(--rule-strong);box-shadow:inset 0 0 0 1px var(--rule-strong)}

/* 카드 슬롯: 본문만 여백을 두어 그림·표의 외곽은 소비자가 정한다. */
.ui-card-body{display:flex;flex-direction:column;gap:var(--density-card-gap,16px);min-width:0;padding:var(--density-card-padding,20px)}
.ui-card-media{display:grid;place-items:center;flex:none;aspect-ratio:5/2;min-width:0;margin:0;padding:8px;overflow:hidden;background:var(--surface-2);box-sizing:border-box}
.ui-card-media>img{display:block;width:100%;height:100%;min-height:0;object-fit:contain}
/* 메타데이터는 dl/dd 기본 여백을 제거하고 값 전체를 읽도록 말줄임하지 않는다. */
.ui-meta{display:grid;gap:12px;min-width:0;margin:0}
.ui-meta>div{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.5fr);align-items:baseline;gap:12px;min-width:0}
/* 3항목 이상이면 항목 사이 옅은 선(2026-10-29 L-1). 간격은 선 위아래로 나눠 준다. */
.ui-meta:where(:not(.is-card-fields)):has(>div:nth-child(3)){gap:0}
/* ui-meta의 현재 서버/JS 생산자는 직계 div만 묶거나 div가 없다. 두 :is 분기의 최대 특이도는 기존 :has와 같다. */
.ui-meta:where(:not(.is-card-fields))>:is(div:nth-last-child(n+3),div:nth-last-child(n+3)~div){padding-block:8px}
.ui-meta:where(:not(.is-card-fields))>:is(div:nth-last-child(n+3),div:nth-last-child(n+3)~div)+div{border-top:1px solid var(--rule)}
.ui-meta dt{margin:0;font-size:var(--t-footnote);font-weight:400;line-height:var(--lh-body);color:var(--ink-2);overflow-wrap:anywhere}
.ui-meta dd{min-width:0;margin:0;text-align:right;font-size:var(--t-subhead);line-height:var(--lh-body);color:var(--ink);font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
/* Reading/detail variants: adjacent labels, one reading width, and native disclosure.
   Financial ui-meta keeps its existing right-aligned values. No document canvas opts in. */
/* A schedule is one readable unit; multi-day endpoints carry explicit roles. */
.ui-time-range{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--space-unit) var(--gap-control);width:fit-content;min-width:0;max-width:100%;box-sizing:border-box;padding:calc(var(--space-unit) * 2) calc(var(--space-unit) * 3);border:1px solid var(--rule);border-radius:var(--radius-group-inner);background:var(--surface-2);font-size:var(--t-body);line-height:var(--lh-ui);color:var(--ink)}
.ui-time-range-clock{display:inline-flex;align-items:baseline;gap:var(--space-unit);white-space:nowrap}
.ui-time-range-date{white-space:nowrap}
.ui-time-range.is-multiday{display:grid;gap:var(--space-unit)}
.ui-time-range-endpoint{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--space-unit) var(--gap-control)}
.ui-time-range-label{flex:0 0 auto;color:var(--ink-2)}
.workspace .ui-time-range time{display:inline;flex:none;margin:0;font:inherit;color:inherit;white-space:nowrap}
.workspace .ui-time-range-endpoint>time{display:flex;flex:0 1 auto;flex-wrap:wrap;gap:var(--space-unit) var(--gap-control);min-width:0;white-space:normal}
@media screen{
 .ui-time-range.is-multiday{align-items:stretch;gap:var(--gap-control);padding:0;border:0;background:transparent}
 .ui-time-range.is-multiday>.ui-time-range-endpoint{display:grid;align-content:start;gap:var(--space-unit);min-width:0;padding:var(--gap-control) calc(var(--space-unit) * 3);border-radius:var(--radius-small);background:var(--surface-2)}
}
.ui-reading-page{--ui-content-width:760px;--ui-content-inset:0;--ui-stack-gap:var(--gap-section)}
.ui-meta.is-reading>div{grid-template-columns:minmax(0,10rem) minmax(0,1fr);gap:var(--gap-control) calc(var(--space-unit) * 4)}
.ui-meta.is-reading dt,.ui-meta.is-reading dd{font-size:var(--t-body);line-height:var(--lh-body)}
.ui-meta.is-reading dd{text-align:start}
/* Read-only values inside a card share one label/value surface. Native links,
   definition-list semantics and full values stay with their existing owners. */
.ui-data-cards{display:flex;flex-wrap:wrap;align-items:stretch;gap:var(--gap-control);min-width:0;max-width:100%}
.ui-data-card{display:grid;align-content:start;gap:var(--space-unit);box-sizing:border-box;min-width:0;max-width:100%;padding:var(--gap-control) calc(var(--space-unit) * 3);border:0;border-radius:var(--radius-small);background:var(--surface-2);box-shadow:none}
.ui-data-card-label{display:block;min-width:0;margin:0;color:var(--ink-2);font-size:var(--t-body);font-weight:400;line-height:var(--lh-ui);overflow-wrap:anywhere}
.ui-data-card-value{display:block;min-width:0;margin:0;color:var(--ink);font-size:var(--t-body);line-height:var(--lh-body);overflow-wrap:anywhere}
/* A card that leads to a data section stays a native link with a touch target. */
.workspace .ui-data-links{gap:var(--gap-control)}
.workspace a.ui-data-link{display:inline-flex;align-items:center;justify-content:center;gap:var(--gap-control);box-sizing:border-box;min-width:0;max-width:100%;min-height:var(--height-touch);padding:var(--gap-control) calc(var(--space-unit) * 3);border:1px solid var(--rule);border-radius:var(--radius-control);background:var(--surface-2);color:var(--ink);font-size:var(--t-body);line-height:var(--lh-ui);text-decoration:none;overflow-wrap:anywhere}
.workspace a.ui-data-link:where(:hover,:active){background:var(--fill-tint);color:var(--accent-strong)}
.workspace a.ui-data-link:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}
.workspace .ui-data-link .ui-data-count{display:inline-flex;align-items:center;justify-content:center;min-width:1.5em;padding-inline:var(--space-unit);border-radius:var(--radius-small);background:var(--surface);color:var(--ink-2);font-size:var(--t-body);font-variant-numeric:tabular-nums}
.ui-meta.is-card-fields{gap:var(--gap-control)}
.workspace .ui-meta.is-card-fields>div{grid-template-columns:minmax(0,1fr);align-items:start;gap:var(--space-unit);padding:var(--gap-control) calc(var(--space-unit) * 3);border:0;border-radius:var(--radius-small);background:var(--surface-2)}
.workspace .ui-meta.is-card-fields :is(dt,dd){display:block;min-width:0;margin:0;font-size:var(--t-body);line-height:var(--lh-body);overflow-wrap:anywhere}
@media(forced-colors:active){.ui-data-card,.workspace .ui-meta.is-card-fields>div{border:1px solid CanvasText}}
.ui-detail-summary{display:grid;gap:calc(var(--space-unit) * 4);min-width:0;padding-block:calc(var(--space-unit) * 6);border-block:1px solid var(--rule)}
.ui-detail-summary>*,.ui-content-section>*{margin-block:0}
.ui-content-section{display:grid;gap:calc(var(--space-unit) * 4);min-width:0}
.ui-content-section+.ui-content-section{padding-block-start:calc(var(--space-unit) * 6);border-top:1px solid var(--rule)}
.ui-disclosure{min-width:0;margin:0}
.ui-disclosure>summary{min-height:var(--height-touch);padding-block:calc(var(--space-unit) * 3);font-size:var(--t-body);color:var(--ink);font-weight:600}
.ui-disclosure-body{display:grid;gap:calc(var(--space-unit) * 6);min-width:0;padding-block:calc(var(--space-unit) * 4)}
/* Named help keeps ordinary task actions outside its compact native popover. */
.ui-help-popover{position:fixed;inset:auto auto 16px 16px;width:min(32rem,calc(100vw - 32px));max-height:calc(100dvh - 32px);box-sizing:border-box;margin:0;padding:calc(var(--space-unit) * 5);overflow:auto;overscroll-behavior:contain;border:1px solid var(--rule);border-radius:var(--radius-panel);background:var(--surface);color:var(--ink);box-shadow:var(--depth-navigation)}
.ui-help-popover-head{position:sticky;top:0;display:flex;align-items:center;justify-content:space-between;gap:var(--gap-control);background:var(--surface)}
.ui-help-popover-head>h2{margin:0;font-size:var(--t-title3);line-height:var(--lh-title)}
.ui-help-popover>p{margin:calc(var(--space-unit) * 4) 0 0;font-size:var(--t-body);line-height:var(--lh-body);overflow-wrap:anywhere}
/* Remaining-content cue paints behind text; it adds no mask, overlay, focus stop or layout space. */
.ui-help-popover:where(.has-scroll-more){background-image:linear-gradient(to top,color-mix(in srgb,var(--ink) 16%,var(--surface)),var(--surface));background-repeat:no-repeat;background-position:bottom;background-size:100% calc(var(--space-unit) * 2);background-attachment:scroll}
@media(prefers-reduced-transparency:reduce),(prefers-contrast:more){
 .ui-help-popover:where(.has-scroll-more){background-image:none;box-shadow:inset 0 calc(var(--space-unit) / -2) 0 var(--accent-strong),var(--depth-navigation)}
}
@media(forced-colors:active){
 .ui-help-popover:where(.has-scroll-more){background-image:none;box-shadow:none;border-bottom-color:Highlight}
}
.ui-timeline{display:grid;gap:calc(var(--space-unit) * 4);margin:0;padding-inline-start:calc(var(--space-unit) * 6)}
.ui-timeline>li{min-width:0;padding-inline-start:var(--space-unit)}
.ui-timeline>li>p{margin:0}
@media (max-width:760px){.ui-card-body{padding:var(--density-card-padding,16px)}.ui-meta.is-reading>div{grid-template-columns:minmax(0,1fr);gap:var(--space-unit)}.ui-meta.is-reading dt{color:var(--ink-2)}}

/* ---------------- 세그먼트: 캡슐 안의 캡슐(기업·보기 고르기). 단추는 aria-pressed, 링크는 aria-current ---------------- */
.ui-segmented{display:inline-flex;flex-wrap:nowrap;gap:4px;max-width:100%;padding:4px;border:1px solid var(--rule);border-radius:var(--radius-pill);
  background:var(--surface-2);box-sizing:border-box;overflow-x:auto}
.ui-segmented:not(.is-filter-nav){scrollbar-width:none}
.ui-segmented:not(.is-filter-nav)::-webkit-scrollbar{display:none}
:is(.workspace,.entry) .ui-segmented>:is(button,a){display:inline-flex;align-items:center;justify-content:center;gap:6px;flex:0 0 auto;min-width:0;min-height:var(--height-touch);
  margin:0;padding:6px 16px;border:0;border-radius:var(--radius-pill);background:transparent;box-shadow:none;color:var(--ink-2);font:inherit;font-size:.9375rem;
  font-weight:500;text-decoration:none;white-space:nowrap;cursor:pointer;transform:none}
:is(.workspace,.entry) .ui-segmented>:is(button[aria-pressed="true"],a[aria-current="page"]){background:var(--surface);color:var(--ink);font-weight:600;box-shadow:0 1px 2px var(--shadow-key)}
.ui-segmented small{font-size:.75rem;font-weight:500;color:var(--ink-3);font-variant-numeric:tabular-nums}
.ui-segmented.is-fill{display:flex;width:100%}
.ui-segmented.is-fill>:is(button,a){flex:1 1 0}

/* 구역 메뉴는 출입관리 조회 메뉴의 탐색면·선택면을 공유한다.
   페이지 이동과 상태 필터는 기존 native 링크와 aria-current를 유지한다. */
.ui-section-nav{display:inline-flex;flex-wrap:wrap;align-items:stretch;width:fit-content;max-width:100%;min-width:0;box-sizing:border-box;gap:var(--space-unit);padding:var(--inset-group);border:1px solid var(--rule-strong);border-radius:var(--radius-group);background:var(--surface-2);box-shadow:none}
:is(.workspace,.entry) .ui-section-nav>a:where(:not(.ui-ai-action)){display:flex;align-items:center;justify-content:center;gap:var(--gap-control);min-width:0;max-width:100%;min-height:var(--height-touch);box-sizing:border-box;margin:0;padding:calc(var(--space-unit) * 2) calc(var(--space-unit) * 3);border:1px solid transparent;border-radius:var(--radius-group-inner);background:transparent;box-shadow:none;font-family:var(--font-title);font-size:var(--t-body);font-weight:500;line-height:1.4;color:var(--ink-2);text-decoration:none;white-space:nowrap;transition:transform var(--dur-press) var(--ease-out),background-color var(--dur-state) var(--ease-standard),box-shadow var(--dur-state) var(--ease-standard),border-color var(--dur-state) var(--ease-standard)}
:is(.workspace,.entry) .ui-section-nav>a:where([aria-current="page"]){border-color:var(--control-quiet-line);background:var(--control-selected-face);box-shadow:var(--control-inner),var(--control-shadow);color:var(--accent-strong);font-weight:600}
:is(.workspace,.entry) .ui-section-nav>a:where([aria-current="location"]){border-color:var(--control-quiet-line);background:var(--control-selected-face);box-shadow:none;color:var(--accent-strong);font-weight:600}
.ui-section-nav .symbol{width:calc(var(--space-unit) * 5);height:calc(var(--space-unit) * 5);flex:none}
@media(hover:hover) and (pointer:fine){:is(.workspace,.entry) .ui-section-nav>a:where(:hover):where(:not(.ui-ai-action)){background:var(--control-hover)}}
:is(.workspace,.entry) .ui-section-nav>a:where(:active):where(:not(.ui-ai-action)){transform:scale(var(--press-scale));background:var(--control-pressed);box-shadow:var(--control-shadow-pressed)}
:is(.workspace,.entry) .ui-section-nav>a:focus-visible{outline:2px solid var(--focus-ring);outline-offset:3px}
/* 구역 메뉴는 본문 층(고정되지 않음)이라 유리를 쓰지 않는다: 불투명 2차 배경과 테두리(2026-10-29 R3). 투명도 줄이기·대비 높이기는 표면색. */
@media(prefers-reduced-transparency:reduce),(prefers-contrast:more){.ui-section-nav{background:var(--surface);-webkit-backdrop-filter:none;backdrop-filter:none}}
@media(max-width:760px){
 .ui-section-nav{display:flex;flex-wrap:nowrap;width:100%;min-width:0;contain:inline-size;overflow-x:auto;overscroll-behavior-inline:contain;scroll-snap-type:x proximity;scroll-padding-inline:var(--gap-control);scrollbar-width:none}
 :is(.workspace,.entry) .ui-section-nav>a{flex:none;justify-content:flex-start;padding-inline:calc(var(--space-unit) * 3);white-space:nowrap;scroll-snap-align:start}
 .ui-section-nav>a>span{min-width:0}
 .ui-section-nav-desktop{display:none}
 .ui-section-nav[data-nav-overflow=end]{-webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 32px),transparent);mask-image:linear-gradient(90deg,#000 calc(100% - 32px),transparent)}
 .ui-section-nav[data-nav-overflow=start]{-webkit-mask-image:linear-gradient(90deg,transparent,#000 32px);mask-image:linear-gradient(90deg,transparent,#000 32px)}
 .ui-section-nav[data-nav-overflow=both]{-webkit-mask-image:linear-gradient(90deg,transparent,#000 32px,#000 calc(100% - 32px),transparent);mask-image:linear-gradient(90deg,transparent,#000 32px,#000 calc(100% - 32px),transparent)}
}
/* 2026-10-30 M17: 태블릿(761~1180px)에서도 줄바꿈 대신 한 줄 가로 넘김 띠. 탭 하나만 다음 줄로 떨어지지 않는다.
   끝단 흐림은 760px 이하에서만 쓰고, 현재 탭은 interface.js가 띠 안에서 보이게 맞춘다. */
@media(min-width:761px) and (max-width:1180px){
 .ui-section-nav{flex-wrap:nowrap;min-width:0;overflow-x:auto;overscroll-behavior-inline:contain;scroll-snap-type:x proximity;scroll-padding-inline:var(--gap-control);scrollbar-width:none}
 :is(.workspace,.entry) .ui-section-nav>a{flex:none;white-space:nowrap;scroll-snap-align:start}
}
/* 인쇄는 폭과 관계없이 전체 줄바꿈·펼친 현장 목록(2026-10-29 0단계 검토). */
@media print{
 .ui-section-nav{flex-wrap:wrap;overflow:visible;contain:none;-webkit-mask-image:none;mask-image:none}
 :is(.workspace,.entry) .ui-section-nav>a:where(:not(.ui-ai-action)){white-space:normal}
 .ui-section-nav.ui-section-nav-desktop{display:flex}
 .ui-site-switcher-mobile{display:none}
}
@media(prefers-reduced-motion:reduce){:is(.workspace,.entry) .ui-section-nav>a{transition:none;transform:none}}
/* 현장 선택: 데스크톱은 펼친 메뉴, 760px 이하는 '현재 현장' 펼침 하나(2026-10-29 전체 점검 R2). */
.ui-site-switcher-mobile{display:none}
@media(max-width:760px){.ui-site-switcher-mobile{display:block}.ui-site-switcher-mobile>summary{display:flex;align-items:center;justify-content:space-between;gap:var(--gap-control);min-height:var(--height-touch);padding:0 calc(var(--space-unit) * 4);border:1px solid var(--rule-strong);border-radius:var(--radius-group);background:var(--surface);cursor:pointer;list-style:none;font-weight:600}.ui-site-switcher-mobile>summary::after{content:'⌄' / '';font-size:1.25em;line-height:1}.ui-site-switcher-mobile[open]>summary::after{transform:rotate(180deg)}.ui-site-switcher-mobile>nav.ui-section-nav{margin-block-start:var(--gap-control);display:grid;grid-template-columns:minmax(0,1fr);overflow:visible;contain:none;scroll-snap-type:none;-webkit-mask-image:none;mask-image:none}:is(.workspace,.entry) .ui-site-switcher-mobile>nav>a{white-space:normal}.ui-site-switcher-mobile>nav>a>span{overflow-wrap:anywhere}}
@media(forced-colors:active){
 .ui-section-nav{background:Canvas;color:CanvasText;border-color:CanvasText;box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none}
 :is(.workspace,.entry) .ui-section-nav>a:where(:not(.ui-ai-action)){background:Canvas;color:CanvasText;box-shadow:none}
 :is(.workspace,.entry) .ui-section-nav>a:where([aria-current="page"],[aria-current="location"]){border-color:Highlight;outline:2px solid Highlight;outline-offset:-2px}
 :is(.workspace,.entry) .ui-section-nav>a:focus-visible{outline-color:Highlight;outline-offset:3px}
}

/* Flat filter navigation shares the segmented links' sizing and native navigation.
   Only explicit consumers scroll in one row on screen; print keeps the full wrapped list.
   Scrollbar paint stays with scroll-surfaces.css, and focus stays inside each link. */
.ui-segmented.is-filter-nav{display:flex;flex-wrap:wrap;align-items:center;gap:2px calc(var(--space-unit) * 3);min-width:0;padding:0;border:0;border-radius:0;background:transparent;box-shadow:none;overflow:visible}
:is(.workspace,.entry) .ui-segmented.is-filter-nav>a{min-width:var(--height-touch);padding:6px 4px;border-bottom:2px solid transparent;border-radius:0;color:var(--ink-2);font-size:var(--t-body);white-space:normal}
:is(.workspace,.entry) .ui-segmented.is-filter-nav>a[aria-current="page"]{border-bottom-color:var(--accent);background:transparent;color:var(--accent-strong);box-shadow:none}
:is(.workspace,.entry) .ui-segmented.is-filter-nav>a:focus-visible{outline-offset:calc(-1 * var(--space-unit))}
@media screen{
 .ui-segmented.is-filter-nav{flex-wrap:nowrap;overflow-x:auto;overscroll-behavior-inline:contain;scroll-padding-inline:var(--space-unit)}
 :is(.workspace,.entry) .ui-segmented.is-filter-nav>a{white-space:nowrap}
}
@media(forced-colors:active){:is(.workspace,.entry) .ui-segmented.is-filter-nav>a[aria-current="page"]{border-bottom-color:Highlight;color:LinkText}}

/* ---------------- 칩: 분류·상태 표시(누르지 않는 글) ---------------- */
.ui-chip{display:inline-flex;align-items:center;gap:4px;max-width:100%;padding:2px 8px;border-radius:var(--radius-badge);background:var(--surface-2);color:var(--ink-2);
  font-size:.75rem;font-weight:500;line-height:1.5;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ui-chip.is-warn{background:var(--warn-bg);color:var(--warn-ink)}
.ui-chip.is-accent{background:var(--fill-tint);color:var(--accent-strong)}
.ui-chip .symbol{width:14px;height:14px;flex:none}
.ui-chips{display:flex;flex-wrap:wrap;gap:4px;margin:0;padding:0;list-style:none}

/* ---------------- 숫자 묶음: 가격·합계. 첫 값(.is-key)이 기준 값 ---------------- */
.ui-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,118px),1fr));gap:8px;margin:0;padding:8px 12px;border-radius:var(--radius-small);background:var(--surface-2)}
.ui-stats>div{min-width:0}
.ui-stats dt{font-size:.75rem;color:var(--ink-3)}
.ui-stats dd{margin:0;font-size:.9375rem;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ui-stats .is-key dd{color:var(--accent-strong)}
.ui-stats.is-large dd{font-size:1.25rem;font-weight:700}

/* ---------------- 체크: 상자 20px, 누르는 곳은 터치 44px ---------------- */
.ui-check{display:inline-flex;flex-wrap:nowrap;align-items:center;gap:8px;max-width:100%;min-width:0;min-height:var(--height-touch);box-sizing:border-box;font-size:.875rem;color:var(--ink-2);cursor:pointer;white-space:normal;overflow-wrap:anywhere}
/* 2026-10-30 M13: 설명이 길면 상자 옆에서 줄을 바꾼다(390에서 상자와 설명이 갈라지거나 넘치지 않게).
   refinement.css의 760px 이하 `label:has(>input[type=checkbox]){flex-wrap:wrap}`가 이겨도 설명 기준 폭 0이라 상자 옆에 남는다. */
.ui-check>:where(span){flex:1 1 0;min-width:0}
.ui-check input{flex:none;width:20px;height:20px;margin:0;accent-color:var(--accent);cursor:inherit}
.ui-check:has(input:disabled){opacity:.5;cursor:not-allowed}
/* Opt in when the disabled choice also reports an explanation or saved state.
   Keep that label readable; native disabled behavior and the default style stay intact. */
.ui-check.ui-check--readable-disabled:has(:where(input):disabled){opacity:1}
.ui-check.ui-check--readable-disabled :where(input):disabled{opacity:.5}
/* Legacy checkbox labels share the same hit area without enlarging the box. */
:where(.workspace #content) .ui-check-target{display:inline-flex;align-items:center;gap:8px;min-height:var(--height-touch);min-width:var(--height-touch);box-sizing:border-box;cursor:pointer}
:where(.workspace #content) .ui-check-target>input{flex:none}
:where(.workspace #content) .ui-field-help a[href]:where(:not(.ui-action,.hub-button,.ui-back-link)){display:inline-flex;align-items:center;min-height:var(--height-touch);min-width:var(--height-touch);max-width:100%;box-sizing:border-box;vertical-align:middle}

/* ---------------- 스위치: 켜짐/꺼짐 하나를 바로 바꾼다. 누르는 곳은 터치 44px, 켜짐은 색과 손잡이 위치를 함께 쓴다 ---------------- */
.ui-switch{position:relative;display:inline-flex;align-items:center;gap:12px;min-height:var(--height-touch);cursor:pointer;color:var(--ink);font-size:var(--text-control);font-weight:600;user-select:none;-webkit-user-select:none}
.ui-switch input{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:inherit}
.ui-switch-track{position:relative;flex:none;width:44px;height:26px;border-radius:var(--radius-pill);background:var(--field-rule);transition:background var(--motion-normal) var(--motion-fluid)}
.ui-switch-track::after{content:"";position:absolute;top:3px;left:3px;width:20px;height:20px;border-radius:50%;background:var(--surface);box-shadow:0 1px 3px var(--shadow-deep);transition:transform var(--motion-normal) var(--motion-fluid)}
/* 처음 그릴 때 저장된 상태로 맞추는 동안(is-settling)에는 손잡이가 움직이지 않는다. 스크립트가 맞춘 뒤 이 클래스를 뺀다. */
.ui-switch.is-settling .ui-switch-track,.ui-switch.is-settling .ui-switch-track::after{transition:none}
.ui-switch input:checked+.ui-switch-track{background:var(--accent)}
.ui-switch input:checked+.ui-switch-track::after{transform:translateX(18px);background:var(--on-accent)}
.ui-switch input:focus-visible+.ui-switch-track{outline:2px solid var(--focus-ring);outline-offset:3px}
@media(prefers-reduced-motion:reduce){.ui-switch-track,.ui-switch-track::after{transition:none}}

/* ---------------- 입력 묶음: 찾기·고르기 칸 높이를 터치 44px로 맞춘다 ---------------- */
:is(.workspace,.entry) .ui-field{width:100%;box-sizing:border-box;min-height:var(--height-touch);margin:0;padding:8px 14px;border:1px solid var(--rule);
  border-radius:var(--radius-field);background:var(--field-bg);color:var(--field-ink);font:inherit;font-size:var(--t-input,var(--t-body));font-weight:400;line-height:var(--lh-ui)}
:is(.workspace,.entry) .ui-field::placeholder{color:var(--field-placeholder);opacity:1}
/* 읽기 전용 칸: 고칠 수 없다는 것을 바탕으로 구분한다. 두 테마 모두 글자 4.5:1 이상(design-tokens.css --field-readonly-*). */
:is(.workspace,.entry) .ui-field[readonly]{background:var(--field-readonly-bg);color:var(--field-readonly-ink)}
:is(.workspace,.entry) .ui-field:focus{outline:2px solid var(--focus-ring);outline-offset:1px;border-color:transparent}
/* Field body typography/geometry belongs here. office.css excludes only explicit ui-field controls.
   Preserve the established border/focus specificity against legacy focus-visible rules;
   invalid-state consumers may still provide their own semantic border colour. */
:is(.workspace,.entry) .ui-field:not([type=checkbox]):not([type=radio]):not([type=color]){border-color:var(--field-rule)}
:is(.workspace,.entry) .ui-field:not([type=checkbox]):not([type=radio]):not([type=color]):focus{border-color:transparent}

/* Native selection with an explicit indicator slot; the whole control keeps its
   OS picker and keyboard behavior. Insets belong here, not to each list page. */
.ui-select{--ui-select-start:14px;--ui-select-end:14px;--ui-select-indicator:18px;--ui-select-gap:var(--gap-control);position:relative;display:block;min-width:0;max-width:100%;box-sizing:border-box}
:is(.workspace,.entry) .ui-select>select.ui-field{display:block;appearance:none;width:100%;min-width:0;max-width:100%;box-sizing:border-box;margin:0;padding-inline-start:var(--ui-select-start);padding-inline-end:calc(var(--ui-select-end) + var(--ui-select-indicator) + var(--ui-select-gap));text-overflow:ellipsis}
:is(.workspace,.entry) .ui-select>select.ui-field:where(:disabled){background:var(--field-readonly-bg);color:var(--field-readonly-ink);cursor:not-allowed}
:is(.workspace,.entry) .ui-select>select.ui-field:where([aria-invalid="true"]){--field-rule:var(--danger-ink)}
.ui-select>.symbol{position:absolute;inset-inline-end:var(--ui-select-end);top:50%;transform:translateY(-50%);width:var(--ui-select-indicator);height:var(--ui-select-indicator);margin:0;pointer-events:none;color:var(--ink-2)}
.ui-select:has(>select:disabled)>.symbol{color:var(--field-placeholder)}
@media (forced-colors:active){
 :is(.workspace,.entry) .ui-select>select.ui-field{appearance:auto;padding-inline-end:var(--ui-select-end)}
 .ui-select>.symbol{display:none}
}

/* List filters share a control baseline and readable labels. The field group is
   the flex item, including when the native select has an indicator wrapper. */
.ui-list-filters{--ui-list-filters-wrap:wrap;--ui-action-min-height:var(--height-control);display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--gap-control);min-width:0}
.ui-list-filters>.ui-fieldgroup{flex:0 1 7.5rem;min-width:0;margin:0;gap:var(--space-unit)}
.ui-list-filters>.ui-list-query{flex:3 1 16rem}
.ui-list-filters>.ui-list-choice{flex:1 1 10rem}
.ui-list-filters .ui-field-label{font-size:var(--t-body);line-height:var(--lh-ui);font-weight:500;color:var(--ink-2)}
.ui-list-filters :is(.ui-field,.ui-action,.hub-button){min-height:var(--height-control)}
.ui-list-filter-actions{display:flex;flex:none;flex-wrap:wrap;align-items:center;align-self:flex-end;gap:var(--gap-control);min-width:0;max-width:100%}
.ui-list-filter-actions>:is(button,a){margin:0}
.ui-list-feedback{gap:var(--gap-control);margin-block:var(--gap-control)}
/* Keep native AI pending/recovery status visible without an extra form box. */
.ui-list-feedback>form.ui-list-search-ai-form{display:contents}
.ui-list-feedback-head{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--gap-control) calc(var(--space-unit) * 4);min-width:0}
.ui-list-feedback-head>.ui-help{margin:0;max-width:100%}
.ui-list-feedback .ui-status{font-size:var(--t-body)}
.ui-list-feedback .ui-status:empty{min-height:0;height:0}
.ui-list-results{margin-inline-start:auto;justify-content:flex-end;max-width:100%}
@media (max-width:1180px){.ui-list-filters>.ui-list-query{flex-basis:var(--ui-list-query-basis,100%)}}
@media (max-width:760px){
 .ui-list-filters>.ui-list-date{flex:1 1 7rem}
 .ui-list-filters .ui-select{--ui-select-end:12px;--ui-select-indicator:16px;--ui-select-gap:var(--space-unit)}
 .ui-list-filters>.ui-list-filter-actions{flex-basis:100%;justify-content:flex-end}
 .ui-list-filter-actions>.ui-action:first-child{flex:1}
}

/* ---------------- 작은 단추: 카드·막대 안의 보조 동작(그래도 터치 44px) ----------------
   '작은'은 배치·여백의 역할이다. 읽어야 하는 동작명은 본문 크기를 상속한다.
   화면마다 14px를 다시 키우는 재정의 대신 이 소유 규칙에서 --t-body를 쓴다. */
:is(.workspace,.entry) .ui-action{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-width:var(--height-touch);min-height:var(--ui-action-min-height,var(--height-touch));
  margin:0;padding:6px 14px;border-radius:var(--radius-pill);font-size:var(--t-body);font-weight:600;white-space:nowrap;box-sizing:border-box}
.ui-action:where(:not(.ui-ai-action)) .symbol{width:16px;height:16px;flex:none}
/* Shared action paint. Keep each owner's dimensions, density, typography and
   semantics: a document cell, photo/row trigger or resize handle is not a CTA.
   Actual ui-plain actions may opt in with ui-action/ui-icon-button. Page owners
   still own placement and can map these same material tokens to their controls. */
@media screen{
 :is(.workspace,.entry) :is(button:where(:not(.ui-plain)),.button,.hub-button,.ui-action,.ui-icon-button,.shell-action,.portal-return):where(:not(.paper *,.paper-a4 *,.wb-presentation-stage *,.wb-presentation-surface *,[role="checkbox"],[role="switch"],.calendar-resize,[data-resize-handle])){
  background:var(--ui-control-face,var(--control-face));color:var(--ui-control-ink,var(--ink));border-color:var(--ui-control-line,var(--control-line));
  box-shadow:var(--ui-control-shadow,inset 0 0 0 1px var(--ui-control-line,var(--control-line)),var(--control-inner),var(--control-shadow));
  text-shadow:none;transition:background-color var(--dur-state) var(--ease-standard),border-color var(--dur-state) var(--ease-standard),box-shadow var(--dur-state) var(--ease-standard),color var(--dur-state) var(--ease-standard);
 }
 :is(.workspace,.entry) :is(button,.button,.hub-button,.ui-action,.ui-icon-button,.shell-action,.portal-return):where(.quiet,.secondary,.ui-icon-button){
  --ui-control-face:var(--control-quiet-face);--ui-control-line:var(--control-quiet-line);--ui-control-ink:var(--ink-2);
 }
 :is(.workspace,.entry) :is(button,.button,.hub-button,.ui-action,.ui-icon-button,.shell-action,.portal-return):where(.primary,.shell-action,.hub-button:not(.secondary)){
  --ui-control-face:var(--control-primary-face);--ui-control-hover:var(--control-primary-hover);--ui-control-pressed:var(--control-primary-pressed);--ui-control-line:var(--accent);--ui-control-ink:var(--on-accent);
 }
 :is(.workspace,.entry) .ui-icon-button:where(.is-glass){
  --ui-control-face:var(--material-glass);--ui-control-hover:var(--material-glass);--ui-control-pressed:var(--fill-tint);--ui-control-line:var(--material-border);--ui-control-ink:var(--accent-strong);--ui-control-shadow:var(--depth-control);
  -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturation));backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturation));
 }
 :is(.workspace,.entry) :is(button,a).ui-icon-button:where(.primary,.is-glass){
  background:var(--ui-control-face,var(--control-primary-face));color:var(--ui-control-ink,var(--on-accent));border-color:var(--ui-control-line,var(--accent));
 }
 :is(.workspace,.entry) :is(button,.button,.hub-button,.ui-action,.ui-icon-button,.shell-action,.portal-return):where([aria-pressed="true"],[aria-selected="true"],[aria-current="page"],.is-selected){
  --on-accent:var(--accent-strong);--ui-control-face:var(--control-selected-face);--ui-control-hover:var(--control-selected-hover);--ui-control-pressed:var(--control-selected-face);--ui-control-line:var(--accent);--ui-control-ink:var(--accent-strong);
 }
 :is(.workspace,.entry) :is(button,.button,.hub-button,.ui-action,.ui-icon-button,.shell-action,.portal-return):where(.danger,[name="action"][value="suspend"],[name="action"][value="reset_mfa"]){
  --accent:var(--danger-ink);--on-accent:var(--danger-ink);--ui-control-face:var(--control-danger-face);--ui-control-hover:var(--control-danger-hover);--ui-control-pressed:var(--control-danger-pressed);--ui-control-line:var(--danger-ink);--ui-control-ink:var(--danger-ink);
 }
 @media(hover:hover) and (pointer:fine){
  :is(.workspace,.entry) :is(button:where(:not(.ui-plain)),.button,.hub-button,.ui-action,.ui-icon-button,.shell-action,.portal-return):where(:not(:disabled,[aria-disabled="true"],[aria-busy="true"],.paper *,.paper-a4 *,.wb-presentation-stage *,.wb-presentation-surface *,[role="checkbox"],[role="switch"],.calendar-resize,[data-resize-handle])):hover{
   background:var(--ui-control-hover,var(--control-hover));color:var(--ui-control-ink,var(--ink));border-color:var(--ui-control-line,var(--control-line));
   box-shadow:var(--ui-control-shadow,inset 0 0 0 1px var(--ui-control-line,var(--control-line)),var(--control-inner),var(--control-shadow-hover));
  }
 }
 :is(.workspace,.entry) :is(button:where(:not(.ui-plain)),.button,.hub-button,.ui-action,.ui-icon-button,.shell-action,.portal-return):where(:not(:disabled,[aria-disabled="true"],[aria-busy="true"],.paper *,.paper-a4 *,.wb-presentation-stage *,.wb-presentation-surface *,[role="checkbox"],[role="switch"],.calendar-resize,[data-resize-handle])):active{
  background:var(--ui-control-pressed,var(--control-pressed));box-shadow:var(--ui-control-shadow,inset 0 0 0 1px var(--ui-control-line,var(--control-line)),var(--control-shadow-pressed));
 }
 :is(.workspace,.entry) :is(button,.button,.hub-button,.ui-action,.ui-icon-button,.shell-action,.portal-return):focus-visible{outline:2px solid var(--focus-ring);outline-offset:3px}
 :is(.workspace,.entry) :is(button:where(:not(.ui-plain)),.button,.hub-button,.ui-action,.ui-icon-button,.shell-action,.portal-return):is(:disabled,[aria-disabled="true"]){
  /* Legacy hub-button colours use these local semantic tokens with important.
     Keep disabled text readable instead of lowering the whole control opacity. */
  --accent:var(--ink-3);--on-accent:var(--ink-3);--ui-control-face:var(--surface-2);--ui-control-hover:var(--surface-2);--ui-control-pressed:var(--surface-2);--ui-control-line:var(--rule);--ui-control-ink:var(--ink-3);--ui-control-shadow:none;
  opacity:1;background:var(--surface-2);color:var(--ink-3);border-color:var(--rule);
  box-shadow:none;cursor:not-allowed;transform:none;filter:none;transition:none;
 }
 :is(.workspace,.entry) :is(button:where(:not(.ui-plain)),.button,.hub-button,.ui-action,.ui-icon-button,.shell-action,.portal-return)[aria-busy="true"]{
  --accent:var(--ink-2);--on-accent:var(--ink-2);--ui-control-face:var(--surface-2);--ui-control-hover:var(--surface-2);--ui-control-pressed:var(--surface-2);--ui-control-line:var(--field-rule);--ui-control-ink:var(--ink-2);--ui-control-shadow:inset 0 0 0 1px var(--field-rule);
  background:var(--surface-2);color:var(--ink-2);border-color:var(--field-rule);box-shadow:var(--ui-control-shadow);cursor:progress;transform:none;filter:none;transition:none;
 }
}
@media(prefers-reduced-motion:reduce){
 :is(.workspace,.entry) :is(button,.button,.hub-button,.ui-action,.ui-icon-button,.shell-action,.portal-return){transition:none}
}
@media(prefers-reduced-transparency:reduce),(prefers-contrast:more){
 :is(.workspace,.entry) .ui-icon-button:where(.is-glass){--ui-control-face:var(--surface);--ui-control-hover:var(--surface-2);--ui-control-line:var(--rule-strong);--ui-control-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none}
}
@media(forced-colors:active){
 :is(.workspace,.entry) .ui-icon-button:where(.is-glass){-webkit-backdrop-filter:none;backdrop-filter:none}
 :is(.workspace,.entry) :is(button:where(:not(.ui-plain)),.button,.hub-button,.ui-action,.ui-icon-button,.shell-action,.portal-return){--accent:ButtonText;--on-accent:ButtonText;--ui-control-face:ButtonFace;--ui-control-hover:ButtonFace;--ui-control-pressed:ButtonFace;--ui-control-line:ButtonText;--ui-control-ink:ButtonText;--ui-control-shadow:0 0 0 0 ButtonFace;color:ButtonText;border-color:ButtonText;box-shadow:none}
 :is(.workspace,.entry) :is(button:where(:not(.ui-plain)),.button,.hub-button,.ui-action,.ui-icon-button,.shell-action,.portal-return):is([aria-pressed="true"],[aria-selected="true"],[aria-current="page"],.is-selected){--accent:ButtonText;--on-accent:ButtonText;--ui-control-line:Highlight;background:ButtonFace;color:ButtonText;border-color:Highlight;outline:2px solid Highlight}
 :is(.workspace,.entry) :is(button:where(:not(.ui-plain)),.button,.hub-button,.ui-action,.ui-icon-button,.shell-action,.portal-return):is(:disabled,[aria-disabled="true"]){--accent:GrayText;--on-accent:GrayText;--ui-control-face:ButtonFace;--ui-control-hover:ButtonFace;--ui-control-pressed:ButtonFace;--ui-control-line:GrayText;--ui-control-ink:GrayText;--ui-control-shadow:0 0 0 0 ButtonFace;color:GrayText;border-color:GrayText}
 :is(.workspace,.entry) :is(button:where(:not(.ui-plain)),.button,.hub-button,.ui-action,.ui-icon-button,.shell-action,.portal-return)[aria-busy="true"]{--accent:ButtonText;--on-accent:ButtonText;--ui-control-face:ButtonFace;--ui-control-hover:ButtonFace;--ui-control-pressed:ButtonFace;--ui-control-line:ButtonText;--ui-control-ink:ButtonText;--ui-control-shadow:0 0 0 0 ButtonFace;color:ButtonText;border-color:ButtonText}
 :is(.workspace,.entry) :is(button,.button,.hub-button,.ui-action,.ui-icon-button,.shell-action,.portal-return):focus-visible{outline-color:Highlight}
}
@media print{
 :is(.ui-action,.button,.hub-button,.ui-icon-button,.shell-action,.portal-return){background-image:none;box-shadow:none;text-shadow:none;filter:none}
}
/* legacy hub 보조 단추의 초록 글자를 보존하며 중복 important를 없앤다. */
:is(.workspace,.entry) .hub-button:where(.secondary:not(.ui-ai-action)){--ui-control-ink:var(--accent)}
/* 표준 AI 진입. 크기는 ui-action, 칠·상태는 위 공통 조작 소재가 소유한다. */
:is(.workspace,.entry) .ui-ai-action{
 --ui-control-face:var(--ai-tint);--ui-control-hover:var(--control-selected-hover);--ui-control-pressed:var(--control-selected-face);--ui-control-line:var(--ai-accent);--ui-control-ink:var(--ai-accent);
 display:inline-flex;align-items:center;justify-content:center;gap:var(--gap-control);min-width:var(--height-touch);min-height:var(--ui-action-min-height,var(--height-touch));max-width:100%;height:auto;margin:0;padding:6px 14px;border:1px solid var(--ui-control-line);border-radius:var(--radius-pill);font-family:var(--font-ui);font-size:var(--t-body);font-weight:600;line-height:var(--lh-ui);text-decoration:none;white-space:normal;vertical-align:middle;box-sizing:border-box;cursor:pointer;
}
:is(.workspace,.entry) .ui-ai-action:where(.is-strong){--ui-control-face:var(--control-primary-face);--ui-control-hover:var(--control-primary-hover);--ui-control-pressed:var(--control-primary-pressed);--ui-control-line:var(--ai-accent);--ui-control-ink:var(--ai-on-accent)}
:is(.workspace,.entry) .ui-ai-action:where(.is-icon-only){width:var(--height-touch);height:var(--height-touch);padding:0;flex:none}
:where(.workspace,.entry) .ui-ai-action>:where(.symbol,.nav-icon){display:block;width:20px;height:20px;flex:0 0 20px;margin:0;stroke-width:1.75}
:where(.ui-ai-action) .ui-ai-action-label{min-width:0;overflow-wrap:anywhere}
@media print{:is(.workspace,.entry) .ui-ai-action{display:none}}
@media(forced-colors:active){
 :is(.workspace,.entry) .ui-ai-action{--ui-control-face:ButtonFace;--ui-control-hover:ButtonFace;--ui-control-pressed:ButtonFace;--ui-control-line:ButtonText;--ui-control-ink:ButtonText;--ui-control-shadow:0 0 0 0 ButtonFace}
}
/* 파일로 새 문서를 만드는 안내는 실행 링크와 설명을 한 묶음으로 둔다. */
:where(.workspace) .pr-import-entry{display:flex;flex-wrap:wrap;align-items:center;gap:var(--gap-control)}
:where(.pr-import-entry)>p{flex:1 1 28ch;margin:0;min-width:0}
/* 문서 AI는 검색 바로 앞에 둔다. 1180 이하 아이콘 고정, 컴퓨터는 실제 여유가 있을 때만 글자를 펼친다. */
:where(.workspace,.entry) .header-actions{--document-ai-search-margin:0;display:flex;align-items:center;gap:var(--gap-nav-pair);flex:none;margin-inline-start:auto}
.header-actions>:where(*){margin-block:0}
:where(.workspace) .document-ai-control{position:static;display:flex;align-items:center;flex:none;min-width:var(--height-touch);margin:0}
.workspace .document-ai-launch{width:var(--height-touch);height:var(--height-touch);padding:0;flex:none;white-space:nowrap}
:where(.document-ai-control) .ui-ai-action-label{display:none}
.workspace .document-ai-control:where(.is-roomy) .document-ai-launch{width:auto;padding-inline:var(--gap-nav-pair)}
:where(.document-ai-control.is-roomy) .ui-ai-action-label{display:inline}
:where(.workspace) .document-ai-options{position:absolute;inset-block-start:calc(100% + var(--gap-control));inset-inline-end:var(--gap-control);z-index:1;display:grid;gap:var(--space-unit);width:max-content;max-width:calc(100% - var(--gap-control) * 2);padding:var(--gap-control);box-sizing:border-box;border-radius:var(--radius-group);background:var(--surface);box-shadow:var(--depth-control)}
.workspace .document-ai-options .ui-action{justify-content:flex-start;min-width:0;white-space:normal;text-align:start;box-shadow:none}
:where(.document-ai-options)[hidden]{display:none}
@media(max-width:1180px){
 .workspace .document-ai-control:where(.is-roomy) .document-ai-launch{width:var(--height-touch);padding:0}
 :where(.document-ai-control.is-roomy) .ui-ai-action-label{display:none}
}

/* ---------------- 아래 고정 막대: 선택 상태와 다음 동작 ---------------- */
.ui-actionbar{position:sticky;bottom:0;z-index:5;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px 16px;min-height:var(--height-tab);
  padding:8px 16px;border-top:1px solid var(--rule);background:var(--surface);box-sizing:border-box}

/* ---------------- 큰 창(시트): 컴퓨터·태블릿은 가운데, 휴대폰은 좌우 8px 띄운 전체 화면(DESIGN-SYSTEM ‘휴대폰 하단 시트’) ---------------- */
:is(.workspace,.entry) dialog.ui-sheet{width:min(1240px,calc(100vw - 32px));max-width:none;height:min(920px,calc(100dvh - 32px));max-height:none;margin:auto;padding:0;
  border:0;border-radius:var(--radius-panel);background:var(--surface);color:var(--ink);box-shadow:0 24px 64px var(--shadow-deep);overflow:auto;overscroll-behavior:contain}
:is(.workspace,.entry) dialog.ui-sheet::backdrop{background:#0f172a73}
.ui-sheet-head{position:sticky;top:0;z-index:6;display:flex;align-items:center;gap:12px;padding:14px 18px 12px 24px;border-bottom:1px solid var(--rule);background:var(--surface)}
.ui-sheet-head h2{margin:0;font-size:1.25rem;font-weight:600;letter-spacing:-.015em}
.ui-sheet-head p{margin:2px 0 0;font-size:.8125rem;color:var(--ink-3)}
.ui-sheet-head>:last-child{margin-left:auto}

/* ---------------- 빈 상태·알림 ---------------- */
.ui-empty{padding:32px 16px;border:1px dashed var(--rule-strong);border-radius:var(--radius-card);text-align:center;color:var(--ink-2);font-size:.9375rem}
/* 알림 띠(2026-10-29 구분감 개선): 기본은 중립(안쪽 카드와 같은 면). 정상은 무채색, 예외만 색.
   조치해야 결과가 맞는 경우만 .is-warn, 실패·저장 안 됨은 .is-error, 알아 두면 좋은 변화는 .is-info. */
.ui-notice{margin:0;padding:8px 12px;border:1px solid var(--rule);border-radius:var(--radius-small);background:var(--surface-inset);color:var(--ink-2);font-size:var(--t-body);font-weight:500;line-height:var(--lh-body);overflow-wrap:anywhere}
.ui-notice.is-warn{border-color:var(--warn-rule);background:var(--warn-bg);color:var(--warn-ink)}
.ui-notice.is-info{border-color:transparent;background:var(--info-bg);color:var(--info-ink)}
.ui-notice.is-error{border-color:var(--danger-rule);background:var(--danger-bg);color:var(--danger-ink)}
/* Informational copy is enhanced into native disclosure; original nodes remain intact. */
:where(.workspace #content) :where(.has-ui-help-disclosure){min-width:0;max-width:100%}
:where(.workspace #content) .ui-help-disclosure{margin-block:var(--gap-title);min-width:0;max-width:100%;border-block-end:1px solid var(--rule)}
:where(.workspace #content) .ui-help-disclosure>summary{display:flex;align-items:center;gap:8px;min-height:var(--height-touch);padding:4px 0;box-sizing:border-box;color:var(--ink-2);font-size:var(--t-body);font-weight:400;list-style:none}
.ui-help-summary{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ui-help-toggle{flex:none;font-size:var(--t-footnote);font-weight:500;color:var(--ink)}
.ui-help-toggle::before{content:'펼치기'}
.ui-help-disclosure[open] .ui-help-toggle::before{content:'접기'}
.ui-help-body{display:grid;gap:8px;padding-block:8px 12px}
.ui-help-disclosure>summary:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}
@media print{.ui-help-disclosure>summary{display:none}.ui-help-disclosure>.ui-help-body{display:block}}
@media(forced-colors:active){.ui-notice{border-color:CanvasText}}

@media (max-width:760px){
  :is(.workspace,.entry) dialog.ui-sheet{width:calc(100vw - 16px);height:calc(100dvh - 16px)}
  .ui-sheet-head{padding:12px 14px 10px 18px}
  .ui-sheet-head p{display:none}
  .ui-actionbar{flex-wrap:nowrap;padding:8px 14px}
}
/* ---------------- 고정 막대 가림 방지: 붙어 있는 머리글·떠 있는 하단 탭 높이(interface.js가 잼)만큼 스크롤 목표를 띄운다(2026-10-15, 기준표 2-4) ---------------- */
html{scroll-padding-top:var(--shell-scroll-clearance,var(--shell-header-clearance,0px))}
html:where([style*="--tabbar-clearance"]){scroll-padding-bottom:var(--tabbar-clearance)}

/* ---------------- 비로그인 화면 휴대폰 끝선(2026-10-15 H1-01): 머리글 상자와 본문 카드의 좌우 끝을 16px 한 줄에 맞춘다 ---------------- */
@media (max-width:760px){
  .entry .page-shell>header{margin-left:16px;margin-right:16px}
  .entry .login-layout{padding-left:16px;padding-right:16px}
  .entry main>.card.narrow{margin-left:16px;margin-right:16px}
}

/* ---------------- 본문으로 이동(건너뛰기 링크): 포커스가 없을 때는 화면 밖이 아니라 잘라서 숨긴다(2026-10-15 H3-8).
   예전처럼 위로 -100px만 밀어 두면 이어 찍은 사진·확대 화면에서 본문 중간에 떠 보였다. 포커스되면 portal.css대로 왼쪽 위에 나온다. ---------------- */
.skip-link:not(:focus){clip-path:inset(50%);overflow:hidden;white-space:nowrap}

/* ---------------- 진행 표시(2026-10-15 대표 지시: 로딩·작업 진행 표시를 토스·Apple HIG 기준으로) ----------------
   Apple HIG Progress indicators: 알 수 있으면 진행률 막대, 모르면 무한 표시. 같은 자리에서 원형↔막대를 바꾸지 않는다.
   움직임 줄이기(prefers-reduced-motion)에서는 돌거나 미끄러지지 않고 제자리에서 천천히 흐려졌다 진해진다(기준표 1-5).
   JS 도우미는 assets/interface.js의 window.PortalBusy(300ms 뒤에 보이고, 보이면 400ms 유지). */
/* 원형 무한 표시: 기본 16px, 큰 것 24px. 색은 글자색을 따른다. 장식이므로 aria-hidden="true", 상태 글은 따로 둔다. */
.ui-spinner{display:inline-block;flex:none;width:16px;height:16px;box-sizing:border-box;vertical-align:-3px;border:2px solid color-mix(in srgb,currentColor 22%,transparent);
  border-top-color:currentColor;border-radius:50%;animation:ui-spin .8s linear infinite}
.ui-spinner-lg{width:24px;height:24px;border-width:3px;vertical-align:-6px}
/* 막대 진행 표시: value가 있으면 진행률, 없으면 무한 표시. 높이 4px(화면 맨 위 화면 이동 표시줄은 2px, system.css .office-progress). */
progress.ui-progress{display:block;width:100%;height:4px;margin:0;padding:0;border:0;border-radius:var(--radius-pill);overflow:hidden;appearance:none;-webkit-appearance:none;
  background:var(--rule);color:var(--accent)}
progress.ui-progress::-webkit-progress-bar{background:var(--rule);border-radius:var(--radius-pill)}
progress.ui-progress::-webkit-progress-value{background:var(--accent);border-radius:var(--radius-pill);transition:width var(--dur-state,220ms) var(--ease-standard,ease)}
progress.ui-progress::-moz-progress-bar{background:var(--accent);border-radius:var(--radius-pill)}
progress.ui-progress:indeterminate{background:var(--rule) linear-gradient(90deg,var(--accent),var(--accent)) no-repeat;background-size:35% 100%;
  animation:ui-indeterminate 1.4s var(--ease-standard,ease) infinite}
progress.ui-progress:indeterminate::-webkit-progress-bar{background:transparent}
progress.ui-progress:indeterminate::-moz-progress-bar{background:transparent}
/* 진행 중 단추: JS가 시작할 때의 폭·높이를 그대로 고정하고(옆 요소가 움직이지 않게), 흐리게 하지 않는다. 다시 누름은 JS가 막는다. */
:is(button,input,a,.ui-action)[aria-busy="true"]{cursor:progress}
.ui-busy-content{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-width:0;max-width:100%}
/* 기준선은 글에서 잡는다(스피너가 첫 항목이면 단추가 옆 단추보다 위로 뜬다). 줄바꿈은 원래 단추 규칙을 따른다(두 줄 단추가 한 줄로 바뀌어 높이가 변하지 않게). */
.ui-busy-content>span:not(.ui-spinner){align-self:baseline;min-width:0;overflow-wrap:anywhere}
/* 짧은 상태 글: role="status" aria-live="polite". data-kind=progress(원형 표시)·done(확인 기호)·error(느낌표 원). 색만으로 나누지 않는다. */
.ui-status{display:flex;align-items:center;gap:8px;min-width:0;margin:0;color:var(--ink-2);font-size:.875rem;line-height:1.5}
.ui-status[hidden]{display:none}
.ui-status>.ui-spinner{color:var(--accent)}
.ui-status>.symbol{flex:none;width:16px;height:16px}
.ui-status[data-kind="done"]{color:var(--ok-ink)}
.ui-status[data-kind="error"]{color:var(--danger-ink)}
.ui-status[data-kind="info"]{color:var(--ink-2)}
/* 자리표시: 목록·카드를 불러오는 동안 같은 자리에 같은 크기로. 장식이므로 aria-hidden="true", 감싼 영역에 aria-busy="true". */
.ui-skeleton{display:block;min-height:12px;border-radius:var(--radius-small);
  background:var(--surface-2) linear-gradient(90deg,transparent,color-mix(in srgb,var(--surface) 70%,transparent),transparent) no-repeat;background-size:40% 100%;
  animation:ui-shimmer 1.6s var(--ease-standard,ease) infinite}
.ui-skeleton.is-line{height:14px;margin:8px 0}
.ui-skeleton.is-line:last-child{width:60%}
.ui-skeleton.is-block{height:120px;border-radius:var(--radius-card)}
@keyframes ui-spin{to{transform:rotate(360deg)}}
@keyframes ui-indeterminate{from{background-position:-54% 0}to{background-position:154% 0}}
@keyframes ui-shimmer{from{background-position:-70% 0}to{background-position:170% 0}}
@keyframes ui-breathe{from{opacity:1}to{opacity:.35}}

@media (prefers-reduced-motion:reduce){
  .ui-card{transition:none}
  .ui-spinner{border-color:currentColor;animation:ui-breathe 1.2s ease-in-out infinite alternate}
  progress.ui-progress:indeterminate{background-position:50% 0;animation:ui-breathe 1.6s ease-in-out infinite alternate}
  progress.ui-progress::-webkit-progress-value{transition:none}
  .ui-skeleton{background-image:none;animation:none}
}

/* 스크롤 창(ui-scroll-pane, 2026-10-19): 스크롤이 많은 영역은 자기 스크롤바가 있는 창으로. 동작은 scroll-pane.js(data-scroll-pane).
   컴퓨터에서만 창이 된다(.is-pane). 카드 그림자가 창 가장자리에서 잘리지 않게 안쪽 여백만큼 바깥으로 넓힌다. */
.ui-scroll-pane.is-pane{position:sticky;top:var(--pane-top,96px);max-height:var(--pane-h,calc(100dvh - 112px));overflow:auto;
  margin-inline:-8px;padding:4px 8px 12px;scroll-padding-top:12px}
.ui-scroll-pane.is-pane :target{scroll-margin-top:12px}


/* Optional workspace visibility follows the explicit browser mode, including first paint. */
:root:not([data-portal-theme="shinyoung"]) [data-portal-mode="shinyoung"],:root[data-portal-theme="shinyoung"] [data-portal-mode-default]{display:none}

/* ---------------- 누름 영역(2026-10-29 전체 점검 R5, HIG-B01·B02) ----------------
   휴대폰(≤760px)은 44px(--height-touch), 그 밖은 28px 이상. 문장 안 링크(p·.ui-copy 안)는 글줄 그대로 둔다.
   :where()로 낮은 우선순위를 두어 화면 소유 규칙이 정한 더 큰 크기는 그대로 이긴다.
   대상: 동작 단추, 안내 summary, 단계 링크, 목록·카드의 단독 링크, 체크 상자 label. 칩(.ui-chip)은 누르지 않는 글이라 제외.
   제목(h2~h4) 안 링크는 말줄임·제목 높이를 화면이 정하므로 대상이 아니다(캘린더 .hub-day>h2>a). 체크 상자를 담은 문단(p)도 문장이 쪼개지지 않게 대상이 아니다.
   표 칸(td·th)의 단독 링크는 행 높이를 지키려고 높이 대신 위아래 안쪽 여백만 넓히고 같은 만큼 바깥 여백을 줄인다(누름 영역만 커진다). */
:where(.workspace,.entry) :where(main) :where(li,dd,dt)>a:where(:only-child):where(:not(.ui-plain,.ui-copy a,p a)){display:inline-flex;align-items:center;min-height:calc(var(--space-unit) * 7)}
:where(.workspace,.entry) :where(main) :where(td,th)>a:where(:only-child):where(:not(.ui-plain)){padding-block:var(--space-unit);margin-block:calc(var(--space-unit) * -1)}
:where(.workspace,.entry) :where(main) :where(details)>summary{min-height:calc(var(--space-unit) * 7);align-content:center}
:where(.workspace,.entry) :where(main) :where(label:has(>input[type=checkbox]),label:has(>input[type=radio])){display:inline-flex;align-items:center;gap:var(--gap-control);min-height:calc(var(--space-unit) * 7)}
:where(.workspace,.entry) :where(main) :where([aria-current="step"]){min-height:calc(var(--space-unit) * 7)}
@media(max-width:760px){
 :where(.workspace,.entry) :where(main) :where(td,th)>a:where(:only-child):where(:not(.ui-plain)){padding-block:calc(var(--space-unit) * 3);margin-block:calc(var(--space-unit) * -3)}
 :where(.workspace,.entry) :where(main) :where(li,dd,dt)>a:where(:only-child):where(:not(.ui-plain,.ui-copy a,p a)),
 :where(.workspace,.entry) :where(main) :where(details)>summary,
 :where(.workspace,.entry) :where(main) :where(label:has(>input[type=checkbox]),label:has(>input[type=radio])),
 :where(.workspace,.entry) :where(main) :where(ol,ul,nav)>:where(li)>a:where([aria-current="step"]),
 :where(.workspace,.entry) :where(main) .ui-action{min-height:var(--height-touch)}
}

/* ---------------- 표 부품(2026-10-29 R8): 머리글 고정·숫자 열·옆으로 넘기는 영역 ----------------
   .ui-table-scroll: 긴 표를 감싸는 스크롤 영역. 세로 높이를 화면 안으로 묶어 머리글이 붙어 있게 한다.
   기존 .table-wrap·.wa-table-wrap도 같은 머리글 고정과 가장자리 흐림을 받는다(낮은 우선순위, 화면 규칙이 이긴다).
   넘칠 때 interface.js가 role=region·tabindex=0·aria-label·넘김 안내와 data-table-overflow(start·end·both)를 단다.
   .ui-num: 숫자 열(금액·수량)은 끝 정렬과 고정폭 숫자. 머리글 칸에도 같이 붙인다. */
.ui-table-scroll{max-width:100%;overflow:auto;overscroll-behavior-inline:contain}
:where(.table-wrap,.wa-table-wrap,.ui-table-scroll)>table>thead :where(th){position:sticky;top:0;z-index:1;background:var(--surface)}
:where(.table-wrap,.wa-table-wrap,.ui-table-scroll):focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}
:where(.table-wrap,.wa-table-wrap,.ui-table-scroll)[data-table-overflow=end]{-webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 32px),transparent);mask-image:linear-gradient(90deg,#000 calc(100% - 32px),transparent)}
:where(.table-wrap,.wa-table-wrap,.ui-table-scroll)[data-table-overflow=start]{-webkit-mask-image:linear-gradient(90deg,transparent,#000 32px);mask-image:linear-gradient(90deg,transparent,#000 32px)}
:where(.table-wrap,.wa-table-wrap,.ui-table-scroll)[data-table-overflow=both]{-webkit-mask-image:linear-gradient(90deg,transparent,#000 32px,#000 calc(100% - 32px),transparent);mask-image:linear-gradient(90deg,transparent,#000 32px,#000 calc(100% - 32px),transparent)}
/* 끝단 흐림(mask)은 감싸개 바깥 포커스 링·그림자와 가장자리 칸의 포커스까지 지운다. 감싸개나 그 안 항목에 키보드 포커스가 있으면 흐림을 끈다. */
:where(.table-wrap,.wa-table-wrap,.ui-table-scroll)[data-table-overflow]:is(:focus-visible,:has(:focus-visible)){-webkit-mask-image:none;mask-image:none}
.ui-num{text-align:end;font-variant-numeric:tabular-nums;white-space:nowrap}
@media(min-width:761px){.ui-table-scroll{max-height:calc(100dvh - var(--shell-header-clearance,0px) - var(--space-unit) * 8)}}
@media print{.ui-table-scroll{max-height:none;overflow:visible}:where(.table-wrap,.wa-table-wrap,.ui-table-scroll){-webkit-mask-image:none;mask-image:none}}

/* 셸 메뉴의 상위 범위 표시(2026-10-29 R6): 본문 구역 메뉴가 page를 가질 때 셸 메뉴 항목은 aria-current="location".
   선택 알약은 office.js가 같은 자리에 그리고, 글자는 page와 같은 강조색·굵기. */
:where(.workspace) .sidebar nav a[aria-current="location"],:where(.workspace) .work-area-nav>a[aria-current="location"],:where(.workspace) .mobile-tabbar>a[aria-current="location"],:where(.workspace) .office-menu-links>a[aria-current="location"]{color:var(--accent-strong);font-weight:600}
:where(.workspace) .mobile-tabbar>a[aria-current="location"] .nav-text{color:var(--accent-strong)}
/* 선택 알약(.nav-indicator, absolute z-index 0)이 '전체' 단추 내용 위에 칠해지지 않게 탭 링크와 같은 쌓임을 준다. */
:where(.workspace) .mobile-tabbar>button{position:relative;z-index:1}
/* page 전용이던 강조도 location에 같게: 아이콘 채움·굵기(system.css 18절), 묶음 제목의 현재 표시(office.css), 강제 색상 테두리(materials.css). */
:where(.workspace :is(.sidebar nav,.work-area-nav),.workspace .office-menu-links) a[aria-current="location"] .nav-icon{stroke-width:2.1}
:where(.workspace :is(.sidebar nav,.work-area-nav),.workspace .office-menu-links) a[aria-current="location"] .ic-body{fill:currentColor;fill-opacity:.16}
:where(.workspace) .mobile-tabbar a[aria-current="location"] .nav-icon{stroke-width:1.9}
:where(.workspace) .mobile-tabbar a[aria-current="location"] .ic-body{fill:currentColor;fill-opacity:1}
:where(.workspace) .mobile-tabbar a[aria-current="location"] .ic-cut{stroke:var(--fill-tint)}
:where(.workspace .sidebar) .nav-disclosure:has(a[aria-current="location"])>:where(summary)>.nav-group-current{display:inline}
@media(forced-colors:active){
 :where(.workspace) .sidebar nav a[aria-current="location"]{border:2px solid Highlight}
 :where(.workspace) .mobile-tabbar a[aria-current="location"]{background:Canvas;border:2px solid Highlight;color:Highlight}
}

/* ---------------- 구분감·간격·계층(2026-10-29 대표 요청, 근거 PLAN 5·6장) ----------------
   선은 옅은 선(--rule)·진한 선(--rule-strong) 두 가지만 쓴다. 한 요소에 선은 한 방향, 진한 선은 구역 머리와 표 머리글에만.
   표: 행 선은 portal.css th,td(--rule). 머리글 아래만 진한 선. 고정 머리글은 border-collapse 선이 스크롤과 함께 사라지므로 inset 그림자로 그린다. */
:where(.workspace,.entry) :where(main) thead th{border-bottom-color:var(--rule-strong)}
:where(.table-wrap,.wa-table-wrap,.ui-table-scroll)>table>thead th{border-bottom-color:transparent;box-shadow:inset 0 -1px 0 var(--rule-strong)}
@media(hover:hover) and (pointer:fine){:where(.table-wrap,.wa-table-wrap,.ui-table-scroll) tbody tr:hover>:where(td,th){background-color:var(--surface-2)}}

/* 반복 목록: 3항목 이상이면 항목 사이 옅은 선. 범례·칩·단추 묶음에는 쓰지 않는다. */
.ui-rows{display:grid;gap:0;min-width:0;margin:0;padding:0;list-style:none}
.ui-rows>*{min-width:0;padding-block:8px}
.ui-rows>:where(:first-child):nth-last-child(n+3)~*{border-top:1px solid var(--rule)}

/* 안쪽 카드: 카드 안 고정 정보(정상 빈 상태·기준 안내). 아이콘 + 글자, 색만으로 나누지 않는다. */
.ui-inset{display:flex;align-items:flex-start;gap:8px;min-width:0;margin:0;padding:12px 14px;border:1px solid var(--rule);border-radius:var(--radius-small);background:var(--surface-inset);color:var(--ink-2);font-size:var(--t-ui);font-weight:400;line-height:var(--lh-body);overflow-wrap:anywhere}
.ui-inset>.symbol{flex:none;width:18px;height:18px;margin-top:3px;margin-top:calc((1lh - 18px) / 2);color:var(--ink-3)}
.ui-inset :where(b,strong){color:var(--ink);font-weight:600}
.ui-inset.is-info{border-color:transparent;background:var(--info-bg);color:var(--info-ink)}
.ui-inset.is-warn{border-color:var(--warn-rule);background:var(--warn-bg);color:var(--warn-ink)}
.ui-inset:is(.is-danger,.is-error){border-color:var(--danger-rule);background:var(--danger-bg);color:var(--danger-ink)}
.ui-inset:is(.is-info,.is-warn,.is-danger,.is-error)>.symbol{color:currentColor}

/* Source context is an inset variant, after the base inset's margin reset. */
.ui-origin-context{margin-block-end:var(--gap-subsection);min-width:0}
.ui-origin-context .ui-copy{margin:0;max-width:80ch;overflow-wrap:anywhere}
.ui-origin-context .ui-action{max-width:100%;white-space:normal}

/* Low-priority context stays beside its controls, without a full-width notice surface. */
.ui-context-hint{display:flex;flex-wrap:wrap;align-items:center;gap:0 var(--gap-subsection);inline-size:fit-content;max-inline-size:min(100%,76ch);margin-block:var(--gap-control);color:var(--ink-2);font:400 var(--t-body)/var(--lh-body) var(--font-ui)}
.ui-context-hint>p{margin:0}
.ui-context-hint>details{min-width:0;max-width:100%;margin:0}
.ui-context-hint>details>summary{display:inline-flex;align-items:center;gap:var(--space-unit);min-height:var(--height-touch);padding:0;list-style:none;font:500 var(--t-body)/var(--lh-ui) var(--font-ui);color:var(--accent-strong);cursor:pointer}
.ui-context-hint>details>summary::marker{content:""}
.ui-context-hint>details>summary::after{content:none}
.ui-context-hint>details>summary>.symbol{width:16px;height:16px;flex:none}
.ui-context-hint>details[open]{flex-basis:100%}
.ui-context-hint>:where(details[open])>summary>.symbol{transform:rotate(180deg)}
.ui-context-hint>details>p{margin:0;overflow-wrap:anywhere}

/* 구역 머리: 제목 + 오른쪽 메타(조회 시각·건수), 아래 진한 선. 최상위 구역에만 쓴다(카드 안 h3·h4에는 선 없음). */
.ui-section-head{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:var(--space-unit) var(--inset-content);min-width:0;margin:0;padding-bottom:12px;border-bottom:1px solid var(--rule-strong)}
.ui-section-head>*{margin:0;min-width:0}

/* 카드 3칸: 머리(제목+상태 칩)·본문·바닥(보조 정보+동작). 바닥은 위쪽 옅은 선으로 나눈다. */
.ui-card-head{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--gap-control);min-width:0;padding:var(--density-card-padding,16px) var(--density-card-padding,20px) 0}
.ui-card-head>*{margin:0;min-width:0}
.ui-card-foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--gap-control);min-width:0;margin-top:auto;padding:12px 20px;border-top:1px solid var(--rule);background:var(--surface-inset)}
.ui-card-foot>*{margin:0}
.ui-card-head+.ui-card-body{padding-top:12px}
@media(max-width:760px){.ui-card-head{padding:14px 16px 0}.ui-card-foot{padding:12px 16px}}
/* 상태 칩(카드 머리): 정상은 무채색 테두리 칩. 예외 색은 기존 .ui-chip.is-warn을 쓴다. */
.ui-chip.is-outline{border:1px solid var(--rule);background:transparent;font-size:var(--t-footnote);font-weight:600}

/* 어두운 테마 카드는 면 차이(1.18:1)만으로 약해 테두리가 경계를 맡는다(진한 선 2.5:1). */
@media(prefers-color-scheme:dark){.ui-card{border-color:var(--rule-strong)}}
@media(forced-colors:active){:is(.ui-inset,.ui-section-head,.ui-card-foot){border-color:CanvasText}}

/* 바탕 위 담개(2026-10-29 s6 맨글자 구조 개선, DESIGN-SYSTEM.md '바탕 위 글자').
   원칙: 페이지 제목(h1)·구역 제목(h2/h3)·푸터 밖의 글자는 바탕(--canvas) 위에 직접 두지 않는다. 담개는 아래 여섯 가지와 기존 ui-inset·ui-card뿐이다.
   특이도: 부품은 클래스 하나(0,1,0), 변형은 클래스 둘, 문맥은 :where()로 감싼다. 화면 CSS에 더 강한 규칙이 있으면 화면 규칙을 지워서 맞춘다.
   아이콘은 components/nav_icon.html(symbol=True)을 쓴다: 조회 시각 hours, 날짜 calendar, 현장 location, 설명 info, 뒤로 chevron-left. */
/* 1 메타 칩: 조회 시각·범위·확인 n곳·n건. 구역 머리(ui-section-head) 오른쪽에 두며 좁은 화면에서는 제목 아래 줄로 내려간다.
   페이지 문맥(현장명·분류·날짜)은 h1 위 ui-meta-chips 줄에 is-context 칩으로 둔다. 글자는 span 하나로 감싼다(아이콘과 6px 간격). */
.ui-meta-chips{display:flex;justify-self:start;flex-wrap:wrap;align-items:center;gap:6px;min-width:0;margin:0;padding:0;list-style:none}
.ui-meta-chip{display:inline-flex;align-items:center;gap:6px;min-height:var(--chip-height);max-width:100%;margin:0;padding:2px 12px 2px 10px;box-sizing:border-box;border:1px solid var(--on-canvas-rule);border-radius:var(--radius-pill);background:var(--on-canvas-bg);color:var(--on-canvas-ink);font-size:var(--t-footnote);font-weight:500;line-height:1.4;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
.ui-meta-chip>.symbol{flex:none;width:14px;height:14px;color:var(--on-canvas-icon)}
.ui-meta-chip :where(time,strong,b){color:var(--ink);font-weight:600}
.ui-meta-chip.is-context{color:var(--ink)}
.ui-meta-chip:where(.is-readout){min-height:0;padding:0;border:0;border-radius:0;background:transparent;color:var(--ink-2);font-size:var(--t-body);line-height:var(--lh-body)}
:where(.ui-section-head)>.ui-meta-chip{align-self:center}
/* 2 소개 상자: h1 바로 아래 한두 문장(페이지 범위 설명). 카드보다 낮은 단계(반경 small, 그림자 없음). 페이지마다 하나만. */
.ui-page-intro{display:flex;align-items:flex-start;gap:10px;max-width:100%;margin:0;padding:12px 16px;box-sizing:border-box;border:1px solid var(--on-canvas-rule);border-radius:var(--radius-small);background:var(--on-canvas-bg);color:var(--on-canvas-ink);font-size:var(--t-subhead);font-weight:400;line-height:var(--lh-body);overflow-wrap:anywhere}
.ui-page-intro>.symbol{flex:none;width:16px;height:16px;margin-top:3px;margin-top:calc((var(--ui-intro-line,1.7rem) - 16px) / 2);color:var(--on-canvas-icon)}
/* 소개 상자 글자(p)는 portal.css 기본 p(1rem/1.7)로 그려진다. 아이콘 중심을 그 첫 줄 중심에 맞춘다. 글자를 상자 글꼴 그대로 쓰는 앱은 --ui-intro-line:1lh. */
.ui-page-intro>p{margin:0}
/* 2026-10-30 M19: 상자는 아래 전체 폭 카드와 오른쪽 끝선을 맞추고, 읽기 길이는 글자(p)에서 72ch로 묶는다. */
.ui-page-intro>:where(p){max-width:72ch}
/* 2-1 간격 리듬(s7): h1→소개 상자·칩 줄→h1은 --gap-title. 카드 안 제목→본문은 portal.css 기본 h2/p 여백이 flex 카드에서 겹치지 않아 22~38px로 벌어졌다:
   제목 아래 --gap-title, 카드 몸통(gap 16px)에서는 제목 여백 없이 gap만, 제목 다음 덩어리의 위 여백은 없앤다. 특이도는 요소 하나(0,0,1)·부품 하나(0,1,0)를 넘지 않는다. */
:where(h1)+.ui-page-intro{margin-block-start:var(--gap-title)}
.ui-meta-chips:where([data-ui-before-h1]){margin-block-end:var(--gap-title)}
:where(.ui-card,.ui-inset)>:is(h2,h3){margin-block-end:var(--gap-title)}
:where(.ui-card-body)>:is(h2,h3){margin-block-end:0}
:where(.ui-card,.ui-card-body,.ui-inset)>:is(h2,h3)+*{margin-block-start:0}
/* 3 접이식 카드: summary가 카드 머리(44px), 열면 본문이 같은 카드 안 옅은 선 아래. 꺾쇠는 system.css 공용 details 꺾쇠를 그대로 쓴다. */
.ui-disclosure-card{min-width:0;margin:0;border:1px solid var(--on-canvas-rule);border-radius:var(--radius-control);background:var(--surface);overflow:hidden}
.ui-disclosure-card>summary{display:flex;align-items:center;justify-content:space-between;gap:var(--gap-control);min-height:var(--height-touch);padding:0 16px;color:var(--ink);font-size:var(--t-ui);font-weight:600;cursor:pointer}
/* .workspace 밖(작업자 출입 공개 화면 등)에는 system.css 공용 details 꺾쇠가 없다. 같은 모양을 여기서만 그린다(.workspace 안과 겹치지 않음). */
.ui-disclosure-card:where(:not(.workspace *))>summary{list-style:none}
.ui-disclosure-card:where(:not(.workspace *))>summary::after{content:"";flex:none;width:16px;height:16px;margin-left:auto;background:currentColor;color:var(--ink-3);-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 9l7 7 7-7'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 9l7 7 7-7'/%3E%3C/svg%3E") center/contain no-repeat;transition:transform var(--dur-state) var(--spring-gentle)}
.ui-disclosure-card:where(:not(.workspace *))[open]>summary::after{transform:rotate(180deg)}
@media(prefers-reduced-motion:reduce){.ui-disclosure-card:where(:not(.workspace *))>summary::after{transition:none}}
@media(forced-colors:active){.ui-disclosure-card:where(:not(.workspace *))>summary::after{background:CanvasText}}
.ui-disclosure-card>summary:focus-visible{outline:2px solid var(--focus-ring);outline-offset:-2px}
.ui-disclosure-card>:not(summary){margin:0;padding:12px 16px 16px;border-top:1px solid var(--rule)}
:where(.ui-card) .ui-disclosure-card{border-color:var(--rule)}
/* 4 카드 바닥 칸 주석: 기존 ui-card-foot에 글자 규칙만 더한다(표 각주·출처·카드에 딸린 기준). 아이콘이 따로 줄을 차지하지 않게 줄바꿈하지 않는다. */
.ui-card-foot.is-note{flex-wrap:nowrap;align-items:flex-start;justify-content:flex-start;color:var(--ink-2);font-size:var(--t-footnote);line-height:var(--lh-body)}
.ui-card-foot.is-note>.symbol{flex:none;width:14px;height:14px;margin-top:4px;margin-top:calc((1lh - 14px) / 2);color:var(--ink-3)}
/* 5 필터 막대: 라벨+선택 상자 묶음과 결과 요약(ui-filter-result)을 하나의 면으로. */
.ui-filter-bar{display:flex;flex-wrap:wrap;align-items:flex-end;gap:12px;min-width:0;margin:0;padding:12px 16px;box-sizing:border-box;border:1px solid var(--on-canvas-rule);border-radius:var(--radius-control);background:var(--on-canvas-bg)}
.ui-filter-bar :where(label){display:grid;gap:4px;color:var(--ink-2);font-size:var(--t-footnote);font-weight:500}
.ui-filter-result{margin:0 0 0 auto;color:var(--ink-2);font-size:var(--t-footnote);font-variant-numeric:tabular-nums}
/* 5-1 필터 막대 안 입력·선택·단추는 한 높이(--height-control)로 같은 바닥선에 선다(2026-10-30 s8c, 선택 48·입력 53·단추 44가 섞이던 문제). */
.ui-filter-bar :is(select,input:not([type=checkbox],[type=radio],[type=hidden],[type=file]),button,.hub-button,.ui-action){box-sizing:border-box;height:var(--height-control);min-height:var(--height-control)}
/* 6 뒤로 가기 알약: 바탕 위 단독 링크는 누르는 곳임을 모양으로 보인다. 누르는 담개라 경계는 입력 경계(--field-rule, 바탕 위 3.22:1 이상). */
.ui-back-link{display:inline-flex;align-items:center;justify-self:start;align-self:start;width:max-content;max-width:100%;gap:4px;min-height:var(--height-touch);padding:0 14px 0 10px;box-sizing:border-box;border:1px solid var(--field-rule);border-radius:var(--radius-pill);background:var(--surface);color:var(--ink);font-size:var(--t-ui);font-weight:500;text-decoration:none}
.ui-back-link>.symbol{flex:none;width:16px;height:16px;color:var(--ink-2)}
.ui-back-link:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}
@media(hover:hover) and (pointer:fine){.ui-back-link:hover{background:var(--surface-2)}}
@media(forced-colors:active){:is(.ui-meta-chip,.ui-page-intro,.ui-disclosure-card,.ui-filter-bar,.ui-back-link){border-color:CanvasText}}
/* 7 파일 고르기(2026-10-30 M9): interface.js가 input[type=file]을 .ui-file로 감싸고 한국어 단추·파일 이름 면(.ui-file-face)을 붙인다.
   원래 입력은 투명하게 면 위에 덮어 누르기·끌어 놓기·키보드·스크린리더·필수 검증을 그대로 받는다. 이름이 길면 한 줄 말줄임(390 잘림 없음). */
:where(.ui-file){position:relative;display:flex;width:100%;max-width:100%;min-width:0;box-sizing:border-box;overflow:hidden;border-radius:var(--radius-field)}
:where(.ui-file)>input[type=file]{position:absolute;inset:0;z-index:1;width:100%;height:100%;min-height:0;margin:0;padding:0;opacity:0;cursor:pointer}
:where(.ui-file)>input[type=file]:disabled{cursor:not-allowed}
.ui-file-face{display:flex;align-items:center;gap:var(--gap-control);width:100%;min-width:0;min-height:var(--height-touch);padding:3px 12px 3px 3px;box-sizing:border-box;border:1px solid var(--field-rule);border-radius:var(--radius-field);background:var(--field-bg)}
.ui-file-button{display:inline-flex;align-items:center;flex:none;min-height:36px;padding:0 14px;box-sizing:border-box;border:1px solid var(--rule-strong);border-radius:var(--radius-pill);background:var(--surface);color:var(--accent);font-size:var(--t-subhead);font-weight:500;white-space:nowrap}
.ui-file-name{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ink-3);font-size:var(--t-subhead)}
.ui-file.has-file .ui-file-name{color:var(--field-ink)}
.ui-file>:where(input[type=file]:focus-visible)+.ui-file-face{outline:2px solid var(--focus-ring);outline-offset:-3px}
.ui-file>:where(input[type=file]:disabled)+.ui-file-face{opacity:.6}
@media(hover:hover) and (pointer:fine){.ui-file>:where(input[type=file]:hover:not(:disabled))+.ui-file-face>.ui-file-button{background:var(--fill-tint)}}
@media(forced-colors:active){.ui-file-face,.ui-file-button{border-color:CanvasText}}
/* 2026-10-30 M16: 소개 상자 안 덧붙임 설명. 상자가 이미 정보 아이콘을 가지므로 ⓘ 대신 '자세히' 글자 접기로 연다({% tip … more=True %}). */
.ui-intro-more{display:block;width:fit-content;max-width:100%;margin:2px 0 0}
.ui-intro-more>summary{min-height:var(--height-touch);color:var(--accent);font-size:var(--t-subhead);font-weight:500}
.ui-intro-more>summary:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px;border-radius:var(--radius-small)}
.ui-intro-more>[role=note]{display:block;padding-block-end:4px;color:var(--on-canvas-ink)}
/* 7 페이지 머리 정렬(2026-10-30 s8c, 대표 제보 '업무 홈 원형 단추가 한 줄 아래로'): portal-bootstrap.css(빌드 고정 파일, 마지막에 실림)는
   1180px 이하에서 한 칸 격자라 동작 묶음이 늘 다음 줄로 내려가고, 그 이상에서는 align-items:center라 h1+소개 묶음 전체의 가운데에 섰다.
   workhub.css:3도 800px 이하에서 .hub-heading을 column으로 바꿔 같은 일이 났다. flex 줄바꿈 한 줄로 바꿔 동작은 h1 첫 줄 오른쪽 끝에 둔다.
   자리가 모자라면 제목 쪽이 줄바꿈하고, 넓은 글자 단추 묶음은 다음 줄 왼쪽에서 시작한다(위 간격 --gap-control).
   세로 중심: 동작이 있는 머리에서 h1의 한 줄 상자를 동작 높이(--height-touch)와 같게 위아래로 채우고(1lh = h1 자신의 줄 높이), 동작은 윗선에 맞춘다.
   portal-bootstrap.css보다 먼저 실리므로 요소 하나(0,0,1)만 더해 이긴다(상한 0,3,1). */
.workspace .portal-ui :is(div,section,header).ui-page-header:where(:not(.office-home-heading)){display:flex;flex-direction:row;flex-wrap:wrap;align-items:flex-start;column-gap:calc(var(--space-unit) * 4);row-gap:var(--gap-control)}
/* data-ui-*는 서버가 기존 포함/형제 조건을 표시한다. 반복 element :is는 기존 :has(h1)의 특이도 0,0,1을 보존한다. */
.workspace main :is(div,section,header):is(.hub-heading,.page-heading,.quality-heading,.context-heading):where(:not(.office-home-heading)):where([data-ui-has-h1]):is(div,section,header){flex-direction:row;flex-wrap:wrap;align-items:flex-start;row-gap:var(--gap-control)}
:is(.workspace .portal-ui,.workspace main) :is(div,section,header):is(.ui-page-header,.hub-heading,.page-heading,.quality-heading,.context-heading):where(:not(.office-home-heading))>:where(.ui-page-header-main,[data-ui-has-h1],h1){flex:1 1 min(100%,16rem);min-width:0}
:is(.workspace .portal-ui,.workspace main) :is(div,section,header):is(.ui-page-header,.hub-heading,.page-heading,.quality-heading,.context-heading):where(:not(.office-home-heading))>:where(.ui-page-header-actions,a,button,nav,details,form,.ui-cluster,[class*="-actions"],[class*="-tools"]):where(:not([data-ui-has-h1],.wa-header-actions)){flex:0 1 auto;align-self:flex-start;width:auto;max-width:100%;margin:var(--ui-head-action-offset,0px) 0 0;justify-self:auto}
:where(.workspace main) :where(.ui-page-header,.hub-heading,.page-heading,.quality-heading,.context-heading):where(:not(.office-home-heading)):where([data-ui-header-actions]) :where(h1){padding-block:max(0px,calc((var(--height-touch) - 1lh) / 2))}
/* h1 위에 문맥 칩(.ui-meta-chip)이 먼저 오는 머리: 동작을 칩 높이+칩 아래 간격만큼 내려 h1 줄에 맞춘다. */
:where(.workspace main) :where(.ui-page-header,.hub-heading,.page-heading,.quality-heading,.context-heading):where(:not(.office-home-heading)):where([data-ui-title-chip]){--ui-head-action-offset:calc(var(--chip-height) + var(--gap-title))}
