/* ============================================
   shadcn-theme.css — Jazz It Up Design System
   A "스윙 볼룸"(Savoy Ballroom) 컨셉 — 에스프레소 블랙 + 브라스 골드 + 버건디 포인트.
   음악 앱 구조(사이드바·트랙 리스트)는 유지하고 토큰 값만 교체한다. 토큰 이름은 shadcn 체계 유지.
   명세: docs/design/swing-ballroom-concept.md
   ============================================ */

/* --- CSS Variables (Light Mode = 기본 클래스 없음, JS 가 다크를 기본값으로 적용) ---
   라이트 = 크림(아이보리) 바탕. 브라스를 "글자"로 쓸 때는 반드시 어두운 금색(--primary #7a5a1c)을 쓴다
   (밝은 골드 #d6a445 는 크림 위 약 2.1:1 로 AA 미달). */
:root {
  --background: #fbf8f3;
  --foreground: #1e1712;
  --card: #ffffff;
  --card-foreground: #1e1712;
  --popover: #ffffff;
  --popover-foreground: #1e1712;
  --primary: #7a5a1c;
  --primary-foreground: #ffffff;
  --secondary: #f1e9dc;
  --secondary-foreground: #1e1712;
  --muted: #f1e9dc;
  --muted-foreground: #66574a;
  --accent: #f1e9dc;
  --accent-foreground: #1e1712;
  --destructive: #b42318;
  --destructive-foreground: #ffffff;
  --border: #e3d8c8;
  --input: #d9ccb8;
  --ring: #7a5a1c;
  --radius: 0.5rem;
  --header-glow: rgba(143, 45, 60, 0.14);   /* 버건디 저채도 */
  --sidebar-width: 240px;
  --topbar-height: 56px;

  /* 보조색·의미색 (A 신규) */
  --brand-2: #8f2d3c;            /* 버건디 — 장식·그라데이션 전용, 본문 글자 금지 */
  --success: #2f6b3a;            /* 성공·상승 의미 (프라이머리가 그린→브라스로 바뀌어 분리) */
  --success-foreground: #ffffff;

  /* 스타일 칩 색 (곡 제목 BPM_스타일_제목 의 LI/BA/BL) */
  --style-li: #8f400f;           /* 린디합 — 번트 오렌지 */
  --style-ba: #17625a;           /* 발보아 — 틸 */
  --style-bl: #3a52ad;           /* 블루스 — 인디고 */

  /* Chart colors — dj_total_dashboard.php 가 hex 뒤에 '33'(알파)을 붙여 쓰므로 반드시 6자리 hex */
  --chart-1: #a8781f;
  --chart-2: #17625a;
  --chart-3: #a24c14;
  --chart-4: #3a52ad;
  --chart-5: #8f2d3c;

  /* Sidebar */
  --sidebar-bg: #f3ede4;
  --sidebar-foreground: #4d4034;
  --sidebar-border: #e3d8c8;
  --sidebar-accent: #e9dfd0;
  --sidebar-accent-foreground: #1e1712;
  --sidebar-primary: #7a5a1c;    /* 활성 메뉴 — 골드 */

  /* Fonts — 라틴 폰트를 앞에 둔다(한글 폰트의 라틴 글리프가 영문을 가로채지 않도록).
     Limelight/Do Hyeon 은 400 한 굵기뿐 → 쓰는 곳에서 font-weight:400 으로 가짜 볼드를 막는다. */
  --font-display: 'Limelight', 'Do Hyeon', 'Noto Sans KR', 'Noto Sans SC', serif;       /* 로고·대형 숫자(라틴 전용) */
  --font-head: 'Josefin Sans', 'Do Hyeon', 'Noto Sans KR', 'Noto Sans SC', sans-serif;  /* 페이지 타이틀 */
  --font-body: 'Josefin Sans', 'Noto Sans KR', 'Noto Sans SC', system-ui, -apple-system, sans-serif;
  --font-num: 'Josefin Sans', 'Noto Sans KR', system-ui, sans-serif;                     /* BPM·통계 숫자(작은 크기) */
}

/* --- Dark Mode (사이트 기본값, menu.php/index.php 의 JS 가 .dark 를 우선 부여) --- */
.dark {
  --background: #17120f;         /* 에스프레소 블랙 */
  --foreground: #f5ede1;
  --card: #211a15;
  --card-foreground: #f5ede1;
  --popover: #211a15;
  --popover-foreground: #f5ede1;
  --primary: #d6a445;            /* 브라스 골드 */
  --primary-foreground: #1b1206;
  --secondary: #2d241d;
  --secondary-foreground: #f5ede1;
  --muted: #2d241d;
  --muted-foreground: #b8a994;
  --accent: #2d241d;
  --accent-foreground: #f5ede1;
  --destructive: #e5484d;
  --destructive-foreground: #1b0a0a;
  --border: #3b3027;
  --input: #3b3027;
  --ring: #d6a445;
  --header-glow: rgba(143, 45, 60, 0.42);

  --brand-2: #b0414f;
  --success: #7cc48a;
  --success-foreground: #0d1a10;

  --style-li: #e8944a;
  --style-ba: #4fb5a8;
  --style-bl: #8ea3ee;

  --chart-1: #d6a445;
  --chart-2: #4fb5a8;
  --chart-3: #e8944a;
  --chart-4: #8ea3ee;
  --chart-5: #c65a68;

  --sidebar-bg: #0e0b09;
  --sidebar-foreground: #b8a994;
  --sidebar-border: #2a211b;
  --sidebar-accent: #211a15;
  --sidebar-accent-foreground: #f5ede1;
  --sidebar-primary: #d6a445;
}

/* --- Base --- */
*, *::before, *::after {
  border-color: var(--border);
}

