/* ═══════════════════════════════════════════════════════════════════════
   Ryan Motion Language — v1.4.3 (2026-09-19)
   tokens.css 뒤에 로드한다. 값은 tokens.css, 여기는 «움직임의 규칙».
   ───────────────────────────────────────────────────────────────────────
   원칙 넷
     1. 스프링 없다. 되튐(overshoot)도 없다 — 라이언 판정 «촌스럽다».
        진입은 ease-out, 퇴장은 ease-in, 자리 이동은 ease-in-out.
     2. 280ms 를 넘기지 않는다. 넘으면 «느리다» 가 아니라 «멈췄다» 로 읽힌다.
     3. 들어올리지 않는다(--hover-lift: 0). 호버는 선·색으로 말한다.
     4. 한 번에 두 속성까지. opacity + transform 이 기본이고 layout(width·height)은
        애니메이션하지 않는다(transform 으로 대신한다).

   이름 규칙 — 유틸은 `.u-*`. Studio 가 쓰던 이름을 그대로 승격했다.
     .u-press  누름      .u-enter  등장     .u-exit  퇴장
     .u-toggle 상태전환  .u-pop    팝오버   .u-sheet 바텀시트
     .u-backdrop 가림막  .u-modal  모달     .u-shimmer 스켈레톤  .u-spin 스피너

   햅틱은 CSS 가 못 한다 — `motion.js` 의 `haptic('tap')` 과 짝으로 쓴다.
   콘텐츠(영상)로 옮길 때는 `motion.json` 의 frames30/frames60 을 쓴다.
   ═══════════════════════════════════════════════════════════════════════ */

:root {
    /* 다섯 단계 — 이보다 잘게 쪼개지 않는다 */
    --dur-instant: 60ms;    /* 누름 피드백 */
    --dur-fast:    120ms;   /* 호버·색·보더·토글 */
    --dur-enter:   200ms;   /* 등장·팝오버·토스트 */
    --dur-modal:   240ms;   /* 모달·바텀시트 */
    --dur-screen:  280ms;   /* 화면 전환 */
    --dur-spin:    800ms;   /* 무한 회전 */
    --dur-shimmer: 1500ms;  /* 스켈레톤 */

    /* 이징 셋 + linear 예외(무한 회전·드래그 추종만) */
    --ease-entrance: var(--ease-out);      /* 진입·열림 */
    --ease-leave:    var(--ease-in);       /* 퇴장·닫힘 */
    --ease-move:     var(--ease-in-out);   /* 자리 이동·정렬 */
    --ease-standard: ease;                 /* 색·보더 */

    --enter-rise: 6px;      /* 등장 시 올라오는 거리 — 이보다 크면 «튄다» */
    --sheet-rise: 100%;

    /* 누름의 두 갈래. --press-scale(0.98)은 tokens.css 가 갖고 있다.
       --press-dim 은 Studio 실측에서 온 값이다 — 누를 수 있는 것의 79%가 44pt 미만이라
       3% 줄여도 1px 이 안 움직이고, 크기 축소는 translate 로 배치한 것을 깨뜨린다.
       그래서 «틀이 분명한 부품»(.btn·.chip·.tab·.seg)만 줄이고, 나머지는 밝기로 답한다. */
    --press-dim: .55;
}

/* 웹 티 제거 — 탭 하이라이트 깜빡임과 크롬 글자 선택 */
* { -webkit-tap-highlight-color: transparent; }
button, a, label, select, [role="button"],
.tab, .seg, .chip, .btn { -webkit-user-select: none; user-select: none; }

/* ── 유틸 ──────────────────────────────────────────────────────────────── */
/* 누를 수 있게 생긴 것의 전환은 여기서 한 번에 정한다.
   transition 은 덮어쓰기다 — 컴포넌트마다 다시 적으면 여기 값이 그걸 지우거나
   그게 여기를 지운다. 그래서 색·보더·투명도까지 이 한 줄에 모아 둔다. */
.u-press,
button, .btn, .chip, .tab, .seg,
[role="button"], input[type="submit"], a[href], label[for], summary {
    transition: transform    var(--dur-instant) var(--ease-entrance),
                background   var(--dur-fast)    var(--ease-standard),
                border-color var(--dur-fast)    var(--ease-standard),
                color        var(--dur-fast)    var(--ease-standard),
                opacity      var(--dur-fast)    var(--ease-standard),
                box-shadow   var(--dur-fast)    var(--ease-standard);
}
.u-toggle   { transition: background var(--dur-fast) var(--ease-standard),
                          color var(--dur-fast) var(--ease-standard),
                          border-color var(--dur-fast) var(--ease-standard); }
