/* =========================================================================
   JNC Holdings — Feedback & status
   Requires colors_and_type.css + semantic-roles.css.
   인지·UX 근거:
   · 시스템 상태 가시성(NN/g #1): 진행/대기/완료를 즉시 보여 불확실성↓.
   · 토스트는 비차단(작업 흐름 유지) + 자동 소멸, 토스트로 치명 오류를 전달하지
     않는다(놓치면 안 되는 정보는 banner/.jstatus 사용).
   · 스켈레톤은 빈 화면의 인지부하·체감 대기를 줄인다(규칙 1.4).
   · 색만으로 상태를 전달하지 않음 — 아이콘/형태 동반(규칙 1.7).
   ========================================================================= */

/* =========================================================================
   PROGRESS — linear, determinate  .jprogress
   ========================================================================= */
.jprogress { width: 100%; height: 6px; border-radius: var(--r-pill);
  background: var(--surface-inset); overflow: hidden; box-shadow: var(--sh-inset); }
.jprogress > .bar { height: 100%; border-radius: var(--r-pill); background: var(--brand);
  transition: width var(--dur-slow) var(--ease-standard); }
.jprogress.sm { height: 4px; }
.jprogress.lg { height: 10px; }
/* market-neutral variants reuse status roles where meaningful */
.jprogress.success > .bar { background: var(--success); }
.jprogress.warning > .bar { background: var(--warning); }
.jprogress.error   > .bar { background: var(--error); }
/* indeterminate */
.jprogress.indeterminate > .bar { width: 40%; animation: jprog-slide 1.4s var(--ease-in-out) infinite; }
@keyframes jprog-slide { 0% { transform: translateX(-100%); } 100% { transform: translateX(350%); } }

/* meter (capacity/allocation) — distinct from progress (achievement) */
.jmeter { width: 100%; height: 8px; border-radius: var(--r-pill); background: var(--surface-inset);
  display: flex; overflow: hidden; }
.jmeter > span { height: 100%; display: block; }

/* =========================================================================
   SPINNER  .jspinner  (indeterminate, brief waits)
   ========================================================================= */
.jspinner { display: inline-block; width: var(--icon-md); height: var(--icon-md);
  border: 2.5px solid var(--border); border-top-color: var(--brand); border-radius: var(--r-pill);
  animation: jspin 0.7s linear infinite; }
.jspinner.sm { width: var(--icon-sm); height: var(--icon-sm); border-width: 2px; }
.jspinner.lg { width: var(--icon-lg); height: var(--icon-lg); border-width: 3px; }
.jspinner.on-brand { border-color: rgba(255,255,255,0.35); border-top-color: var(--white); }
@keyframes jspin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .jspinner { animation-duration: 1.6s; }
  .jprogress.indeterminate > .bar { animation-duration: 2.4s; }
  .jskeleton { animation: none; }
}

/* =========================================================================
   SKELETON  .jskeleton  (loading placeholder)
   ========================================================================= */
.jskeleton { display: block; background: var(--surface-sunken); border-radius: var(--r-sm);
  position: relative; overflow: hidden; }
.jskeleton::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.55), transparent);
  transform: translateX(-100%); animation: jshimmer 1.3s var(--ease-in-out) infinite; }
@keyframes jshimmer { to { transform: translateX(100%); } }
.jskeleton.text { height: 12px; border-radius: var(--r-xs); }
.jskeleton.text.lg { height: 18px; }
.jskeleton.title { height: 26px; width: 60%; }
.jskeleton.circle { border-radius: var(--r-pill); }
.jskeleton.line-80 { width: 80%; } .jskeleton.line-60 { width: 60%; } .jskeleton.line-40 { width: 40%; }

/* =========================================================================
   TOAST / SNACKBAR  .jtoast  (inverse surface, transient, non-blocking)
   ========================================================================= */