body {
  background-color: var(--background);
  color: var(--foreground);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* --- Typography --- */
h1, h2, h3, h4, h5, h6 {
  color: var(--foreground);
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.2;
}

p {
  color: var(--foreground);
  line-height: 1.625;
}

.text-muted {
  color: var(--muted-foreground) !important;
}

a {
  color: var(--foreground);
  text-decoration: none;
}
a:hover {
  color: var(--foreground);
  opacity: 0.8;
}

/* --- Card --- */
.shadcn-card {
  background-color: var(--card);
  color: var(--card-foreground);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.5rem;
}

.shadcn-card-header {
  padding-bottom: 1rem;
}

.shadcn-card-title {
  font-size: 1.125rem;
  font-weight: 600;
  letter-spacing: -0.025em;
  color: var(--card-foreground);
}

.shadcn-card-description {
  font-size: 0.875rem;
  color: var(--muted-foreground);
}

.shadcn-card-content {
  padding-top: 0;
}

/* --- Button --- */
.shadcn-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  white-space: nowrap;
  border-radius: calc(var(--radius) - 2px);
  font-size: 0.875rem;
  font-weight: 500;
  padding: 0.5rem 1rem;
  height: 2.25rem;
  border: 1px solid transparent;
  cursor: pointer;
  transition: all 0.15s ease;
}
.shadcn-btn:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}

.shadcn-btn-default {
  background-color: var(--primary);
  color: var(--primary-foreground);
}
.shadcn-btn-default:hover {
  opacity: 0.9;
}

.shadcn-btn-secondary {
  background-color: var(--secondary);
  color: var(--secondary-foreground);
}
.shadcn-btn-secondary:hover {
  background-color: var(--secondary);
  opacity: 0.8;
}

.shadcn-btn-outline {
  border-color: var(--input);
  background-color: var(--background);
  color: var(--foreground);
}
.shadcn-btn-outline:hover {
  background-color: var(--accent);
  color: var(--accent-foreground);
}

.shadcn-btn-ghost {
  background-color: transparent;
  color: var(--foreground);
  border: none;
}
.shadcn-btn-ghost:hover {
  background-color: var(--accent);
  color: var(--accent-foreground);
}

.shadcn-btn-destructive {
  background-color: var(--destructive);
  color: var(--destructive-foreground);
}
.shadcn-btn-destructive:hover {
  opacity: 0.9;
}

.shadcn-btn-sm {
  height: 2rem;
  padding: 0.25rem 0.75rem;
  font-size: 0.8125rem;
}

.shadcn-btn-lg {
  height: 2.75rem;
  padding: 0.5rem 2rem;
  font-size: 1rem;
}

.shadcn-btn-icon {
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
}
/* 상단바·모바일 드로어 아이콘 버튼은 터치 기기에서 44px 히트 영역(아이콘 크기는 그대로) — 2026-10-11 menu-review P2.
   .shadcn-btn-icon 전체가 아니라 이 두 영역만(표 안 아이콘 버튼은 폭이 좁아 넓히면 깨진다 — 음악 검색 등과 같은 기존 절충 유지) */
@media (pointer: coarse) {
  .app-topbar .shadcn-btn-icon, #mobileMenu .shadcn-btn-icon {
    width: 2.75rem;
    height: 2.75rem;
  }
}

/* --- Badge --- */
.shadcn-badge {
  display: inline-flex;
  align-items: center;
  border-radius: 9999px;
  padding: 0.125rem 0.625rem;
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1;
  transition: color 0.15s ease;
}

.shadcn-badge-default {
  background-color: var(--primary);
  color: var(--primary-foreground);
}

.shadcn-badge-secondary {
  background-color: var(--secondary);
  color: var(--secondary-foreground);
}

.shadcn-badge-outline {
  background-color: transparent;
  border: 1px solid var(--border);
  color: var(--foreground);
}

.shadcn-badge-destructive {
  background-color: var(--destructive);
  color: var(--destructive-foreground);
}

/* --- Input / Form --- */
.shadcn-input {
  display: flex;
  width: 100%;
  height: 2.5rem;
  border-radius: calc(var(--radius) - 2px);
  border: 1px solid var(--input);
  background-color: var(--background);
  color: var(--foreground);
  padding: 0.5rem 0.75rem;
  font-size: 0.875rem;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.shadcn-input::placeholder {
  color: var(--muted-foreground);
}
.shadcn-input:focus {
  outline: none;
  border-color: var(--ring);
  box-shadow: 0 0 0 1px var(--ring);
}

.shadcn-label {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--foreground);
  margin-bottom: 0.375rem;
  display: block;
}

.shadcn-select {
  display: flex;
  width: 100%;
  height: 2.5rem;
  border-radius: calc(var(--radius) - 2px);
  border: 1px solid var(--input);
  background-color: var(--background);
  color: var(--foreground);
  padding: 0.5rem 0.75rem;
  font-size: 0.875rem;
  appearance: none;
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%2371717a' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
  background-position: right 0.5rem center;
  background-repeat: no-repeat;
  background-size: 1.5em 1.5em;
}
.shadcn-select:focus {
  outline: none;
  border-color: var(--ring);
  box-shadow: 0 0 0 1px var(--ring);
}

/* --- Table --- */
.shadcn-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
}

.shadcn-table thead th {
  height: 2.5rem;
  padding: 0.5rem 1rem;
  text-align: left;
  font-weight: 500;
  color: var(--muted-foreground);
  border-bottom: 1px solid var(--border);
  background-color: transparent;
  white-space: nowrap;
  word-break: keep-all;
}

.shadcn-table tbody td {
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border);
  color: var(--foreground);
}

.shadcn-table tbody tr:hover {
  background-color: var(--muted);
}

.shadcn-table tbody tr:last-child td {
  border-bottom: none;
}

/* --- Separator --- */
.shadcn-separator {
  height: 1px;
  width: 100%;
  background-color: var(--border);
  margin: 1rem 0;
}

/* --- DataTables shadcn Override --- */
.dataTables_wrapper {
  overflow-x: auto;
}

table.dataTable {
  border-collapse: collapse !important;
}

table.dataTable thead th,
table.dataTable thead td {
  border-bottom: 1px solid var(--border) !important;
  color: var(--muted-foreground);
  font-weight: 500;
  font-size: 0.8125rem;
  letter-spacing: 0.01em;
  background-color: transparent !important;
  padding: 0.75rem 1rem !important;
  white-space: nowrap;
  word-break: keep-all;
}

