/* theme.css - the admin portal's color tokens, one block per theme.
 *
 * The theme is the data-theme attribute on <html>, set before first paint by theme.js from the
 * browser's saved choice. Colors are stored as space-separated sRGB channels so Tailwind's
 * opacity modifiers keep working: theme.js maps them as rgb(var(--color-x) / <alpha-value>), and
 * markup says bg-surface, text-muted, border-default, bg-primary, ring-focus ...
 * Outside Tailwind, use rgb(var(--color-x)) or rgb(var(--color-x) / 0.5).
 *
 * Themes: light-harbor (default), light-dusk, dark-ios, dark-pwa.
 * Names follow the PWA's token set (pwa/src/assets/main.css) where one exists there.
 * Every theme defines every token; theme.test.js checks that, and the AA contrast of each
 * text/background pair. A later "custom accent" only has to override the primary group.
 */

/* ---------- Light (Harbor), the default. Sampled from images/long-banner.png. Navy #15194B chrome (sidebar), blue #186DAD buttons, the lettering's orange #FF6206 marks where you are; mist-blue work area. No white page, no indigo (Daniel, 2026-11-11). ---------- */
:root,
[data-theme="light-harbor"] {
  color-scheme: light;

  --color-background: 226 233 241;
  --color-surface: 243 246 250;
  --color-surface-soft: 232 238 245;
  --color-surface-hover: 217 225 234;
  --color-control: 208 218 230;   /* quiet button and text-field fill (no outline) */
  --color-control-hover: 196 207 221;
  --color-border: 204 214 226;
  --color-border-strong: 127 142 163;
  --color-overlay: 12 22 42;
  --color-text-primary: 16 28 48;
  --color-text-secondary: 44 58 80;
  --color-text-subtle: 70 86 108;
  --color-primary: 24 109 173;
  --color-primary-hover: 19 91 147;
  --color-on-primary: 255 255 255;
  --color-primary-soft: 212 229 243;
  --color-primary-text: 16 82 136;
  --color-primary-border: 150 190 222;
  --color-nav-active: 24 109 173;
  --color-on-nav-active: 255 255 255;
  --color-focus: 20 96 154;

  --color-accent: 24 109 173;   /* the brand tint: progress, toggles, unread dots, checkboxes, selection */
  --color-on-accent: 255 255 255;

  --color-on-status: 255 255 255;
  --color-danger: 200 30 30;
  --color-danger-soft: 250 228 226;
  --color-danger-text: 172 24 24;
  --color-danger-border: 240 180 180;
  --color-success: 21 128 61;
  --color-success-soft: 222 242 229;
  --color-success-text: 22 101 52;
  --color-success-border: 150 215 175;
  --color-warning: 170 78 8;
  --color-warning-soft: 250 238 205;
  --color-warning-text: 140 60 12;
  --color-warning-border: 235 200 110;
  --color-info: 3 105 161;
  --color-info-soft: 219 234 247;
  --color-info-text: 7 89 133;
  --color-info-border: 150 205 235;

  --radius-md: 0.375rem;
  --radius-lg: 0.5rem;
  --radius-xl: 0.75rem;
  --font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

/* Harbor's sidebar: the same tokens, re-valued for navy chrome. Everything inside it follows. */
:root:not([data-theme]) #sidebar,
[data-theme="light-harbor"] #sidebar {
  color-scheme: dark;
  --color-control: 32 38 102;
  --color-control-hover: 44 52 126;
  --color-accent: 255 98 6;
  --color-on-accent: 31 10 0;
  --color-background: 15 18 58;
  --color-surface: 21 25 75;
  --color-surface-soft: 30 35 96;
  --color-surface-hover: 42 48 120;
  --color-border: 44 50 118;
  --color-border-strong: 127 147 181;
  --color-text-primary: 255 255 255;
  --color-text-secondary: 213 222 236;
  --color-text-subtle: 169 183 205;
  --color-primary-soft: 42 48 120;
  --color-primary-text: 255 160 110;
  --color-primary-border: 70 78 160;
  --color-nav-active: 255 98 6;
  --color-on-nav-active: 31 10 0;
  --color-focus: 255 98 6;
  --color-info-soft: 28 47 82;
  --color-info-text: 140 205 245;
  --color-danger-soft: 72 30 52;
  --color-danger-text: 255 160 150;
  --color-success-soft: 24 60 72;
  --color-success-text: 120 225 160;
  --color-warning-soft: 72 56 44;
  --color-warning-text: 250 204 96;
}