.jtoast {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  min-width: 280px; max-width: 420px; padding: var(--sp-3) var(--sp-4);
  background: var(--surface-toast); color: var(--on-surface-toast);
  border-radius: var(--r-md); box-shadow: var(--sh-lg); z-index: var(--z-toast);
  font-size: var(--fs-body-sm); line-height: 1.45;
}
.jtoast .ico { flex: none; display: inline-flex; margin-top: 1px; }
.jtoast .ico svg { width: var(--icon-sm); height: var(--icon-sm); }
.jtoast.success .ico { color: #6FD79B; }
.jtoast.error   .ico { color: #FF8A85; }
.jtoast.warning .ico { color: #F2C76B; }
.jtoast .body { flex: 1; }
.jtoast .title { font-weight: 600; color: var(--white); }
.jtoast .jtoast-action { margin-left: auto; background: transparent; border: 0; cursor: pointer;
  color: var(--orange-300); font: var(--w-semibold) var(--fs-body-sm)/1 var(--font-sans); padding: 2px 4px; flex: none; }
.jtoast .jtoast-x { background: transparent; border: 0; color: var(--fg-oninverse2); cursor: pointer;
  display: inline-flex; padding: 2px; flex: none; border-radius: var(--r-xs); }
.jtoast .jtoast-x:hover { color: var(--white); }
/* stacking region */
.jtoast-region { position: fixed; bottom: var(--sp-6); right: var(--sp-6);
  display: flex; flex-direction: column; gap: var(--sp-2); z-index: var(--z-toast); }

/* =========================================================================
   TOOLTIP  .jtooltip  (ink, pointer-following, supplementary only)
   ========================================================================= */
.jtooltip {
  display: inline-block; max-width: 240px; padding: 6px 10px;
  background: var(--surface-tooltip); color: var(--on-surface-tooltip);
  border-radius: var(--r-sm); font-size: var(--fs-caption); line-height: 1.4;
  box-shadow: var(--sh-md); z-index: var(--z-tooltip); position: relative;
}
.jtooltip::after {       /* caret */
  content: ""; position: absolute; width: 8px; height: 8px; background: var(--surface-tooltip);
  transform: rotate(45deg); left: 50%; margin-left: -4px; bottom: -4px;
}
.jtooltip.top::after    { bottom: -4px; top: auto; }
.jtooltip.bottom::after { top: -4px; bottom: auto; }
.jtooltip.right::after  { left: -4px; top: 50%; bottom: auto; margin: -4px 0 0 0; }   /* tooltip right of anchor */
.jtooltip.left::after   { right: -4px; left: auto; top: 50%; bottom: auto; margin: -4px 0 0 0; }  /* tooltip left of anchor */

/* =========================================================================
   BADGE / COUNT / DOT  .jbadge
   ========================================================================= */
.jbadge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--r-pill);
  background: var(--brand); color: var(--on-brand);
  font: var(--w-bold) 11px/1 var(--font-num); font-variant-numeric: tabular-nums;
}
.jbadge.neutral { background: var(--surface-sunken); color: var(--fg2); }
.jbadge.error   { background: var(--error); color: var(--on-error); }
.jbadge.dot { min-width: 8px; width: 8px; height: 8px; padding: 0; }
/* anchor a badge to a host (icon button etc.) */
.jbadge-anchor { position: relative; display: inline-flex; }
.jbadge-anchor > .jbadge { position: absolute; top: -6px; right: -6px; box-shadow: 0 0 0 2px var(--surface); }

/* =========================================================================
   EMPTY STATE  .jempty  (no data — guides next action, reduces dead-end)
   ========================================================================= */
.jempty { display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: var(--sp-3); padding: var(--sp-12) var(--sp-6); color: var(--fg2); }
.jempty .ico { display: grid; place-items: center; width: 56px; height: 56px;
  border-radius: var(--r-pill); background: var(--surface-sunken); color: var(--fg3); }
.jempty .ico svg { width: var(--icon-lg); height: var(--icon-lg); }
.jempty .title { font: var(--w-semibold) var(--fs-h4)/1.3 var(--font-sans); color: var(--fg1); }
.jempty .desc { font-size: var(--fs-body-sm); max-width: 360px; color: var(--fg2); text-wrap: pretty; }

/* =========================================================================
   CIRCULAR PROGRESS  .jring  (determinate ring; conic-gradient)
   --val: 0–100 (set inline: style="--val:62"). 인지: 시스템 상태 가시성(NN/g #1).
   ========================================================================= */
.jring { --val: 0; /* @kind other */ --sz: 48px; --thick: 5px; width: var(--sz); height: var(--sz); border-radius: var(--r-pill);
  display: inline-grid; place-items: center; flex: none;
  background: conic-gradient(var(--brand) calc(var(--val) * 1%), var(--surface-inset) 0); }
.jring::before { content: ""; position: absolute; width: calc(var(--sz) - var(--thick) * 2); height: calc(var(--sz) - var(--thick) * 2); border-radius: var(--r-pill); background: var(--surface); }
.jring { position: relative; }
.jring > .val { position: relative; font: var(--w-bold) 12px/1 var(--font-num); color: var(--fg1); font-variant-numeric: tabular-nums; }
.jring.sm { --sz: 32px; --thick: 4px; } .jring.lg { --sz: 64px; --thick: 6px; }
.jring.success { background: conic-gradient(var(--success) calc(var(--val)*1%), var(--surface-inset) 0); }

/* =========================================================================
   TOOLTIP FAMILY (Carbon 분화: tooltip / toggletip / definition)
   · tooltip(.jtooltip, 위 정의)  = hover, 비인터랙티브, 보조 정보
   · toggletip(.jtoggletip)       = click 토글, 인터랙티브 콘텐츠 가능, "i" 아이콘
   · definition(.jdefn)           = 용어 점선밑줄 → 짧은 정의
   근거: 필수 정보는 툴팁에 숨기지 않는다(carbon forms). "i"=추가정보, "?"≠.
   ========================================================================= */
.jtoggletip { position: relative; display: inline-flex; }
.jtoggletip > .trigger { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px;
  border: 0; background: transparent; color: var(--fg3); cursor: pointer; border-radius: var(--r-pill); padding: 0; }
.jtoggletip > .trigger:hover { color: var(--brand-stronger); }
.jtoggletip > .trigger:focus-visible { outline: none; box-shadow: var(--sh-focus); }
.jtoggletip > .trigger svg { width: 16px; height: 16px; }
.jtoggletip > .bubble {
  position: absolute; top: calc(100% + 8px); left: 0; z-index: var(--z-popover);
  min-width: 200px; max-width: 280px; padding: var(--sp-3) var(--sp-4);
  background: var(--surface-popover); color: var(--on-surface-popover);
  border: 1px solid var(--outline); border-radius: var(--r-md); box-shadow: var(--elevation-overlay);
  font-size: var(--fs-body-sm); line-height: 1.5;
}
.jtoggletip:not([data-open="true"]) > .bubble { display: none; }

.jdefn { border-bottom: 1px dashed var(--border-strong); cursor: help; color: inherit; }
.jdefn:hover { border-bottom-color: var(--brand); }

/* =========================================================================
   INLINE / ACTIONABLE NOTIFICATION  (Carbon notification family)
   · inline   = .jstatus (semantic-roles.css) — quiet, in-flow
   · actionable = .jnotify — inline + leading status bar + action + dismiss
   놓치면 안 되는 정보는 toast가 아닌 inline/actionable로(규칙 1.4).
   ========================================================================= */
.jnotify {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4); border-radius: var(--r-md);
  border: 1px solid var(--outline); border-left: 3px solid var(--info);
  background: var(--surface); color: var(--fg1); font-size: var(--fs-body-sm); line-height: 1.5;
}
.jnotify .ico { flex: none; display: inline-flex; margin-top: 1px; color: var(--info); }
.jnotify .ico svg { width: var(--icon-sm); height: var(--icon-sm); }
.jnotify .body { flex: 1; min-width: 0; }
.jnotify .title { font-weight: 600; }
.jnotify .jnotify-action { background: transparent; border: 0; cursor: pointer; color: var(--link); font: var(--w-semibold) var(--fs-body-sm)/1 var(--font-sans); padding: 2px 4px; flex: none; }
.jnotify .jnotify-x { background: transparent; border: 0; color: var(--fg3); cursor: pointer; display: inline-flex; padding: 2px; flex: none; border-radius: var(--r-xs); }
.jnotify .jnotify-x:hover { color: var(--fg1); background: var(--state-hover-surface); }
.jnotify.success { border-left-color: var(--success); } .jnotify.success .ico { color: var(--success); }
.jnotify.warning { border-left-color: var(--warning); } .jnotify.warning .ico { color: var(--on-warning-container); }
.jnotify.error   { border-left-color: var(--error); }   .jnotify.error .ico { color: var(--error); }
.jnotify.brand   { border-left-color: var(--brand); }   .jnotify.brand .ico { color: var(--brand); }

