/* «در حال بارگذاری اطلاعات...» — the one loading state the whole panel waits with
   (تسک ۱۴۰۵/۰۶/۱۱/۰۱، بند ۱ تا ۳۰).

   Two shapes, and the difference between them is بند ۱۰: how much of the screen is
   actually waiting.

   1. **The page's own state** (`.fi-panel-loading`). Drawn when the whole page is
      being made — a management opened from the menu, an address typed in, a
      refresh, a step back through the browser's history. It covers the content
      area and nothing else: the panel's bar stays where it is, so what the
      operator sees is the panel waiting rather than the browser waiting
      (بند ۶ و ۷).

   2. **A table's own state** (`.fi-panel-loading-bar`, `[data-panel-loading]`).
      Drawn when only the rows are being fetched again — a search, a filter, a
      sort, a page of the list, a tab of a management. It is a strip pinned to the
      top of that one table with its rows dimmed under it, so the search box the
      operator is typing in is never covered and the rest of the panel stays
      usable (بند ۱۰).

   Both are painted in Baligpa's own colours — the panel's round mark, the identity
   green of `panel-identity.css`, the panel's own type — rather than in a spinner of
   their own (بند ۱۱). Nothing here delays anything: the states are removed the
   moment the thing they are waiting for is ready (بند ۱۵).

   The error state (بند ۱۹ و ۲۰) is the same box with `data-state="error"`: the
   waiting stops, the words change, and there is a button. A wait and a failure can
   never look the same. */

.fi-panel-loading {
    position: fixed;
    inset-block-start: var(--baligpa-topbar-height, 2.5rem);
    inset-block-end: 0;
    inset-inline: 0;
    /* Filament's bar is `z-20` and its sidebar `z-30`; below both on purpose, so the
       panel's own chrome is never covered by its loading state (بند ۶). */
    z-index: 15;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: rgb(var(--gray-50, 249 250 251));
    /* Present from the first moment of the wait, and merely *legible* a breath
       later: a page that is already ready is removed before this finishes, so a
       fast page shows nothing and a slow one shows the state at once (بند ۳ و ۱۵). */
    animation: fi-panel-loading-in 140ms ease-out both;
}

.dark .fi-panel-loading {
    background-color: rgb(var(--gray-950, 3 7 18));
}

.fi-panel-loading[hidden] {
    display: none;
}

@keyframes fi-panel-loading-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

.fi-panel-loading-box {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    padding: 1.5rem;
    text-align: center;
}

/* The mark, with the panel's green turning around it. */
.fi-panel-loading-mark {
    position: relative;
    width: 4.5rem;
    height: 4.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
}

.fi-panel-loading-mark img {
    width: 3rem;
    height: 3rem;
    border-radius: 9999px;
}