/* ---------- Light (Dusk): a mid-tone, between the app's black and a white page; the banner lettering's orange #FF6206 with dark text on it (white on it is 3:1). ---------- */
[data-theme="light-dusk"] {
  color-scheme: light;

  --color-background: 197 206 216;
  --color-surface: 219 226 234;
  --color-surface-soft: 207 216 225;
  --color-surface-hover: 193 203 214;
  --color-control: 181 192 205;   /* quiet button and text-field fill (no outline) */
  --color-control-hover: 170 182 196;
  --color-border: 176 188 201;
  --color-border-strong: 101 115 132;
  --color-overlay: 10 16 26;
  --color-text-primary: 14 22 34;
  --color-text-secondary: 34 46 60;
  --color-text-subtle: 56 68 84;
  --color-primary: 255 98 6;
  --color-primary-hover: 232 85 0;
  --color-on-primary: 31 10 0;
  --color-primary-soft: 236 214 198;
  --color-primary-text: 120 42 6;
  --color-primary-border: 205 150 115;
  --color-nav-active: 255 98 6;
  --color-on-nav-active: 31 10 0;
  --color-focus: 150 56 10;

  --color-accent: 168 65 13;   /* the brand tint: progress, toggles, unread dots, checkboxes, selection */
  --color-on-accent: 255 255 255;

  --color-on-status: 255 255 255;
  --color-danger: 200 30 30;
  --color-danger-soft: 240 210 206;
  --color-danger-text: 172 24 24;
  --color-danger-border: 214 150 150;
  --color-success: 21 128 61;
  --color-success-soft: 205 228 212;
  --color-success-text: 22 101 52;
  --color-success-border: 130 190 155;
  --color-warning: 170 78 8;
  --color-warning-soft: 240 224 180;
  --color-warning-text: 140 60 12;
  --color-warning-border: 205 170 90;
  --color-info: 3 105 161;
  --color-info-soft: 200 220 238;
  --color-info-text: 7 89 133;
  --color-info-border: 125 180 215;

  --radius-md: 0.375rem;
  --radius-lg: 0.5rem;
  --radius-xl: 0.75rem;
  --font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

/* ---------- Dark, iOS style: the native app. Black page, gray grouped cards, gray capsule buttons;
   orange is only ever a tint (labels, icons, the selected item), never a fill or a brown wash. ---------- */
[data-theme="dark-ios"] {
  color-scheme: dark;

  --color-background: 0 0 0;            /* systemBackground */
  --color-surface: 28 28 30;            /* secondarySystemBackground / systemGray6 */
  --color-surface-soft: 44 44 46;       /* tertiarySystemBackground / systemGray5 */
  --color-surface-hover: 58 58 60;      /* systemGray4 */
  --color-control: 50 50 54;   /* quiet button and text-field fill (no outline) */
  --color-control-hover: 58 58 62;
  --color-border: 56 56 58;             /* separator */
  --color-border-strong: 124 124 128;   /* toward systemGray, 3:1 on the surface */
  --color-overlay: 0 0 0;

  --color-text-primary: 255 255 255;    /* label */
  --color-text-secondary: 209 209 214;
  --color-text-subtle: 164 164 171;     /* secondaryLabel, lifted to pass AA on systemGray5 */

  --color-primary: 58 58 60;   /* button fill: a gray capsule, as in the app (systemGray4) */
  --color-primary-hover: 66 66 68;
  --color-on-primary: 255 153 51;   /* ...with the tint as its label. AccentColor.colorset: sRGB 1.0 0.6 0.2 */
  --color-primary-soft: 44 44 46;   /* neutral fill; the app has no brown tints */
  --color-primary-text: 255 153 51;
  --color-primary-border: 58 58 60;
  --color-nav-active: 44 44 46;   /* gray pill, orange label: the app's selected tab */
  --color-on-nav-active: 255 153 51;
  --color-focus: 255 153 51;

  --color-accent: 255 153 51;   /* the brand tint: progress, toggles, unread dots, checkboxes, selection */
  --color-on-accent: 31 18 0;

  --color-on-status: 255 255 255;
  --color-danger: 200 40 31;
  --color-danger-soft: 64 35 34;
  --color-danger-text: 255 105 97;      /* systemRed (dark), lifted for small text */
  --color-danger-border: 122 46 41;
  --color-success: 26 127 55;
  --color-success-soft: 31 57 39;
  --color-success-text: 48 209 88;      /* systemGreen (dark) */
  --color-success-border: 31 107 58;
  --color-warning: 154 103 0;
  --color-warning-soft: 64 55 27;
  --color-warning-text: 255 214 10;     /* systemYellow (dark) */
  --color-warning-border: 122 106 20;
  --color-info: 0 108 214;
  --color-info-soft: 40 57 66;
  --color-info-text: 100 210 255;       /* systemCyan (dark) */
  --color-info-border: 47 111 138;

  --radius-md: 0.75rem;                 /* the app's capsule buttons and big grouped cards */
  --radius-lg: 1rem;
  --radius-xl: 1.5rem;
  --font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", system-ui, sans-serif;
}

/* ---------- Dark, PWA style: pwa/src/assets/main.css body.dark-theme (slate text, indigo, sky) ---------- */
[data-theme="dark-pwa"] {
  color-scheme: dark;

  --color-background: 0 0 0;            /* --color-background */
  --color-surface: 28 28 30;            /* --color-surface */
  --color-surface-soft: 44 44 46;       /* --color-surface-soft */
  --color-surface-hover: 46 54 69;      /* toward slate-700 */
  --color-control: 40 44 52;   /* quiet button and text-field fill (no outline) */
  --color-control-hover: 46 54 69;
  --color-border: 51 65 85;             /* --color-border: slate-700 */
  --color-border-strong: 100 116 139;   /* slate-500, 3:1 on the surface */
  --color-overlay: 2 6 23;

  --color-text-primary: 226 232 240;    /* --color-text-primary: slate-200 */
  --color-text-secondary: 203 213 225;  /* slate-300 */
  --color-text-subtle: 148 163 184;     /* --color-text-secondary: slate-400 */

  --color-primary: 79 70 229;           /* --color-primary: indigo-600 */
  --color-primary-hover: 67 56 202;
  --color-on-primary: 255 255 255;
  --color-primary-soft: 49 46 129;      /* indigo-900, as the PWA's tag background family */
  --color-primary-text: 165 180 252;    /* --color-tag-text: indigo-300 */
  --color-primary-border: 67 56 202;
  --color-nav-active: 79 70 229;
  --color-on-nav-active: 255 255 255;
  --color-focus: 125 211 252;           /* the PWA's sky tint (practice and PDF tools) */

  --color-accent: 129 140 248;   /* the brand tint: progress, toggles, unread dots, checkboxes, selection */
  --color-on-accent: 20 18 70;

  --color-on-status: 255 255 255;
  --color-danger: 220 38 38;
  --color-danger-soft: 59 29 31;
  --color-danger-text: 252 165 165;
  --color-danger-border: 127 29 29;
  --color-success: 21 128 61;
  --color-success-soft: 23 50 36;
  --color-success-text: 74 222 128;
  --color-success-border: 22 101 52;
  --color-warning: 180 83 9;
  --color-warning-soft: 58 46 18;
  --color-warning-text: 251 191 36;     /* amber: the PWA's accent family */
  --color-warning-border: 124 90 16;
  --color-info: 3 105 161;
  --color-info-soft: 18 48 61;
  --color-info-text: 125 211 252;
  --color-info-border: 14 116 144;

  --radius-md: 0.5rem;                  /* --border-radius-md: 8px */
  --radius-lg: 0.5rem;
  --radius-xl: 1rem;                    /* --border-radius-lg: 16px */
  --font-sans: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
}

/* ---------- What the browser draws itself ---------- */
html {
  font-family: var(--font-sans);
  accent-color: rgb(var(--color-accent));
  scrollbar-color: rgb(var(--color-border-strong)) transparent;
}

::selection {
  background: rgb(var(--color-accent) / 0.3);
  color: rgb(var(--color-text-primary));
}

/* Keyboard focus is always visible, including on controls that never asked for a ring. */
:focus-visible {
  outline: 2px solid rgb(var(--color-focus));
  outline-offset: 2px;
}

/* Text fields follow the theme without each one naming a background. :where() keeps this at zero
   specificity, so any utility on the element still wins. */
:where(input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="color"]):not([type="submit"]):not([type="button"]), select, textarea) {
  background-color: rgb(var(--color-surface));
  color: rgb(var(--color-text-primary));
}
::placeholder {
  color: rgb(var(--color-text-subtle));
  opacity: 1;
}

