/* TIL File Manager 패널 재현 — 원본은 c:\Users\facec\Desktop\sfx-trim\TIL-File-Manager\client\
   (index.html·css\style.css, v1.7.5)다. Railway 미배포 상태라 도메인이 아니라 이 로컬
   소스에서 마크업·토큰을 직접 옮겼다(2026-08-28 사용자 지시 — 이전엔 오래된 중간 사본을
   썼는데 실제 프로그램과 벌어져 있었다). 배치는 이 무대에 맞춰 다시 짰다 — 앞뒤 교차 클릭은
   옮기지 않는다(스크롤이 장면을 넘기는 무대라 클릭 대상이 아니다). 부유 애니메이션 이름도
   첫 화면 카드와 겹치지 않게 갈라 놓았다. */

/* ---- 무대 배치 — 패널은 그리드 첫 칸에 서고, 비트마다 하나씩 들어온다.
   등장·퇴장은 첫 화면 카드와 같은 부품(.win-slot)이 맡으므로 여기서는 자리만 정한다.
   원본(sfx-trim/static/css/plugin.css .pg-stage)의 push 방식 그대로 옮긴다 — 그리드를
   무대 오른쪽 밖으로, 홈을 왼쪽 밖으로 밀어 겹치는 폭을 만든다(2026-09-10 사용자 지시 —
   "완전히 페이지 그대로"). ---- */
.til-stage {
  position: relative;
  grid-column: 1;
  height: min(calc(62 * var(--vh)), 520px);
  --push-r: 4%;
  /* 원본(.pg-stage)은 페이지 여백 안에서 밀지만, 이 무대는 왼쪽이 뷰포트 진짜 가장자리까지
     흘러나가 있어(.scene-shots의 음수 마진) 원본 값(14%)대로 밀면 홈 패널 왼쪽이 실제
     화면 밖으로 잘려 스크롤로도 못 본다(실측: 1432px에서 x=-45). 원본이 좁은 화면용으로
     이미 갖고 있는 완화값(9%, plugin.css @media 1000px 이하)을 기본값으로 그대로 쓴다. */
  --push-l: 9%;
}

.mock-slot { position: absolute; cursor: pointer; }
.mock-slot-home { width: 70%; max-width: 404px; bottom: 0; left: calc(-1 * var(--push-l)); --arc-dir: 1; }
.mock-slot-grid { width: 90%; max-width: 540px; top: 0; right: calc(-1 * var(--push-r)); --arc-dir: -1; }

/* 앞뒤는 windows.js가 DOM 첫 슬롯(홈)에 붙이는 is-front를 그대로 따른다 — 원본의 초기
   상태(홈이 앞)와 이미 같다. 여기서는 뒤 패널을 원본과 같이 살짝 작게 줄이기만 한다
   (밝기는 windows.css의 --rest-bright를 그대로 물려받는다). 클릭으로 앞뒤를 바꾸는 동작은
   js/til-flip.js가 이 두 클래스와 아래 flip-to-front/back 애니메이션을 오간다. */
.til-stage .mock-slot { transform: translateY(var(--ey)) scale(var(--rest-scale, 1)); }
.til-stage .mock-slot.is-front { --rest-scale: 1; cursor: default; }
.til-stage .mock-slot.is-back { --rest-scale: .945; }
.til-stage .mock-slot.is-back:hover { --rest-bright: .88; }

/* 교차 모션 — 원본 키프레임을 그대로 옮긴다. 진폭은 px로 고정(%는 큰 패널이 더 크게
   튄다), 밝기는 50%에서 갈라 둬 z가 바뀌는 순간이 관통처럼 보이지 않게 한다. */
.til-stage .mock-slot.flip-to-front { animation: til-slot-to-front 700ms linear both; }
.til-stage .mock-slot.flip-to-back { animation: til-slot-to-back 700ms linear both; }