table.dataTable tbody td {
  border-bottom: 1px solid var(--border) !important;
  padding: 0.75rem 1rem !important;
  color: var(--foreground);
}

table.dataTable tbody tr:hover {
  background-color: var(--muted) !important;
}

table.dataTable.no-footer {
  border-bottom: 1px solid var(--border) !important;
}

.dataTables_wrapper .dataTables_length select,
.dataTables_wrapper .dataTables_filter input {
  border: 1px solid var(--input);
  border-radius: calc(var(--radius) - 2px);
  padding: 0.375rem 0.625rem;
  font-size: 0.875rem;
  background-color: var(--background);
  color: var(--foreground);
}

.dataTables_wrapper .dataTables_filter input:focus {
  outline: none;
  border-color: var(--ring);
  box-shadow: 0 0 0 1px var(--ring);
}

.dataTables_wrapper .dataTables_info {
  color: var(--muted-foreground);
  font-size: 0.8125rem;
}

.dataTables_wrapper .dataTables_paginate .paginate_button {
  border: 1px solid var(--border) !important;
  border-radius: calc(var(--radius) - 2px) !important;
  background: var(--background) !important;
  color: var(--foreground) !important;
  padding: 0.25rem 0.75rem !important;
  margin: 0 0.125rem !important;
  font-size: 0.8125rem !important;
}

.dataTables_wrapper .dataTables_paginate .paginate_button:hover {
  background: var(--accent) !important;
  color: var(--accent-foreground) !important;
  border-color: var(--border) !important;
}

.dataTables_wrapper .dataTables_paginate .paginate_button.current {
  background: var(--primary) !important;
  color: var(--primary-foreground) !important;
  border-color: var(--primary) !important;
}

/* --- Filter Bar (검색/필터 툴바) ---
   grid-cols-* 로 셀렉트·입력이 화면 폭에 비례해 늘어나는 문제를 막는다.
   내용 폭 기준(min/max-width)으로 좁히고 한 줄에 배치, 넘치면 줄바꿈한다. */
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.625rem;
}
.filter-bar .shadcn-select {
  width: auto;
  min-width: 7rem;
  max-width: 14rem;
}
.filter-bar .shadcn-input {
  width: auto;
  min-width: 10rem;
  max-width: 20rem;
  flex: 1 1 10rem;
}
.filter-bar .filter-label {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--foreground);
  white-space: nowrap;
}
.filter-bar .filter-field {
  display: flex;
  align-items: center;
  gap: 0.375rem;
}
.filter-bar .filter-actions {
  display: flex;
  gap: 0.5rem;
  margin-left: auto;
}
@media (max-width: 640px) {
  .filter-bar {
    gap: 0.5rem;
  }
  .filter-bar .shadcn-select,
  .filter-bar .shadcn-input {
    flex: 1 1 calc(50% - 0.5rem);
    max-width: none;
    min-height: 44px;
  }
  .filter-bar .filter-field {
    flex: 1 1 calc(50% - 0.5rem);
  }
  .filter-bar .filter-field .shadcn-select {
    flex: 1 1 auto;
  }
  .filter-bar .filter-actions {
    margin-left: 0;
    width: 100%;
  }
  .filter-bar .filter-actions .shadcn-btn {
    flex: 1 1 auto;
    min-height: 44px;
  }
}

/* --- Utilities --- */
.border-border {
  border-color: var(--border) !important;
}

.bg-background {
  background-color: var(--background) !important;
}

.bg-card {
  background-color: var(--card) !important;
}

.bg-muted {
  background-color: var(--muted) !important;
}

.text-foreground {
  color: var(--foreground) !important;
}

.text-muted-foreground {
  color: var(--muted-foreground) !important;
}

/* --- Transitions --- */
.dark-transition,
.dark-transition *,
.dark-transition *::before,
.dark-transition *::after {
  transition: background-color 0.3s ease, color 0.2s ease, border-color 0.3s ease !important;
}

/* ============================================
   Spotify 컨셉 — 사이드바 / 모바일 탑바·드로어 레이아웃
   menu.php 전용. 31개 페이지가 include 해도 body 여백만으로 호환.
   ============================================ */

/* 데스크톱: 본문이 사이드바에 가리지 않도록 (menu.php 를 포함해 .app-sidebar 가 실제로 렌더된 페이지에만 적용 —
   index.php, dj_result_view.php 등 menu.php 를 포함하지 않는 페이지는 영향 없음) */
@media (min-width: 768px) {
  body:has(.app-sidebar) { padding-left: var(--sidebar-width); }
}
/* 모바일: 본문이 상단 고정바에 가리지 않도록 */
@media (max-width: 767px) {
  body:has(.app-topbar) { padding-top: var(--topbar-height); }
}

.app-sidebar {
  display: none;
}
@media (min-width: 768px) {
  .app-sidebar {
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0; left: 0; bottom: 0;
    width: var(--sidebar-width);
    background-color: var(--sidebar-bg);
    border-right: 1px solid var(--sidebar-border);
    color: var(--sidebar-foreground);
    z-index: 40;
    overflow-y: auto;
  }
}

/* 로고: 아르데코 디스플레이(Limelight, 400 단일 굵기) + 원 안 이음표 마크(음표 모티프) */
.app-sidebar-brand {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 1.25rem 1.25rem 0.75rem;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.375rem;
  line-height: 1.1;
  letter-spacing: 0.01em;
  color: var(--sidebar-accent-foreground);
}
.brand-mark {
  flex: 0 0 auto;
  width: 1.75rem;
  height: 1.75rem;
  color: var(--sidebar-primary);
}
.app-topbar .app-brand-mobile {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.125rem;
  color: var(--sidebar-accent-foreground);
  /* 리뷰 보드 P1: 글꼴 확대(삼성 인터넷 '글꼴 크기' 한 단계)에서 'Jazz It Up' 이 두 줄로 접혀 고정 상단 바(56px)를
     넘쳤다 — 로고는 줄이거나 줄임표 없이 한 줄(white-space:nowrap) + 줄어들지 않게(flex:none). 옆 아이콘 버튼은
     flex-shrink 기본값(1)이라 공간이 부족하면 대신 그쪽이 줄어든다(버튼 자체 크기 규칙은 그대로, 폭만) */
  white-space: nowrap;
  flex: none;
}
.app-topbar .brand-mark { width: 1.375rem; height: 1.375rem; }