/* ---------- Shell pieces that are not Tailwind classes ---------- */
#auth-loader {
  background: rgb(var(--color-background));
  color: rgb(var(--color-text-secondary));
}

/* Toasts (dashboard.js showToast): data-type picks the status group. */
.portal-toast {
  padding: 0.75rem 1rem;
  border-radius: var(--radius-lg);
  font-size: 0.875rem;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.2s ease;
  border: 1px solid rgb(var(--color-info-border));
  background: rgb(var(--color-info-soft));
  color: rgb(var(--color-info-text));
  box-shadow: 0 4px 12px -2px rgb(0 0 0 / 0.18);
}
.portal-toast[data-type="success"] {
  border-color: rgb(var(--color-success-border));
  background: rgb(var(--color-success-soft));
  color: rgb(var(--color-success-text));
}
.portal-toast[data-type="error"] {
  border-color: rgb(var(--color-danger-border));
  background: rgb(var(--color-danger-soft));
  color: rgb(var(--color-danger-text));
}
.portal-toast[data-type="warning"] {
  border-color: rgb(var(--color-warning-border));
  background: rgb(var(--color-warning-soft));
  color: rgb(var(--color-warning-text));
}

/* Theme picker swatch: a chip painted with the tokens of the theme named on the chip itself. */
.theme-swatch {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  flex: none;
  width: 2.25rem;
  height: 1.5rem;
  padding: 0 0.3rem;
  border-radius: 0.375rem;
  background: rgb(var(--color-background));
  border: 1px solid rgb(var(--color-border-strong));
  box-shadow: inset 0.85rem 0 0 rgb(var(--color-surface));
}
.theme-swatch::after {
  content: "";
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 9999px;
  background: rgb(var(--color-accent));
}