@keyframes til-slot-to-front {
  0%   { z-index: 1; transform: translate3d(0, 0, 0) scale(0.9450) rotateZ(0deg); filter: brightness(0.740); }
  10%  { z-index: 1; transform: translate3d(0, calc(var(--arc-dir) * 29.4px), 43px)  scale(0.9465) rotateZ(calc(var(--arc-dir) * -0.62deg)); filter: brightness(0.800); }
  20%  { z-index: 1; transform: translate3d(0, calc(var(--arc-dir) * 55.9px), 82px)  scale(0.9507) rotateZ(calc(var(--arc-dir) * -1.18deg)); filter: brightness(0.860); }
  30%  { z-index: 1; transform: translate3d(0, calc(var(--arc-dir) * 76.9px), 113px) scale(0.9569) rotateZ(calc(var(--arc-dir) * -1.62deg)); filter: brightness(0.910); }
  40%  { z-index: 1; transform: translate3d(0, calc(var(--arc-dir) * 90.3px), 133px) scale(0.9644) rotateZ(calc(var(--arc-dir) * -1.90deg)); filter: brightness(0.950); }
  50%  { z-index: 4; transform: translate3d(0, calc(var(--arc-dir) * 95px), 140px)   scale(0.9725) rotateZ(calc(var(--arc-dir) * -2.00deg)); filter: brightness(0.980); }
  60%  { z-index: 4; transform: translate3d(0, calc(var(--arc-dir) * 90.3px), 133px) scale(0.9806) rotateZ(calc(var(--arc-dir) * -1.90deg)); filter: brightness(0.992); }
  70%  { z-index: 4; transform: translate3d(0, calc(var(--arc-dir) * 76.9px), 113px) scale(0.9881) rotateZ(calc(var(--arc-dir) * -1.62deg)); filter: brightness(0.998); }
  80%  { z-index: 4; transform: translate3d(0, calc(var(--arc-dir) * 55.9px), 82px)  scale(0.9943) rotateZ(calc(var(--arc-dir) * -1.18deg)); filter: brightness(1); }
  90%  { z-index: 4; transform: translate3d(0, calc(var(--arc-dir) * 29.4px), 43px)  scale(0.9985) rotateZ(calc(var(--arc-dir) * -0.62deg)); filter: brightness(1); }
  100% { z-index: 4; transform: translate3d(0, 0, 0) scale(1.0000) rotateZ(0deg); filter: brightness(1); }
}

@keyframes til-slot-to-back {
  0%   { z-index: 3; transform: translate3d(0, 0, 0) scale(1.0000) rotateZ(0deg); filter: brightness(1); }
  10%  { z-index: 3; transform: translate3d(0, calc(var(--arc-dir) * 24.7px), -37px)  scale(0.9985) rotateZ(calc(var(--arc-dir) * 0.49deg)); filter: brightness(0.950); }
  20%  { z-index: 3; transform: translate3d(0, calc(var(--arc-dir) * 47.0px), -71px)  scale(0.9943) rotateZ(calc(var(--arc-dir) * 0.94deg)); filter: brightness(0.900); }
  30%  { z-index: 3; transform: translate3d(0, calc(var(--arc-dir) * 64.7px), -97px)  scale(0.9881) rotateZ(calc(var(--arc-dir) * 1.29deg)); filter: brightness(0.860); }
  40%  { z-index: 3; transform: translate3d(0, calc(var(--arc-dir) * 76.1px), -114px) scale(0.9806) rotateZ(calc(var(--arc-dir) * 1.52deg)); filter: brightness(0.820); }
  50%  { z-index: 1; transform: translate3d(0, calc(var(--arc-dir) * 80px), -120px)   scale(0.9725) rotateZ(calc(var(--arc-dir) * 1.60deg)); filter: brightness(0.790); }
  60%  { z-index: 1; transform: translate3d(0, calc(var(--arc-dir) * 76.1px), -114px) scale(0.9644) rotateZ(calc(var(--arc-dir) * 1.52deg)); filter: brightness(0.770); }
  70%  { z-index: 1; transform: translate3d(0, calc(var(--arc-dir) * 64.7px), -97px)  scale(0.9569) rotateZ(calc(var(--arc-dir) * 1.29deg)); filter: brightness(0.755); }
  80%  { z-index: 1; transform: translate3d(0, calc(var(--arc-dir) * 47.0px), -71px)  scale(0.9507) rotateZ(calc(var(--arc-dir) * 0.94deg)); filter: brightness(0.747); }
  90%  { z-index: 1; transform: translate3d(0, calc(var(--arc-dir) * 24.7px), -37px)  scale(0.9465) rotateZ(calc(var(--arc-dir) * 0.49deg)); filter: brightness(0.742); }
  100% { z-index: 1; transform: translate3d(0, 0, 0) scale(0.9450) rotateZ(0deg); filter: brightness(0.740); }
}

