/* TACTILE UI primitives · v4.1.0 — 라이트 고정, 알약 버튼 3종 + 원형 아이콘, 글래스 3단계, 1차 컴포넌트 14종 + 흐름 8종, 브랜드 로딩 표시. Tokens live in tokens.css. */
*,*::before,*::after{box-sizing:border-box}
body{margin:0;background:var(--canvas);color:var(--ink);font-family:var(--font);font-size:15px;line-height:1.65;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;word-break:keep-all;overflow-wrap:break-word}
body.modal-open{overflow:hidden}
button,input,textarea,select{font:inherit;color:inherit}
button,a,input,textarea,select{-webkit-tap-highlight-color:transparent}
button:focus-visible,a:focus-visible,input:focus-visible,textarea:focus-visible,select:focus-visible,summary:focus-visible,[tabindex]:focus-visible{outline:2px solid rgba(17,17,17,.9);outline-offset:3px}
h1,h2,h3,p{margin:0}
h1,h2,h3{font-weight:var(--fw-light);line-height:var(--lh-heading)}
h1,h2{letter-spacing:var(--ls-heading)}
ul,ol{padding:0;margin:0;list-style:none}
::selection{background:var(--ice);color:var(--ink)}
[hidden]{display:none!important}
.icon-sprite{position:absolute;width:0;height:0;overflow:hidden}
.icon{display:inline-block;flex:none;width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;vertical-align:middle}
.eyebrow{font-size:11px;font-weight:550;letter-spacing:.18em;line-height:1.6;text-transform:uppercase}
.mono{font-family:var(--mono)}
.muted{color:var(--muted)}
.accent{color:var(--accent)}
.rule{border:0;border-top:1px solid var(--line);margin:0}
.skip-link{position:fixed;left:20px;top:-80px;z-index:1000;padding:10px 20px;background:var(--ink);color:var(--white);border-radius:8px}
.skip-link:focus{top:16px}
/* 버튼 4종 — 주(알약)·보조(알약)·텍스트·원형 아이콘. 상태: 기본·hover·focus·active·disabled·loading.
   글 → 버튼 24px(--text-to-action)은 배치 규칙이라 .btn 이 margin 을 갖지 않는다. 버튼 사이 12px(.btn-row). */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:var(--control-h);padding:0 24px;border:1px solid transparent;border-radius:var(--radius-pill);font-size:14px;font-weight:var(--fw-medium);line-height:1.2;letter-spacing:-.01em;white-space:nowrap;cursor:pointer;transition:transform var(--t-1) var(--ease-out),background var(--t-2),border-color var(--t-2),color var(--t-2),opacity var(--t-2)}