/* Upload / Collection Mode call to action: a primary button with a waveform drawn along its
   bottom edge. (Was three copies of a neon cyan-and-purple rule in dashboard.html, upload.html and
   the music-tab partial.) */
@keyframes wavy-line {
  from { -webkit-mask-position: 0 bottom; mask-position: 0 bottom; }
  to { -webkit-mask-position: -390px bottom; mask-position: -390px bottom; }
}
.animated-wavy-button {
  position: relative;
  overflow: hidden;
  background-color: rgb(var(--color-primary));
  border: 1.5px solid rgb(var(--color-primary));
  color: rgb(var(--color-on-primary));
  transition: background-color 0.2s ease;
}
.animated-wavy-button:hover {
  background-color: rgb(var(--color-primary-hover));
}
.animated-wavy-button::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: rgb(var(--color-on-primary) / 0.6);
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='390' height='50' viewBox='0 0 390 50'><path fill='none' stroke='black' stroke-width='1.5' stroke-miterlimit='10' d='M0,47.585c0,0,97.5,0,130,0 c13.75,0,28.74-38.778,46.168-19.416C192.669,46.5,243.603,47.585,260,47.585c31.821,0,130,0,130,0'/></svg>") no-repeat 0 bottom;
  mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='390' height='50' viewBox='0 0 390 50'><path fill='none' stroke='black' stroke-width='1.5' stroke-miterlimit='10' d='M0,47.585c0,0,97.5,0,130,0 c13.75,0,28.74-38.778,46.168-19.416C192.669,46.5,243.603,47.585,260,47.585c31.821,0,130,0,130,0'/></svg>") no-repeat 0 bottom;
  animation: wavy-line 1s forwards;
}
@media (prefers-reduced-motion: reduce) {
  .animated-wavy-button::after { animation: none; }
}

/* FullCalendar (events partial) reads its skin from these variables. Event colors are per-choir
   content and are not themed. */