.app-sidebar-section { padding: 0.5rem 0.75rem; }

.app-sidebar-section-title {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--sidebar-foreground);
  opacity: 0.7;
}

.app-sidebar-link {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.5rem 0.75rem;
  margin: 0.0625rem 0;
  border-radius: calc(var(--radius) - 2px);
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--sidebar-foreground);
  transition: background-color 0.15s ease, color 0.15s ease;
}
.app-sidebar-link:hover {
  background-color: var(--sidebar-accent);
  color: var(--sidebar-accent-foreground);
  opacity: 1;
}
/* 활성 메뉴: 골드 글자 + 좌측 골드 룰(아르데코 1px~3px 골드 선) */
.app-sidebar-link.active {
  color: var(--sidebar-primary);
  background-color: var(--sidebar-accent);
  font-weight: 700;
  box-shadow: inset 3px 0 0 var(--sidebar-primary);
}

.app-sidebar-footer {
  margin-top: auto;
  padding: 0.75rem;
  border-top: 1px solid var(--sidebar-border);
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

/* 메뉴 항목 아이콘 — PC 사이드바를 접었을 때(레일)만 보인다. 드로어·펼친 사이드바는 글자만(2026-10-09 이전과 같은 모양) */
.jz-nav-ic { display: none; }
/* 휴대폰 드로어의 'PC' 표시(DJ Deck) */
.app-sidebar-link .jz-nav-tag { margin-left: auto; padding: 0 0.375rem; border: 1px solid var(--border); border-radius: 4px;
  font-size: 0.65rem; font-weight: 700; line-height: 1.25rem; color: var(--muted-foreground); letter-spacing: 0.04em; }
/* 사이드바 접기 버튼 — 펼침: 로고 줄 오른쪽 위, 접힘: 로고 아래 가운데 */
.app-sidebar-rail-btn { display: none; }
@media (min-width: 768px) {
  .app-sidebar-rail-btn {
    display: inline-flex; align-items: center; justify-content: center;
    position: absolute; top: 1.125rem; right: 0.5rem;
    width: 2rem; height: 2rem; border-radius: calc(var(--radius) - 2px);
    color: var(--sidebar-foreground); opacity: 0.6; background: transparent; border: 0; cursor: pointer;
  }
  .app-sidebar-rail-btn:hover, .app-sidebar-rail-btn:focus-visible { opacity: 1; background-color: var(--sidebar-accent); }
  .app-sidebar-rail-btn:focus-visible { outline: 2px solid var(--ring); outline-offset: 1px; }
  .app-sidebar-brand { padding-right: 2.75rem; }

  /* 접힌 사이드바(아이콘 레일). 본문·하단 플레이어·읽기 전용 띠는 모두 --sidebar-width 를 따르므로 값 하나만 바꾼다 */
  html.jz-rail { --sidebar-width: 64px; }
  html.jz-rail .app-sidebar { overflow-x: hidden; }
  html.jz-rail .app-sidebar-brand { justify-content: center; padding: 1rem 0 0.25rem; }
  html.jz-rail .app-sidebar-brand > span { display: none; }
  html.jz-rail .app-sidebar-rail-btn { position: static; margin: 0 auto 0.25rem; }
  html.jz-rail .app-sidebar-section { padding: 0.25rem 0.5rem; }
  /* 그룹 이름 대신 얇은 구분선 — 그룹은 늘 펼친 상태(접을 그룹 상태가 없음) */
  html.jz-rail .app-sidebar-section-title { padding: 0; margin: 0.25rem 0.5rem; height: 0; overflow: hidden; border-top: 1px solid var(--sidebar-border); opacity: 1; }
  html.jz-rail .app-sidebar .app-sidebar-link { justify-content: center; padding: 0.375rem 0; position: relative; }
  html.jz-rail .app-sidebar .jz-nav-ic { display: inline-block; width: 1.25rem; text-align: center; font-size: 1rem; }
  html.jz-rail .app-sidebar .jz-nav-label { display: none; }
  html.jz-rail .app-sidebar .lg-nav .lg-badge { position: absolute; top: 0.125rem; right: 0.25rem; margin-left: 0; transform: scale(0.85); }
  html.jz-rail .app-sidebar-footer { padding: 0.5rem 0.25rem; align-items: center; }
  html.jz-rail .app-sidebar-footer .jz-nav-foot-row { flex-direction: column; gap: 0.375rem; }
  html.jz-rail .app-sidebar-footer .jz-nav-foot-row > div { flex-direction: column; }
  html.jz-rail .app-sidebar-footer .jz-nav-name, html.jz-rail .app-sidebar-footer img { display: none; }
}

/* 모바일 상단 고정바 */
.app-topbar {
  display: flex;
  position: fixed;
  top: 0; left: 0; right: 0;
  height: var(--topbar-height);
  align-items: center;
  justify-content: space-between;
  padding: 0 0.75rem;
  background-color: var(--sidebar-bg);
  border-bottom: 1px solid var(--sidebar-border);
  color: var(--sidebar-foreground);
  z-index: 50;
}
@media (min-width: 768px) {
  .app-topbar { display: none; }
}

/* 모바일 드로어 (기존 #mobileMenu 재사용) */
@media (max-width: 767px) {
  #mobileMenu {
    position: fixed;
    top: 0; bottom: 0; left: 0;
    width: min(82vw, 300px);
    max-width: 300px;
    background-color: var(--sidebar-bg);
    color: var(--sidebar-foreground);
    border-right: 1px solid var(--sidebar-border);
    border-top: none;
    z-index: 60;
    overflow-y: auto;
    transform: translateX(-100%);
    transition: transform 0.2s ease;
  }
  #mobileMenu:not(.hidden) { transform: translateX(0); }
}

.app-drawer-backdrop {
  display: none;
}
@media (max-width: 767px) {
  .app-drawer-backdrop.show {
    display: block;
    position: fixed;
    inset: 0;
    background-color: rgba(0, 0, 0, 0.6);
    z-index: 55;
  }
}