.u-enter    { animation: u-rise var(--dur-enter) var(--ease-entrance) both; }
.u-exit     { animation: u-fall var(--dur-fast) var(--ease-leave) forwards; }
.u-pop      { animation: u-pop var(--dur-enter) var(--ease-entrance) both; }
.u-modal    { animation: u-pop var(--dur-modal) var(--ease-entrance) both; }
.u-backdrop { animation: u-fade var(--dur-modal) var(--ease-standard) both; }
.u-sheet    { animation: u-sheet var(--dur-modal) var(--ease-entrance) both; }
.u-toast    { animation: u-toast var(--dur-enter) var(--ease-entrance) both; }
.u-spin     { animation: u-spin var(--dur-spin) linear infinite; }
.u-shimmer  { animation: u-shimmer var(--dur-shimmer) ease-in-out infinite;
              background: linear-gradient(90deg, var(--bg-elevated) 25%,
                          var(--bg-elevated-2) 50%, var(--bg-elevated) 75%);
              background-size: 200% 100%; }

/* ── 누르면 답한다 ─────────────────────────────────────────────────────
   클래스를 안 붙여도 «누를 수 있게 생긴 것» 은 전부 답해야 한다. 방식은 둘로 나눈다.

     틀이 분명한 부품  .btn .chip .tab .seg .u-press  →  크기(--press-scale)
     그 밖의 모든 것   button [role] a[href] label summary → 밝기(--press-dim)

   왜 나누나: 크기 축소는 translate 로 배치한 요소를 밀어 보이게 하고, 작은 타깃에서는
   눈에 안 띈다(Studio 실측 — 누를 수 있는 것 234개 중 134개가 무반응이었다).
   밝기는 배치를 건드리지 않고 작은 것에서도 확실히 보인다. 겹치지 않게 :not 으로 가른다.
   비활성은 답하지 않는다 — 답이 오면 «먹혔다» 로 읽힌다. */
:is(.u-press, .btn, .chip, .tab, .seg):not(:disabled, [aria-disabled="true"]):active {
    opacity: 1;
}
@media (prefers-reduced-motion: no-preference) {
    :is(.u-press, .btn, .chip, .tab, .seg):not(:disabled, [aria-disabled="true"]):active {
        transform: scale(var(--press-scale));
    }
}
:is(button, [role="button"], input[type="submit"], a[href], label[for],
    summary):not(.btn, .chip, .tab, .seg, .u-press, :disabled, [aria-disabled="true"]):active {
    opacity: var(--press-dim);
}

/* 마우스가 없는 기기에서는 «얹음» 색이 손가락을 뗀 뒤에도 눌어붙는다 — 즉시 되돌린다. */
@media (hover: none) {
    button:hover, .btn:hover, .chip:hover, .tab:hover, .seg:hover,
    [role="button"]:hover, a[href]:hover { transition-duration: 0s; }
}

/* ── keyframes — 표면마다 다시 적지 않는다 ───────────────────────────── */
@keyframes u-rise   { from { opacity: 0; transform: translateY(var(--enter-rise)); } to { opacity: 1; transform: none; } }
@keyframes u-fall   { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(var(--enter-rise)); } }
@keyframes u-pop    { from { opacity: 0; transform: translateY(calc(-1 * var(--enter-rise))) scale(.97); } to { opacity: 1; transform: none; } }
@keyframes u-fade   { from { opacity: 0; } to { opacity: 1; } }
@keyframes u-sheet  { from { transform: translateY(var(--sheet-rise)); } to { transform: translateY(0); } }
@keyframes u-toast  { from { opacity: 0; transform: translate(-50%, var(--enter-rise)); } to { opacity: 1; transform: translate(-50%, 0); } }
@keyframes u-spin   { to { transform: rotate(360deg); } }
@keyframes u-shimmer{ 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } }

/* 화면 전환 — 네이티브. 미지원 브라우저는 자동으로 즉시 전환된다. */
@view-transition { navigation: auto; }

/* ── 모션을 줄이겠다고 한 사람에게는 전부 끈다 ─────────────────────── */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
    .u-shimmer { background: var(--bg-elevated); }
}