.fc {
  --fc-border-color: rgb(var(--color-border));
  --fc-page-bg-color: rgb(var(--color-surface));
  --fc-neutral-bg-color: rgb(var(--color-surface-soft));
  --fc-neutral-text-color: rgb(var(--color-text-subtle));
  --fc-today-bg-color: rgb(var(--color-primary-soft));
  --fc-highlight-color: rgb(var(--color-accent) / 0.15);
  --fc-list-event-hover-bg-color: rgb(var(--color-surface-hover));
  /* Toolbar buttons are quiet filled controls, like ui-btn; the page's one filled button is Add Event. */
  --fc-button-text-color: rgb(var(--color-text-primary));
  --fc-button-bg-color: rgb(var(--color-control));
  --fc-button-border-color: transparent;
  --fc-button-hover-bg-color: rgb(var(--color-control-hover));
  --fc-button-hover-border-color: transparent;
  --fc-button-active-bg-color: rgb(var(--color-control-hover));
  --fc-button-active-border-color: transparent;
}
.fc .fc-button { font-size: 0.875rem; font-weight: 600; border-radius: var(--radius-lg); box-shadow: none !important; }
.fc .fc-button:disabled { opacity: 0.45; }
.fc .fc-toolbar-title { font-size: 1.25rem; font-weight: 700; color: rgb(var(--color-text-primary)); }
.fc .fc-col-header-cell-cushion { font-size: 0.8125rem; font-weight: 600; color: rgb(var(--color-text-subtle)); }

/* ====================================================================================
 * Components. The weight of the UI lives here, so it is tuned in one place: quiet filled
 * controls with no outlines, borderless cards, plain-case table headers, roomy rows.
 * Tailwind utilities on the same element still win (they are injected after this file).
 * Pages move onto these as they get their layout pass; the whole dashboard and the standalone director pages use them.
 * ==================================================================================== */
.ui-page-title { font-size: 1.75rem; line-height: 2.125rem; font-weight: 700; letter-spacing: -0.015em; color: rgb(var(--color-text-primary)); text-wrap: balance; }
.ui-section-title { font-size: 0.9375rem; line-height: 1.25rem; font-weight: 700; color: rgb(var(--color-text-subtle)); }
.ui-card { background: rgb(var(--color-surface)); border-radius: var(--radius-xl); }
.ui-label { display: block; margin-bottom: 0.375rem; font-size: 0.8125rem; line-height: 1.125rem; font-weight: 600; color: rgb(var(--color-text-subtle)); }

.ui-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  padding: 0.5rem 0.875rem; border: 0; border-radius: var(--radius-lg);
  font-size: 0.875rem; line-height: 1.25rem; font-weight: 600; white-space: nowrap;
  background: rgb(var(--color-control)); color: rgb(var(--color-text-primary));
  transition: background-color 0.15s ease, filter 0.15s ease;
}
.ui-btn:hover { background: rgb(var(--color-control-hover)); }
.ui-btn:disabled { opacity: 0.45; cursor: not-allowed; }
.ui-btn.hidden { display: none; }
.ui-btn-sm { padding: 0.3125rem 0.625rem; font-size: 0.8125rem; }
.ui-btn-primary { background: rgb(var(--color-primary)); color: rgb(var(--color-on-primary)); }
.ui-btn-primary:hover { background: rgb(var(--color-primary-hover)); }
.ui-btn-danger { background: rgb(var(--color-danger-soft)); color: rgb(var(--color-danger-text)); }
.ui-btn-warning { background: rgb(var(--color-warning-soft)); color: rgb(var(--color-warning-text)); }
.ui-btn-success { background: rgb(var(--color-success-soft)); color: rgb(var(--color-success-text)); }
.ui-btn-danger-solid { background: rgb(var(--color-danger)); color: rgb(var(--color-on-status)); }
.ui-btn-danger:hover, .ui-btn-warning:hover, .ui-btn-success:hover, .ui-btn-danger-solid:hover { filter: brightness(0.93) saturate(1.15); }
.ui-btn-danger:hover { background: rgb(var(--color-danger-soft)); }
.ui-btn-warning:hover { background: rgb(var(--color-warning-soft)); }
.ui-btn-success:hover { background: rgb(var(--color-success-soft)); }
.ui-btn-danger-solid:hover { background: rgb(var(--color-danger)); }

/* Text-style action (table rows, inline links). */
.ui-link { border-radius: 0.25rem; font-weight: 600; color: rgb(var(--color-primary-text)); }
.ui-link:hover { text-decoration: underline; text-underline-offset: 3px; }
.ui-link-danger { color: rgb(var(--color-danger-text)); }