/* =========================================================================
   TAG / CHIP — deepen: sizes + operational(icon) + categorical colors
   (.jtag base in jnc-components.css)
   ========================================================================= */
.jtag.sm { height: 20px; padding: 0 8px; font-size: 11px; }
.jtag.lg { height: 28px; padding: 0 12px; font-size: 13px; }
.jtag .lead-ico { display: inline-flex; } .jtag .lead-ico svg { width: 12px; height: 12px; }
/* operational tag (whole tag clickable to filter/operate — single target) */
.jtag.operational { cursor: pointer; transition: background var(--transition-base), color var(--transition-base); }
.jtag.operational:hover { background: var(--brand-soft); color: var(--brand-stronger); }
.jtag.operational:active { background: var(--brand-soft); filter: brightness(0.96); }
/* categorical (non-directional grouping — uses data-viz palette, NOT market color) */
.jtag.cat-1 { background: color-mix(in srgb, var(--cat-1) 16%, white); color: var(--cat-1); }
.jtag.cat-4 { background: color-mix(in srgb, var(--cat-4) 18%, white); color: #4C5949; }
.jtag.cat-5 { background: color-mix(in srgb, var(--cat-5) 18%, white); color: #6B5270; }

/* =========================================================================
   TRUST-MEASUREMENT / AI(Artificial Intelligence·인공지능) PRESENCE
   방향성 고찰 O-01 — 신뢰 계측 계층. 추천·수치의 "왜·출처·확신도"를 화면에서
   증명한다(투자자문 도메인 핵심). 모두 기존 토글팁/태그/카드 위에 가산.
   · .jai-card    = AI 보조/생성 콘텐츠 카드(좌측 광원 + 라벨). 시장색·--error와 분리.
   · .jai-label   = AI 존재 표식(점+글로우 — 형태로 식별, 색만 아님; 규칙 1.7)
   · .jwhy        = reason-why[근거 공개]. <details>로 접고 펼 수 있음.
   · .jprovenance = 기준시점·출처·감사 추적 캡션(mono·tabular 숫자)
   · .jconfidence = 확신 등급(색 + 막대 개수 이중표시 — 비방향 중립; 규칙 4.2)
   벤치마킹(검증): Carbon for AI — AI 라벨 + explainability[설명가능성] 의무·빛으로
   식별 [carbondesignsystem.com/guidelines/carbon-for-ai] · "신뢰는 제품 그 자체"
   [fintech.global 2025/10] · 신뢰 방정식·설명가능성 [weforum.org 2025].
   접근성: AI 라벨에는 텍스트를 반드시 동반(아이콘·점 단독 금지), reason-why는
   네이티브 <details>/<summary>로 키보드·스크린리더 기본 지원(규칙: 네이티브 우선).
   ========================================================================= */
.jai-card {
  position: relative; overflow: hidden;
  padding: var(--sp-4); padding-inline-start: calc(var(--sp-4) + 3px);
  background: var(--ai-surface); border: 1px solid var(--outline);
  border-radius: var(--r-lg); color: var(--fg1);
}
.jai-card::before { content: ""; position: absolute; inset-block: 0; inset-inline-start: 0;
  width: 3px; background: var(--ai-edge); }

/* AI 존재 표식 — 점(+글로우)으로 형태 식별, 텍스트 라벨 반드시 동반 */
.jai-label { display: inline-flex; align-items: center; gap: 6px; height: 22px; padding: 0 9px;
  background: var(--ai-label-surface); border: 1px solid var(--ai-label-outline);
  border-radius: var(--r-pill); color: var(--ai-label-fg);
  font: var(--w-bold) 11px/1 var(--font-sans); letter-spacing: 0.03em; white-space: nowrap; }
.jai-label .g { width: 6px; height: 6px; border-radius: var(--r-pill); background: var(--ai-dot);
  box-shadow: 0 0 0 3px var(--ai-dot-glow); flex: none; }
.jai-label svg { width: 13px; height: 13px; }

/* reason-why[근거 공개] — 추천 근거를 분리·공개 */
.jwhy { margin-top: var(--sp-3); padding-top: var(--sp-3); border-top: 1px dashed var(--outline);
  font-size: var(--fs-caption); line-height: 1.55; color: var(--fg2); }
.jwhy > .k { font-weight: 700; color: var(--fg1); margin-inline-end: 4px; }
/* 접을 수 있는 변형: <details class="jwhy toggle"><summary>왜</summary>…</details> */
.jwhy.toggle { padding-top: 0; }
.jwhy.toggle > summary { list-style: none; cursor: pointer; padding-top: var(--sp-3);
  display: inline-flex; align-items: center; gap: 6px; color: var(--link); font-weight: 600; }
.jwhy.toggle > summary::-webkit-details-marker { display: none; }
.jwhy.toggle > summary::after { content: "›"; transition: transform var(--dur-fast) var(--ease-standard); }
.jwhy.toggle[open] > summary::after { transform: rotate(90deg); }
.jwhy.toggle > summary:focus-visible { outline: none; box-shadow: var(--focus-ring-shadow); border-radius: var(--r-xs); }
.jwhy.toggle > .why-body { margin-top: var(--sp-2); color: var(--fg2); }

/* 프로비넌스 캡션 — 기준시점·출처·감사 링크 */
.jprovenance { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-4); margin-top: var(--sp-2);
  font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 11px; line-height: 1.5;
  color: var(--provenance-fg); font-variant-numeric: tabular-nums; }
.jprovenance > span { display: inline-flex; align-items: center; gap: 4px; }
.jprovenance a { color: var(--link); text-decoration: none; }
.jprovenance a:hover { text-decoration: underline; }

/* 확신도 — 색 + 막대 개수(형태) 이중표시. 비방향 중립(시장색 아님). 막대 3개 기준. */
.jconfidence { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-caption);
  color: var(--fg2); font-weight: 600; }