/* ============================================
   Spotify 컨셉 — 헤더 그라데이션 / 카드 그리드 / 트랙 리스트 / 별점 / pill 버튼
   ============================================ */

/* 공용 페이지 헤더 — 슬림 스테이지 + 8카운트 리듬 점 (php/page_header.php, DESIGN.md "Page Header")
   .jz-ph .page-header-title 이 아래 .page-header-title 보다 먼저 나오지만 선택자 우선순위(0,2,0)로 이긴다 */
.jz-ph { position: relative; border-bottom: 1px solid var(--border); background: var(--background); }
.jz-ph-inner { position: relative; max-width: 1280px; margin: 0 auto; padding: 1rem 1rem 0.95rem; }
.jz-ph-row { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; }
.jz-ph-icon { color: var(--primary); font-size: 1.125rem; width: 1.375rem; text-align: center; flex: none; }
.jz-ph-text { min-width: 0; }
.jz-ph-section { font-size: 0.74rem; line-height: 1.3; color: var(--muted-foreground); }
.jz-ph .page-header-title { font-size: 1.5rem; }
/* 제목 아래 한 줄 설명(desc) — 2026-10-11 menu-review P2: 현황 화면이 무엇을 보는지 밝힌다 */
.jz-ph-desc { margin: 0.2rem 0 0; font-size: 0.82rem; line-height: 1.4; color: var(--muted-foreground); }
.jz-ph-chips { margin-left: auto; display: flex; align-items: center; gap: 0.375rem; flex-wrap: wrap; }
/* 사용자 의견(VOC) — 도움말 '?' 바로 왼쪽(2026-10-14 voc-entry 사용자 결정). 알약 모양은 공용 .jz-fb-btn-full(feedback.css),
   여기선 자리만: 칩이 있으면 그 뒤에, 없으면 혼자 오른쪽으로 민다. 휴대폰은 상단바의 같은 버튼(jz_fb_button)을 쓴다 */
.jz-ph-fb { margin-left: auto; flex: none; }
.jz-ph-chips + .jz-ph-fb { margin-left: 0; }
.jz-ph-fb + .jz-ph-help { margin-left: 0; }
/* !important 필요 — feedback.css 의 .jz-fb-btn-full 기본 규칙(display:inline-flex)이 이 파일보다 나중에 실려
   같은 상세도(0,1,0)에서 소스 순서로 이기는 것을 막는다(2026-10-14 voc-entry 헤드리스 발견: 휴대폰에서 알약이 그대로 보임) */
@media (max-width: 767px) { .jz-ph-fb { display: none !important; } }
/* 도움말 '?' — 헤더 오른쪽 끝(칩·의견 버튼이 있으면 그 뒤, 없으면 혼자 오른쪽). 휴대폰은 상단바의 같은 링크를 쓴다 */
.jz-ph-help { margin-left: auto; flex: none; display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: 9999px; color: var(--muted-foreground); font-size: 1.05rem; }
.jz-ph-chips + .jz-ph-help { margin-left: 0; }
.jz-ph-help:hover { background: var(--muted); color: var(--foreground); }
.jz-ph-help:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
@media (max-width: 767px) { .jz-ph-help { display: none; } }
.jz-ph-chip { font-size: 0.76rem; line-height: 1.4; border: 1px solid var(--border); border-radius: 9999px; padding: 0.1875rem 0.625rem; color: var(--muted-foreground); white-space: nowrap; }
.jz-ph-chip b { color: var(--foreground); font-weight: 700; font-variant-numeric: tabular-nums; }
.jz-ph-actions { display: inline-flex; align-items: center; gap: 0.375rem; }
/* 8카운트 리듬 점: 헤더 아래 테두리에 걸친다(바탕색 받침으로 선을 끊음) */
.jz-rhythm { position: absolute; left: 1rem; bottom: -4px; display: inline-flex; align-items: center; gap: 5px; padding-right: 8px; background: var(--background); }
.jz-rhythm i { display: block; width: 7px; height: 7px; border-radius: 50%; background: var(--primary); }
.jz-rhythm i.s { width: 5px; height: 5px; opacity: 0.75; }
.jz-rhythm i.g { margin-left: 6px; }
@media (min-width: 640px) {
  .jz-ph-inner { padding-left: 1.5rem; padding-right: 1.5rem; }
  .jz-rhythm { left: 1.5rem; }
}
@media (max-width: 639px) {
  .jz-ph .page-header-title { font-size: 1.3rem; }
  .jz-ph-chips { margin-left: 0; width: 100%; }
}

/* 화면 탭 줄(jz_page_header() 의 'tabs' — 곡 찾기·현황처럼 같은 그룹 화면을 메뉴 그대로 두고 오가게 한다.
   2026-10-11 menu-review 2단계). 실제 페이지 이동(링크)이라 role=tablist 는 쓰지 않는다. */
.jz-ph-tabs { display: flex; gap: 0.25rem; max-width: 1280px; margin: 0 auto; padding: 0 1rem; overflow-x: auto;
  -webkit-overflow-scrolling: touch; border-bottom: 1px solid var(--border); background: var(--background); }
.jz-ph-tab { display: inline-flex; align-items: center; min-height: 44px; padding: 0 0.875rem; font-size: 0.86rem;
  font-weight: 600; color: var(--muted-foreground); text-decoration: none; white-space: nowrap;
  border-bottom: 2px solid transparent; margin-bottom: -1px; }
.jz-ph-tab:hover { color: var(--foreground); }
.jz-ph-tab.active { color: var(--primary); border-bottom-color: var(--primary); }
.jz-ph-tab:focus-visible { outline: 2px solid var(--ring); outline-offset: -2px; }
@media (min-width: 640px) { .jz-ph-tabs { padding: 0 1.5rem; } }

/* 라틴은 Josefin Sans 700, 한글은 Do Hyeon(400 단일 굵기).
   font-synthesis:none 이라 Do Hyeon 은 가짜 볼드 없이 본래 굵기로 그려진다. */
.page-header-title {
  font-family: var(--font-head);
  font-weight: 700;
  font-synthesis: none;
  letter-spacing: 0;
  font-size: 2rem;
  line-height: 1.15;
  color: var(--foreground);
}