@media (prefers-reduced-motion: reduce) {
  .til-stage .mock-slot.flip-to-front,
  .til-stage .mock-slot.flip-to-back { animation: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  .tfm-float-a, .tfm-float-b, .tfm-eq i { animation: none !important; }
}

.tfm {
  --tfm-bg: #1e1e1e;
  --tfm-bg-elevated: #262626;
  --tfm-bg-card: #272727;
  --tfm-bg-card-hover: #323232;
  --tfm-bg-card-playing: #3a2f57;
  --tfm-border: rgba(255, 255, 255, 0.08);
  --tfm-border-strong: rgba(255, 255, 255, 0.16);
  --tfm-text: #e9e9ea;
  --tfm-text-muted: #9a9a9d;
  /* 원본 프로그램 값(#6c6c6f)은 이 배경에서 2.89:1이라 웹 기준(4.5:1)에 못 미친다.
     목업의 인상을 유지하는 선에서 가장 어두운 값으로 올렸다 — #262626 위 5.05:1. */
  --tfm-text-faint: #949498;
  --tfm-accent: #8b7cf6;
  --tfm-accent-strong: #a596ff;
  --tfm-accent-soft: rgba(139, 124, 246, 0.16);
  --tfm-favorite: #f5c542;
  --tfm-radius-thumb: 5px;
  --tfm-radius-card: 10px;
  --tfm-control-h: 25px;

  position: relative;
  width: 100%;
  display: flex;
  flex-direction: column;
  border-radius: var(--win-radius);
  background: var(--tfm-bg);
  border: 1px solid var(--tfm-border-strong);
  box-shadow: var(--win-shadow);
  overflow: hidden;
  color: var(--tfm-text);
  font-family: "Segoe UI", -apple-system, sans-serif;
  /* 9.5px는 한글이 뭉개져 흐릿하게 보였다 — 실제 패널과 같은 비율감을 유지하면서
     읽히는 하한선까지 올린다. will-change는 두지 않는다(레이어를 1배로 고정 래스터해
     확대·회전 시 글자가 뭉갠다 — 부유 애니메이션 정도는 없어도 충분히 매끄럽다). */
  font-size: 11px;
  line-height: 1.4;
  /* 포인터 시차용 — JS가 --px/--py를 채운다 */
  --px: 0px;
  --py: 0px;
}

/* 상시 부유 모션 — 회전 기울기(-1.8deg/1.4deg)는 패널의 기본 스큐이고, 애니메이션은
   그 값을 중심으로 위치·각도를 오간다. .mock-slot(바깥, 앞뒤 교차 담당)과 별개 레이어인
   .tfm(안쪽)에서만 돈다 — 그래서 뒤로 넘어간 뒤에도 자기 궤도를 멈추지 않고 계속 돈다.
   주기·경로·시작 지연을 서로 다르게 둬서 두 패널이 한 몸처럼 안 보이게 한다. */
/* both(fill-mode)이 반드시 필요하다 — 시작 지연이 걸린 쪽은 fill-mode가 없으면 지연 동안
   애니메이션이 아예 적용되지 않아 기본 스큐(0deg)로 서 있다가, 지연이 끝나는 순간 0% 키프레임의
   기울기로 한 프레임에 튄다(실측: float-b가 0deg로 등장한 뒤 898ms에 1.4deg로 점프 —
   등장 모션이 자리를 잡는 타이밍과 겹쳐 "각도가 확 변한다"로 보였다).
   backwards로 0% 값을 미리 물려두면 두 패널 모두 처음부터 제 기울기로 등장하고, 지연은
   위치·각도의 위상차만 벌린다. */
.tfm-float-a { animation: tfm-float-a 12s ease-in-out infinite both; }
.tfm-float-b { animation: tfm-float-b 15.5s ease-in-out infinite 0.7s both; }

@keyframes tfm-float-a {
  0%   { transform: translate3d(0, 0, 0) rotate(-1.8deg); }
  22%  { transform: translate3d(-4px, -10px, 0) rotate(-2.7deg); }
  48%  { transform: translate3d(3px, -15px, 0) rotate(-1.0deg); }
  74%  { transform: translate3d(5px, -6px, 0) rotate(-2.3deg); }
  100% { transform: translate3d(0, 0, 0) rotate(-1.8deg); }
}

@keyframes tfm-float-b {
  0%   { transform: translate3d(0, 0, 0) rotate(1.4deg); }
  30%  { transform: translate3d(6px, 9px, 0) rotate(2.4deg); }
  58%  { transform: translate3d(-4px, 13px, 0) rotate(0.5deg); }
  83%  { transform: translate3d(-6px, 4px, 0) rotate(2.0deg); }
  100% { transform: translate3d(0, 0, 0) rotate(1.4deg); }
}

/* ---- 타이틀바 ----
   CEP 클라이언트 자체(TIL-File-Manager/client)에는 없지만, 이 패널을 소개하는 실제
   페이지(sfx-trim/static/css/plugin.css)는 "떠 있는 창"으로 보이도록 점 세 개짜리
   타이틀바를 얹는다 — 그 페이지를 그대로 옮기는 것이 이번 요청이라 되살렸다. */
.tfm-titlebar {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 6px 9px;
  background: #171717;
  border-bottom: 1px solid var(--tfm-border);
  flex-shrink: 0;
}
.tfm-titlebar span {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #3a3a3d;
}

/* ---- 헤더 ---- */
.tfm-header {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 8px;
  padding: 7px 9px;
  background: var(--tfm-bg-elevated);
  border-bottom: 1px solid var(--tfm-border);
  flex-shrink: 0;
}

.tfm-btn-icon {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: var(--tfm-control-h);
  padding: 0 8px;
  background: transparent;
  border: 1px solid var(--tfm-border-strong);
  border-radius: 5px;
  color: var(--tfm-text);
  font-family: inherit;
  font-size: 11px;
  cursor: pointer;
  white-space: nowrap;
  transition-property: background-color, border-color, transform;
  transition-duration: 120ms;
  transition-timing-function: ease-out;
}

.tfm-btn-icon:hover {
  background: rgba(255, 255, 255, 0.06);
  border-color: var(--tfm-accent);
}
.tfm-btn-icon:active { transform: scale(0.96); }

/* 원본 .btn-back — 경로가 길어져도 뒤로 버튼은 줄어들지 않는다 */
.tfm-back-btn { flex-shrink: 0; }

.tfm-breadcrumb {
  display: flex;
  align-items: center;
  gap: 3px;
  min-width: 0;
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
}

.tfm-crumb {
  color: var(--tfm-text-muted);
  padding: 2px 4px;
  border-radius: 3px;
  cursor: pointer;
  transition-property: color, background-color;
  transition-duration: 100ms;
}
.tfm-crumb:hover { color: var(--tfm-accent-strong); background: rgba(255, 255, 255, 0.05); }
.tfm-crumb.current { color: var(--tfm-text); cursor: default; }
.tfm-crumb.current:hover { background: none; color: var(--tfm-text); }
.tfm-crumb-sep { color: var(--tfm-text-faint); flex-shrink: 0; }

/* ---- 툴바 ----
   원본(plugin.css .tfm-toolbar)은 두 줄로 못 박아 둔다 — 폭에 따라 접히게 두면 넓은
   패널은 검색이 첫 줄 끝에, 좁은 패널은 둘째 줄 앞에 놓여 두 패널이 서로 다른
   프로그램처럼 보인다. 줄 구성을 마크업(.tfm-tool-row)으로 고정해 어느 폭에서든
   같은 자리에 같은 항목이 오게 한다. */
.tfm-toolbar {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  row-gap: 6px;
  padding: 7px 9px;
  background: var(--tfm-bg-elevated);
  border-bottom: 1px solid var(--tfm-border);
  flex-shrink: 0;
}

.tfm-tool-row {
  display: flex;
  align-items: center;
  column-gap: 7px;
  min-width: 0;
}

/* 오른쪽 묶음(즐겨찾기 · 언어 · 로그인) — 줄바꿈이 일어나도 마지막 버튼 하나만 다음 줄
   왼쪽에 떨어지지 않고 셋이 함께 접혀 오른쪽에 붙는다. */
.tfm-tool-end {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-left: auto;
}

.tfm-tool-group {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  gap: 5px;
  color: var(--tfm-text-muted);
}

.tfm-tool-label { font-size: 10.5px; white-space: nowrap; }

.tfm-select {
  position: relative;
  height: var(--tfm-control-h);
  display: inline-flex;
  align-items: center;
  background: var(--tfm-bg);
  color: var(--tfm-text);
  border: 1px solid var(--tfm-border-strong);
  border-radius: 5px;
  padding: 0 17px 0 8px;
  white-space: nowrap;
  cursor: pointer;
  transition: border-color 120ms ease-out;
}
.tfm-select:hover { border-color: var(--tfm-accent); }
.tfm-select::after {
  content: "";
  position: absolute;
  right: 5px; top: 50%;
  width: 4px; height: 4px;
  border-right: 1.2px solid var(--tfm-text-muted);
  border-bottom: 1.2px solid var(--tfm-text-muted);
  transform: translateY(-70%) rotate(45deg);
}

/* 슬라이더 — 원본의 --fill 그라디언트 트랙 방식 그대로 */
.tfm-slider {
  -webkit-appearance: none;
  appearance: none;
  width: 54px;
  height: var(--tfm-control-h);
  background: transparent;
  cursor: pointer;
}
.tfm-slider::-webkit-slider-runnable-track {
  height: 3px;
  border-radius: 2px;
  background: linear-gradient(to right,
    var(--tfm-accent) 0%, var(--tfm-accent) var(--fill, 50%),
    var(--tfm-border-strong) var(--fill, 50%), var(--tfm-border-strong) 100%);
}
.tfm-slider::-moz-range-track {
  height: 3px;
  border-radius: 2px;
  background: linear-gradient(to right,
    var(--tfm-accent) 0%, var(--tfm-accent) var(--fill, 50%),
    var(--tfm-border-strong) var(--fill, 50%), var(--tfm-border-strong) 100%);
}
.tfm-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 11px; height: 11px;
  margin-top: -4px;
  border-radius: 50%;
  background: var(--tfm-accent-strong);
  border: 1.5px solid var(--tfm-bg-elevated);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
  transition: transform 100ms ease-out;
}
.tfm-slider::-moz-range-thumb {
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--tfm-accent-strong);
  border: 1.5px solid var(--tfm-bg-elevated);
}
.tfm-slider:active::-webkit-slider-thumb { transform: scale(1.15); }