.ui-field {
  width: 100%; padding: 0.5rem 0.75rem; border: 1px solid transparent; border-radius: var(--radius-md);
  font-size: 0.9375rem; line-height: 1.375rem;
  background: rgb(var(--color-control)); color: rgb(var(--color-text-primary));
}
.ui-field:hover { background: rgb(var(--color-control-hover)); }
.ui-field:focus { outline: 2px solid rgb(var(--color-focus)); outline-offset: 0; background: rgb(var(--color-control)); }
.ui-field[readonly], .ui-field:disabled { color: rgb(var(--color-text-subtle)); }
.ui-field[readonly]:hover { background: rgb(var(--color-control)); }

.ui-table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.ui-table th { padding: 0.75rem 0.875rem; text-align: left; font-size: 0.8125rem; line-height: 1.125rem; font-weight: 600; white-space: nowrap; color: rgb(var(--color-text-subtle)); background: rgb(var(--color-surface)); }
.ui-table td { padding: 0.8125rem 0.875rem; font-size: 0.9375rem; line-height: 1.375rem; }
.ui-table tbody tr { border-top: 1px solid rgb(var(--color-border)); }
.ui-table tbody tr:hover { background: rgb(var(--color-control) / 0.6); }
/* Approvals: a submission's text wants 28rem before it shares its row with the buttons. */
.approval-card-text { flex: 1 1 28rem; min-width: 0; }
/* A denser table for long lists with controls in the rows (Permissions). */
.ui-table-compact td { padding-top: 0.3125rem; padding-bottom: 0.3125rem; vertical-align: middle; }
.ui-table-compact th { padding-top: 0.5rem; padding-bottom: 0.5rem; }

/* Drop target for files: a dashed hairline that fills quietly on hover and while a file is over it. */
.ui-dropzone { border: 1px dashed rgb(var(--color-border-strong)); border-radius: var(--radius-xl); padding: 2rem 1.5rem; text-align: center; transition: background-color 0.15s ease, border-color 0.15s ease; }
.ui-dropzone:hover, .ui-dropzone.dragover { background: rgb(var(--color-control)); }
.ui-dropzone.dragover { border-color: rgb(var(--color-accent)); }

/* Small pill for a state word beside a name (Primary, Marked, Archived). Status color comes from utilities. */
.ui-badge { display: inline-flex; align-items: center; gap: 0.25rem; flex: none; padding: 0.125rem 0.5rem; border-radius: 9999px; font-size: 0.75rem; line-height: 1rem; font-weight: 600; white-space: nowrap; background: rgb(var(--color-control)); color: rgb(var(--color-text-secondary)); }

/* Dialog pieces, so every modal has the same quiet frame. */
.ui-modal { background: rgb(var(--color-surface)); border-radius: var(--radius-xl); box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.35); }
.ui-modal-title { font-size: 1.25rem; line-height: 1.75rem; font-weight: 600; color: rgb(var(--color-text-primary)); }
.ui-modal-close { border-radius: 0.25rem; font-size: 1.5rem; line-height: 1; color: rgb(var(--color-text-subtle)); }
.ui-modal-close:hover { color: rgb(var(--color-text-primary)); }

/* Drag-and-drop song lists (Curate Event, Manage Music Tab). The scripts toggle these state classes. */
.music-item { cursor: grab; }
.music-item.custom-selected { background: rgb(var(--color-primary-soft)); }
.music-item.fade-out-and-remove { opacity: 0; transition: opacity 0.3s ease; }
.song-slot.dragover, #song-list-simple.dragover, #collect-zone.dragover { border-color: rgb(var(--color-accent)); background: rgb(var(--color-control)); }
#collect-zone.dragover { border-color: rgb(var(--color-danger-text)); background: rgb(var(--color-danger-soft)); filter: brightness(0.95) saturate(1.2); }
.song-slot.slot-populated { border-style: solid; border-color: transparent; background: rgb(var(--color-control)); }
.song-display, .simple-list-item { display: flex; align-items: center; gap: 0.5rem; }
.song-display > .remove-song-btn, .simple-list-item > .remove-song-btn { margin-left: auto; }
.simple-list-item { padding: 0.625rem 0.75rem; border-radius: var(--radius-lg); background: rgb(var(--color-control)); cursor: grab; }
.simple-list-item.dragging { opacity: 0.4; }
.drag-placeholder { height: 2.75rem; border: 1px dashed rgb(var(--color-accent)); border-radius: var(--radius-lg); }
.remove-song-btn { flex: none; padding: 0 0.375rem; border-radius: 0.25rem; font-size: 1.25rem; line-height: 1.5rem; color: rgb(var(--color-text-subtle)); }
.remove-song-btn:hover { color: rgb(var(--color-danger-text)); }
.sortable-ghost { opacity: 0.4; }