.page-header-subtitle {
  color: var(--muted-foreground);
  font-size: 0.875rem;
  margin-top: 0.25rem;
}

/* 카드 그리드 */
.media-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 1.5rem;
}

.media-card {
  background-color: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem;
  transition: background-color 0.15s ease;
}
.media-card:hover { background-color: var(--accent); }

.media-card-art {
  aspect-ratio: 1 / 1;
  width: 100%;
  border-radius: calc(var(--radius) - 2px);
  background-color: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted-foreground);
  font-size: 1.75rem;
  font-weight: 700;
  margin-bottom: 0.75rem;
}

.media-card-title {
  font-weight: 600;
  color: var(--card-foreground);
  font-size: 0.9375rem;
}

.media-card-subtitle {
  color: var(--muted-foreground);
  font-size: 0.8125rem;
  margin-top: 0.125rem;
}

/* 트랙 리스트 행 (일반 목록/테이블 공용) */
.track-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.5rem 0.75rem;
  border-radius: calc(var(--radius) - 2px);
  transition: background-color 0.15s ease;
}
.track-row:hover { background-color: var(--accent); }

.track-row-index {
  width: 1.5rem;
  text-align: center;
  color: var(--muted-foreground);
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
}
.track-row:hover .track-row-index { color: var(--foreground); }

.track-row-title { font-weight: 500; color: var(--foreground); font-size: 0.875rem; }
.track-row-artist { color: var(--muted-foreground); font-size: 0.8125rem; }

/* DataTables 를 트랙 리스트처럼 */
table.dataTable tbody tr {
  height: 56px;
}
table.dataTable tbody tr:hover td {
  background-color: var(--accent) !important;
}

/* 별점 */
.star-rating {
  display: inline-flex;
  align-items: center;
  gap: 0.125rem;
  color: var(--border);
  font-size: 0.875rem;
}
.star-rating .star-filled { color: var(--primary); }

/* 라인댄스 곡 행 강조 (기존 인라인 #FFC19E 대체 — 차트 토큰 기반, 다크/라이트 모두 가독) */
.row-tag-linedance {
  background-color: color-mix(in srgb, var(--chart-3) 20%, var(--card));
}

/* pill 버튼 (CTA / 필터) */
.shadcn-btn-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  border-radius: 9999px;
  font-weight: 700;
  font-size: 0.875rem;
  padding: 0.625rem 1.5rem;
  border: 1px solid transparent;
  background-color: var(--primary);
  color: var(--primary-foreground);
  cursor: pointer;
  transition: opacity 0.15s ease, transform 0.1s ease;
}
.shadcn-btn-pill:hover { opacity: 0.9; }
.shadcn-btn-pill:active { transform: scale(0.98); }

.shadcn-btn-pill-outline {
  background-color: transparent;
  border: 1px solid var(--border);
  color: var(--foreground);
}
.shadcn-btn-pill-outline:hover { background-color: var(--accent); }

/* ============================================
   A 스윙 볼룸 — BPM·스타일 칩 (php/js/track-title.js 가 생성)
   BPM 은 숫자(고정 폭 가운데 정렬), 스타일은 색 칩. 색은 --style-* 토큰만.
   ============================================ */
/* 좁은 화면에서 제목 열이 한 글자 폭으로 무너지지 않도록 최소 폭(표는 overflow-x-auto 안에 있음) */
.track-title {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem;
  min-width: 10rem;
}
.track-title-text {
  font-weight: 600;
  color: var(--foreground);
  overflow-wrap: break-word;   /* 단어 중간에서 끊지 않음(한 단어가 넘칠 때만) */
}
.track-title-fav {
  color: var(--brand-2);
  font-size: 0.8125rem;
}
.bpm-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.5rem;
  padding: 0.125rem 0.375rem;
  border-radius: 4px;
  font-family: var(--font-num);
  font-weight: 700;
  font-size: 0.8125rem;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
  color: var(--foreground);
  background-color: var(--muted);
  box-shadow: inset 0 0 0 1px var(--border);
}
.bpm-chip small {
  margin-left: 0.2rem;
  font-size: 0.625rem;
  font-weight: 600;
  color: var(--muted-foreground);
}
.style-chip {
  --sc: var(--muted-foreground);
  display: inline-flex;
  align-items: center;
  padding: 0.125rem 0.4rem;
  border-radius: 4px;
  font-family: var(--font-num);
  font-weight: 700;
  font-size: 0.6875rem;
  line-height: 1.2;
  letter-spacing: 0.04em;
  color: var(--sc);
  background-color: color-mix(in srgb, var(--sc) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--sc) 55%, transparent);
}
.style-chip--li { --sc: var(--style-li); }
.style-chip--ba { --sc: var(--style-ba); }
.style-chip--bl { --sc: var(--style-bl); }

/* DataTables 기본 줄무늬·정렬열 음영은 순수 검정 알파(차가운 회색)라 크림 라이트에서 톤이 어긋난다
   → 같은 선택자로 --foreground(웜 톤) 기반 틴트로 교체(redesign-skill: 회색 계열 통일) */
table.dataTable.stripe > tbody > tr.odd > *,
table.dataTable.display > tbody > tr.odd > * {
  box-shadow: inset 0 0 0 9999px color-mix(in srgb, var(--foreground) 3%, transparent);
}
table.dataTable.display > tbody > tr > .sorting_1,
table.dataTable.order-column.stripe > tbody > tr > .sorting_1 {
  box-shadow: inset 0 0 0 9999px color-mix(in srgb, var(--foreground) 4%, transparent);
}
table.dataTable.display > tbody > tr.odd > .sorting_1,
table.dataTable.order-column.stripe > tbody > tr.odd > .sorting_1 {
  box-shadow: inset 0 0 0 9999px color-mix(in srgb, var(--foreground) 6%, transparent);
}

/* ============================================
   A 스윙 볼룸 — 셋의 흐름(set-flow.js) / 공연 티켓(DJ 후기 목록) / 쉬는 박자 / 섹션 제목
   명세: docs/superpowers/specs/2026-10-01-swing-mood-step4-design.md, DESIGN.md "Set Flow / Review Ticket / Empty State / Section Title"
   ============================================ */