/* ---- 검색 (원본 .search-group/.search-input 이식) ----
   첫째 줄 가장 우측 끝에 고정한다 — margin-left:auto로 둘째 줄의 .tfm-tool-end와 같은
   방식으로 밀어 붙인다. 기본 폭은 118px, 좁은 패널에서만 84px까지 줄어든다. */
.tfm-search-group {
  position: relative;
  flex: 0 1 118px;
  min-width: 84px;
  margin-left: auto;
}
.tfm-search-icon { position: absolute; left: 7px; top: 50%; transform: translateY(-50%); color: var(--tfm-text-faint); pointer-events: none; }
.tfm-search-input {
  width: 100%;
  height: var(--tfm-control-h);
  background: var(--tfm-bg);
  color: var(--tfm-text);
  border: 1px solid var(--tfm-border-strong);
  border-radius: 5px;
  padding: 0 21px 0 23px;
  font-family: inherit;
  font-size: 10.5px;
  transition: border-color 120ms ease-out, box-shadow 120ms ease-out;
}
.tfm-search-input:hover { border-color: var(--tfm-accent); }
.tfm-search-input:focus {
  outline: none;
  border-color: var(--tfm-accent);
  box-shadow: 0 0 0 2px var(--tfm-accent-soft);
}
.tfm-search-input::placeholder { color: var(--tfm-text-faint); }