.btn:active:not(:disabled):not([aria-busy=true]){transform:scale(var(--press-scale))}
.btn-primary{color:var(--primary-text);background:var(--primary-base);border-color:var(--primary-border)}
.btn-primary:hover:not(:disabled){background:var(--primary-hover);border-color:var(--primary-hover)}
.btn-secondary{color:var(--ink);background:var(--secondary-fill);border-color:var(--secondary-border);box-shadow:var(--secondary-shadow)}
.btn-secondary:hover:not(:disabled){background:var(--secondary-hover)}
.btn-quiet{color:var(--ink);background:var(--secondary-fill);border-color:var(--secondary-border)} /* 구형 이름 — 보조와 같다. 새 화면은 .btn-secondary */
.btn-quiet:hover:not(:disabled){background:var(--secondary-hover)}
.btn-text{min-height:var(--touch-min);padding:0 4px;border-radius:4px;background:transparent;color:var(--ink);text-decoration:underline;text-underline-offset:5px;text-decoration-thickness:1px;text-decoration-color:var(--line-strong)}
.btn-text:hover:not(:disabled){text-decoration-color:var(--ink)}
.btn-sm{min-height:var(--control-h-sm);padding:0 16px;font-size:13px;gap:6px}
.btn-lg{min-height:var(--control-h);padding:0 24px;font-size:14px} /* 구형 이름 — 기본 크기와 같다 */
.btn:disabled,.btn[aria-disabled=true]{opacity:.38;cursor:not-allowed;box-shadow:none}
/* 처리 중 — 기본 스피너 없음(§11). 폭 유지, 글자 「처리 중」 불투명도 숨쉬기. 브랜드 로딩 표시는 2단계. */
.btn[aria-busy=true]{position:relative;color:transparent!important;pointer-events:none}
.btn[aria-busy=true]::after{content:attr(data-busy-label);position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:var(--primary-text);font-size:inherit;animation:busy-breathe var(--t-5) var(--ease-inout) infinite alternate}
.btn[aria-busy=true]:not([data-busy-label])::after{content:"처리 중"}
/* 브랜드 로딩 표시(.loader)가 안에 있으면: 원래 글자는 투명(폭 유지), 가운데에 표시 + 「처리 중」 글자(::after — 접근 이름에 「처리 중」이 남고 감속 모드 정지 화면에도 보인다). 짝 영역 .btn-status 는 그래도 필수(§9 BUSY). */
.btn[aria-busy=true]:has(.loader)::after{padding-left:22px;animation:none;opacity:1}
.btn[aria-busy=true]:has(.loader){min-width:calc(var(--busy-w,44px) + 30px)} /* 짧은 버튼(「취소」 56px)만 로더 + 「처리 중」이 들어갈 폭까지 넓어진다. 그 이상은 폭 유지 */
.btn[aria-busy=true] .loader{position:absolute;left:50%;top:50%;width:16px;height:16px;transform:translate(calc(-50% - var(--busy-w,44px) / 2),-50%);color:var(--ink)}
.btn-sm{--busy-w:41px}
.btn-primary[aria-busy=true] .loader{color:var(--primary-text)}
.btn-secondary[aria-busy=true]::after,.btn-text[aria-busy=true]::after,.btn-quiet[aria-busy=true]::after{color:var(--ink)}
@keyframes busy-breathe{from{opacity:1}to{opacity:.6}} /* 최저 .6 — 가장 어두운 순간에도 글자 대비 4.5:1 이상 */
/* 작은 버튼: 보이는 높이 36, 누르는 영역 44(위아래 4px) */
.btn-sm{position:relative}
.btn-sm::before{content:"";position:absolute;left:0;right:0;top:-4px;bottom:-4px}
.btn .icon{width:16px;height:16px}
.btn-row{display:flex;flex-wrap:wrap;align-items:center;gap:12px}
/* 처리 중 짝 영역 — 버튼 옆 role="status" aria-live="polite". 「처리 중」 → 「완료」/「실패: …」를 읽어 준다. 기본은 숨김 글자, .btn-status--visible 이면 보임 */
.btn-status{position:absolute;left:0;top:0;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0} /* left/top 0 — 제자리(static) 위치로 스크롤 영역 밖 문서 폭을 넓히지 않는다 */
.btn-status--visible{position:static;left:auto;top:auto;width:auto;height:auto;margin:0;overflow:visible;clip:auto;white-space:normal;font-size:var(--fs-small);color:var(--muted)}
/* UA a:link/a:visited 는 (0,1,1)이라 .btn-primary(0,1,0)보다 강하다. 앵커 .btn 은 button 과 같은 글자·밑줄 없음. */
a.btn:link,a.btn:visited,a.btn:hover,a.btn:active,a.btn:focus{color:inherit;text-decoration:none}
a.btn-primary:link,a.btn-primary:visited,a.btn-primary:hover,a.btn-primary:active,a.btn-primary:focus{color:var(--primary-text)}
a.btn-text:link,a.btn-text:visited,a.btn-text:hover,a.btn-text:active,a.btn-text:focus{color:var(--ink);text-decoration:underline;text-underline-offset:5px;text-decoration-thickness:1px}
.icon-btn{display:inline-flex;align-items:center;justify-content:center;width:var(--icon-btn-size);height:var(--icon-btn-size);padding:0;border:1px solid var(--secondary-border);border-radius:var(--radius-circle);background:var(--secondary-fill);color:var(--ink);cursor:pointer;transition:background var(--t-2),transform var(--t-1) var(--ease-out),opacity var(--t-2)}
.icon-btn:hover:not(:disabled){background:var(--secondary-hover)}
.icon-btn:active:not(:disabled){transform:scale(var(--press-scale))}
.icon-btn:disabled{opacity:.38;cursor:not-allowed}
.icon-btn .icon{width:18px;height:18px}
.icon-btn-ink{background:var(--primary-base);color:var(--primary-text);border-color:var(--primary-border)}
.icon-btn-ink:hover:not(:disabled){background:var(--primary-hover)}
.icon-btn[aria-busy=true]{pointer-events:none}
.icon-btn[aria-busy=true] .icon{animation:busy-breathe var(--t-5) var(--ease-inout) infinite alternate}
/* 글래스 3단계 — 테두리는 네 변 고른 1px 링(inset 0 0 0 1px)과 바깥 헤어라인. 위쪽 한 변 inset 하이라이트는 쓰지 않는다. */
.glass{background:var(--glass-fill);border:1px solid var(--glass-edge);backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));-webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));box-shadow:var(--shadow-float),inset 0 0 0 1px var(--glass-ring);border-radius:var(--radius-card)}
.glass-1{background:var(--glass-1-fill);border:1px solid var(--glass-edge);backdrop-filter:blur(var(--glass-1-blur)) saturate(var(--glass-saturate));-webkit-backdrop-filter:blur(var(--glass-1-blur)) saturate(var(--glass-saturate));box-shadow:var(--depth-2),inset 0 0 0 1px var(--glass-ring);border-radius:var(--radius-pill)}
.glass-2{background:var(--glass-2-fill);border:1px solid var(--glass-edge);backdrop-filter:blur(var(--glass-2-blur)) saturate(var(--glass-saturate));-webkit-backdrop-filter:blur(var(--glass-2-blur)) saturate(var(--glass-saturate));box-shadow:var(--depth-3),inset 0 0 0 1px var(--glass-ring);border-radius:var(--radius-card)}
.glass-3{background:var(--glass-3-fill);color:var(--glass-3-ink);border:1px solid rgba(0,0,0,.35);backdrop-filter:blur(var(--glass-3-blur)) saturate(var(--glass-saturate));-webkit-backdrop-filter:blur(var(--glass-3-blur)) saturate(var(--glass-saturate));box-shadow:var(--depth-4),inset 0 0 0 1px rgba(207,211,218,.19);border-radius:var(--radius-panel)}
@media(max-width:700px){.glass-2{backdrop-filter:blur(var(--glass-2-blur-mobile)) saturate(var(--glass-saturate));-webkit-backdrop-filter:blur(var(--glass-2-blur-mobile)) saturate(var(--glass-saturate))}}
/* 비칠 층 — 정적 빛 그라데이션(이미지·점 없음). 히어로·집중 구간·앱 바탕에만. 장식이므로 aria-hidden. */
.backdrop-layer{position:absolute;inset:0;pointer-events:none;overflow:hidden;background:radial-gradient(60% 50% at 78% 22%,var(--backdrop-tint-accent),transparent 70%),radial-gradient(50% 40% at 18% 80%,var(--backdrop-tint-white),transparent 70%),radial-gradient(40% 35% at 60% 90%,var(--backdrop-tint-mist),transparent 70%)}
.panel{background:var(--panel-fill);border:1px solid var(--line);border-radius:var(--radius-card)}
/* 가는 큰 숫자 — 점 매트릭스 대신. 고정폭 숫자. */
.num{font-weight:var(--fw-thin);letter-spacing:var(--ls-num);line-height:1;font-variant-numeric:tabular-nums}
.num-xl{font-size:var(--fs-num-xl)}.num-lg{font-size:var(--fs-num-lg)}.num-md{font-size:var(--fs-num-md)}
.num small{font-size:max(12px,.38em);font-weight:var(--fw-regular);letter-spacing:0;color:var(--muted);margin-left:.15em}
.display{font-size:var(--fs-display);font-weight:var(--fw-thin);letter-spacing:var(--ls-display);line-height:var(--lh-tight)}
.label{font-size:var(--fs-label);font-weight:var(--fw-medium);color:var(--muted);letter-spacing:.02em}
/* 상태 점 — 기능 표시. 라벨과 함께만. */
.status-dot{display:inline-flex;align-items:center;gap:6px;font-size:var(--fs-label);font-weight:var(--fw-medium);color:var(--ink)}
.status-dot::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--n-400);flex:none}
.status-dot.is-review::before{background:var(--accent)}.status-dot.is-done::before{background:var(--ink)}.status-dot.is-low::before{background:var(--n-300)}
.field{display:flex;flex-direction:column;gap:8px}
.field label,.field-label{font-size:12px;font-weight:550;line-height:1.5}
.field input,.field textarea,.field select,.input{width:100%;border:1px solid rgba(17,17,17,.16);border-radius:var(--radius-input);background:rgba(255,255,255,.68);min-height:46px;padding:12px 14px;font-size:13px;line-height:1.55;transition:border-color var(--duration),box-shadow var(--duration);appearance:none}
.field textarea{resize:vertical;min-height:120px}
.field input:focus,.field textarea:focus,.field select:focus,.input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px rgba(17,17,17,.10)}
.field input::placeholder,.field textarea::placeholder,.input::placeholder{color:var(--muted)}
.field small{font-size:12px;color:var(--muted)}
.field input[aria-invalid=true]{border-color:var(--accent-deep);box-shadow:0 0 0 1px var(--accent-deep)}
.error-text{font-size:12px;color:var(--accent-deep)}
fieldset{padding:0;margin:0;border:0;min-width:0}
legend{padding:0;margin:0 0 10px}
.choice-group{display:flex;flex-wrap:wrap;gap:8px}
.choice{position:relative;display:inline-flex;cursor:pointer}
.choice input{position:absolute;opacity:0;inset:0;width:100%;height:100%;margin:0;cursor:pointer}
.choice span{display:inline-flex;align-items:center;justify-content:center;min-height:40px;padding:9px 15px;border:1px solid var(--line);border-radius:9px;font-size:12px;background:rgba(255,255,255,.45);transition:background var(--duration),border-color var(--duration)}
.choice input:checked+span{background:rgba(17,17,17,.58);border-color:rgba(17,17,17,.4);color:var(--accent-deep)}
.choice input:focus-visible+span{outline:3px solid rgba(17,17,17,.5);outline-offset:3px}
.dialog{padding:0;border:1px solid var(--white);border-radius:24px;background:rgba(251,251,252,.96);box-shadow:0 30px 100px rgba(17,17,17,.2);width:min(540px,calc(100vw - 32px));max-height:calc(100dvh - 48px);color:var(--ink);overflow:auto}
.dialog::backdrop{background:rgba(17,17,17,.25);backdrop-filter:blur(7px);-webkit-backdrop-filter:blur(7px)}
.dialog-inner{padding:34px}
.dialog-top{display:flex;align-items:center;justify-content:space-between;gap:20px;margin-bottom:24px}
.dialog-top .icon-btn{position:relative;width:36px;height:36px;border:none;background:rgba(17,17,17,.04)}.dialog-top .icon-btn::before{content:"";position:absolute;inset:-4px}
.dialog h2{font-size:32px;line-height:1.35;margin-bottom:12px}
.dialog-lead{font-size:13px;color:var(--muted);line-height:1.8;margin-bottom:26px}
.toast{position:fixed;right:28px;bottom:28px;z-index:300;display:flex;align-items:center;gap:12px;max-width:min(440px,calc(100vw - 32px));padding:14px 16px;background:rgba(251,251,252,.94);border:1px solid var(--white);border-radius:14px;box-shadow:0 0 0 1px var(--line),var(--shadow-float);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);opacity:0;visibility:hidden;transform:translateY(12px);transition:opacity .2s,transform .3s var(--ease),visibility .2s;font-size:12px;line-height:1.6}
.toast.visible{opacity:1;visibility:visible;transform:translateY(0)}
.toast button{position:relative;display:inline-flex;align-items:center;justify-content:center;min-width:36px;min-height:36px;margin:-4px -5px -4px 4px;color:var(--muted)}.toast button::before{content:"";position:absolute;inset:-4px}
.toast button .icon{width:16px;height:16px}
.copy-fallback{font-family:var(--mono);font-size:12px;width:100%;height:160px;border:1px solid var(--line);background:var(--white);border-radius:10px;padding:14px}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){.glass{background:var(--glass-fallback)}}
@media(prefers-reduced-transparency:reduce){.glass,.glass-1,.glass-2{background:var(--glass-fallback);backdrop-filter:none;-webkit-backdrop-filter:none}.glass-3{background:#22262C;backdrop-filter:none;-webkit-backdrop-filter:none}}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}.btn[aria-busy=true]::after,.icon-btn[aria-busy=true] .icon{animation:none;opacity:.6}*,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}}
.segmented{display:inline-flex;align-items:center;gap:2px;padding:3px;border:1px solid rgba(17,17,17,.045);border-radius:var(--radius-pill);background:rgba(17,17,17,.035);flex:none}
.segmented button{position:relative;min-height:36px;font-size:12px;line-height:1.2;padding:8px 14px;border-radius:var(--radius-pill);white-space:nowrap;color:var(--muted);transition:background .2s,box-shadow .2s}
.segmented button::before{content:"";position:absolute;left:0;right:0;top:-4px;bottom:-4px}
.segmented button[aria-pressed=true],.segmented button[aria-selected=true]{color:var(--ink);background:rgba(255,255,255,.9);box-shadow:0 1px 4px rgba(17,17,17,.07)}
input[type=range]{-webkit-appearance:none;appearance:none;display:block;width:100%;height:3px;margin:15px 0;border-radius:3px;background:var(--mist);cursor:pointer;padding:0}
input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:15px;height:15px;border-radius:50%;background:var(--surface);border:1px solid rgba(17,17,17,.11);box-shadow:0 1px 3px rgba(17,17,17,.15)}
input[type=range]::-moz-range-thumb{width:15px;height:15px;border-radius:50%;background:var(--surface);border:1px solid rgba(17,17,17,.11);box-shadow:0 1px 3px rgba(17,17,17,.15)}.select-wrap>.icon{position:absolute;right:12px;top:14px;width:15px;height:15px;pointer-events:none;color:var(--muted)}
.check-label{display:flex;align-items:center;gap:10px;font-size:13px;cursor:pointer;min-height:var(--touch-min);color:var(--muted)}
.check-label input{appearance:none;-webkit-appearance:none;width:16px;height:16px;margin:0;border:1px solid rgba(17,17,17,.2);border-radius:4px;background:rgba(255,255,255,.6);cursor:pointer;position:relative;flex:none}
.check-label input:checked{background:var(--accent);border-color:var(--accent)}
.check-label input:checked::after{content:'';position:absolute;left:4px;top:1px;width:5px;height:9px;border-right:1.6px solid var(--white);border-bottom:1.6px solid var(--white);transform:rotate(45deg)}
.check-label input:disabled{opacity:.4;cursor:not-allowed}
.check-label:has(input:disabled){opacity:.55;cursor:not-allowed}
.switch-label{display:flex;align-items:center;justify-content:space-between;gap:15px;cursor:pointer;min-height:var(--touch-min);font-size:13px}
.switch{position:relative;display:inline-flex;flex:none;width:34px;height:21px}
.switch input{position:absolute;inset:0;opacity:0;cursor:pointer;margin:0;z-index:2;width:100%;height:100%}
.switch-track{position:absolute;inset:0;background:var(--mist);border:1px solid rgba(17,17,17,.05);border-radius:30px;transition:background .2s}
.switch-track::after{content:'';width:15px;height:15px;position:absolute;left:2px;top:2px;background:var(--white);border-radius:50%;box-shadow:0 1px 3px rgba(17,17,17,.15);transition:transform .22s var(--ease)}
.switch input:checked+.switch-track{background:var(--accent)}
.switch input:checked+.switch-track::after{transform:translateX(13px)}
.switch input:focus-visible+.switch-track{outline:3px solid rgba(17,17,17,.5);outline-offset:4px}
.tabs{display:flex;gap:27px;border-bottom:1px solid var(--line)}
.tabs button{position:relative;font-size:12px;padding:12px 1px 14px;color:var(--muted);min-height:var(--touch-min)}
.tabs button[aria-selected=true]{font-weight:550;color:var(--ink)}
.tabs button[aria-selected=true]{text-decoration:underline;text-underline-offset:14px;text-decoration-thickness:2px;text-decoration-color:var(--ink)}
.dialog-buttons{display:flex;align-items:center;justify-content:flex-end;gap:var(--space-3);margin-top:var(--space-5)}
body,.ds-header,.sidebar{transition:background-color .2s ease,color .2s ease,border-color .2s ease}
::selection{background:var(--selected-fill);color:var(--ink)}
button:focus-visible,a:focus-visible,input:focus-visible,textarea:focus-visible,select:focus-visible,summary:focus-visible,[tabindex]:focus-visible{outline-color:var(--focus-ring)}
.btn:focus-visible,.icon-btn:focus-visible{outline:2px solid var(--focus-ring);outline-offset:3px}
.skip-link{background:var(--ink);color:var(--canvas)}
.panel{background:var(--panel-fill);border-color:var(--line)}
.field input,.field textarea,.field select,.input{background:var(--input-fill);border-color:var(--input-border)}
.field input:focus,.field textarea:focus,.field select:focus,.input:focus{border-color:var(--focus-ring);box-shadow:0 0 0 2px var(--selected-fill)}
.choice span{background:var(--control-fill)}
.choice input:checked+span{background:var(--selected-fill);border-color:var(--selected-border);color:var(--selected-text)}
.choice input:focus-visible+span,.switch input:focus-visible+.switch-track{outline-color:var(--focus-ring)}
.dialog{background:var(--overlay-fill);border-color:var(--overlay-border);box-shadow:var(--shadow-float);backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px)}
.dialog::backdrop{background:var(--overlay-backdrop)}
.dialog-top .icon-btn{background:var(--control-fill)}
.toast{background:var(--overlay-fill);border-color:var(--overlay-border)}
.copy-fallback{background:var(--surface);color:var(--ink)}
.segmented{background:var(--segment-track);border-color:var(--line-soft)}
.segmented button[aria-pressed=true],.segmented button[aria-selected=true]{background:var(--segment-selected);box-shadow:0 1px 4px rgba(17,17,17,.07)}
input[type=range]{background:var(--control-track)}
input[type=range]::-webkit-slider-thumb{background:var(--surface-raised);border-color:var(--line-strong);box-shadow:var(--shadow)}
input[type=range]::-moz-range-thumb{background:var(--surface-raised);border-color:var(--line-strong);box-shadow:var(--shadow)}
.check-label input{background:var(--control-fill);border-color:var(--input-border)}
.check-label input:checked{background:var(--control-on);border-color:var(--control-on)}
.check-label input:checked::after{border-color:var(--control-mark)}
.switch-track{background:var(--control-track);border-color:var(--line)}
.switch-track::after{background:var(--palette-white)}
.switch input:checked+.switch-track::after{background:var(--control-mark)}
.switch input:checked+.switch-track{background:var(--control-on)}
[data-theme=dark] input[type=range]::-webkit-slider-thumb{background:#AEB4BD;border-color:#CFD3DA}
[data-theme=dark] input[type=range]::-moz-range-thumb{background:#AEB4BD;border-color:#CFD3DA}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .glass,.glass-1,.glass-2,.material-card{background:var(--glass-fallback)}
  .glass-3{background:#22262C}
  .dialog,.toast,.sort-menu{background:var(--surface-raised)}
}

/* Appearance controls and color documentation. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* 강조 다크 구간(허용 두 곳: coSchema 캔버스 집중 패널 · 푸터) — 테마 전환이 아니다. 요소에 data-theme="dark" 를 붙여 토큰만 바꾼다. */
.ink-band{background:var(--canvas);color:var(--ink)}

/* ===== v4.1.0 · 1차 컴포넌트 14종 (2026-10-01 2단계). 상태 6종(기본·hover·focus·active·disabled·처리 중)은 누르는 요소에 걸린다.
   문서 상태 표는 data-state="hover|focus|active" 로 같은 모양을 고정해 보인다(components.html 전용 — 제품 화면에서 쓰지 않는다). ===== */
/* 02 칩·필터 — 알약, 보이는 높이 36, 누르는 영역 44(.btn-sm 과 같은 ::before 확장). aria-pressed 로 선택. */
.chip-group{display:flex;flex-wrap:wrap;gap:8px}
.chip{position:relative;display:inline-flex;align-items:center;gap:6px;min-height:var(--control-h-sm);padding:0 14px;border:1px solid var(--line);border-radius:var(--radius-pill);background:var(--control-fill);color:var(--ink);font-size:13px;line-height:1.2;cursor:pointer;transition:background var(--t-2),border-color var(--t-2),transform var(--t-1) var(--ease-out),opacity var(--t-2)}
.chip::before{content:"";position:absolute;left:0;right:0;top:-4px;bottom:-4px}
.chip .icon{width:14px;height:14px}
.chip:hover:not(:disabled),.chip[data-state=hover]{background:var(--control-hover)}
.chip:active:not(:disabled),.chip[data-state=active]{transform:scale(var(--press-scale))}
.chip[aria-pressed=true]{background:var(--selected-fill);border-color:var(--selected-border);color:var(--selected-text)}
.chip:disabled,.chip[aria-disabled=true]{opacity:.38;cursor:not-allowed}
.chip[aria-busy=true]{pointer-events:none}.chip[aria-busy=true]>span{animation:busy-breathe var(--t-5) var(--ease-inout) infinite alternate}
.chip-count{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
/* 04 프롬프트 입력 — 겹친 탭 카드. 겹친 카드는 모양이고 역할은 세그먼트(role=group + aria-pressed, 각 버튼이 Tab 순서)다 — tablist 가 아니다. 입력 상자와 보내기 원형 버튼이 한 줄. 패밀리 골격의 하단 프롬프트. */
.prompt{display:flex;flex-direction:column}
.prompt-tabs{display:flex;gap:4px;padding:0 16px;position:relative;z-index:1}
.prompt-tabs button{min-height:var(--touch-min);padding:10px 14px 12px;border:1px solid var(--line);border-bottom:0;border-radius:12px 12px 0 0;background:var(--control-fill);color:var(--muted);font-size:12px;line-height:1.2;margin-bottom:-1px;cursor:pointer;transition:background var(--t-2),color var(--t-2)}
.prompt-tabs button:hover:not(:disabled),.prompt-tabs button[data-state=hover]{background:var(--control-hover);color:var(--ink)}
.prompt-tabs button[aria-pressed=true]{background:var(--surface);color:var(--ink);font-weight:var(--fw-medium);position:relative;z-index:2}
.prompt-tabs button:disabled{opacity:.38;cursor:not-allowed}
.prompt-box{display:flex;align-items:flex-end;gap:12px;padding:14px 14px 14px 18px;border:1px solid var(--line);border-radius:var(--radius-card);background:var(--surface);box-shadow:var(--depth-1);transition:border-color var(--t-2),box-shadow var(--t-2)}
.prompt-box:focus-within,.prompt-box[data-state=focus]{border-color:var(--focus-ring);box-shadow:0 0 0 2px var(--selected-fill)}
.prompt-box[data-state=hover]{border-color:var(--line-strong)}
.prompt-box textarea{flex:1 1 auto;min-width:0;min-height:44px;max-height:160px;padding:11px 0;border:0;background:transparent;resize:none;font-size:14px;line-height:1.55;outline:none}
.prompt-box textarea::placeholder{color:var(--muted)}
.prompt-box textarea:disabled{opacity:.5}
.prompt.is-disabled .prompt-box,.prompt-box[data-state=disabled]{opacity:.55}
.prompt-hint{font-size:var(--fs-caption);color:var(--muted);padding:8px 18px 0}
/* 05 수치 카드 — 가는 큰 숫자 + 이름 + 기간 + 증감 문장. 색 없는 증감(문구로). */
.metric{display:flex;flex-direction:column;gap:10px;padding:22px 24px;min-width:0}
.metric-label{font-size:var(--fs-label);font-weight:var(--fw-medium);color:var(--muted);letter-spacing:.02em}
.metric-value{font-size:var(--fs-num-lg)}
.metric-delta{font-size:var(--fs-small);color:var(--muted)}.metric-delta b{color:var(--ink);font-weight:var(--fw-medium)}
a.metric,button.metric{text-align:left;border:1px solid var(--line);border-radius:var(--radius-card);background:var(--panel-fill);color:inherit;text-decoration:none;cursor:pointer;transition:background var(--t-2),border-color var(--t-2),transform var(--t-1) var(--ease-out)}
a.metric:hover,button.metric:hover:not(:disabled),.metric[data-state=hover]{background:var(--surface);border-color:var(--line-strong)}
a.metric:active,button.metric:active:not(:disabled),.metric[data-state=active]{transform:scale(.99)}
button.metric:disabled,.metric[data-state=disabled]{opacity:.38;cursor:not-allowed}
.metric[aria-busy=true] .metric-value{animation:busy-breathe var(--t-5) var(--ease-inout) infinite alternate}
/* 07 알약 행 표 + 상태 칩 — 표의 각 행이 알약(radius 999). 머리 행은 라벨만. 누르는 행은 button/a. */
.pill-table{display:flex;flex-direction:column;gap:6px;min-width:0}
.pill-table-head,.pill-row{display:grid;grid-template-columns:var(--pill-cols,1.6fr 1fr 1fr auto);align-items:center;gap:16px;min-height:var(--touch-min);padding:0 8px 0 20px}
.pill-table-head{font-size:var(--fs-label);font-weight:var(--fw-medium);color:var(--muted);min-height:32px}
.pill-row{border:1px solid var(--line);border-radius:var(--radius-pill);background:var(--panel-fill);font-size:14px;color:var(--ink);text-align:left;width:100%;cursor:default;transition:background var(--t-2),border-color var(--t-2),transform var(--t-1) var(--ease-out),opacity var(--t-2)}
.pill-row>span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pill-row .num{font-size:18px}
button.pill-row,a.pill-row{cursor:pointer;text-decoration:none}
button.pill-row:hover:not(:disabled),a.pill-row:hover,.pill-row[data-state=hover]{background:var(--control-hover);border-color:var(--line-strong)}
button.pill-row:active:not(:disabled),.pill-row[data-state=active]{transform:scale(.995)}
button.pill-row:disabled,.pill-row[data-state=disabled]{opacity:.38;cursor:not-allowed}
.pill-row[aria-busy=true]{pointer-events:none}.pill-row[aria-busy=true] .status-chip{animation:busy-breathe var(--t-5) var(--ease-inout) infinite alternate}
.status-chip{display:inline-flex;align-items:center;gap:6px;min-height:26px;padding:0 10px;border-radius:var(--radius-pill);background:var(--control-fill);border:1px solid var(--line);font-size:var(--fs-label);font-weight:var(--fw-medium);color:var(--ink);white-space:nowrap;justify-self:start}
.status-chip::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--n-400);flex:none}
.status-chip.is-review::before{background:var(--accent)}.status-chip.is-done::before{background:var(--ink)}.status-chip.is-low::before{background:var(--n-300)}
/* 08 벤토 그리드 — 12칸. 패널은 .panel 또는 글래스. 모든 칸의 첫 요소 자리는 같다(C3). */
.bento{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:16px}
.bento>*{grid-column:span 4;min-width:0}
.bento .span-3{grid-column:span 3}.bento .span-4{grid-column:span 4}.bento .span-6{grid-column:span 6}.bento .span-8{grid-column:span 8}.bento .span-12{grid-column:span 12}
.bento .row-2{grid-row:span 2}
@media(max-width:900px){.bento>*,.bento .span-3,.bento .span-4,.bento .span-6,.bento .span-8{grid-column:span 6}}
@media(max-width:600px){.bento>*,.bento .span-3,.bento .span-4,.bento .span-6,.bento .span-8{grid-column:span 12}}
/* 09 상단 알약 내비 — 글래스 1 알약 한 줄: 제품 타일 · 메뉴 · 원형 버튼. 활성 메뉴는 글자 굵기 + 밑줄. */
.topnav{display:flex;align-items:center;gap:8px;min-height:56px;padding:6px 8px 6px 10px;border-radius:var(--radius-pill);width:100%;min-width:0}
.topnav-tile{display:inline-flex;align-items:center;gap:10px;min-height:var(--touch-min);padding:0 10px 0 0;color:inherit;text-decoration:none;flex:none}
.topnav-tile img{display:block;width:32px;height:32px;border-radius:9px;box-shadow:var(--depth-1)}
.topnav-tile b{font-size:14px;font-weight:var(--fw-medium);white-space:nowrap}
.topnav-menu{display:flex;align-items:center;gap:2px;flex:1 1 auto;min-width:0;overflow:hidden}
.topnav-menu a,.topnav-menu button{display:inline-flex;align-items:center;min-height:var(--touch-min);padding:0 14px;border-radius:var(--radius-pill);color:var(--muted);font-size:13px;text-decoration:none;white-space:nowrap;background:transparent;cursor:pointer;transition:background var(--t-2),color var(--t-2),transform var(--t-1) var(--ease-out)}
.topnav-menu :is(a,button):hover,.topnav-menu [data-state=hover]{background:var(--control-hover);color:var(--ink)}
.topnav-menu :is(a,button):active,.topnav-menu [data-state=active]{transform:scale(var(--press-scale))}
.topnav-menu [aria-current=page],.topnav-menu [aria-current=true]{color:var(--ink);font-weight:var(--fw-medium);text-decoration:underline;text-underline-offset:6px;text-decoration-thickness:1.5px}
.topnav-menu [aria-disabled=true],.topnav-menu button:disabled{opacity:.38;pointer-events:none}
.topnav-tools{display:flex;align-items:center;gap:6px;flex:none;margin-left:auto}
@media(max-width:700px){.topnav-menu{display:none}.topnav-tile b{display:none}}
/* 10 세로 아이콘 레일 — 원형 아이콘 버튼 세로 열. 현재 위치는 잉크 채움(아쿠아 아님). */
.rail{display:flex;flex-direction:column;align-items:center;gap:8px;padding:10px 8px;width:60px;border-radius:var(--radius-pill)}
.rail .icon-btn{border-color:transparent;background:transparent}
.rail .icon-btn:hover:not(:disabled),.rail .icon-btn[data-state=hover]{background:var(--control-hover)}
.rail .icon-btn[aria-current=page],.rail .icon-btn[aria-current=true]{background:var(--primary-base);color:var(--primary-text)}
.rail-gap{flex:1 1 auto;min-height:8px}
/* 11 노드 카드 + 포트 + 연결선 — coSchema 캔버스. 포트는 8px 정사각(원 아님), 연결선은 1px. 두 포트가 라벨과 함께라 장식 점이 아니다. */
.node{position:relative;display:flex;flex-direction:column;gap:8px;min-width:0;padding:16px 18px;border:1px solid var(--line);border-radius:var(--radius-card);background:var(--surface);box-shadow:var(--depth-1);text-align:left;color:inherit;transition:border-color var(--t-2),box-shadow var(--t-2),transform var(--t-1) var(--ease-out),opacity var(--t-2)}
.node-kicker{font-size:var(--fs-label);font-weight:var(--fw-medium);color:var(--muted);letter-spacing:.02em}
.node-title{font-size:16px;font-weight:var(--fw-medium);line-height:1.3}
.node-meta{font-size:var(--fs-small);color:var(--muted)}
button.node,a.node{cursor:pointer;text-decoration:none}
button.node:hover:not(:disabled),a.node:hover,.node[data-state=hover]{border-color:var(--line-strong);box-shadow:var(--depth-2)}
button.node:active:not(:disabled),.node[data-state=active]{transform:scale(.99)}
.node[aria-current=true],.node.is-current{border-color:var(--ink);box-shadow:var(--depth-2),inset 0 0 0 1px var(--ink)}
button.node:disabled,.node[data-state=disabled]{opacity:.38;cursor:not-allowed}
.node[aria-busy=true] .node-meta{animation:busy-breathe var(--t-5) var(--ease-inout) infinite alternate}
.node-port{position:absolute;top:50%;width:8px;height:8px;margin-top:-4px;border-radius:2px;background:var(--surface);border:1px solid var(--ink)}
.node-port.is-in{left:-5px}.node-port.is-out{right:-5px}
.node-port.is-live{background:var(--accent);border-color:var(--accent)}
.node-canvas{position:relative;display:grid;grid-template-columns:1fr 48px 1fr;align-items:center;gap:0}
.node-link{height:1px;background:var(--line-strong);align-self:center;position:relative}
.node-link.is-live{background:var(--accent)}
.node-link::after{content:"";position:absolute;right:-1px;top:-3px;width:7px;height:7px;border-top:1px solid currentColor;border-right:1px solid currentColor;transform:rotate(45deg);color:var(--line-strong)} /* bar-ok: 화살촉(직각 두 변), 강조 바 아님 */
.node-link.is-live::after{color:var(--accent)}
/* 12 쌓인 카드 스택 — 뒤 카드 두 장은 불투명 면(글자 없음). 눌러 넘기는 건 앞 카드 안의 버튼. */
.stack{position:relative;padding:0 0 16px 0}
.stack-card{position:relative;z-index:3;padding:20px 22px;border:1px solid var(--line);border-radius:var(--radius-card);background:var(--surface);box-shadow:var(--depth-2)}
.stack::before,.stack::after{content:"";position:absolute;left:12px;right:12px;bottom:8px;height:40px;border:1px solid var(--line);border-radius:var(--radius-card);background:var(--surface-raised);z-index:2}
.stack::after{left:24px;right:24px;bottom:0;z-index:1;background:var(--n-100)}
.stack-count{font-size:var(--fs-label);color:var(--muted);font-variant-numeric:tabular-nums}
/* 13 검색 — 알약 틀(테·채움은 틀에) 안에 돋보기 · 테두리 없는 입력 · 지우기 원형 버튼(36, 누르는 영역 44)이 나란히. 겹침 없음. */
.search{display:flex;align-items:center;gap:10px;min-height:var(--control-h);padding:0 6px 0 16px;border:1px solid var(--input-border);border-radius:var(--radius-pill);background:var(--input-fill);min-width:0;transition:border-color var(--t-2),box-shadow var(--t-2)}
.search>.icon{width:16px;height:16px;color:var(--muted);flex:none}
.search input{flex:1 1 auto;min-width:0;min-height:44px;padding:0;border:0;background:transparent;font-size:14px;line-height:1.2;outline:none;appearance:none}
.search input::-webkit-search-cancel-button{display:none}
.search:hover,.search[data-state=hover]{border-color:var(--line-strong)}
.search:focus-within,.search[data-state=focus]{border-color:var(--focus-ring);box-shadow:0 0 0 2px var(--selected-fill)}
.search:has(input:disabled),.search[data-state=disabled]{opacity:.5}
.search .icon-btn{position:relative;width:36px;height:36px;border-color:transparent;background:transparent;flex:none}
.search .icon-btn::before{content:"";position:absolute;inset:-4px}
.search[aria-busy=true] input{animation:busy-breathe var(--t-5) var(--ease-inout) infinite alternate}
/* 14 목록 행 — 제목·메타·오른쪽 동작. 행 전체가 a/button 이면 누른다. */
.list{display:flex;flex-direction:column;border:1px solid var(--line);border-radius:var(--radius-card);background:var(--panel-fill);overflow:hidden}
.list-row{display:flex;align-items:center;gap:16px;min-height:56px;padding:12px 20px;border-top:1px solid var(--line);color:inherit;text-decoration:none;text-align:left;width:100%;background:transparent;transition:background var(--t-2),opacity var(--t-2)}
.list-row:first-child{border-top:0}
.list-row-main{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:2px}
.list-row-title{font-size:14px;font-weight:var(--fw-medium);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.list-row-meta{font-size:var(--fs-caption);color:var(--muted)}
.list-row-side{flex:none;display:flex;align-items:center;gap:10px;font-size:var(--fs-small);color:var(--muted)}
a.list-row,button.list-row{cursor:pointer}
a.list-row:hover,button.list-row:hover:not(:disabled),.list-row[data-state=hover]{background:var(--control-hover)}
a.list-row:active,button.list-row:active:not(:disabled),.list-row[data-state=active]{background:var(--control-fill)}
a.list-row:focus-visible,button.list-row:focus-visible,.list-row[data-state=focus]{outline-offset:-3px}
button.list-row:disabled,.list-row[data-state=disabled]{opacity:.38;cursor:not-allowed}
.list-row[aria-busy=true] .list-row-side{animation:busy-breathe var(--t-5) var(--ease-inout) infinite alternate}
.list-row[aria-current=true] .list-row-title{text-decoration:underline;text-underline-offset:4px}
/* 세그먼트·토글·탭 상태 보강(2단계): disabled · 처리 중 · 문서 상태 표 */
.segmented button:hover:not(:disabled):not([aria-pressed=true]):not([aria-selected=true]),.segmented button[data-state=hover]{color:var(--ink)}
.segmented button:active:not(:disabled),.segmented button[data-state=active]{transform:scale(var(--press-scale))}
.segmented button:disabled,.segmented[aria-disabled=true] button{opacity:.38;cursor:not-allowed}
.segmented button[aria-busy=true]{animation:busy-breathe var(--t-5) var(--ease-inout) infinite alternate;pointer-events:none}
.switch-label:has(input:disabled){opacity:.55;cursor:not-allowed}
.switch:hover .switch-track,.switch[data-state=hover] .switch-track{border-color:var(--line-strong)}
.switch[data-state=focus] .switch-track{outline:3px solid var(--focus-ring);outline-offset:4px}
.switch[data-state=active] .switch-track::after{transform:translateX(13px) scale(.9)}
.switch[aria-busy=true] .switch-track::after{animation:busy-breathe var(--t-5) var(--ease-inout) infinite alternate}
.tabs button:hover:not(:disabled),.tabs button[data-state=hover]{color:var(--ink)}
.tabs button:disabled{opacity:.38;cursor:not-allowed}
.tabs button[aria-busy=true]{animation:busy-breathe var(--t-5) var(--ease-inout) infinite alternate;pointer-events:none}
.icon-btn[data-state=hover]{background:var(--secondary-hover)}.icon-btn-ink[data-state=hover]{background:var(--primary-hover)}
.icon-btn[data-state=active]{transform:scale(var(--press-scale))}
.btn-primary[data-state=hover]{background:var(--primary-hover);border-color:var(--primary-hover)}
.btn-secondary[data-state=hover]{background:var(--secondary-hover)}
.btn-text[data-state=hover]{text-decoration-color:var(--ink)}
.btn[data-state=active]{transform:scale(var(--press-scale))}
[data-state=focus]:is(.btn,.icon-btn,.chip,.pill-row,.node,.list-row,.metric,.prompt-tabs button,.segmented button,.tabs button,.topnav-menu a,.topnav-menu button){outline:2px solid var(--focus-ring);outline-offset:3px}
.list-row[data-state=focus]{outline-offset:-3px}
.tabs button[data-state=focus],.prompt-tabs button[data-state=focus]{outline-offset:-2px}

/* ===== 흐름 컴포넌트 8종 (F2·F3·F4·F6·F7) ===== */
/* F1 빈 상태 — 「무슨 일 · 왜 · 지금」 세 줄 + 첫 사용 체크리스트 + 복구 버튼 하나(.btn-row 와 24px). */
.empty,.error-block{display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-5);padding:28px;min-width:0}
.three{display:flex;flex-direction:column;gap:4px;font-size:14px;color:var(--ink)}
.three b{font-weight:var(--fw-medium);font-size:16px}.three span{color:var(--muted)}
.checklist{display:flex;flex-direction:column;gap:8px;margin:0;padding:0;list-style:none;font-size:14px}
.checklist li{display:flex;align-items:center;gap:10px;min-height:24px}
.checklist li::before{content:"";width:14px;height:14px;border:1px solid var(--line-strong);border-radius:4px;flex:none}
.checklist li.is-done::before{background:var(--ink);border-color:var(--ink)}
.checklist li.is-done{color:var(--muted);text-decoration:line-through}
/* F2 오류 — role="alert" 는 세 줄 묶음에만. 복구 버튼은 보조, 짝 영역 .btn-status 는 묶음 밖. */
.error-block .three b::before{content:"!";display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;margin-right:8px;border:1px solid var(--ink);border-radius:50%;font-size:12px;font-weight:600;vertical-align:2px}
/* F3 결제 전 요약 — 항목 행·합계(가는 큰 숫자)·조건 문장·확정 버튼. 취소 없음 문장을 글로 쓴다. */
.checkout{display:flex;flex-direction:column;gap:var(--space-5);padding:28px;min-width:0}
.checkout-rows{display:flex;flex-direction:column;gap:10px;font-size:14px}
.checkout-rows>div{display:flex;justify-content:space-between;gap:16px}
.checkout-rows>div span:first-child{color:var(--muted)}
.checkout-total{display:flex;align-items:baseline;justify-content:space-between;gap:16px;padding-top:14px;border-top:1px solid var(--line)}
.checkout-total .num{font-size:var(--fs-num-md)}
.checkout-terms{font-size:var(--fs-caption);color:var(--muted);line-height:1.6}
/* F4 고정 CTA 띠 — 화면 아래 고정(sticky) 글래스 2. 글 + 주 버튼 하나. 모바일은 세로. 측정 훅 cta_click(placement:"band"). */
.cta-band{position:sticky;bottom:16px;z-index:40;display:flex;align-items:center;justify-content:space-between;gap:24px;padding:14px 16px 14px 24px;border-radius:var(--radius-pill);min-width:0}
.cta-band p{margin:0;font-size:14px;min-width:0}
.cta-band p b{font-weight:var(--fw-medium)}
.cta-band .btn{flex:none}
.cta-band.is-static{position:relative;bottom:auto}
@media(max-width:600px){.cta-band{flex-direction:column;align-items:stretch;border-radius:var(--radius-card);padding:16px}.cta-band .btn{width:100%}}
/* F5 진행 표시 — 단계 칩 · 퍼센트 막대 · 고리. 영역은 role="status" aria-live="polite". 300ms 뒤에만 보인다(.wait-delay). */
.progress{display:flex;flex-direction:column;gap:10px;font-size:14px;min-width:0}
.progress-steps{display:flex;flex-wrap:wrap;gap:6px}
.progress-steps span{display:inline-flex;align-items:center;min-height:28px;padding:0 12px;border-radius:var(--radius-pill);border:1px solid var(--line);background:var(--control-fill);font-size:var(--fs-label);color:var(--muted)}
.progress-steps span[aria-current=step]{background:var(--primary-base);color:var(--primary-text);border-color:var(--primary-border)}
.progress-steps span.is-done{color:var(--ink);text-decoration:line-through}
.progress-bar{height:4px;border-radius:2px;background:var(--n-200);overflow:hidden}
.progress-bar i{display:block;height:100%;background:var(--ink);transition:width var(--t-3) var(--ease-out)}
.progress-row{display:flex;justify-content:space-between;gap:16px;font-variant-numeric:tabular-nums}
.progress-row .num{font-size:var(--fs-num-md)}
.progress-ring{position:relative;width:64px;height:64px;flex:none}
.progress-ring svg{display:block;width:100%;height:100%;transform:rotate(-90deg)}
.progress-ring circle{fill:none;stroke-width:3}
.progress-ring .track{stroke:var(--n-200)}
.progress-ring .fill{stroke:var(--ink);stroke-dasharray:176;stroke-dashoffset:calc(176 - 176 * var(--p,0));transition:stroke-dashoffset var(--t-3) var(--ease-out)}
.progress-ring output{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:14px;font-variant-numeric:tabular-nums}
.wait-delay{animation:wait-appear 1ms linear 300ms both}
@keyframes wait-appear{from{visibility:hidden}to{visibility:visible}}
/* F6 토스트(되돌리기) — 기존 .toast 에 되돌리기 텍스트 버튼. 문서에서는 .toast.is-inline 으로 흐름 안에 둔다. */
.toast .btn-text{min-height:36px;margin:0}
.toast.is-inline{position:static;opacity:1;visibility:visible;transform:none;max-width:none}
/* F7 대안 경로 — 막혔을 때 대신 가는 길 두 개. 측정 훅 dead_end_alt_click. */
.alt-path{display:flex;flex-direction:column;gap:var(--space-4);padding:28px;min-width:0}
.alt-path-options{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px}
.alt-path-option{display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-5);padding:18px 20px;border:1px solid var(--line);border-radius:var(--radius-card);background:var(--surface);min-width:0}
.alt-path-option b{font-size:15px;font-weight:var(--fw-medium)}
.alt-path-option p{margin:0;font-size:var(--fs-small);color:var(--muted)}
/* F8 이어서 하기 — 마지막 상태 한 줄 + 「이어서 하기」 주 버튼 + 「처음부터」 텍스트. */
.resume{display:flex;flex-direction:column;gap:var(--space-5);padding:28px;min-width:0}
.resume-state{display:flex;flex-direction:column;gap:4px;font-size:14px}
.resume-state b{font-weight:var(--fw-medium);font-size:16px}
.resume-state span{color:var(--muted)}
.resume-when{font-size:var(--fs-caption);color:var(--muted)}