/* 섹션 제목 — 앞 리듬 점 하나 + 뒤로 흐려지는 선 */
.jz-section-title {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  margin-block: 1.25rem 0.625rem;
  font-family: var(--font-head);
  font-size: 1rem;
  color: var(--foreground);
}
.jz-section-title::before {
  content: "";
  width: 7px;
  height: 7px;
  flex: none;
  border-radius: 9999px;
  background: var(--primary);
}
.jz-section-title::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, var(--border), transparent);
}

/* 셋 흐름 곡선 (큰 패널용) */
.jz-flow svg { width: 100%; height: 150px; display: block; }

/* 스타일 비율 막대 — 알약 모양. 티켓 안 미니는 .mini 쪽에서 6px 로 낮춤 */
.jz-mix { display: grid; gap: 0.5rem; }
.jz-mix-bar { display: flex; height: 12px; border-radius: 9999px; overflow: hidden; background: var(--muted); }
.jz-mix-bar span { display: block; }
.jz-mix-empty { height: 12px; border-radius: 9999px; background: var(--muted); }
.jz-mix-legend { display: grid; gap: 0.375rem; font-size: 0.84rem; }
.jz-mix-legend div { display: flex; justify-content: space-between; gap: 0.5rem; }
.jz-mix-legend b { font-variant-numeric: tabular-nums; }
.jz-mix-dot { display: inline-block; width: 9px; height: 9px; border-radius: 4px; margin-right: 0.375rem; vertical-align: middle; }

/* 쉬는 박자(빈 상태) */
.jz-rest {
  display: grid;
  gap: 0.625rem;
  justify-items: start;
  padding: 1.25rem;
  border-radius: 8px;
  background: var(--card);
  border: 1px solid var(--border);
}
.jz-rest strong { font-family: var(--font-head); font-size: 1rem; }
.jz-rest .jz-rest-meta { font-size: 0.82rem; color: var(--muted-foreground); }
.jz-rest .jz-rest-count { display: flex; gap: 0.625rem; font-weight: 700; font-size: 0.82rem; color: var(--muted-foreground); }
.jz-rest .jz-rest-count span.on { color: var(--primary); }