.tfm-search-clear {
  position: absolute;
  right: 5px;
  top: 50%;
  transform: translateY(-50%);
  width: 16px; height: 16px;
  padding: 0;
  display: none;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  border-radius: 50%;
  color: var(--tfm-text-faint);
  cursor: pointer;
  transition-property: background-color, color;
  transition-duration: 120ms;
}
.tfm-search-clear.is-on { display: flex; }
.tfm-search-clear:hover { background: rgba(255, 255, 255, 0.08); color: var(--tfm-text); }
.tfm-search-clear svg { display: block; }

/* ---- 로그인 (원본 .auth-group/.auth-btn 이식) ---- */
.tfm-auth-btn { min-width: 46px; justify-content: center; }

.tfm-checkbox {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: var(--tfm-control-h);
  color: var(--tfm-text-muted);
  font-size: 10.5px;
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
.tfm-checkbox:hover { color: var(--tfm-text); }
.tfm-checkbox input {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
}
.tfm-checkbox-box {
  position: relative;
  width: 13px; height: 13px;
  flex-shrink: 0;
  border: 1px solid var(--tfm-border-strong);
  border-radius: 3px;
  background: var(--tfm-bg);
  transition-property: background-color, border-color;
  transition-duration: 120ms;
}
.tfm-checkbox:hover .tfm-checkbox-box { border-color: var(--tfm-accent); }
.tfm-checkbox input:checked + .tfm-checkbox-box {
  background: var(--tfm-accent);
  border-color: var(--tfm-accent);
}
.tfm-checkbox-box::after {
  content: "";
  position: absolute;
  left: 3.5px; top: 0.5px;
  width: 3px; height: 6.5px;
  border: solid #17131f;
  border-width: 0 1.6px 1.6px 0;
  transform: rotate(45deg) scale(0);
  transition: transform 120ms ease-out;
}
.tfm-checkbox input:checked + .tfm-checkbox-box::after { transform: rotate(45deg) scale(1); }

.tfm-lang-btn { font-variant-numeric: tabular-nums; font-weight: 600; }

/* ---- 드롭다운 (원본 .dropdown-menu 이식) ---- */
.tfm-menu { position: relative; display: inline-flex; align-items: center; }
/* 오른쪽으로 열리는 메뉴 — 여는 방향만 정한다. margin-left:auto를 여기 두면 안 된다:
   원본에서 오른쪽으로 미는 것은 즐겨찾기 그룹 하나뿐(.favorites-filter-group)이라,
   언어 메뉴에도 걸면 줄이 넘칠 때 즐겨찾기와 언어·로그인이 따로 떨어져 두 덩어리로
   갈라진다(실측 — 툴바가 두세 줄로 뒤죽박죽 보이던 원인). */
.tfm-menu-right { position: relative; }

.tfm-select[data-menu] {
  border: 1px solid var(--tfm-border-strong);
  font-family: inherit;
  font-size: 11px;
}

.tfm-dropdown {
  position: absolute;
  top: calc(100% + 5px);
  left: 0;
  min-width: 118px;
  padding: 4px;
  background: var(--tfm-bg-elevated);
  border: 1px solid var(--tfm-border-strong);
  border-radius: 7px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
  z-index: 20;
  opacity: 0;
  transform: translateY(-4px) scale(0.98);
  transform-origin: top left;
  pointer-events: none;
  transition-property: opacity, transform;
  transition-duration: 130ms;
  transition-timing-function: ease-out;
}

.tfm-menu-right .tfm-dropdown {
  left: auto;
  right: 0;
  transform-origin: top right;
  min-width: 126px;
}

.tfm-menu.is-open .tfm-dropdown {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}

.tfm-dropdown-item {
  display: flex;
  align-items: center;
  gap: 7px;
  width: 100%;
  height: 26px;
  padding: 0 7px;
  background: transparent;
  border: none;
  border-radius: 5px;
  color: var(--tfm-text);
  font-family: inherit;
  font-size: 11px;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 100ms;
}

.tfm-dropdown-item:hover {
  background: var(--tfm-accent-soft);
  color: var(--tfm-accent-strong);
}

.tfm-dropdown-item.is-active { color: var(--tfm-accent-strong); }

/* ---- 그리드 ---- */
.tfm-grid {
  position: relative;
  flex: 1;
  padding: 10px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
  align-content: start;
}

.tfm-grid-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 150px;
}

