/* ============================================================
   FluxHub — Loading Components (fs-*)
   ------------------------------------------------------------
   범위: 대기 상태 공통 컴포넌트(인라인 스피너 / 블록 로더 /
   풀 로더 / 스켈레톤). 마케팅 계열(site.css 로드)과 대시보드
   계열(main.css 로드) 양쪽 페이지에서 모두 쓰인다 — 두 스타일
   시트 중 어느 쪽이 로드됐는지 이 파일은 모른다. 그래서 모든
   색·라운딩 값은 var(--fs-*, 리터럴폴백) 형태로 선언해 site.css
   토큰이 있으면 그것을, 없으면(main.css만 있는 페이지) 같은
   톤의 리터럴 값을 쓴다. main.css/site.css 어느 파일도 이 시트는
   건드리지 않는다(둘 다 불가침 또는 최소수정 대상).

   컴포넌트: .fs-spin(인라인) / .fs-blockloader(패널) /
   .fs-fullloader(전체 오버레이, 예비) / .fs-skeleton(자리표시)
   ============================================================ */

.fs-loading-scope,
.fs-spin,
.fs-blockloader,
.fs-fullloader,
.fs-skeleton {
    --fsl-accent:      var(--fs-accent, #047857);
    --fsl-accent-ink:  var(--fs-accent-ink, #0c5c40);
    --fsl-ink:         var(--fs-ink, #000000);
    --fsl-ink-2:       var(--fs-ink-2, #5d5f6d);
    --fsl-ink-3:       var(--fs-ink-3, #727582);
    --fsl-bg-soft:     var(--fs-bg-soft, #f5f5f5);
    --fsl-bg-sunken:   var(--fs-bg-sunken, #f3f6fb);
    --fsl-line:        var(--fs-line, #ededf0);
    --fsl-radius:      var(--fs-r, 20px);
    --fsl-radius-sm:   var(--fs-r-sm, 12px);
    --fsl-radius-full: var(--fs-r-full, 999px);
    /* 위험/경고 — main.css 계열은 --flux-danger/--flux-warning 이 이미 있다.
       없는 페이지(site.css 계열)는 page-demo.php 의 에러 톤과 같은 값으로 맞춘다. */
    --fsl-danger:      var(--flux-danger, #a52c1d);
    --fsl-danger-bg:   var(--flux-danger-bg, #fef3f2);
    --fsl-danger-line: #fbd5d0;
}

/* ======================== 1) 인라인 스피너 ========================
   버튼 안, 텍스트 옆에 들어간다. 버튼은 고정 height 를 쓰므로
   (fs-btn / flux-btn 둘 다) 스피너가 추가돼도 버튼 높이는 흔들리지
   않는다 — 너비만 살짝 늘어난다. */
.fs-spin {
    display: inline-block;
    flex: none;
    width: var(--fs-spin-size, 16px);
    height: var(--fs-spin-size, 16px);
    border-radius: 50%;
    border: 2px solid currentColor;
    border-top-color: transparent;
    opacity: .85;
    animation: fs-spin-rotate .7s linear infinite;
}
.fs-spin--onDark { color: #fff; opacity: .9; }
.fs-spin--lg { --fs-spin-size: 28px; border-width: 3px; }

@keyframes fs-spin-rotate {
    to { transform: rotate(360deg); }
}

/* 버튼에 붙이는 로딩 상태 — 마크업/텍스트는 그대로 두고 스피너만
   앞뒤로 끼워 넣는 용도. 버튼을 직접 비활성화하는 것은 JS 쪽 책임. */
.fs-btn[aria-busy="true"],
.is-loading[aria-busy="true"] {
    cursor: progress;
}

/* ======================== 2) 블록 로더 ========================
   카드/패널 내부가 채워지길 기다릴 때. 영역 중앙 정렬. */
.fs-blockloader {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 28px 16px;
    text-align: center;
    color: var(--fsl-ink-2);
}
.fs-blockloader__spin { color: var(--fsl-accent); }
.fs-blockloader__text {
    font-size: 14.5px;
    line-height: 1.6;
    color: var(--fsl-ink-2);
}
.fs-blockloader__elapsed {
    font-size: 13px;
    color: var(--fsl-ink-3, #9298a6);
}
/* 실패/지연 톤 — 색은 새로 만들지 않고 danger 폴백 체인을 그대로 쓴다 */
.fs-blockloader--stalled .fs-blockloader__text { color: var(--fsl-danger); }

/* 카드형 — 상품 상세/주문완료처럼 다른 콘텐츠 사이에 박스로 얹을 때 */
.fs-blockloader--card {
    border: 1px solid var(--fsl-line);
    border-radius: var(--fsl-radius);
    background: var(--fsl-bg-sunken);
}
.fs-blockloader__icon {
    font-size: 26px;
    line-height: 1;
}
.fs-blockloader__cta {
    margin-top: 4px;
}

/* ======================== 3) 풀 로더 (예비) ========================
   수십 초~수 분 걸리는 작업용. 기본은 패널 내부에 꽉 차는 형태로 쓰고
   (전체 화면을 덮어야 하면 --overlay 수정자로 fixed 오버레이가 된다).
   진행률 막대는 넣지 않는다 — 실제 값이 없으면 채우지 않는다. */
.fs-fullloader {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16px;
    padding: 48px 20px;
    text-align: center;
    border-radius: var(--fsl-radius);
    background: var(--fsl-bg-sunken);
}
.fs-fullloader--overlay {
    position: fixed;
    inset: 0;
    z-index: 500;
    background: rgba(255, 255, 255, .92);
    border-radius: 0;
}
.fs-fullloader__title {
    font-size: 17px;
    font-weight: 700;
    color: var(--fsl-ink);
}
.fs-fullloader__desc {
    font-size: 14.5px;
    line-height: 1.6;
    color: var(--fsl-ink-2);
    max-width: 360px;
}
.fs-fullloader__elapsed {
    font-size: 13px;
    color: var(--fsl-ink-3, #9298a6);
    font-variant-numeric: tabular-nums;
}
.fs-fullloader--stalled {
    background: var(--fsl-danger-bg);
}
.fs-fullloader--stalled .fs-fullloader__title { color: var(--fsl-danger); }

/* ======================== 4) 스켈레톤 ========================
   목록/카드가 채워지기 전 자리를 잡아 레이아웃 점프를 막는다. */
.fs-skeleton {
    position: relative;
    display: block;
    overflow: hidden;
    background: var(--fsl-bg-soft);
    border-radius: var(--fsl-radius-sm);
}
.fs-skeleton::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .55), transparent);
    transform: translateX(-100%);
    animation: fs-skeleton-shimmer 1.4s ease-in-out infinite;
}
.fs-skeleton--text { height: 14px; margin: 6px 0; }
.fs-skeleton--title { height: 22px; margin: 8px 0; width: 60%; }
.fs-skeleton--avatar { width: 44px; height: 44px; border-radius: 50%; }
.fs-skeleton--block { height: 120px; }

@keyframes fs-skeleton-shimmer {
    100% { transform: translateX(100%); }
}

/* ======================== 접근성: 모션 축소 ======================== */
@media (prefers-reduced-motion: reduce) {
    .fs-spin { animation: none; border-top-color: currentColor; opacity: .45; }
    .fs-skeleton::after { animation: none; display: none; }
}

/* ======================== 360px 확인 ========================
   블록/풀 로더는 padding 만으로 구성돼 있어 고정폭 요소가 없다.
   좁은 화면에서 패딩만 살짝 줄인다. */
@media (max-width: 380px) {
    .fs-blockloader { padding: 20px 12px; }
    .fs-fullloader { padding: 32px 14px; }
}