/* 공연 티켓(DJ 후기 목록 전용 — 다른 페이지에는 쓰지 않는다) */
.jz-tickets { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.875rem; }
@media (max-width: 900px) {
  .jz-tickets { grid-template-columns: 1fr; }
}
.jz-ticket {
  --stub: 108px;
  display: grid;
  grid-template-columns: var(--stub) minmax(0, 1fr);
  background: var(--card);
  border-radius: 8px;
  box-shadow: inset 0 0 0 1px var(--border);
  -webkit-mask:
    radial-gradient(circle 9px at var(--stub) 0, transparent 98%, #000) top / 100% 51% no-repeat,
    radial-gradient(circle 9px at var(--stub) 100%, transparent 98%, #000) bottom / 100% 51% no-repeat;
  mask:
    radial-gradient(circle 9px at var(--stub) 0, transparent 98%, #000) top / 100% 51% no-repeat,
    radial-gradient(circle 9px at var(--stub) 100%, transparent 98%, #000) bottom / 100% 51% no-repeat;
}
@media (max-width: 900px) {
  .jz-ticket { --stub: 84px; }
  .jz-ticket-stub .jz-ticket-day { font-size: 1.9rem; }
  .jz-ticket-mini { grid-template-columns: 1fr; }
}
.jz-ticket-stub {
  padding: 0.875rem 0.5rem;
  border-right: 2px dashed var(--border);
  display: grid;
  align-content: start;
  justify-items: center;
  gap: 1px;
  text-align: center;
  background: radial-gradient(circle, color-mix(in srgb, var(--primary) 16%, transparent) 1px, transparent 1.5px) 0 0 / 6px 6px;
}
.jz-ticket-stub .jz-ticket-mon { font-size: 0.7rem; color: var(--muted-foreground); letter-spacing: 0.08em; }
.jz-ticket-stub .jz-ticket-day { font-family: var(--font-display); font-weight: 400; font-synthesis: none; font-size: 2.4rem; line-height: 1; color: var(--primary); }
.jz-ticket-stub .jz-ticket-yr { font-size: 0.7rem; color: var(--muted-foreground); }
.jz-ticket-stub .jz-ticket-part { margin-top: 0.5rem; font-size: 0.7rem; border: 1px solid var(--border); border-radius: 9999px; padding: 1px 7px; white-space: nowrap; }
.jz-ticket-body { padding: 0.875rem 1rem; display: grid; gap: 0.5rem; min-width: 0; }
.jz-ticket-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 0.5rem; flex-wrap: wrap; }
.jz-ticket-top h2 { font-family: var(--font-head); font-size: 1.02rem; line-height: 1.25; }
.jz-ticket-who { font-size: 0.8rem; color: var(--muted-foreground); }
.jz-ticket-who b { color: var(--foreground); font-weight: 600; }
.jz-ticket-rec { font-size: 0.74rem; white-space: nowrap; color: var(--muted-foreground); }
.jz-ticket-rec b { font-family: var(--font-display); font-weight: 400; font-synthesis: none; font-size: 1.05rem; color: var(--foreground); }
.jz-ticket-mini { display: grid; grid-template-columns: minmax(0, 1fr) 92px; gap: 0.625rem; align-items: end; }
.jz-ticket-mini svg { width: 100%; height: 36px; display: block; }
.jz-ticket-mini .jz-mix-bar, .jz-ticket-mini .jz-mix-empty { height: 6px; }
.jz-ticket-foot { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.jz-ticket-tag { font-size: 0.74rem; color: var(--muted-foreground); }

/* 템포 막대(곡 목록 행) — track-title.js 가 제목 뒤에 붙인다. 8칸, BPM 에 비례해 앞칸부터 금색.
   휴대폰(≤640px)에서는 숨겨 글자가 세로로 쪼개지지 않게 한다. */
.jz-tempo { display: inline-flex; gap: 2px; align-items: flex-end; height: 18px; vertical-align: middle; }
.jz-tempo i { display: block; width: 3px; border-radius: 9999px; background: var(--border); }
.jz-tempo i.on { background: var(--primary); }
@media (max-width: 640px) {
  .jz-tempo { display: none; }
}

/* 대시보드 KPI 카드 — border-l-4 없이 큰 숫자(Display) + 이름(Headline). 두 대시보드가 같은 클래스를 쓴다(Gate 2). */
.jz-kpi { display: grid; gap: 2px; align-content: start; }
.jz-kpi-label { font-size: 0.76rem; color: var(--muted-foreground); }
.jz-kpi-num {
  font-family: var(--font-display);
  font-weight: 400;
  font-synthesis: none;
  font-size: 2rem;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
  color: var(--foreground);
}
.jz-kpi-num .jz-kpi-unit { font-family: var(--font-body); font-size: 0.8rem; color: var(--muted-foreground); margin-left: 0.25rem; }
.jz-kpi-who { font-family: var(--font-head); font-size: 0.98rem; }
.jz-kpi.is-rest .jz-kpi-num { color: var(--muted-foreground); font-size: 1.3rem; letter-spacing: 0.08em; }

/* 빈 차트 상자 — 높이를 줄인 쉬는 박자 블록(큰 캔버스 자리 대체) */
/* 이미 .shadcn-card 안에 들어가므로 중첩 테두리를 만들지 않도록 테두리·바탕 제거 */
.jz-rest-chart { min-height: 0; padding: 1rem 1.25rem; border: none; background: transparent; }

/* 모바일: 하단 고정 챗봇 버블이 본문 마지막 내용(버튼 등)을 가리지 않도록 여유 공간 확보.
   menu.php 를 포함하는 페이지들이 공통으로 쓰는 본문 래퍼(.max-w-screen-xl.mx-auto.py-6)에 적용 —
   데스크톱(>640px)은 영향 없음 */
@media (max-width: 640px) {
  .max-w-screen-xl.mx-auto.py-6 { padding-bottom: 88px; }
}

/* ── 모바일 보정(2026-10-02 전 화면 점검 결과) ─────────────────────────────
   1) 휴대폰(≤640px)에서 입력·선택칸 글자가 16px 보다 작으면 iOS Safari 가 포커스 때 화면을 확대한다
      — 입력류만 16px 로(데스크톱은 기존 0.875rem 유지)
   2) 터치 기기(pointer:coarse)에서 표 페이지 버튼·열 보기 링크를 44px 터치 영역으로
      (player.css .jp-row-play, dj-result-edit.css 와 같은 기준)
   3) 너무 작은 보조 글자(0.7~0.74rem)를 12px(0.75rem) 하한으로 */
@media (max-width: 640px) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]),
  select, textarea,
  .shadcn-input, .shadcn-select,
  .dataTables_wrapper .dataTables_filter input,
  .dataTables_wrapper .dataTables_length select {
    font-size: 16px !important;
  }
}
@media (pointer: coarse) {
  .dataTables_wrapper .dataTables_paginate .paginate_button {
    min-width: 44px; min-height: 44px;
    display: inline-flex; align-items: center; justify-content: center;
  }
  a.toggle-vis {
    display: inline-flex; align-items: center; min-height: 44px; padding: 0 0.5rem;
  }
}
.jz-ph-section { font-size: 0.75rem; }
.jz-ticket-stub .jz-ticket-mon,
.jz-ticket-stub .jz-ticket-yr { font-size: 0.75rem; }
@media (pointer: coarse) {
  .app-sidebar-link { min-height: 44px; }
}
/* DataTables Responsive 펼치기(+/-) 아이콘 — 라이브러리 기본 초록/빨강 대신 테마 토큰 */
table.dataTable.dtr-column > tbody > tr > td.dtr-control:before,
table.dataTable.dtr-column > tbody > tr > th.dtr-control:before,
table.dataTable.dtr-inline.collapsed > tbody > tr > td.dtr-control:before {
  background-color: var(--primary) !important;
  color: var(--primary-foreground) !important;
  border-color: var(--background) !important;
  box-shadow: none !important;
}
table.dataTable.dtr-column > tbody > tr.parent > td.dtr-control:before,
table.dataTable.dtr-inline.collapsed > tbody > tr.parent > td.dtr-control:before {
  background-color: var(--muted-foreground) !important;
}
.jz-ticket-part, .jz-ticket-rec, .jz-ticket-tag { font-size: 0.75rem; }
.jz-ticket-stub .jz-ticket-part { font-size: 0.75rem; }

/* NAS 장애 — 복제본 읽기 전용 띠(menu.php). 화면 위 고정: 데스크톱은 사이드바 오른쪽, 모바일은 상단바 아래.
   본문은 띠 높이만큼 더 내린다(menu.php 를 body 끝에서 include 하는 화면이 있어 고정 배치).
   대비: 라이트 #fff/#b42318 약 6.5:1, 다크 #1b0a0a/#e5484d 약 4.9:1 (AA) */
:root { --ro-banner-height: 2.5rem; }
.jz-ro-banner {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 45;
  height: var(--ro-banner-height);
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: 0 1rem;
  background-color: var(--destructive);
  color: var(--destructive-foreground);
  font-size: .875rem;
}
.jz-ro-banner i { flex-shrink: 0; }
.jz-ro-banner span { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
body:has(.jz-ro-banner) { padding-top: var(--ro-banner-height); }
/* 띠가 있을 때 화면 위에서 더 비워야 할 높이 — 고정·sticky 요소가 top·높이 계산에 var(--ro-offset, 0px) 로 더하거나 뺀다
   (set-workbench.css .sw-chat, player.css .jtc). 띠가 없으면 정의되지 않아 0px */
body:has(.jz-ro-banner) { --ro-offset: var(--ro-banner-height); }
@media (min-width: 768px) {
  .jz-ro-banner { left: var(--sidebar-width); }
}
@media (max-width: 767px) {
  .jz-ro-banner { top: var(--topbar-height); }
  body:has(.jz-ro-banner) { padding-top: calc(var(--topbar-height) + var(--ro-banner-height)); }
}