/* ===== 브랜드 로딩(모임) — SVG 선 모티프(원 · 점 · 곡선 바 · 회전 고리 없음). 무채색 + Aquamarine 한 선.
   .loader 20px(글줄·버튼) · .loader-lg 40px(화면). 길이가 다른 세 선(10·14·6)이 가운데로 모였다 벌어진다. 2026-10-01 결정(다른 시안은 지움, §11).
   짧은 대기(300ms 뒤) · 긴 대기(단계 문장·퍼센트·취소) · 버튼 처리 중(.btn[aria-busy] 안)에 같은 모양. 감속 모드는 정지 상태. ===== */
.loader{display:inline-block;width:20px;height:20px;flex:none;vertical-align:middle;overflow:visible;color:var(--ink)}
.loader-lg{width:40px;height:40px}
.loader line,.loader rect{stroke:currentColor;stroke-width:2;stroke-linecap:butt;fill:none;vector-effect:non-scaling-stroke}
.loader .acc{stroke:var(--accent)}
.loader-a line{transform-box:fill-box;transform-origin:center;animation:loader-gather 1.4s var(--ease-inout) infinite} /* 세 선은 길이가 다르다(10·14·6) — 정지 화면이 일시정지 기호로 읽히지 않는다 */
.loader-a .l1{animation-name:loader-gather-l}.loader-a .l2{animation:loader-gather-mid 1.4s var(--ease-inout) infinite}.loader-a .l3{animation-name:loader-gather-r} /* 바깥 두 선이 대칭으로 가운데에 모였다 벌어진다 */
@keyframes loader-gather-l{0%,100%{transform:translateX(0)}50%{transform:translateX(5px)}}
@keyframes loader-gather-r{0%,100%{transform:translateX(0)}50%{transform:translateX(-5px)}}
@keyframes loader-gather-mid{0%,100%{opacity:.35}50%{opacity:1}}
.btn-primary .loader .acc{stroke:var(--primary-text)}
.icon-btn[aria-busy=true] .loader{width:16px;height:16px}.icon-btn-ink[aria-busy=true] .loader{color:var(--primary-text)}.icon-btn-ink .loader .acc{stroke:var(--primary-text)}
.wait{display:flex;align-items:center;gap:12px;font-size:14px;min-width:0}
.wait-lg{flex-direction:column;align-items:flex-start;gap:14px}
.wait-copy{display:flex;flex-direction:column;gap:4px}
.wait-copy span{color:var(--muted);font-size:var(--fs-small)}
@media(prefers-reduced-motion:reduce){.loader-a line{animation:none}.loader-a .l2{opacity:1}.wait-delay{animation:none;visibility:visible}.chip[aria-busy=true]>span,.metric[aria-busy=true] .metric-value,.pill-row[aria-busy=true] .status-chip,.node[aria-busy=true] .node-meta,.search[aria-busy=true] input,.list-row[aria-busy=true] .list-row-side,.segmented button[aria-busy=true],.tabs button[aria-busy=true],.switch[aria-busy=true] .switch-track::after{animation:none;opacity:.6}}