.jconfidence .bars { display: inline-flex; gap: 2px; }
.jconfidence .bars i { width: 4px; height: 11px; border-radius: 1px; background: var(--confidence-track); display: block; }
.jconfidence.high .bars i:nth-child(-n+3) { background: var(--confidence-high); }
.jconfidence.med  .bars i:nth-child(-n+2) { background: var(--confidence-med); }
.jconfidence.low  .bars i:nth-child(-n+1) { background: var(--confidence-low); }
.jconfidence.high { color: var(--confidence-high); }

/* forced-colors[강제색·고대비] 안전망 — 새 신뢰 계측 컴포넌트의 경계·식별 복원.
   WHCM(Windows High Contrast Mode·윈도우 고대비 모드)에서 채움·그림자가 소실돼도
   광원 edge·점·막대가 시스템 색으로 유지되게 한다(규칙 1.7). 일반 렌더 무영향. */
@media (forced-colors: active) {
  .jai-card { border: 1px solid CanvasText; }
  .jai-card::before { background: Highlight; forced-color-adjust: none; }
  .jai-label { border: 1px solid CanvasText; }
  .jai-label .g { background: Highlight; box-shadow: none; }
  .jconfidence .bars i { background: GrayText; }
  .jconfidence.high .bars i:nth-child(-n+3),
  .jconfidence.med  .bars i:nth-child(-n+2),
  .jconfidence.low  .bars i:nth-child(-n+1) { background: CanvasText; }
}