/* 진열 창 격자 칸의 바닥 높이를 잡아 둔다 */
.mock-slot-grid .tfm-grid { min-height: 340px; }

.tfm-card {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 5px;
  border-radius: var(--tfm-radius-card);
  border: 1px solid transparent;
  position: relative;
  cursor: pointer;
  transition-property: background-color, border-color, transform;
  transition-duration: 120ms;
  transition-timing-function: ease-out;
}
.tfm-card:hover { background: var(--tfm-bg-card-hover); border-color: var(--tfm-border-strong); }
.tfm-card.playing { background: var(--tfm-bg-card-playing); border-color: var(--tfm-accent); }

.tfm-thumb {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: var(--tfm-radius-thumb);
  background: var(--tfm-bg-card);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 파형 — 원본 canvas(rgba(165,150,255,.85), 1px 간격, 중앙 기준 대칭)를 막대로 재현 */
.tfm-wave {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1px;
  width: 100%;
  height: 100%;
  padding: 0 2px;
}
.tfm-wave i {
  flex: 1 1 auto;
  min-width: 1px;
  background: rgba(165, 150, 255, 0.85);
  border-radius: 0.5px;
}

.tfm-wave-progress {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 0%;
  background: rgba(255, 255, 255, 0.14);
  border-right: 1px solid var(--tfm-accent-strong);
  pointer-events: none;
  transition: width 60ms linear;
}

/* 원본 .playing-badge는 즐겨찾기 별 오른쪽에 선다(left:32px) — 별과 자리를 겹치지 않게
   한 배치라 목업도 별 폭(20px)만큼 밀어 둔다. */
.tfm-eq {
  position: absolute;
  left: 30px; top: 5px;
  display: flex;
  align-items: flex-end;
  gap: 1.5px;
  height: 9px;
  opacity: 0;
  transition: opacity 120ms;
}
.tfm-card.playing .tfm-eq { opacity: 1; }
.tfm-eq i {
  width: 2px;
  background: var(--tfm-accent-strong);
  border-radius: 1px;
  animation: tfm-eq 0.9s ease-in-out infinite;
}
.tfm-eq i:nth-child(1) { height: 40%; animation-delay: 0ms; }
.tfm-eq i:nth-child(2) { height: 90%; animation-delay: 150ms; }
.tfm-eq i:nth-child(3) { height: 60%; animation-delay: 300ms; }

/* ---- 즐겨찾기 별 (원본 .fav-btn 이식 — 평소 숨었다가 카드 hover 시 뜬다)
   원본은 좌상단에 둔다: 우상단의 가져오기/제거 버튼과 자리를 겹치지 않게 하려는
   의도적 배치라 그대로 따른다(원본 주석: "misaimed click can't hit the wrong one"). ---- */
.tfm-fav-btn {
  position: absolute;
  left: 5px; top: 5px;
  z-index: 2;
  width: 20px; height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: rgba(0, 0, 0, 0.55);
  border: none;
  border-radius: 50%;
  color: var(--tfm-text);
  cursor: pointer;
  opacity: 0;
  transform: translateY(-2px);
  transition-property: opacity, transform, background-color, color;
  transition-duration: 130ms;
  transition-timing-function: ease-out;
}

.tfm-card:hover .tfm-fav-btn { opacity: 1; transform: translateY(0); }
.tfm-fav-btn:hover { background: rgba(0, 0, 0, 0.75); color: var(--tfm-favorite); }
.tfm-fav-btn:active { transform: scale(0.9); }

/* 켜둔 별은 hover가 아니어도 계속 보인다 */
.tfm-fav-btn.is-on {
  opacity: 1;
  transform: translateY(0);
  color: var(--tfm-favorite);
}
.tfm-fav-btn.is-on svg { fill: currentColor; }

@keyframes tfm-eq {
  0%, 100% { transform: scaleY(0.4); }
  50%      { transform: scaleY(1); }
}

.tfm-name {
  font-size: 10.5px;
  color: var(--tfm-text);
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.tfm-meta { font-size: 9.5px; color: var(--tfm-text-faint); font-variant-numeric: tabular-nums; }

/* ---- 빈 상태 ---- */
.tfm-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  color: var(--tfm-text-faint);
  text-align: center;
}
.tfm-empty p { margin: 0; font-size: 11px; }

.tfm-btn-primary {
  height: 27px;
  padding: 0 13px;
  background: var(--tfm-accent);
  color: #17131f;
  border: none;
  border-radius: 5px;
  font-family: inherit;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  transition-property: background-color, transform;
  transition-duration: 120ms;
}
.tfm-btn-primary:hover { background: var(--tfm-accent-strong); }
.tfm-btn-primary:active { transform: scale(0.96); }

/* ---- 상태바 ---- */
.tfm-status {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 5px 9px;
  background: var(--tfm-bg-elevated);
  border-top: 1px solid var(--tfm-border);
  color: var(--tfm-text-faint);
  font-size: 10px;
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}

/* 원본 .status-left — 항목 수와 버전이 한 덩어리이고 가운뎃점은 버전 쪽 ::before가 낸다 */
.tfm-status-left { display: flex; align-items: center; gap: 5px; min-width: 0; }
.tfm-version::before { content: "·"; margin-right: 5px; }

.tfm-now-playing {
  display: none;
  align-items: center;
  gap: 4px;
  color: var(--tfm-accent-strong);
  min-width: 0;
}
.tfm-now-playing.is-on { display: flex; }
.tfm-now-playing-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 150px;
}

/* ---- 조작은 앞으로 나온 패널에서만 ----
   뒤 패널에서는 내부 컨트롤이 클릭을 먹지 않아야 '앞으로 꺼내기'가 항상 우선한다. */
.mock-slot.is-back .tfm { pointer-events: none; }
.mock-slot.is-back .tfm * { pointer-events: none; }