.fi-panel-loading-mark::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 9999px;
    border: 3px solid color-mix(in srgb, var(--panel-accent, #1f7957) 22%, transparent);
    border-block-start-color: var(--panel-accent, #1f7957);
    animation: fi-panel-loading-spin 900ms linear infinite;
}

@keyframes fi-panel-loading-spin {
    to { transform: rotate(360deg); }
}

.fi-panel-loading-text {
    font-size: 0.9375rem;
    font-weight: 600;
    color: var(--panel-accent-text, #1f7957);
}

.dark .fi-panel-loading-text {
    color: #6fd0a5;
}

/* بند ۱۹ و ۲۰ — the wait ended and it ended badly. The mark stops turning, the
   words say so, and there is something to press. */
.fi-panel-loading[data-state='error'] .fi-panel-loading-mark::after {
    animation: none;
    border-color: rgb(var(--danger-500, 239 68 68));
}

.fi-panel-loading[data-state='error'] .fi-panel-loading-text {
    color: rgb(var(--danger-600, 220 38 38));
}

.dark .fi-panel-loading[data-state='error'] .fi-panel-loading-text {
    color: rgb(var(--danger-400, 248 113 113));
}

.fi-panel-loading-retry {
    display: none;
    border-radius: 0.5rem;
    padding: 0.375rem 1rem;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--panel-on-accent, #fff);
    background-color: var(--panel-accent, #1f7957);
}

.fi-panel-loading-retry:hover {
    background-color: var(--panel-accent-hover, #196146);
}

.fi-panel-loading[data-state='error'] .fi-panel-loading-retry {
    display: inline-block;
}

/* ---- a table's own state (بند ۹ و ۱۰) --------------------------------------- */

/* Pinned to the top of the table's own scrolling box, so it is on screen whether
   the operator is at the first row or the hundredth. Above the pinned column-title
   row, which is `z-index: 10`. */
.fi-panel-loading-bar {
    position: sticky;
    inset-block-start: 0;
    inset-inline-start: 0;
    z-index: 12;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    padding: 0.875rem 1rem;
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--panel-accent-text, #1f7957);
    background-color: rgb(var(--gray-50, 249 250 251));
    box-shadow: inset 0 -1px 0 color-mix(in srgb, var(--panel-accent, #1f7957) 30%, transparent);
    animation: fi-panel-loading-in 140ms ease-out both;
}

.dark .fi-panel-loading-bar {
    color: #6fd0a5;
    background-color: rgb(var(--gray-900, 17 24 39));
}

/* The same mark as the page's own state, at the size a strip can carry: بند ۱۱ asks
   for one visual identity, so the two shapes differ in scope and in nothing else. */
.fi-panel-loading-bar-mark {
    position: relative;
    flex: none;
    width: 2rem;
    height: 2rem;
    display: flex;
    align-items: center;
    justify-content: center;
}

.fi-panel-loading-bar-mark img {
    width: 1.25rem;
    height: 1.25rem;
    border-radius: 9999px;
}

.fi-panel-loading-bar-mark::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 9999px;
    border: 2px solid color-mix(in srgb, currentColor 25%, transparent);
    border-block-start-color: currentColor;
    animation: fi-panel-loading-spin 900ms linear infinite;
}

/* The rows underneath say «not this, yet» without disappearing: the previous tab's
   or page's content must not be mistaken for the new one (بند ۹), and an empty box
   is the very thing بند ۷ forbids. */
[data-panel-loading] .fi-ta-content {
    opacity: 0.45;
    pointer-events: none;
    transition: opacity 140ms ease-out;
}

/* بند ۱۹ — a failed fetch leaves a message, never a state that keeps turning. */
/* A wait that has gone past thirty seconds and is **still running** — تسک ۰۵، بند ۱۸.
   Amber rather than red, and the mark keeps turning, because nothing has failed: the
   request is open and the server is still working. Only a request the server actually
   refused reaches the red state below. */
.fi-panel-loading-bar[data-state='slow'] {
    color: rgb(var(--warning-600, 217 119 6));
    background-color: color-mix(in srgb, rgb(var(--warning-500, 245 158 11)) 10%, rgb(var(--gray-50, 249 250 251)));
    box-shadow: inset 0 -1px 0 color-mix(in srgb, rgb(var(--warning-500, 245 158 11)) 30%, transparent);
}

.dark .fi-panel-loading-bar[data-state='slow'] {
    color: rgb(var(--warning-400, 251 191 36));
    background-color: color-mix(in srgb, rgb(var(--warning-500, 245 158 11)) 22%, rgb(var(--gray-900, 17 24 39)));
}

.fi-panel-loading-bar[data-state='error'] {
    color: rgb(var(--danger-600, 220 38 38));
    background-color: color-mix(in srgb, rgb(var(--danger-500, 239 68 68)) 10%, rgb(var(--gray-50, 249 250 251)));
    box-shadow: inset 0 -1px 0 color-mix(in srgb, rgb(var(--danger-500, 239 68 68)) 30%, transparent);
}

.dark .fi-panel-loading-bar[data-state='error'] {
    color: rgb(var(--danger-400, 248 113 113));
    background-color: color-mix(in srgb, rgb(var(--danger-500, 239 68 68)) 22%, rgb(var(--gray-900, 17 24 39)));
}

.fi-panel-loading-bar[data-state='error'] .fi-panel-loading-bar-mark::after {
    animation: none;
    border-color: currentColor;
}

.fi-panel-loading-bar-retry {
    text-decoration: underline;
    font-weight: 700;
}

/* ---- a form's wait floats, and moves nothing (تسک ۱۴۰۵/۰۷/۰۹/۱۲، بند ۴۱ تا ۴۴) ----

   A management with a table has its wait drawn inside that table's own scrolling box,
   where a sticky strip costs nothing: the box scrolls, the page does not change height.
   A **form** screen has no table. `FormTabsLoadingScope` names the tab strip as the scope
   instead, and the same sticky strip is then inserted into the page's own flow — so every
   Livewire commit on مدیریت بازی (choosing a stage, a group, a team) grew the document by
   the strip's height, pushed the tabs and the whole form down, and shrank it again when
   the answer arrived. The screenshots attached to the task are that jump, frame by frame.

   `fixed` rather than `sticky` takes the strip out of the flow altogether, so the page
   height, the tabs, the form and the scroll position are all exactly what they were before
   the wait began (بند ۴۳). It floats over the page instead — centred, near the top, with
   the same mark and the same words — which is بند ۴۲'s «Popup / Overlay شناور».

   Addressed to the scope attribute rather than to one screen, so every form in the panel
   that names a tab strip behaves the same way: بند ۴۴ asks for «یک رفتار Loading یکپارچه
   در کل مدیریت بازی», and مدیریت رقابت and مدیریت تیم use the very same scope. */
.fi-fo-tabs[data-panel-loading-scope] > .fi-panel-loading-bar {
    position: fixed;
    inset-block-start: 5rem;
    inset-inline-start: 50%;
    inset-inline-end: auto;
    transform: translateX(-50%);
    width: auto;
    max-width: 90vw;
    z-index: 60;
    border-radius: 9999px;
    padding: 0.625rem 1.25rem;
    border: 1px solid rgba(17, 24, 39, 0.1);
    box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.25);
}

.dark .fi-fo-tabs[data-panel-loading-scope] > .fi-panel-loading-bar {
    border-color: rgba(255, 255, 255, 0.14);
}

/* …and the tab strip must not become a containing block for it, or `fixed` above would be
   measured from the strip rather than from the viewport and the jump would come back. */
.fi-fo-tabs[data-panel-loading-scope] {
    position: static;
}