/* Manage Music Tab only (`.music-tab-page`). Touch handling ported from the old portal (f00f7b5):
   rows are picked up by the handle, text is not selected mid-drag, a bar shows where the song will land. */
.music-tab-page .music-item { cursor: default; gap: 0.5rem; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; transition: background-color 0.2s ease, box-shadow 0.15s ease; }
.music-tab-page .song-title { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; }
.music-tab-page #music-library-list, .music-tab-page #song-list-container, .music-tab-page #collect-zone { touch-action: pan-y; -webkit-overflow-scrolling: touch; }
.music-tab-page .drag-handle { flex: none; display: flex; align-items: center; justify-content: center; padding: 0.25rem; border-radius: 0.25rem; cursor: grab; touch-action: none; color: rgb(var(--color-text-subtle)); }
.music-tab-page .drag-handle:hover { color: rgb(var(--color-text-primary)); }
.music-tab-page .drag-handle:active { cursor: grabbing; color: rgb(var(--color-accent)); }
.music-tab-page .music-item button, .music-tab-page .music-item input[type="checkbox"] { position: relative; z-index: 1; }
.music-tab-page #song-list-container.dragover { border-color: rgb(var(--color-accent)); background: rgb(var(--color-control)); }
/* The row in hand, and the bar that marks where it will land. */
.music-tab-page .sortable-chosen { box-shadow: 0 0 0 2px rgb(var(--color-accent)); }
.music-tab-page .sortable-fallback { opacity: 0.95 !important; transform: rotate(1.5deg); box-shadow: 0 0 0 2px rgb(var(--color-accent)), 0 12px 32px rgb(0 0 0 / 0.25) !important; }
.music-tab-page .sortable-ghost { opacity: 1; height: 4px !important; min-height: 4px !important; padding: 0 !important; margin: 0.5rem 0 !important; overflow: hidden; border-radius: 2px; background: rgb(var(--color-accent)) !important; box-shadow: none; }
.music-tab-page .sortable-ghost * { display: none !important; }
/* A finger needs 44px (Apple's minimum); a mouse does not. */
@media (hover: none) and (pointer: coarse) {
  .music-tab-page .drag-handle { min-width: 44px; min-height: 44px; margin: -0.375rem; }
  .music-tab-page .music-library-actions button, .music-tab-page .remove-song-btn { min-width: 44px; min-height: 44px; justify-content: center; }
}
/* Keep paired actions on one line; stacked touch targets doubled row height. */
.music-tab-page.narrow-library .music-library-actions { flex-direction: row; gap: 0.125rem; }
.music-tab-page.narrow-library #music-library-list .music-item { padding-left: 0.5rem; padding-right: 0.5rem; }
.music-tab-page.narrow-library #music-library-list .music-item input[type="checkbox"] { margin-right: 0.25rem; }
/* Collection mode: the zone sits beside the list, or as a strip above it when the column is narrow. */
.music-tab-page #right-panel-grid.collecting { grid-template-columns: minmax(0, 1fr) 11rem; gap: 1rem; align-items: end; }
.music-tab-page.narrow-list #right-panel-grid.collecting { grid-template-columns: minmax(0, 1fr); }
.music-tab-page.narrow-list #right-panel-grid.collecting #collect-column { order: -1; }
.music-tab-page.narrow-list #right-panel-grid.collecting #collect-zone { height: 6rem; }
.music-tab-page.narrow-list #right-panel-grid.collecting #song-list-container { height: calc(60vh - 9.5rem); min-height: 12rem; }
/* The round count on the floating "Add Selected" button. */
.add-selected-count { display: inline-flex; align-items: center; justify-content: center; min-width: 1.5rem; height: 1.5rem; padding: 0 0.375rem; border-radius: 9999px; font-size: 0.8125rem; font-weight: 700; background: rgb(var(--color-on-primary)); color: rgb(var(--color-primary)); }
