/*
  Layout animation styles — applied globally to both desktop and mobile.

  Strategy: give specific elements a CSS transition + @starting-style so
  they animate when shown/hidden by JS. We NEVER override .hidden (display:none)
  or touch anything that has its own animation or must not move.
*/

/* ── Shared enter/exit transition ─────────────────────────────────────────
   Every element listed here gets an opacity+transform transition.
   @starting-style defines the "from" state when the element first becomes
   visible (either .hidden removed, display changed, or added to DOM).
   transition-behavior: allow-discrete lets the browser run the transition
   even when display is changing.
*/

/* manage.ejs — daemon warning */
#daemonOfflineWarning,
#daemonOfflineWarningRow,

/* manage.ejs — install banner */
#installBanner,

/* manage.ejs — server page body and stats cards */
#server-page-body,
.console-wrap,

/* dashboard — folder popup, new folder dialog */
.folder-popup-overlay .folder-popup,
.dialog-overlay .dialog-box,

/* overview.ejs — update check results */
#updateStatus,
#performUpdateBtn,
#updateInfo,

/* servers.ejs — radar modal phases and scan mode toggle */
#scanModeToggle,
#builtinPickerSection,
#vtScanSection,
#radarPickerPhase,
#radarResultsPhase,
#radarRescanBtn,
#radarScanModal,
#radarServerTabs,
#radarSummaryBar,
#radarResultsBody,

/* files.ejs — upload zone / preview swap, path hint */
#filePreview,
#dropZone,
#fileNamePreview,
#renamePreview,

/* apikeys.ejs — create modal, panel accordion */
#createApiKeyModal,

/* apikeys/docs.ejs — response panel */
#responseContainer,

/* template.ejs — search dropdown */
#searchResults,

/* sftp.ejs — sftp state panels */
#sftpLoading,
#sftpError,
#sftpCredentials,

/* store.ejs / addons — loading/grid/empty/error states */
#storeLoading,
#storeGrid,
#storeEmpty,
#storeError,

/* analytics.ejs — chart loading state */
#chartLoading,
#chartContainer,

/* analytics.ejs — player details modal */
#serverDetailsModal,

/* create server — variables section */
#variablesSection,

/* worlds.ejs — table / empty message */
#serverTable,
#noWorldsMessage,

/* serverHeader.ejs — uptime container */
[data-server-started-container],

/* account.ejs — inline feedback */
#username-feedback,
#current-password-feedback,

/* loading-state.ejs / error-state.ejs */
#loading-state,
#error-state,

/* tab panels (analytics, addons store, apikeys docs) */
.tab-content,
.m-pane {
  transition:
    opacity   0.38s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.38s cubic-bezier(0.16, 1, 0.3, 1);
  transition-behavior: allow-discrete;
}

/* Enter state — what the element looks like the instant it becomes visible */
@starting-style {
  #daemonOfflineWarning,
  #daemonOfflineWarningRow,
  #installBanner,
  #server-page-body,
  .console-wrap,
  .folder-popup-overlay .folder-popup,
  .dialog-overlay .dialog-box,
  #updateStatus,
  #performUpdateBtn,
  #updateInfo,
  #scanModeToggle,
  #builtinPickerSection,
  #vtScanSection,
  #radarPickerPhase,
  #radarResultsPhase,
  #radarRescanBtn,
  #radarScanModal,
  #radarServerTabs,
  #radarSummaryBar,
  #radarResultsBody,
  #filePreview,
  #dropZone,
  #fileNamePreview,
  #renamePreview,
  #createApiKeyModal,
  #responseContainer,
  #searchResults,
  #sftpLoading,
  #sftpError,
  #sftpCredentials,
  #storeLoading,
  #storeGrid,
  #storeEmpty,
  #storeError,
  #chartLoading,
  #chartContainer,
  #serverDetailsModal,
  #variablesSection,
  #serverTable,
  #noWorldsMessage,
  [data-server-started-container],
  #username-feedback,
  #current-password-feedback,
  #loading-state,
  #error-state,
  .tab-content,
  .m-pane {
    opacity: 0;
    transform: translateY(10px);
  }
}

/* ── Page-content children — layout shift transitions ─────────────────────
   When a warning banner or section appears/disappears, sibling elements
   below it need to shift position smoothly. This transition lets the
   JS FLIP in layout-animations.js animate them.
*/

#page-content > *,
#server-page-body > * {
  transition:
    transform 0.36s cubic-bezier(0.4, 0, 0.2, 1),
    opacity   0.36s cubic-bezier(0.16, 1, 0.3, 1);
}

/* ── Server & folder card load-in ─────────────────────────────────────────
   Cards animate in on page load with a stagger driven by CSS custom
   properties set inline. Each card gets --i: N where N is its index.
*/
.server-card,
.folder-card {
  animation: card-enter 0.4s cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: calc(var(--i, 0) * 50ms);
}

@keyframes card-enter {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ── Admin table rows load-in ─────────────────────────────────────────────*/
.img-row,
.addon-row {
  animation: row-enter 0.3s cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: calc(var(--i, 0) * 30ms);
}

@keyframes row-enter {
  from { opacity: 0; transform: translateX(-4px); }
  to   { opacity: 1; transform: translateX(0); }
}

/* ── Stats cards load-in ──────────────────────────────────────────────────*/
.stats-card {
  animation: card-enter 0.4s cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: calc(var(--i, 0) * 60ms);
}

/* ── Never animate these ──────────────────────────────────────────────────*/

canvas,
#terminal,
#terminal *,
[class*="xterm"],
.animate-spin,
.animate-ping,
.mobile-top-bar,
.mobile-top-bar *,
.mobile-bottom-nav,
.mobile-bottom-nav *,
.mobile-more-sheet,
.mobile-more-sheet *,
#pl-overlay,
#pl-overlay *,
#active-background,
svg,
img {
  transition: none !important;
}
