/* ================================================================
   IBM PLEX SANS CONDENSED / IBM PLEX SANS — lokalno vendorani fontovi,
   preuzeti iz službenog Reflect XR brand paketa (Visual Identity
   Guidelines, 2026-07-28), zamjena za Karlu (uklonjena isti dan).
   Nema @import prema fonts.googleapis.com — radi i bez interneta.
   Relativni url(../fonts/...) radi jer je fonts/ jednu razinu iznad
   css/, isti mehanizam kao menu-bg slika niže u ovoj datoteci.

   Guideline dodjeljuje dvije uloge (vidi type-standards stranicu):
   - PRIMARY = "Plex Condensed" (IBM Plex Sans Condensed, Bold/SemiBold) -
     naslovi, page-title, card-title, nav labele, gumbi/bedževi. Vidi
     --heading-font-family niže i .uses-heading-font grupu selektora.
     Uppercase transform (2026-07-28) uklonjen 2026-07-28 - potvrđeno da
     to NIJE stvarni zahtjev guideline-a (case ostaje onakav kakav je
     napisan u view-u), samo font/weight/letter-spacing ostaju.
   - SECONDARY = "Plex Sans" (IBM Plex Sans, Regular/Italic, sentence
     case) - sav ostali tekst (default), vidi --default-font-family.
   ================================================================ */
@font-face {
  font-family: "Plex Condensed";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(../fonts/ibm-plex-sans-condensed-semibold.woff2) format("woff2");
}
@font-face {
  font-family: "Plex Condensed";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(../fonts/ibm-plex-sans-condensed-bold.woff2) format("woff2");
}
@font-face {
  font-family: "Plex Condensed";
  font-style: italic;
  font-weight: 600;
  font-display: swap;
  src: url(../fonts/ibm-plex-sans-condensed-semibolditalic.woff2) format("woff2");
}
@font-face {
  font-family: "Plex Condensed";
  font-style: italic;
  font-weight: 700;
  font-display: swap;
  src: url(../fonts/ibm-plex-sans-condensed-bolditalic.woff2) format("woff2");
}
@font-face {
  font-family: "Plex Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(../fonts/ibm-plex-sans-regular.woff2) format("woff2");
}
@font-face {
  font-family: "Plex Sans";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url(../fonts/ibm-plex-sans-italic.woff2) format("woff2");
}

/* ================================================================
   TIPOGRAFSKI SUSTAV (2026-07-28, uppercase uklonjen isti dan) - primary
   (Plex Condensed, bold) na naslove/nav/gumbe/bedževe, secondary (Plex
   Sans, regular) ostaje default svugdje drugdje (--default-font-family,
   postavljen gore). Uppercase transform je uklonjen (2026-07-28
   feedback - nije stvarni zahtjev guideline-a kako se prvo mislilo);
   naslovi/nav/gumbi/bedževi sada prate case onakav kakav je napisan
   u view-u. font-family/weight/letter-spacing ostaju - condensed font
   i tracking i dalje razlikuju naslove/nav/gumbe od običnog teksta. */
h1, h2, h3, h4, h5, h6,
.page-title,
.card-title,
.side-menu__label,
.btn,
.badge {
  font-family: var(--heading-font-family);
  font-weight: 700;
  letter-spacing: 0.02em;
}

/* ================================================================
   GLOBALNE BRAND BOJE — ReflectXR, službena paleta iz
   "Dokumentacija/color pallete.png". Ovaj blok opisuje TRENUTNO/FINALNO stanje
   (ažurirano 2026-07-29 - VRAĆENO na stanje prije istodnevnog "potpuni remap
   uloga" pokušaja, koji je odbačen isti dan; vidi memory zapis
   "project_reflect_xr_coral_indigo_rebrand" za povijest SVIH prijašnjih
   raspodjela, uključujući i taj kratkotrajni remap).

   ULOGE:
     primary    = Soft Coral       #FF8282, bijeli tekst (svi CTA gumbi, oba teme)
     secondary  = Cool Gray        #E6E8EB  (neutralni sekundarni gumbi/badge-ovi, tamni ink tekst)
     success    = Twilight Indigo  #1F305E  (isto kao sidebar)
     danger     = crvena           #DC3545  (izvan zvanične palete - treba zasićenu crvenu za error semantiku)
     warning    = jantar           #E8A33D  (izvan zvanične palete - Light/Pale Coral su preblizu primary/card boji)
     info       = Slate Blue       #586F8A
     page bg (light) = Off White   #FAFAFB
     page bg (dark)  = Twilight Indigo #1F305E
     surface (kartice, dropdownovi, modali) = tek nijansu tamnija od pozadine (vidi --custom-white
                  niže - 2026-07-30 "boja sličnija pozadinskoj", ranije izraženiji Cool Gray).
                  Card HEADER/FOOTER specifično koristi standardni (tamniji) Cool Gray #E6E8EB da
                  se vizualno odvoji od svjetlijeg tijela kartice - vidi ".card .card-header"
                  override niže. Kartice imaju tanki Slate Blue obrub (--bootstrap-card-border,
                  2026-07-30 zahtjev - birano nad Twilight Indigo opcijom), u oba teme - landing
                  stranice ostaju bez obruba (.landing-body .card, zaseban raniji zahtjev).
     ink/tekst  = Twilight Indigo  #1F305E  (naslovi/tekst, i dark mode pozadina)
     sidebar    = Twilight Indigo #1F305E, FIKSNO u oba teme (ne prati light/dark toggle)
     header     = prati page bg po temi (Off White u light modu, Twilight Indigo u dark modu -
                  "header ista boja kao body" konvencija; header NE dijeli boju sa sidebarom)
     brand-accent (dekorativni akcent: feature ikone, linkovi, .pricing-card.popular) = Soft Coral
                  #FF8282, ista boja kao primary

   Body pozadina je solid boja (--default-body-bg-color), bez dekorativne grafike - wave-lines
   SVG pozadina (wwwroot/assets/images/backgrounds/body-wave-lines.svg) je uklonjena 2026-07-28
   ("na pozadini jos vidim one linije, makni ih"); sam SVG file ostaje na disku nereferenciran.

   --default-text-color/--text-muted su tamni ink (Twilight Indigo/Slate Blue) posvuda, u OBA
   teme - light-modov platno (Off White) je svijetlo pa je taman tekst ispravan default svugdje
   (kartice, dropdownovi, page-title, landing tekst...) bez potrebe za kontekstno-ovisnim
   iznimkama.

   PRAVILO (cascade trap, vidi i dark blok niže): svaki vendorski token
   pregažen ovdje u :root MORA imati odgovarajuću vrijednost u
   [data-theme-mode="dark"] bloku u OVOJ datoteci — site.css se učitava
   nakon styles.css pa :root deklaracije inače pregaze vendorski dark blok.

   DRUGI CASCADE TRAP (otkriven 2026-07-27): [data-theme-mode="light"] kao
   selektor NE POGAĐA Landing/Auth stranice (_LayoutLanding.cshtml) - njihov
   <html> tag nema uopće data-theme-mode atribut u light modu (samo inline
   skripta DODAJE data-theme-mode="dark" kad treba, nikad ne postavlja
   ="light" eksplicitno). Samo _Layout.cshtml (autenticirani app shell)
   postavlja atribut eksplicitno u markupu. Zato "light-mode-specific" CSS
   ispravke OVDJE idu kao UNSCOPED (bazno) pravilo koje vrijedi posvuda,
   s eksplicitnim [data-theme-mode="dark"] pravilom da ga pregazi tamo gdje
   treba - isti obrazac kao glavni brand token blok ispod (:root = default/
   light, [data-theme-mode="dark"] override) - NE koristiti
   "[data-theme-mode="light"] .nešto" pattern za nove ispravke.

   --brand-* varijable su dodatni "meki" set (pastelne pozadine/oznake),
   koristi se odvojeno od primary/secondary/success/info: bg-brand-primary,
   text-brand-primary, bg-brand-accent…
   ================================================================ */

:root {
  --primary-rgb:   255, 130, 130;    /* #FF8282 — Soft Coral */
  --secondary-rgb: 230, 232, 235;    /* #E6E8EB — Cool Gray */
  --success-rgb:   31, 48, 94;       /* #1F305E — Twilight Indigo (reverted 2026-08-22 - "gumb success vrati na onu plavu boju kako je i bilo", undoing the same day's earlier green recolor) */
  --danger-rgb:    220, 53, 69;      /* #DC3545 */
  --validation-error-rgb: 178, 51, 69; /* #B23345 — tamnija od --danger-rgb, za validation-error tekst (veći kontrast/naglasak od standardnog text-danger) */
  --warning-rgb:   232, 163, 61;     /* #E8A33D — jantar */
  --info-rgb:      88, 111, 138;     /* #586F8A — Slate Blue */
  --body-bg-rgb:   250, 250, 251;    /* #FAFAFB — Off White */
  --light-rgb:     230, 232, 235;    /* #E6E8EB — Cool Gray, suptilne pozadine (npr. table thead) */
  --custom-white: #F5F6F8;          /* 2026-07-30 ("boja sličnija pozadinskoj") - kartica sad tek nijansu tamnija od Off White pozadine (#FAFAFB), umjesto ranijeg izraženijeg Cool Gray-a; razlika od pozadine sad dolazi prvenstveno od --bootstrap-card-border niže, ne od kontrasta pozadine same kartice */
  --header-bg:     #FAFAFB;          /* Off White, isto kao body ("header ista boja kao body" konvencija - vraćeno, header ovaj put NE prati sidebar) */
  --form-control-bg: #FFFFFF;        /* čisto bijelo - blaga razlika od svjetlije-sive kartice ispod (recesirani look) */
  --default-text-color: #1F305E;     /* Twilight Indigo - tamni ink, opet ispravan default sad kad je platno opet svijetlo (Off White) */
  /* Bootstrap's OWN --bs-body-color (bootstrap.css root, #212529 by default) is a separate
     variable from --default-text-color above - anything reading it directly (bootstrap.css's
     own ".card { color: var(--bs-body-color); }" among others) got Bootstrap's stock dark gray
     instead of the brand's Twilight Indigo, close enough in light mode to go unnoticed next to
     genuinely-broken cases (only caught so far as a white-on-white dark-mode bug, see the
     [data-theme-mode="dark"] .card / .landing-body .card overrides below, now redundant but left
     in place). Redefining --bs-body-color itself here (2026-07-30, "twilight indigo kao main/
     primary text color") fixes every such case at the root instead of patching them one by one
     as they're found. */
  --bs-body-color: var(--default-text-color);
  --text-muted:    #586F8A;          /* Slate Blue */
  --input-border:  #E6E8EB;          /* Cool Gray */
  --default-border: #E6E8EB;
  --bootstrap-card-border: rgb(var(--info-rgb)); /* Slate Blue, tanki obrub oko cijele kartice (2026-07-30 zahtjev - biran nad Twilight Indigo opcijom), vidi i dark blok niže */
  --dashboard-card-shadow: 0 10px 24px rgba(31, 48, 94, 0.12); /* Twilight Indigo tint, .card-clickable hover shadow - vidi dark blok niže za tamniju verziju */
  /* Same class of bug as --bs-body-color above (2026-07-30, "ne vidim vanjske rubove tablice") -
     Bootstrap's OWN --bs-border-color (native var, #dee2e6 by default) drives .table-bordered/
     DataTables cell borders via its own --bs-table-border-color: var(--bs-border-color) - never
     redefined here, and this app's dark mode uses [data-theme-mode="dark"] rather than Bootstrap's
     own [data-bs-theme="dark"], so Bootstrap's dark override never activates either. Result: table
     borders were a fixed, barely-there gray in both themes, nearly invisible against the (now even
     closer-to-background) card. Tied to the same Slate Blue used for the card border, at reduced
     opacity so cell-level lines don't compete with the card's own accent. */
  --bs-border-color: rgba(var(--info-rgb), 0.35);
  --header-border-color: #E6E8EB;
  --default-font-family:  "Plex Sans", sans-serif;
  --default-font-weight:  400;
  --heading-font-family:  "Plex Condensed", sans-serif;
}

/* --- BRAND PALETA — promijeni samo ovdje ---
   Dostupno i u dark modu (override ispod). */
:root,
[data-theme-mode="light"] {
  --brand-primary-rgb:  250, 250, 251;  /* #FAFAFB — Off White (pozadina) */
  --brand-accent-rgb:   255, 130, 130;  /* #FF8282 — Soft Coral (isto kao primary sad, i dalje koristan kao odvojen "accent" alias) */
  --brand-success-rgb:  31,  48,  94;   /* #1F305E — Twilight Indigo (reverted 2026-08-22) */
  --brand-danger-rgb:   220, 53,  69;   /* #DC3545 */
  --brand-warning-rgb:  232, 163, 61;   /* #E8A33D — jantar */
  --brand-info-rgb:     88,  111, 138;  /* #586F8A — Slate Blue */

  --brand-primary:  rgb(var(--brand-primary-rgb));
  --brand-accent:   rgb(var(--brand-accent-rgb));
  --brand-success:  rgb(var(--brand-success-rgb));
  --brand-danger:   rgb(var(--brand-danger-rgb));
  --brand-warning:  rgb(var(--brand-warning-rgb));
  --brand-info:     rgb(var(--brand-info-rgb));

  --default-body-bg-color: #FAFAFB !important;
  --body-bg-rgb:           250, 250, 251;
}

[data-theme-mode="dark"] {
  /* Body pozadina u dark modu — Twilight Indigo #1F305E, ista boja kao
     sidebar (fiksno taman u oba teme, vidi [data-menu-styles] niže), pa
     nema vizualnog "šava" između sidebara i sadržaja u dark modu. Mora
     stajati u ovom bloku (poslije :root blokova iznad): :root deklaracije
     iz ovog filea inače pregaze vendorski [data-theme-mode=dark] iz
     styles.css jer se site.css učitava zadnji.
     !important prati !important na --default-body-bg-color u light bloku. */
  --body-bg-rgb:  40, 57, 107;   /* #28396B — kartice/header (vendor ih izvodi iz ove, malo svjetlije od pozadine) */
  --body-bg-rgb2: 31, 48, 94;    /* #1F305E — stvarna pozadina bodyja, isto kao Twilight Indigo sidebar */
  --default-body-bg-color: #1F305E !important;

  /* Dark counterparti za vendorske tokene pregažene u :root gore (pravilo
     iz header komentara) — bez ovih bi dark mod naslijedio svijetle
     vrijednosti jer site.css :root pobjeđuje vendorski dark blok. */
  /* 2026-07-30 ("boja sličnija pozadinskoj") - decoupled from --body-bg-rgb (kept separate on
     purpose, --form-control-bg below still reads --body-bg-rgb unchanged) so the card gets its
     own explicit, closer-to-body shade (#243566) without also shifting form input backgrounds. */
  --custom-white:    #243566;
  /* Header = ista boja kao dark body (zrcali light mod gdje su header/body
     ista Pale Coral); kartice ostaju svjetlije #28396B. Sidebar NE ide
     preko --menu-bg ovdje — fiksiran je direktno na Twilight Indigo u
     [data-menu-styles] bloku niže, isto u oba teme. */
  --header-bg:       rgb(var(--body-bg-rgb2));
  --form-control-bg: rgb(var(--body-bg-rgb));
  --default-text-color: rgba(255, 255, 255, 0.85);
  --bs-body-color: var(--default-text-color); /* see the --bs-body-color comment in :root above */
  --text-muted:      rgba(255, 255, 255, 0.55);
  --input-border:    rgba(255, 255, 255, 0.12);
  --default-border:  rgba(255, 255, 255, 0.12);
  --bootstrap-card-border: rgb(var(--info-rgb)); /* Slate Blue, isto kao light blok - vidi :root komentar iznad */
  --bs-border-color: rgba(var(--info-rgb), 0.45); /* isto kao light blok - vidi :root komentar; malo veći alpha nego light (0.35) jer se ista neprozirnost čita slabije na tamnoj podlozi */
  --dashboard-card-shadow: 0 12px 28px rgba(0, 0, 0, 0.45); /* .card-clickable hover shadow, tamnija verzija - vidi light blok iznad */
  --header-border-color:   rgba(255, 255, 255, 0.12);
  --light-rgb:       40, 57, 107;

  /* Glavne uloge — svjetlije varijante istih boja radi čitljivosti na
     tamnom Twilight Indigo (success/info u light modu su preblizu boji
     pozadine da bi ostale vidljive na istoj nijansi u dark modu). Cool Gray
     i Soft Coral (--primary-rgb) su već dovoljno svijetli/zasićeni pa ostaju
     nepromijenjeni ovdje - primary DOBIVA Slate Blue u dark modu, ali samo
     na .btn-primary (vidi override niže, uz KARTICE sekciju) umjesto ovdje
     na --primary-rgb globalno: --primary-rgb se koristi i za dekorativne/
     ikonske elemente (npr. .landing-step-number, .landing-feature-icon,
     .zspinner__arc-a) koji na tamnoj Twilight Indigo pozadini gube kontrast
     u Slate Blue (preblizu nijanse pozadini) - Soft Coral im tu i dalje
     bolje radi, dok gumbi specifično dobivaju Slate Blue po zahtjevu
     2026-07-27 ("dark mode gumbi koriste slate blue"). */
  --success-rgb:   154, 168, 218;  /* #9AA8DA — svjetliji Twilight Indigo (reverted 2026-08-22),
                                       namjerno više ljubičasto-plav nego --info-rgb (Slate Blue)
                                       niže, da ostanu razlučivi jedan od drugog na tamnoj pozadini */
  --danger-rgb:    232, 99, 111;   /* #E8636F */
  --validation-error-rgb: 240, 146, 154; /* #F0929A — svjetlija/naglašenija nijansa nego --danger-rgb da ostane čitljivo na tamnoj pozadini, uz font-weight koji nosi naglasak u dark modu */
  --warning-rgb:   240, 185, 104;  /* #F0B968 */
  --info-rgb:      141, 163, 194;  /* #8DA3C2 — svjetliji Slate Blue */

  --brand-primary-rgb:  31,  48,  94;   /* #1F305E — tamna pozadina, ista nijansa kao body */
  --brand-accent-rgb:   255, 130, 130;  /* Soft Coral, nepromijenjen */
  --brand-success-rgb:  154, 168, 218;  /* svjetliji Twilight Indigo, vidi napomenu uz --success-rgb */
  --brand-danger-rgb:   232, 99,  111;  /* svjetlija crvena */
  --brand-warning-rgb:  240, 185, 104;  /* svjetliji jantar */
  --brand-info-rgb:     141, 163, 194;  /* svjetliji Slate Blue */


  --brand-accent:   rgb(var(--brand-accent-rgb));
  --brand-success:  rgb(var(--brand-success-rgb));
  --brand-danger:   rgb(var(--brand-danger-rgb));
  --brand-warning:  rgb(var(--brand-warning-rgb));
  --brand-info:     rgb(var(--brand-info-rgb));
}

/* ================================================================
   CLICKABLE DASHBOARD CARDS (2026-08-19, PTI Admin Dashboard demo-approved
   "Accent Bar" hover treatment) — pairs with wwwroot/js/services/clickableCard.js,
   which navigates to data-href unless the click originated inside a nested
   <a>/<button> (e.g. a Needs Attention row's own link to one facility/user).
   A Soft Coral bar sweeps up the card's left edge and the whole card lifts
   slightly on hover/keyboard focus - reusable anywhere a whole card should act
   as one big link, not just the PtiAdmin dashboard.
   ================================================================ */
.card-clickable {
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.card-clickable::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: rgb(var(--primary-rgb));
  transform: scaleY(0);
  transform-origin: bottom;
  transition: transform 0.2s ease;
}
.card-clickable:hover,
.card-clickable:focus-visible {
  transform: translateY(-2px);
  box-shadow: var(--dashboard-card-shadow);
}
.card-clickable:hover::before,
.card-clickable:focus-visible::before {
  transform: scaleY(1);
}
.card-clickable:focus-visible {
  outline: 2px solid rgb(var(--primary-rgb));
  outline-offset: 2px;
}

/* PtiAdmin dashboard "Ledger" stat-card anatomy (2026-08-19, demo-approved) - the two small type
   treatments shared by every stat card's icon+title row and its optional "Total"/"Consumed"
   qualifier label. Color is intentionally NOT set here - callers pair these with a text-muted
   utility class, since the design's whole idea is "color exists only on the number". */
.stat-eyebrow {
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.stat-qualifier {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* PtiAdmin Dashboard's collapsible section headers (2026-08-24 follow-up: "collapse GROWTH,
   SUBSCRIPTIONS AND LICENCES I USAGE I NEED ATTENTION") - pure CSS chevron rotation keyed off the
   aria-expanded attribute Bootstrap's collapse plugin itself toggles, so it needs no JS of its own
   and survives DashboardController.js's ajax innerHTML swap on range change. */
.js-section-chevron {
  transition: transform 0.15s ease-in-out;
}
.js-dashboard-section-toggle[aria-expanded="true"] .js-section-chevron {
  transform: rotate(90deg);
}

/* Horizontal "Tab Style 5/6" look (2026-08-24, reversing the same day's earlier vertical-rail
   pass - "ipak ovako napravi tabove... Na velikom ekranu krecu od lijevo i idu na desno. Na malim
   ekranima neka svaki link bude u svojem redu") - every tab nav in this app (Profile, PtiAdmin
   Users/Details, PtiAdmin Facilities/Details, FacilityAdmin Facility/Index) now sits in one
   full-width row above its tab-content instead of a left-side column. Written as our own rule
   (not just applying the vendored .tab-style-5/.tab-style-6 classes from styles.css) for the same
   reason the vertical pass needed its own rule - those classes' selectors require a .nav-item >
   .nav-link ancestor chain (Bootstrap's <li>-wrapped nav markup), and this app's tabs are plain
   buttons with no <li> wrapper. The d-sm-flex/d-block responsive classes (Bootstrap utilities,
   applied directly in each screen's markup - not part of this rule) are what stacks each link
   onto its own full-width row below the sm breakpoint and lays them out left-to-right at sm+. */
.nav-pills.tabs-horizontal-style5 .nav-link {
  margin-inline-end: 0.5rem;
  margin-bottom: 0.5rem;
  color: var(--text-muted);
}
.nav-pills.tabs-horizontal-style5 .nav-link:last-child {
  margin-inline-end: 0;
}
.nav-pills.tabs-horizontal-style5 .nav-link.active {
  background-color: rgb(var(--primary-rgb));
  color: #fff;
}

/* Account Dashboard's "Your Plans" row detail toggle (2026-08-24 follow-up: "prikazi samo prvi
   red, a ostalo neka bude inicijalno collapsed ali da moze rastvoriti") - same chevron-rotation
   idiom as .js-dashboard-section-toggle above, reused per-row for the Mobile/VR Home plan detail. */
.js-dashboard-plan-chevron {
  transition: transform 0.15s ease-in-out;
}
.js-dashboard-plan-toggle[aria-expanded="true"] .js-dashboard-plan-chevron {
  transform: rotate(90deg);
}

/* Account Dashboard's plan-status/credits split (2026-08-24 follow-up: "stavi u jedan red,
   vizualno razdvoji sa vertical line... manje podataka vidi inicijalno, a ostalo na expand
   ikonu") - vertical divider only from md+ (row-cols stack single-column below that, where a
   left border would just look like a stray line above the credits block); same aria-expanded
   chevron-rotation idiom as .js-dashboard-section-toggle above, reused for the credits column's
   own collapse toggle. */
@media (min-width: 768px) {
  .dashboard-credits-col {
    border-left: 1px solid var(--default-border);
    padding-left: 1.5rem !important;
  }
}
.js-dashboard-credits-chevron {
  transition: transform 0.15s ease-in-out;
}
.js-dashboard-credits-toggle[aria-expanded="true"] .js-dashboard-credits-chevron {
  transform: rotate(90deg);
}

/* Account/Plan/Choose's Monthly/Annual billing switch (2026-08-19) - bigger than a default
   form-switch since it's the primary decision on the page, not a secondary form field; explicit
   Soft Coral checked color rather than relying on Bootstrap's own --bs-primary wiring, so this
   stays correct even if that mapping ever changes. */
.billing-interval-switch .form-check-input {
  width: 3.25rem;
  height: 1.75rem;
  cursor: pointer;
}
.billing-interval-switch .form-check-input:checked {
  background-color: rgb(var(--primary-rgb));
  border-color: rgb(var(--primary-rgb));
}
.billing-interval-switch .form-check-input:focus {
  border-color: rgb(var(--primary-rgb));
  box-shadow: 0 0 0 0.25rem rgba(var(--primary-rgb), 0.25);
}

/* Accessibility: color-blind friendly mode (2026-07-29) - single on/off toggle in the
   accessibility panel (_AccessibilityOffcanvas.cshtml / accessibilityService.js), persisted the
   same way as light/dark mode (data-a11y-colorblind on <html>, set before paint). Desaturates
   the whole UI rather than simulating/correcting one specific colorblindness type, since the
   ask was "reduce color reliance", not per-deficiency accuracy. */
html[data-a11y-colorblind="true"] {
  filter: saturate(0.4);
}

/* --- BRAND UTILITY KLASE ---
   bg-brand-primary, text-brand-success, border-brand-danger ... */
.bg-brand-primary   { background-color: var(--brand-primary)  !important; }
.bg-brand-accent    { background-color: var(--brand-accent)   !important; }
.bg-brand-success   { background-color: var(--brand-success)  !important; }
.bg-brand-danger    { background-color: var(--brand-danger)   !important; }
.bg-brand-warning   { background-color: var(--brand-warning)  !important; }
.bg-brand-info      { background-color: var(--brand-info)     !important; }

.text-brand-primary { color: var(--brand-primary)  !important; }
.text-brand-accent  { color: var(--brand-accent)   !important; }
.text-brand-success { color: var(--brand-success)  !important; }
.text-brand-danger  { color: var(--brand-danger)   !important; }
.text-brand-warning { color: var(--brand-warning)  !important; }
.text-brand-info    { color: var(--brand-info)     !important; }

.border-brand-primary { border-color: var(--brand-primary)  !important; }
.border-brand-accent  { border-color: var(--brand-accent)   !important; }
.border-brand-success { border-color: var(--brand-success)  !important; }
.border-brand-danger  { border-color: var(--brand-danger)   !important; }
.border-brand-warning { border-color: var(--brand-warning)  !important; }
.border-brand-info    { border-color: var(--brand-info)     !important; }

/* Validacijske poruke (asp-validation-for / asp-validation-summary) — zamjena za
   Bootstrapov text-danger: tamnija crvena i bold tekst radi jačeg naglaska. */
.validation-error {
  color: rgb(var(--validation-error-rgb)) !important;
  font-weight: 700;
}

/* Per-field validation spans (asp-validation-for) reserve their line height up front, whether
   or not they currently have text - an empty inline <span> collapses to 0px, so a field-level
   error appearing on submit used to grow that row's height and shove/jump every input below it
   (and, since Bootstrap's .row is flex with equal-height columns, made same-row siblings jump
   too even when only one field actually failed validation). Scoped to the <span> tag only -
   asp-validation-summary's <div class="validation-error"> at the top of a form is unaffected. */
span.validation-error {
  display: block;
  min-height: 1.1rem;
  margin-top: 0.15rem;
}

/* .btn-primary light-mode text/border no longer needs an override here (removed 2026-07-27,
   "primary gumbi soft coral bijeli tekst") - now that primary is Soft Coral again (not Light
   Coral) and cards are Cool-Gray-ish (not coral), vendor's own defaults already do the right thing
   unscoped: white text (styles.css ~2899, good contrast on Soft Coral) and a matching border
   (no longer at risk of "disappearing" against a same-hue card, since card and button are now
   different color families entirely). See git history for the previous Light-Coral-era override
   if this ever needs resurrecting.

   Dark mode primary buttons specifically use Slate Blue (direct request 2026-07-27 - "dark mode
   gumbi koriste slate blue"), NOT via the shared --primary-rgb token (kept as Soft Coral in dark
   mode - see the comment on --success-rgb above for why: --primary-rgb also drives non-button
   decorative accents like .landing-step-number/.landing-feature-icon/.zspinner__arc-a, and those
   lose contrast against the dark Twilight Indigo background in Slate Blue). White text/vendor
   default border already work fine against Slate Blue's mid-tone, no extra border needed like
   the light-mode fix above. */
[data-theme-mode="dark"] .btn-primary,
[data-theme-mode="dark"] .btn-primary:hover,
[data-theme-mode="dark"] .btn-primary:focus,
[data-theme-mode="dark"] .btn-check:focus + .btn-primary,
[data-theme-mode="dark"] .btn-check:active + .btn-primary,
[data-theme-mode="dark"] .btn-check:checked + .btn-primary,
[data-theme-mode="dark"] .btn-primary.active,
[data-theme-mode="dark"] .btn-primary.show,
[data-theme-mode="dark"] .btn-primary:active {
  background-color: rgb(88, 111, 138) !important; /* #586F8A — Slate Blue */
  border-color: rgb(88, 111, 138) !important;
  color: #fff !important;
}

/* .btn-secondary/.badge.bg-secondary hardcode white text the same way .btn-primary does
   (styles.css ~2938) - but unlike primary, --secondary-rgb (Cool Gray) never gets darker in dark
   mode, so white-on-near-white is low contrast in BOTH themes, not just light mode. Fixed
   Twilight Indigo instead of var(--default-text-color) (which now means different things in
   different contexts - see the --default-text-color comment above - and would go the wrong way
   here regardless). Border (Slate Blue) matches the .btn-primary treatment - a plain Cool Gray
   fill with no border reads as flat/washed-out. Both unscoped for the same
   Landing/Auth-attribute-absence reason as .btn-primary. */
.btn-secondary,
.btn-secondary:hover,
.btn-secondary:focus,
.btn-check:focus + .btn-secondary,
.btn-check:active + .btn-secondary,
.btn-check:checked + .btn-secondary,
.btn-secondary.active,
.btn-secondary.show,
.btn-secondary:active {
  color: #1F305E !important; /* Twilight Indigo */
  border-color: rgb(var(--info-rgb)) !important; /* Slate Blue */
}

.badge.bg-secondary {
  color: #1F305E !important;
  border: 1px solid rgb(var(--info-rgb)); /* Slate Blue - badges have no border by default, unlike buttons */
}

/* .btn-outline-secondary hardcodes Cool Gray (--secondary-rgb) as BOTH text and border color in
   its resting state, with no fill to give it any shape at all (styles.css ~3398) - same underlying
   "Cool Gray never darkens" bug as .btn-secondary/.badge.bg-secondary above, but worse here since
   there's no solid background to fall back on: near-white text/border on the light #ededed card
   body reads as basically invisible (2026-08-03, "cancel button barely visible" - Profile/Edit's
   Cancel link). Unlike .btn-secondary (always a pale Cool Gray fill regardless of theme), this
   button's text sits directly on the page/card background, which flips dark in dark mode - so a
   hardcoded dark Twilight Indigo (fine for .btn-secondary's fixed light fill) would go invisible
   the other direction there. var(--text-muted) is already theme-aware (Slate Blue light / light
   translucent white dark - same token the transparent-badge fix above relies on) for exactly this
   "text on the ambient background" case. Hover/focus/active use a low-alpha Slate Blue tint rather
   than inverting to a solid fill - avoids ever needing white text against --info-rgb's lighter
   dark-mode tint, which would itself be low-contrast. */
.btn-outline-secondary {
  color: var(--text-muted) !important;
  border-color: rgb(var(--info-rgb)) !important; /* Slate Blue */
}

.btn-outline-secondary:hover,
.btn-outline-secondary:focus,
.btn-outline-secondary:active,
.btn-check:focus + .btn-outline-secondary,
.btn-check:active + .btn-outline-secondary,
.btn-check:checked + .btn-outline-secondary,
.btn-outline-secondary.active,
.btn-outline-secondary.show {
  color: var(--text-muted) !important;
  background-color: rgba(var(--info-rgb), 0.12) !important;
  border-color: rgb(var(--info-rgb)) !important;
}

/* renderBadge() (datatableHelper.js) builds "bg-{color}-transparent text-{color}" badges, not the
   solid ".badge.bg-secondary" fixed above - a different pair of vendor classes with the identical
   underlying bug. ".text-secondary" is plain Cool Gray text (--secondary-rgb, our palest neutral)
   with no dark-mode adjustment, so it's near-invisible on the light card/page background behind
   it in both themes (2026-07-28, "badge za END USER se ne vidi" - most users have no
   AppUserRole row at all, so UserDataTableRowViewModel's default EndUser badge color is
   "secondary", hitting this on every Users Index page load). var(--text-muted) is Slate Blue in
   light mode / a light translucent white in dark mode - already theme-aware, so one rule covers
   both. */
.badge.bg-secondary-transparent {
  color: var(--text-muted) !important;
}

/* Body background - solid boja bez dekorativnih linija (uklonjeno 2026-07-28, "na pozadini jos
   vidim one linije, makni ih"). Prije je ovdje bio globalni body { background-image: ... }
   ("valovite linije" SVG, wwwroot/assets/images/backgrounds/body-wave-lines.svg) - taj SVG file
   ostaje na disku (nereferenciran) za slučaj da zatreba, ali pozadina je sad opet čisti
   var(--default-body-bg-color) (vendorski, styles.css), bez dodatnog pravila ovdje. */

/* --- KARTICE --- */
/* 2026-07-30 - "makni borders sa svih card i dodaj card background color #ededed": flat light-grey
   card body, no border (border removal below, same request) - replaces the earlier --custom-white/
   Slate-Blue-border look. Light mode only - dark mode's own --custom-white (#243566) is untouched,
   #ededed being a light tone wouldn't read against a dark page anyway. */
html:not([data-theme-mode="dark"]) .card.custom-card,
html:not([data-theme-mode="dark"]) .card {
  background-color: #ededed !important;
}

/* Card header/footer: standardni (tamniji) Cool Gray #E6E8EB, vidno odvojen od svjetlijeg tijela
   kartice iznad (--custom-white) - "Kartice koje imaju header, neka on bude u cool gray boji"
   zahtjev. Vendorski ".card .card-header, .card .card-footer" (styles.css) inače koristi
   var(--custom-white) !important (istu boju kao tijelo kartice) - ovaj override mora imati istu
   specifičnost/!important da pobjedi. */
html:not([data-theme-mode="dark"]) .card .card-header,
html:not([data-theme-mode="dark"]) .card .card-footer {
  background-color: #E6E8EB !important;
}

/* .custom-card (2026-07-30 rollout - "na svim cards koristi custom-card"), border since removed
   (2026-07-30 follow-up - "makni borders sa svih card") - was a Slate Blue border matching plain
   .card, now no border on either, just the vendor's grey box-shadow suppressed. Also asked to
   shrink the header down and pin it to a fixed height so header height stays consistent across
   cards regardless of title length, instead of the vendor default's bigger 1.15rem title / 1.25rem
   padding growing with content. */
.card,
.card.custom-card,
[data-theme-mode="dark"] .card,
[data-theme-mode="dark"] .card.custom-card {
  border: none !important;
  box-shadow: none !important;
  border-radius: 0.75rem !important;
}

.card.custom-card .card-header {
  height: 3rem;
  min-height: 3rem;
  padding: 0 1.25rem;
}

/* Vendor's own .card.custom-card .card-header:first-child / .card-footer round only the top/bottom
   corners to a smaller 0.625rem (styles.css) - bump those to match the card's own new 0.75rem
   radius above, otherwise the header/footer's corners read as a visibly tighter curve than the
   card body around them. */
.card.custom-card .card-header:first-child {
  border-radius: 0.75rem 0.75rem 0 0;
}

.card.custom-card .card-footer:last-child {
  border-radius: 0 0 0.75rem 0.75rem;
}

.card.custom-card .card-header .card-title {
  font-size: 1rem;
  font-weight: 600;
}

/* Sidebar: fiksno Twilight Indigo (#1F305E) u OBA teme - "sidebar navigacija twilight indigo" +
   "dark mode sidebar je uredu" zahtjev, isti dan vraćen na ovo nakon kratkog "prati temu"
   eksperimenta (sidebar bio kratko Slate Blue u light modu, vidi git historiju). custom.js toggle
   za dark mode mijenja data-menu-styles između "light" (spremljeni stil) i "dark" - zato oba
   override-a ovdje MORAJU postaviti identične vrijednosti, inače bi sidebar mijenjao boju zajedno
   s theme togglom. */
[data-menu-styles="light"],
[data-menu-styles="dark"] {
  --menu-bg: #1F305E;
  --menu-prime-color: rgba(250, 250, 251, 0.6);  /* Off White, prigušen - naslovi sekcija (OVERVIEW...), neaktivne stavke */
  --menu-border-color: rgba(250, 250, 251, 0.12);
}

/* 2026-08-13 feedback: logo + "REFLECT XR / by Persistent Technology" wordmark (baked into the
   desktop-dark.svg itself, see the logo asset bullet in CLAUDE.md) sat left-aligned inside the
   sidebar header box instead of centered - the vendor's own .main-sidebar-header is a flex row
   with no justify-content set, so its .header-logo child (and the wordmark image inside it) just
   sits at the flex-start edge. Force it centered instead. */
.app-sidebar .main-sidebar-header {
  justify-content: center !important;
}
.app-sidebar .main-sidebar-header .header-logo {
  display: flex;
  justify-content: center;
}

/* 2026-08-13: bump the logo up from the vendor default (2rem) - applies to both the expanded
   wordmark (.desktop-dark) and the collapsed icon glyph (.toggle-dark), since the vendor's own
   height rule targets .header-logo img generically, not per-variant. */
.app-sidebar .main-sidebar-header .header-logo img {
  height: 2.5rem !important;
  line-height: 2.5rem !important;
}

/* Vendorski "light" stil boji aktivnu/hover ikonu i logo tamnom (dizajniranom
   za svijetlu pozadinu) - budući da je sidebar uvijek taman navy, prisili
   uvijek prikaz .desktop-dark (bijeli wordmark) logo varijante, bez obzira
   na data-theme-mode. Header (.app-header, izvan sidebara) NE dijeli ovu
   sudbinu - ide s pozadinom (Off White/Twilight Indigo po temi, vidi
   --header-bg u :root/dark blokovima gore), pa mijenja logo prema temi kao
   inače - ovo je scoped samo na .app-sidebar. */
.app-sidebar .main-sidebar-header .header-logo .desktop-dark {
  display: block !important;
}
.app-sidebar .main-sidebar-header .header-logo .desktop-logo {
  display: none !important;
}

/* Only .desktop-dark (expanded) and .toggle-dark (collapsed, added below) are ever meant to be
   visible - .toggle-logo/.toggle-white/.desktop-white are unused theme-mode/menu-styles variants
   (this app is permanently Twilight Indigo/[data-menu-styles=light], never switches to a "dark"/
   "color" menu style) but vendor styles.css leaves them targetable by data-theme-mode-scoped
   rules we don't otherwise hit - force-hidden here so nothing can make a second logo appear
   (2026-07-28 feedback: "collapsed state shows two logo icons"). */
.app-sidebar .main-sidebar-header .header-logo .toggle-logo,
.app-sidebar .main-sidebar-header .header-logo .toggle-white,
.app-sidebar .main-sidebar-header .header-logo .desktop-white {
  display: none !important;
}

/* Footer follows the HEADER's background (--header-bg: Off White light / Twilight Indigo dark),
   NOT the sidebar (2026-07-30 request, explicit: "neka prati header, ne sidebar") - matches the
   comment above re: .app-header being independent from the always-dark sidebar. _footer.cshtml
   used to hardcode bg-white, ignoring theme entirely - in dark mode the header went Twilight
   Indigo while the footer stayed glaring white. Text also moves from muted gray to primary
   (Soft Coral) per the same request. */
.footer {
  background-color: var(--header-bg);
}

/* Sidebar collapse - vendor "icon-overlay" mode (2026-07-28 round 4, replaced the earlier
   icon-click attempt after checking how TemplateNet10Zeno's sidebar behaves): _Layout.cshtml sets
   data-vertical-style="overlay", and the vendor's own "icon_overlay" CSS block (styles.css)
   handles the whole collapsed state unscoped - narrow width, hidden labels/categories/angles,
   centered icons, AND hover-expand via [data-icon-overlay=open] (mouseenter/mouseleave listeners
   defaultmenu.min.js attaches while collapsed) - so the previous hand-rolled :hover width/label
   block for icon-click is gone entirely. The ONLY missing piece is the collapsed-state logo swap:
   vendor's overlay rules swap .desktop-logo <-> .toggle-logo (the light-menu variants), but this
   app force-hides those in favor of .desktop-dark/.toggle-dark (dark navy sidebar, see the force
   rules above), so the swap has to be restated here for the -dark pair. :not([data-icon-overlay=
   open]) mirrors the vendor's own collapsed-state scoping, so the wordmark comes back during
   hover-expand exactly like the labels do. */
[data-vertical-style="overlay"][data-toggled="icon-overlay-close"]:not([data-icon-overlay="open"]) .app-sidebar .main-sidebar-header .header-logo .desktop-dark {
  display: none !important;
}
[data-vertical-style="overlay"][data-toggled="icon-overlay-close"]:not([data-icon-overlay="open"]) .app-sidebar .main-sidebar-header .header-logo .toggle-dark {
  display: inline-block !important;
}

/* Mobile header/sidebar logo (2026-07-28 feedback, round 2 - first pass only hid the header-level
   .horizontal-logo while closed; a follow-up screenshot showed the actual open sidebar with NO
   logo at all above its nav items). Two separate vendor logo slots exist on mobile: the header's
   own .horizontal-logo (_main-header.cshtml, next to .sidemenu-toggle) and the sidebar's own
   .main-sidebar-header (same wordmark markup as desktop) - vendor styles.css unconditionally
   hides .main-sidebar-header below 991.98px ("display: none !important", no [data-toggled]
   scoping at all) since its default design expects the HEADER logo to be the only mobile one.
   That's not what was asked for ("logo sa tekstom treba biti u sidebaru na vrhu") - so instead:
   .horizontal-logo is now hidden on mobile in BOTH toggled states (not just closed), and
   .main-sidebar-header is force-shown instead once the sidebar is actually open, giving the
   logo+text exactly one place to live on mobile, inside the sidebar itself, matching the
   desktop-expanded look. */
@media (max-width: 991.98px) {
  .app-header .horizontal-logo {
    display: none !important;
  }
  [data-toggled="open"] .app-sidebar .main-sidebar-header {
    display: flex !important;
  }
  /* Vendor's own mobile block (same @media, styles.css) zeroes .main-sidebar's
     margin-block-start to 0 since it expected .main-sidebar-header to stay hidden - restoring it
     (plus a bit of extra breathing room past just clearing the header) now that the header is
     force-shown above, so the nav list doesn't start flush against/under the logo.

     height fixed 2026-07-30 ("kad menu ima puno itema, ne mogu scrollat do dna") - this rule
     added margin-block-start back without shrinking height to match, so the box's own total
     footprint (margin + the vendor's own height: 100vh) overflowed past .app-sidebar's fixed
     100vh boundary by exactly this margin - permanently unreachable however far you scroll,
     since a position:fixed ancestor never itself scrolls. Not visible until the menu grew long
     enough (this Filters/Audit-heavy PtiAdmin menu) to actually reach that dead zone. */
  [data-toggled="open"] .app-sidebar .main-sidebar {
    margin-block-start: 4.25rem !important;
    padding-block-start: 1rem !important;
    height: calc(100vh - 4.25rem) !important;
  }
}

/* Desktop/tablet counterpart to the mobile fix above (2026-08-21 follow-up: "opet ne mogu doci do
   audit logs, neda mi scroll navigacije nego scrolla po main stranici, kako da to sredimo
   zauvijek") - the identical dead-zone bug, just never patched outside the mobile media query.
   Vendor styles.css's own .main-sidebar rule (no [data-toggled] scoping) keeps height: 100vh while
   margin-block-start pushes the box down 4.25rem to clear the fixed header - its own footprint
   then overflows past .app-sidebar's fixed 100vh boundary by exactly that margin, permanently
   unreachable however far the SimpleBar scrollbar is dragged, since a position:fixed ancestor
   never itself scrolls. Only became visible once a menu (PtiAdmin's - the longest of the three
   areas, "Audit logs" is its literal last item) grew tall enough to actually reach the dead zone;
   the defect exists in every area's sidebar (they all share this one partial/CSS), not just
   PtiAdmin's. overscroll-behavior is a defensive belt-and-suspenders addition, not the actual
   fix - without a real height mismatch left to hit, there's nothing to chain-scroll into the main
   content anyway, but it costs nothing to also stop that from ever happening again. */
@media (min-width: 992px) {
  .app-sidebar .main-sidebar {
    height: calc(100vh - 4.25rem) !important;
  }
}

.app-sidebar .main-sidebar {
  overscroll-behavior: contain;
}

/* Naslovi stranica (h1.page-title) - jedinstvena veličina fonta na svim stranicama,
   umesto da nasleđuju veću default h1 veličinu iz teme (assets/css/styles.css).
   font-weight 700 (ne 500) - "Plex Condensed" ima samo 600/700 rezane, 500 bi se
   preko font-matchinga ionako sveo na 600; eksplicitan 700 je jasniji. */
.page-title {
  font-size: 1.8rem;
  font-weight: 700;
}

/* Floating labels + Choices.js compatibility.
   Choices.js wraps the original <select class="form-select"> in a .choices
   container and hides the select itself, so it no longer matches Bootstrap's
   ".form-control/.form-select ~ label" selectors used to size/float the
   label. Give .choices the same box height/padding as a floating .form-select
   and permanently float its label - Choices always shows a value or
   placeholder text, the same condition that makes Bootstrap permanently float
   labels on native <select> elements. */
.form-floating > .choices {
  /* Fixed 2026-07-30 - was calc(3.5rem - 4px), a 6px mismatch against Bootstrap's own
     ".form-floating > .form-control/.form-select" height (calc(3.5rem + calc(var(--bs-border-width) * 2)),
     i.e. +2px with the default 1px border) - visibly shorter than every other floating input/select
     on the same row (most visible on New Facility's Type/Plan selects next to plain text inputs). */
  height: calc(3.5rem + calc(var(--bs-border-width) * 2));
  margin-bottom: 0;
}

.form-floating > .choices .choices__inner {
  height: 100% !important;
  min-height: auto !important;
  padding: 1.625rem 0.75rem 0.625rem !important;
  display: flex;
  align-items: center;
}

.form-floating > .choices ~ label {
  opacity: 0.65;
  transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
  color: var(--text-muted) !important;
  font-weight: 400;
}

/* An open Choices.js dropdown must paint above whatever form field comes after it.
   Both this field's .choices wrapper and the next field's are position:relative with
   z-index:auto, so without this the later one in the DOM (painted last) covers the
   open dropdown panel instead of the panel sitting on top of it. Raising .choices
   above its own floating label (z-index: 2 from Bootstrap) too, so re-elevate that
   label back above .choices - they visually overlap by design (the label sits inside
   the box's own top padding). */
.choices.is-open {
  position: relative;
  z-index: 50;
}

/* Mobilni razmak između polja (2026-07-27) - "inputi/select liste nemaju dosti razmaka na
   mobitelu": kad se polja u .row.g-3 slože jedno ispod drugog (col-sm-12, 1-up) na malim
   ekranima, redoviti 1rem gutter je pretijesan da vizualno odvoji label sljedećeg polja od inputa
   iznad. Dodaje dodatan razmak izravno na input/select/Choices.js wrapper (radi bez obzira nosi
   li roditeljski .row g-3 ili nešto drugo), umjesto da diramo .row.g-3 globalno (što bi pogodilo i
   ne-formske rasporede, npr. dashboard stat kartice). Zadnje pravilo namjerno pobjeđuje
   ".form-floating > .choices { margin-bottom: 0; }" gore (isti selektor, kasnije u datoteci) - taj
   zero-out ostaje netaknut na desktopu/tabletu, samo na mobilnom dobiva isti razmak kao ostalo. */
@media (max-width: 575.98px) {
  .form-control,
  .form-select,
  .choices,
  .form-floating > .choices {
    margin-bottom: 0.5rem;
  }
}

.choices.is-open ~ label {
  z-index: 51;
}

/* Global loading spinner overlay - shown/hidden via window.displayLoading() /
   window.hideDisplayLoading() in wwwroot/js/loadingSpinner.js. Light neutral
   grey, so it reads as a soft interruption on top of whatever page/theme is
   already showing. */
.overlay {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background: rgba(120, 120, 120, 0.55);
  z-index: 9999;
}

.overlay__wrapper {
  width: 100%;
  height: 100%;
  z-index: 9999;
  position: relative;
}

.overlay__spinner {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
}

/* Was hardcoded text-white (Bootstrap) - didn't hold up once the overlay went
   from a near-opaque dark scrim to a light grey one. --default-text-color is
   already theme-aware (dark ink in light mode, near-white in dark mode), so
   it keeps contrast in both instead of needing a light/dark override here. */
.overlay__label {
  color: var(--default-text-color);
}

/* SVG spinner used in the loading overlay above - colored from the theme's
   --primary-rgb/--secondary-rgb so it follows brand color changes (the old
   spin.gif was a fixed color and couldn't). Two arcs turning opposite ways
   rather than a single track+head ring (previous design). The overlay itself
   is shown/hidden by displayLoading()/hideDisplayLoading() in
   js/services/loadingSpinner.js, which also hooks jQuery's global
   ajaxStart/ajaxStop events - so it now appears automatically for every
   $.ajax call app-wide, including DataTables' own server-side fetches
   (Users/Facilities Index), with no manual per-table wiring needed. */
.zspinner__arc-a {
  stroke: rgb(var(--primary-rgb));
  stroke-dasharray: 55 200;
  transform-origin: 25px 25px;
  animation: spin 1.1s linear infinite;
}

.zspinner__arc-b {
  stroke: rgb(var(--secondary-rgb));
  stroke-dasharray: 34 120;
  transform-origin: 25px 25px;
  animation: spin-reverse 1.6s linear infinite;
}

@keyframes spin-reverse {
  from { transform: rotate(0deg); }
  to { transform: rotate(-360deg); }
}

/* DataTables' own plain-text "Processing..." indicator (Users/Facilities
   Index, both serverSide+processing:true) is redundant now that the global
   ajaxStart/ajaxStop hook above shows the real overlay for the same fetch -
   hidden rather than left to flash underneath it. */
.dataTables_processing {
  display: none !important;
}

/* Responsive DataTables' row-expand control (Facilities/Users Index on mobile, where most
   columns collapse behind it): the vendored theme's default styling renders the library's
   arrow glyph ("►"/"▼") inside an untamed background box - with no fixed size/radius, it comes
   out looking like a stray "play button" rather than an expand affordance, and it sits as
   inline content ahead of whatever the first column renders (see the Name column's avatar+name
   markup), so it needs to be small and vertically centered to read as part of the same row
   instead of floating above it. Swapped for a plain +/- circle instead of the arrow glyphs -
   the clearer, more common convention for "more columns hidden here".
   Loads after wwwroot/assets/css/styles.css (see _styles-base.cshtml), so this !important wins
   the cascade the same way the theme's own override does. */
table.dataTable.dtr-inline.collapsed > tbody > tr > td.dtr-control:before,
table.dataTable.dtr-inline.collapsed > tbody > tr > th.dtr-control:before {
  content: "+" !important;
  /* Centered via flex, not line-height - line-height centering depends on the glyph's own font
     metrics (ascent/descent), which left "+" sitting visibly off-center inside the circle. */
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: 1.25rem !important;
  height: 1.25rem !important;
  line-height: 1 !important;
  font-size: 0.8rem !important;
  border-radius: 50% !important;
  box-shadow: none !important;
  /* This circle and the first column's own content (e.g. Facilities' avatar+name span, see
     indexController.js) are both inline-level boxes sitting on the same line inside the cell -
     with no vertical-align set, an inline-flex box defaults to baseline alignment, which put this
     smaller circle noticeably higher than a taller sibling like an avatar image instead of
     centered against it. */
  vertical-align: middle !important;
}

table.dataTable.dtr-inline.collapsed > tbody > tr.parent > td.dtr-control:before,
table.dataTable.dtr-inline.collapsed > tbody > tr.parent > th.dtr-control:before {
  content: "\2212" !important;
}

/* The vertical-align: middle above only fixed the +/- circle's OWN alignment - it still looked
   off-center (2026-08-03 follow-up screenshot) because its sibling, the avatar+name wrapper span
   Facilities'/Users' indexController.js render() prepends after it, had no vertical-align of its
   own and so stayed at the default "baseline" (effectively its bottom edge), while the circle sat
   at "middle" - two different alignment anchors for two boxes on the same line never line up.
   Both now anchor on the same "middle" reference so their centers actually match. */
table.dataTable.dtr-inline.collapsed > tbody > tr > td.dtr-control > span.d-inline-flex {
  vertical-align: middle !important;
}

/* Every DataTable screen (Users/Facilities/Devices/Entitlements/Billing) wraps its <table> in
   Bootstrap's .table-responsive, which sets overflow-x: auto - per the CSS overflow spec, once one
   axis is non-visible the other axis resolves to auto too (setting overflow-y: visible explicitly
   does NOT stick, confirmed empirically), so .table-responsive ends up clipping in BOTH directions.
   DataTables' own markup (search box, table, pagination) all render as children of that same
   .table-responsive element, and the search input sits flush against its top/right edge with zero
   clearance - so the coral focus ring (.form-control:focus box-shadow above) got its top and right
   edge cut off the instant the box was focused. Padding gives the ring room before the clip edge
   (4px of actual shadow spread + buffer); compensated with a matching negative margin so the table
   itself doesn't shift/shrink inside the surrounding .card-body. */
.table-responsive {
  padding: 0.5rem;
  margin: -0.5rem;
}

/* DataTables' own "No data available in table" / "No matching records found" empty-state cell
   has no color of its own in the vendor CSS, so without an override here it fell through to
   Bootstrap's own ".table > :not(caption) > * > *" rule (styles.css) - a plain class selector
   like ".dataTables_empty" alone can't beat that descendant-combinator's higher specificity, so
   !important is needed the same way the .dtr-control fix above needs it. */
.dataTables_empty {
  color: var(--text-muted, #6c757d) !important;
}

/* Responsive "+" detail card (2026-08-21, "Moze improved expand svugdje") - styling for the
   markup wwwroot/js/services/datatables/responsiveDetailRenderer.js generates in place of
   DataTables' own cramped 2-column mini-table. One shared renderer + this one shared stylesheet
   block covers every responsive: true DataTable in the app (see that file's own doc comment for
   why this is the single choke point, not a per-screen change). */
.dtr-detail-card {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  background-color: var(--default-background);
  border-radius: 0.625rem;
  padding: 0.75rem 0.9rem;
  margin: 0.25rem 0 0.5rem;
}

.dtr-detail-field {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.dtr-detail-lbl {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 600;
  color: var(--text-muted, #6c757d);
}

.dtr-detail-val {
  font-size: 0.8125rem;
}

/* Global DataTables header/cell alignment (2026-07-28) - every DataTable screen (Users,
   Facilities) gets this for free instead of per-screen CSS. Headers bold + centered; data
   cells centered too, including action-button columns - those set an explicit className in the
   column config (see facility/indexController.js, user/indexController.js), which as a
   Bootstrap utility (!important) would otherwise beat a plain text-align here, so those columns
   were switched from "text-end" to "text-center" rather than fighting specificity.
   text-align needed !important as of 2026-07-30 ("nazivi kolona nisu centrirani") - the vendor
   dataTables.bootstrap5.min.css ships its own "table.dataTable thead th { text-align: left }" at
   the exact same selector specificity, loaded per-view via @section Styles (after site.css in
   _Layout.cshtml's <head>), so it was winning purely on source order. */
/* table-bordered also covers the plain (non-DataTable) sub-tables that were deliberately left out
   of the client-side DataTables conversion (Facility/Users Details' Seats/Members/Invites/history
   tables etc.) - 2026-07-30 ask to make "all other tables" match the Facilities table's look
   extends this same centered/bold header treatment to those too, not just DataTable-driven ones. */
table.dataTable thead th,
table.table-bordered thead th {
  font-weight: 700;
  text-align: center !important;
}

/* Body cell text centered too (2026-08-11, "centriraj tekstove u svim tablicama") - previously
   only table.dataTable tbody td was covered, leaving every plain (non-DataTable) table-bordered
   table's body text left-aligned while its own header was already centered above. */
table.dataTable tbody td,
table.table-bordered tbody td {
  text-align: center;
}

/* text-align above only centers inline content - it has no effect on a block-level child, which
   is exactly what every avatar-name cell (avatarCell() helpers) and every button-group Actions
   cell (d-flex-wrapped buttons/forms) actually is. Fixing this one call site at a time (as first
   done for Facility Details' avatarCell()) doesn't scale - this rule catches the whole class of
   cell at once, app-wide, present and future (2026-08-12, "svugdje sve centriraj u tablicama" -
   hit again on the Credit purchases Actions column). Scoped to a DIRECT child so it doesn't reach
   into unrelated nested flex layouts deeper inside a cell (e.g. an avatar's own internal
   align-items-center row shouldn't also get justify-content forced onto it). */
table.dataTable tbody td > .d-flex,
table.table-bordered tbody td > .d-flex {
  justify-content: center;
}

/* DataTables' own "Show X entries" length control and search box (2026-07-30, "uskladi sa temom
   boje da ljepse izgleda") - both render as completely unstyled Bootstrap-default form-select/
   form-control until now. Themed to match the rest of the app's inputs (Cool Gray/translucent
   border, Soft Coral focus ring via the existing .form-control:focus rule above) instead of the
   plain browser-default look. The search box's own right alignment is already the vendor default
   (div.dataTables_wrapper div.dataTables_filter { text-align: right }) - nothing to change there,
   just needed actual styling. */
.dataTables_wrapper .dataTables_length select,
.dataTables_wrapper .dataTables_filter input {
  border-color: var(--input-border);
  background-color: var(--form-control-bg);
  color: var(--default-text-color);
}
.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_filter {
  color: var(--text-muted);
  font-size: 0.8125rem;
  margin-bottom: 0.75rem;
}
.dataTables_wrapper .dataTables_filter input {
  margin-inline-start: 0.5rem;
}

@media (prefers-reduced-motion: reduce) {
  .zspinner__arc-a,
  .zspinner__arc-b {
    animation: none;
  }
}

/* Sidebar contact icons (email/website/phone), centered at the bottom of
   the sidebar navigation. Icon-only by design - the value is revealed via
   the Bootstrap tooltip (title attribute), wired up globally in custom.js. */
.sidebar-contacts {
  position: absolute;
  inset-block-end: 0.75rem;
  inset-inline-start: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 0.5rem;
  z-index: 10;
}

.sidebar-contacts__link {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  color: var(--menu-prime-color);
  background: rgba(var(--primary-rgb), 0.1);
  font-size: 1rem;
  transition: all ease 0.05s;
}

.sidebar-contacts__link:hover {
  color: #fff;
  background: var(--primary-color);
}

.sidebar-contacts__links {
  display: flex;
  gap: 0.5rem;
}

/* Collapsed-sidebar trigger: hidden by default, swapped in for
   .sidebar-contacts__links while the sidebar is shrunk to icon-only width
   (icon-overlay-close) and not currently hover-expanded. Opens
   #sidebarContactsModal instead of showing the icons inline, since they
   don't fit the collapsed rail. */
.sidebar-contacts__trigger {
  display: none;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border: none;
  border-radius: 50%;
  color: var(--menu-prime-color);
  background: rgba(var(--primary-rgb), 0.1);
  font-size: 1rem;
}

.sidebar-contacts__trigger:hover {
  color: #fff;
  background: var(--primary-color);
}

html[data-toggled="icon-overlay-close"]:not([data-icon-overlay="open"]) .sidebar-contacts__links {
  display: none;
}

html[data-toggled="icon-overlay-close"]:not([data-icon-overlay="open"]) .sidebar-contacts__trigger {
  display: flex;
}

/* Transparent, pill-shaped modal anchored to the bottom-center of the
   viewport - no dark backdrop (data-bs-backdrop="false" on the modal), so
   the page stays visible behind it. */
.sidebar-contacts-modal .modal-dialog {
  position: fixed;
  inset-inline-start: 50%;
  inset-block-end: 1.5rem;
  margin: 0;
  max-width: none;
  width: auto;
  transform: translate(-50%, 0.5rem);
  transition: transform 0.15s ease-out, opacity 0.15s ease-out;
}

.sidebar-contacts-modal.show .modal-dialog {
  transform: translate(-50%, 0);
}

.sidebar-contacts-modal .modal-content {
  background: rgba(var(--primary-rgb), 0.12);
  backdrop-filter: blur(8px);
  border: none;
  border-radius: 999px;
  box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.15);
}

.sidebar-contacts-modal__body {
  display: flex;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
}

/* Image collage on the right-hand cover panel of the auth pages
   (Register, Login, ...). Replaces the single centered image with a
   2x2-ish grid so the panel doesn't look like one big empty rectangle
   while the vendored media-*.{jpg,png} files are still gray placeholders. */
.auth-collage {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 1rem;
  width: 100%;
  height: 450px;
}

.auth-collage__item {
  overflow: hidden;
  border-radius: 1rem;
  box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.25);
}

.auth-collage__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.auth-collage__item--lg {
  grid-row: 1 / 3;
}

/* Show/hide password button (Register, Login, Students/Create): the theme
   pins it to inset-block-start: 0, which aligns it with the floated label
   row of a .form-floating input instead of the input's full height, so it
   visually sits above the typed value, not centered on the field. */
.show-password-button {
  inset-block-start: 50%;
  transform: translateY(-50%);
}

/* Sidebar menu labels: the theme forces white-space: nowrap, so a label
   longer than the sidebar width gets clipped instead of shown in full.
   Let it wrap to a second line; the item keeps its default align-items:
   center so the icon stays vertically centered next to the label.
   Scoped to the vertical layout only - in the horizontal top-bar menu the
   items are shrinkable flex children, so this same rule made every label
   wrap letter-by-letter and the whole bar unusable. Below 992px the
   horizontal layout falls back to the same offcanvas sidebar as vertical,
   so the media query re-enables wrapping there for both layouts. */
[data-nav-layout="vertical"] .app-sidebar .side-menu__label {
  white-space: normal;
  word-break: break-word;
}

@media (max-width: 991.98px) {
  .app-sidebar .side-menu__label {
    white-space: normal;
    word-break: break-word;
  }
}

/* Colored dot after the current-page nav link - removed 2026-07-28 ("tocka kod trenutno aktivnog
   itema nije potrebna kad postoji pozadina koja se promijeni") - the active item's own
   background/text color change (theme default) already marks it, so the extra dot was
   redundant. */

/* Header "Kontakti" (help) and light/dark toggle icons: unlike the other
   header icons they don't carry the .header-link-icon class, so they
   inherit the small default icon size instead of the theme's 1rem. Bump
   them up slightly so they're as visible as the rest of the header icons.
   The second selector catches the theme-switcher (equalizer) icon, whose
   <li> isn't wrapped in .header-theme-mode - without it that icon renders
   visibly smaller than its neighbours. */
.header-theme-mode .header-link i,
.header-content-right .header-link > i {
  font-size: 1.2rem;
}

/* Accessibility button's inline SVG (_main-header.cshtml) - same effective size as the bare <i>
   icons above (1.2rem), but set as width/height directly rather than font-size/em since it's an
   svg, not a font glyph; display: block avoids the inline-element baseline gap that would
   otherwise sit it a touch lower than its <i> neighbours inside the flex-centered .header-link. */
.a11y-header-icon {
  width: 1.2rem;
  height: 1.2rem;
  display: block;
}

/* The vendor sizes .avatar.custom-header-avatar at 1.5rem, which makes the
   header user icon noticeably smaller than the other right-side header icons
   (their tap targets are 2rem). Match it to 2rem; the ri-user glyph inside
   keeps its fs-20. Same selector as the vendor rule - site.css loads later,
   so it wins on order. line-height: 1 so the glyph's line box doesn't push
   the icon below the vertical center of its circle. */
.avatar.custom-header-avatar {
  width: 2rem;
  height: 2rem;
  line-height: 1;
}

/* Vendor stretches each right-side .header-element to full header height and
   leaves vertical centering to each link's own content box - the profile
   avatar (a 2rem filled circle) ends up sitting visibly lower than the plain
   glyph icons next to it. Center the elements themselves so every icon shares
   the same vertical axis. */
.main-header-container .header-content-right .header-element {
  align-items: center;
}

/* Mobile header: zadnja ikona desno (user/profil) treba isti razmak od
   ruba ekrana kao logo lijevo. Logo nema svoj header-link wrapper, pa mu
   jedini razmak od ruba daje .main-header-container { padding-inline: 1rem }.
   Zadnja stavka desno ima dodatni padding-inline-end (0.3rem na mobilnom) na
   svom .header-link, pa ikona sjedi dalje od ruba nego logo - uklanjamo ga
   da preostane samo kontejnerski 1rem, isto kao na lijevoj strani. */
@media (max-width: 575.98px) {
  .header-content-right > li.dropdown:last-child > .header-link {
    padding-inline-end: 0;
  }
}

/* Mobile header: na uskim ekranima (iPhone SE/XR i sliče) zbroj logo +
   hamburger + 5 desnih ikona (search/kontakti/tema/switcher/profil) ne
   stane unutar header-a uz default razmak (.header-link padding: 0 0.5rem
   po ikoni), pa zadnje 1-2 ikone (switcher, profil) izlaze izvan vidljive
   širine ekrana. Smanjujemo padding po ikoni s 0.5rem na 0.25rem - vraća
   ~2.5rem (40px) prostora, dovoljno da sve ikone stanu na ekran.
   !important i fizička padding-left/right (umjesto padding-inline) jer
   .main-header-container .header-link u styles.css postavlja padding
   shorthand-om iste specifičnosti - logical-property verzija gubi cascade
   protiv physical shorthand-a kasnije učitanog iz istog selektora. */
@media (max-width: 575.98px) {
  .main-header-container .header-link {
    padding-left: 0.25rem !important;
    padding-right: 0.25rem !important;
  }
  .main-header-container {
    padding-inline: 0.5rem !important;
  }
}

/* Mobile header: with padding squeezed to 0.25rem above, the 4 right-side
   icons (help/theme/switcher/profile) sat glyph-to-glyph with no visible
   gap between them. The "search users" box is hidden below md anyway
   (d-md-block d-none), so there's headroom for a small explicit gap without
   the icons running off-screen again. 0.75rem per explicit request 2026-07-13
   (0.35rem still read as cramped on a phone). */
@media (max-width: 575.98px) {
  .header-content-right {
    gap: 0.75rem;
  }
}

/* Header user/avatar icon (top-right, before the dropdown opens): styled to
   match the other 3 header utility icons (help/theme-toggle/switcher) per
   explicit request 2026-07-10 - same rgb(var(--dark-rgb)) that those icons
   already resolve to (near-black in light mode, near-white in dark mode via
   the vendor's [data-theme-mode] override), instead of the per-role tinted
   circle (bg-danger/warning/success-transparent) used previously. The role
   name text badge next to/below it keeps its own role color - only the icon
   itself changes here. !important needed to beat .avatar's own `color: #fff`. */
.header-user-icon {
  color: rgb(var(--dark-rgb)) !important;
  background-color: rgba(var(--dark-rgb), 0.1) !important;
}

/* Header notification bell (see _main-header.cshtml/notifications.js). Deliberately NOT using
   the vendor's .notifications-dropdown class - despite the name, styles.css hides that class at
   <=575.98px (alongside .cart-dropdown/.header-fullscreen), which is effectively every phone in
   portrait, hiding the bell exactly where users most want it (confirmed 2026-07-21 - it was
   invisible on mobile). The search bar is already hidden below md, so mobile only ever shows
   help/theme/switcher/notification/profile = 5 icons, which fits fine within the existing
   mobile padding (0.25rem) + gap (0.75rem) tuning on .header-content-right/.header-link above -
   no extra media query needed. */
#mainHeaderNotification {
  position: relative;
}

.header-notification-badge {
  position: absolute;
  top: 0.05rem;
  right: 0.05rem;
  min-width: 1rem;
  height: 1rem;
  padding: 0 0.25rem;
  border-radius: 999px;
  font-size: 0.625rem;
  line-height: 1rem;
  text-align: center;
  color: #fff;
  background-color: rgb(var(--danger-rgb));
}

/* Fixed width lives on the dropdown itself (not the inner <ul>) so the "Notifications" header
   row and the list below it are always sized off the same box - previously only the <ul> had an
   explicit width, so a dropdown that happened to render wider left the rows looking narrower
   than the menu around them (confirmed 2026-07-21). */
.notification-dropdown-menu {
  width: 340px;
  max-width: calc(100vw - 2rem);
}

/* Desktop/tablet vertical position (2026-07-28 feedback, "covers the header icons"): vendor's
   .main-header-container .main-header-dropdown rule (styles.css) sets inset-block-start:
   0.9375rem !important, measured from the small toggle <li>'s own position, not from the bottom
   of the 4.25rem-tall .app-header bar - the dropdown was rendering overlapping the header icon
   row instead of clearing below it. First attempt at this override used a plain
   .notification-dropdown-menu selector - !important on both sides means SPECIFICITY still breaks
   the tie, and the vendor's two-class descendant selector beat this rule's one class, so it never
   took effect (confirmed dead on the live site). Matching the vendor's own selector shape
   (.main-header-container .notification-dropdown-menu, same specificity, later in the cascade)
   fixes that. Scoped to .notification-dropdown-menu specifically, not every .main-header-dropdown
   (e.g. the profile dropdown, which doesn't have this problem/wasn't reported). Placed before the
   mobile media query below so that block still wins at <=575.98px. */
.main-header-container .notification-dropdown-menu {
  inset-block-start: 4.5rem !important;
}

/* On mobile, anchoring the dropdown to the bell (right-aligned via .dropdown-menu-end) either
   overflows the screen or sits flush against the edge with no matching gutter on the other side.
   Below 575.98px it's repositioned as a fixed, viewport-centered panel with equal left/right
   margins instead - data-bs-display="static" on the toggle (_main-header.cshtml) is required for
   this to work: without it Bootstrap/Popper controls position via an inline transform, which
   would fight these overrides. 4.25rem matches .app-header's fixed height (styles.css) so the
   panel sits just below the header, not overlapping it. */
@media (max-width: 575.98px) {
  .notification-dropdown-menu {
    position: fixed !important;
    top: calc(4.25rem + 0.5rem) !important;
    left: 1rem !important;
    right: 1rem !important;
    width: auto !important;
    max-width: none !important;
    margin: 0 !important;
  }
}

.notification-list-scroll {
  width: 100%;
  max-height: 360px;
  overflow-y: auto;
}

/* Mobile safe-area (2026-07-28 feedback: "small white patches top-left/top-right above the
   header"): the viewport meta tag (Views/Shared/layouts/_head.cshtml) had no viewport-fit=cover,
   so on notched/rounded-corner phones the browser's own reported viewport excluded the physical
   safe-area insets entirely - .app-header's fixed inset-inline:0/inset-block-start:0 (styles.css)
   was then relative to that SMALLER viewport, leaving the true screen corners uncovered by any
   app background at all (rendered as the browser/OS's own default white chrome, not something
   this app's CSS could reach). With viewport-fit=cover now set, the header spans the true full
   screen width/top - padding-top here keeps its actual icon row clear of the notch/status bar
   instead of rendering underneath it, with height bumped by the same amount so the icon row's
   own height is unaffected. */
@supports (padding-top: env(safe-area-inset-top)) {
  .app-header {
    height: calc(4.25rem + env(safe-area-inset-top));
    padding-top: env(safe-area-inset-top);
  }
}

.notification-item {
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: 0.6rem 1rem;
  border-bottom: 1px solid var(--default-border);
  color: inherit;
}

.notification-item:last-child {
  border-bottom: 0;
}

.notification-item:hover {
  background-color: rgba(var(--primary-rgb), 0.05);
  color: inherit;
}

.notification-item.is-unread {
  background-color: rgba(var(--primary-rgb), 0.08);
}

/* Explicit unread marker (a subtle background tint alone read as too ambiguous - confirmed
   2026-07-21) - a small dot next to unread items, none for read ones, plus bold vs. normal/muted
   title weight (set inline per-item in notifications.js, since it depends on isRead). */
.notification-dot {
  flex: 0 0 auto;
  width: 0.5rem;
  height: 0.5rem;
  margin-top: 0.4rem;
  border-radius: 50%;
  background-color: rgb(var(--primary-rgb));
}

/* Pagination font-size globalno manji od Bootstrap defaulta (1rem) - kao
   custom property na .pagination, jer Bootstrap definira
   --bs-pagination-font-size lokalno unutar .pagination, ne na :root, pa bi
   override na :root inače bio prepisan nazad. */
.pagination {
  --bs-pagination-font-size: 0.875rem;
}

/* Bazna veličina fonta na malim ekranima (mobitel) - manji font da sadržaj stane bez horizontalnog scrolla */
html {
  font-size: 14px;
}

/* Na širim ekranima (tablet/desktop, >=768px) vraća font na standardnu Bootstrap veličinu radi bolje čitljivosti */
@media (min-width: 768px) {
  html {
    font-size: 16px;
  }
}

/* Prilagođen focus outline (umjesto default plavog browser obruba) za dugmiće, linkove i polja forme - usklađen sa bojama teme i bolja vidljivost za keyboard navigaciju (accessibility).
   2026-07-29 fix ("dupli border na inputu kad je focus"): ovo je bilo dvoslojno (unutarnji
   --custom-white prsten od 0.1rem + vanjski primary prsten od 0.25rem) NA VRHU vendorskog
   ".form-control:focus" (styles.css) koji sam odvojeno mijenja border-color u var(--primary05) -
   tri vizualna sloja (bojani border + bijeli razmak + vanjski prsten) čitala su se kao dupli
   obrub. Sad je jedan jedini prsten, a border-color je fiksiran da se ne mijenja na focus (ostaje
   --input-border), umjesto da ga vendorski override i dalje boji. Selektor je i imao typo -
   ".form-check-inpsiut" nikad nije pogađao ništa, pa checkbox focus prsten stvarno nikad nije ni
   radio - ispravljeno na ".form-check-input". */
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  border-color: var(--input-border);
  box-shadow: 0 0 0 0.2rem rgba(var(--primary-rgb), 0.35);
}

/* position: relative + min-height: 100% omogućava da footer ("sticky footer" tehnika) ostane na dnu stranice i kad sadržaja ima malo */
html {
  position: relative;
  min-height: 100%;
}

/* Razmak na dnu stranice da fiksni/sticky footer ne preklapa zadnji sadržaj.
   Skopirano na .has-sticky-footer (glavni app layout) - na auth/login stranicama
   (_LayoutAuth) nema footera, pa je ova margina tamo samo stvarala praznu "rupu"
   na dnu ekrana, najuočljivije ispod plavog desnog panela. */
body.has-sticky-footer {
  margin-bottom: 60px;
}

/* Toastr po defaultu dodaje klasu "toast" svakoj obavijesti, a ta ista klasa je i naziv
   Bootstrap "toast" komponente iz teme (assets/css/styles.css), koja postavlja svoj border
   i border-radius: 0.3rem. Toastr-ov vlastiti border-radius je 3px, pa se obojena pozadina
   ne poklapa tačno s ivicom obruba teme - to stvara ružan bjelkasti rub/ugao oko poruke. */
#toast-container > div.toast {
  border: 0;
  border-radius: 3px;
}

/* Toastr po defaultu prikazuje obavijest s opacity: 0.8 (poluprozirno), pa se elementi
   ispod nje (npr. "Prijavljen" dropdown u headeru, koji je na istoj poziciji gore desno)
   nazire kroz pozadinu i vizualno se preklapa s ikonom/porukom - izgleda kao da ikona i
   poruka nisu u istom retku. Puna neprozirnost to rješava. */
#toast-container > div.toast {
  opacity: 1;
}

/* Toastr-ova ikona je background-image centriran na cijelu visinu kutije (background-position:
   center), ali .toast-message i .toast-close-button su obični block/float elementi poravnati
   na vrh, pa ikona i tekst poruke vizualno ne sjede na istoj visini. Budući da kutija nema
   fiksnu visinu (visina ovisi o sadržaju), postotna visina na djetetu se ne može koristiti za
   centriranje (resolved kao auto) - rješenje je da sama kutija postane flex red s
   align-items: center, što centrira djecu bez obzira na to kako joj se visina računa. */
#toast-container > div.toast {
  display: flex;
  align-items: center;
}

/* min-width: 0 overrides the flex item's default min-width: auto, which otherwise sizes this
   box to its content's full unwrapped width (a long unbroken string like an email address) before
   toastr.css's own "word-wrap: break-word" ever gets a chance to apply - without this, a long
   message pushes past the toast's fixed 300px width instead of wrapping inside it. */
#toast-container > div.toast .toast-message {
  flex: 1 1 auto;
  min-width: 0;
  order: 1;
}

#toast-container > div.toast .toast-close-button {
  order: 2;
  float: none;
  flex: 0 0 auto;
  margin-left: 8px;
}

/* Globalne brand boje toastr poruka (MessageService.showToastrMessage):
   success = success (Twilight Indigo), error = danger, umjesto toastr-ovih
   default zelene/crvene koje nisu iz palete. ID selektor pobjeđuje i
   toastr.css (.toast-success { background-color }) i vendorski .toast
   override iz styles.css bez !important; toastr-ov hardkodirani bijeli
   tekst/ikona ostaju nepromijenjeni - Twilight Indigo je dovoljno taman za
   bijeli tekst u oba teme (--success-rgb već ima svoju posvijetljenu
   dark-mode inačicu, #9AA8DA), pa poseban ink override nije potreban.
   Bilo je vezano na --primary-rgb (Soft Coral) do 2026-07-29 ("login
   success twilight boje toastr za sve success") - success toastovi sad
   koriste --success-rgb izravno, ne primary. */
#toast-container > .toast-success {
  background-color: rgb(var(--success-rgb));
}

#toast-container > .toast-error {
  background-color: rgb(var(--danger-rgb));
}

/* Placeholder tekst u "floating label" poljima poravnat desno dok polje nije u fokusu - vizuelni stil teme za floating forme.
   var(--text-muted) umjesto Bootstrapovog --bs-secondary-color: vendorski dark blok redefinira samo svoje varijable,
   pa je placeholder u dark modu bio taman-na-tamnom (isti razlog kao .error-desc niže). */
.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
  color: var(--text-muted, #6c757d);
  text-align: end;
}

/* Kad korisnik klikne u polje, placeholder se pomera levo (start) - standardno UX ponašanje floating label obrazaca */
.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
  text-align: start;
}

/* Vendorski .form-control:focus mijenja pozadinu na var(--custom-white) (styles.css ~5254) -
   bezopasno dok je --custom-white bio skoro-bijeli ton (blizu neaktivnog --form-control-bg), ali
   otkad je --custom-white postao Light Coral (kartica), fokusirano polje se stopi s pozadinom
   kartice i gubi kontrast/čitljivost (najuočljivije na Login/Register poljima s "autofocus").
   Zadržava isti --form-control-bg i u fokusu umjesto da preskoči na boju kartice. */
.form-control:focus {
  background-color: var(--form-control-bg);
}

/* Same problem as .form-control:focus above, but for checkboxes (2026-07-28 feedback, "I accept"
   checkbox barely visible on Register): vendor .form-check-input (styles.css) fills with
   var(--custom-white) and borders with var(--input-border) - both now near-identical tones to the
   card it sits on (.card.auth-card, --custom-white/Cool Gray), so an unchecked box was reading as
   nearly invisible. Matches text inputs' own --form-control-bg treatment instead. */
.form-check-input {
  background-color: var(--form-control-bg);
  border-color: var(--text-muted);
}

/* Views/Demo/ProductsList.cshtml - selected product row */
/* Vizuelno ističe selektovani red proizvoda (klikom ili čekiranjem checkbox-a) svetlom pozadinom i bojom obruba, da korisnik vidi šta je trenutno izabrano */
.product-list.selected,
.product-list:has(.product-checkbox input:checked) {
  background-color: var(--bs-primary-bg-subtle, #eaf1fe);
  border-color: var(--bs-primary, #4285f4) !important;
}

/* Views/Home/Landing.cshtml */
/* Landing stranica - Slate Blue pozadina (zahtjev 2026-07-27, "slate [blue] neka bude pozadina");
   nema data-theme-mode pa varijabla --body-bg-rgb ne pali, hardkodirano baš kao i ranije Off White/
   Pale Coral verzije. Ranija blur+blob "aurora" pozadina (.landing-aurora/.hero-aurora-*) je
   uklonjena 2026-07-27 - zamijenjena globalnim body background-image (vidi "body {" pravilo niže,
   primjenjuje se na svaki ekran u appu, ne samo landing) koji vjernije prati liniju iz color
   pallete.png reference.

   Tekst: --default-text-color/--text-muted OSTAJU tamni Twilight Indigo/Slate Blue globalno (vidi
   arhitekturnu napomenu na vrhu datoteke) - budući da je .landing-body pozadina opet Off White
   (svijetla), taj default je opet ispravan izravno na platnu, bez posebnog svijetlog overridea
   koji je ovdje ranije postojao dok je pozadina bila Slate Blue (uklonjen zajedno s njom - vidi
   git historiju ako treba referenca). */
.landing-body {
  background-color: #FAFAFB;
}

/* Landing kartice - Cool Gray (svjetlije od standarda), isto kao .card pravilo gore. Coral border
   koji je ovdje ranije postojao je uklonjen 2026-07-27 ("makni na karticama obrube u primary
   boji"), a sad je uklonjen i Bootstrapov ".border" utility obrub iz markupa ("card h-100 border
   shadow-none p-4" u Landing.cshtml) - solid pozadina bez linija i na landingu, isto kao svugdje
   drugdje u appu (--bootstrap-card-border). Jedina kartica bez te klase je
   ".pricing-card.popular" ("ReflectXR Monthly") - ta i dalje dobiva svoj namjerni coral obrub/sjaj
   preko vlastitog ".pricing-card.popular" pravila niže (odvojena svrha - ističe preporučeni plan,
   nije opći card border, pa nije obuhvaćen ovim zahtjevom). */
.landing-body .card {
  background-color: #F2F3F5;
  border-radius: 1rem;
  border-color: transparent !important; /* pobjeđuje Bootstrapov ".border" utility (!important) iz markupa */
}

/* CTA sekcija na dnu - Twilight Indigo, isto kao sidebar/navbar */
.landing-Features {
  background-color: #1F305E !important;
}

/* Footer na landing stranici - Twilight Indigo */
.landing-body .footer {
  background-color: #1F305E !important;
  color: rgba(255, 255, 255, 0.65) !important;
}

.landing-body .footer .text-muted {
  color: rgba(255, 255, 255, 0.5) !important;
}

/* Navigacija na landing stranici - Twilight Indigo, ista boja kao sidebar,
   konstantna u oba teme (nije theme-ovisna, to je brand header). Sticky da ostane
   zalijepljena za vrh prilikom skrolovanja, s border-om da se vizuelno odvoji od
   sadržaja ispod. */
.landing-navbar {
  position: sticky;
  top: 0;
  z-index: 1030;
  background-color: #1F305E;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

/* Mobile safe-area, landing/auth pages (2026-07-28 round 2 - screenshot confirmed the earlier
   .app-header fix, wwwroot/css/site.css, only covered the AUTHENTICATED shell; the public
   Landing page uses this separate .landing-navbar, which had no safe-area handling at all, so
   the notch/status-bar strip above it was still showing the page's own Off White body background
   uncovered by the navy navbar). padding-top extends the sticky navbar's own background up into
   the safe area once it reaches the true top of a viewport-fit=cover viewport (_head.cshtml),
   instead of stopping at the pre-cover viewport edge and leaving a gap. */
@supports (padding-top: env(safe-area-inset-top)) {
  .landing-navbar {
    padding-top: env(safe-area-inset-top);
  }
}

/* Klik na mini-nav link (npr. "How It Works") skrola glatko do sekcije, a scroll-margin-top
   na sekciji sprječava da sticky navbar prekrije naslov sekcije kad se sleti na anchor. */
html {
  scroll-behavior: smooth;
}

.landing-body section[id] {
  scroll-margin-top: 84px;
}

/* Stil linkova u landing navigaciji - bijeli tekst jer je pozadina uvijek tamna (Twilight Indigo) */
.landing-navbar .nav-link {
  font-weight: 500;
  color: rgba(255, 255, 255, 0.85);
}

/* Hover efekat - link u navigaciji prelazi u terakotu (brand accent); primary
   tamni teal se na tamnom ugljenu headera premalo vidi, terakota ima dobar
   kontrast i dolazi iz iste Figma palete (logo akcent). */
.landing-navbar .nav-link:hover {
  color: rgb(var(--brand-accent-rgb));
}

/* Fiksna visina logoa (Horizontal Logo, sa REFLECT XR wordmarkom ugrađenim u SVG - 2026-07-28,
   "za logo stavi onaj sa tekstom") u navigaciji, konzistentna nezavisno od originalne veličine
   slike. Nema više odvojenog tekstualnog "Reflect" spana pored ikone - wordmark je dio same
   slike, pa ni .landing-brand više ne treba svoj color override. */
.landing-brand img {
  height: 34px;
  width: auto;
}

/* Krug/kvadrat sa ikonicom za feature sekciju landing stranice - centrirana ikonica unutar obojenog pozadinskog "balona" radi vizuelnog naglaska */
.landing-feature-icon {
  width: 56px;
  height: 56px;
  border-radius: 14px;
  background-color: rgba(var(--primary-rgb), 0.1);
  color: rgb(var(--primary-rgb));
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 26px;
}

/* Veliki broj koraka u "How It Works" kartici (1/2/3), zamjena za icon-bubble u ovoj sekciji jer dizajn tako traži */
.landing-step-number {
  font-size: 2.25rem;
  font-weight: 600;
  color: rgb(var(--primary-rgb));
  line-height: 1;
}

.landing-main {
  position: relative;
  overflow-x: hidden;
}

/* Logoi partnera/klijenata prikazani u sivim tonovima i blago providni da ne odvlače pažnju od glavnog sadržaja */
.trusted-logos img {
  max-height: 28px;
  opacity: 0.55;
  filter: grayscale(100%);
  transition: opacity 0.2s ease;
}

/* Na hover, logo postaje pun u boji (bez grayscale) kao interaktivni efekat */
.trusted-logos img:hover {
  opacity: 1;
}

/* Dark mode za landing stranicu - .landing-navbar NIJE ovdje jer je Twilight Indigo
   header konstantan u oba teme (nije theme-ovisan), pa base stil gore već vrijedi. */
[data-theme-mode="dark"] .landing-body {
  background-color: rgb(var(--brand-primary-rgb));
  color: rgba(255, 255, 255, 0.85);
}

/* Bootstrap's .card { color: var(--bs-body-color); } (bootstrap.css) sets an explicit color
   directly on the card element - --bs-body-color is a native Bootstrap variable the app's
   [data-theme-mode="dark"] toggle never redefines (only the vendor theme's own --default-text-color/
   --text-muted are dark-aware), so anything without its own color class (e.g. plain <li> text)
   inherited that permanently-light color and went unreadable on the dark card. Overriding it here
   restores inheritance for those plain elements. */
[data-theme-mode="dark"] .landing-body .card {
  background-color: rgba(255, 255, 255, 0.04);
  border-color: transparent !important; /* bez linija i u dark modu, ista logika kao light-mode pravilo gore */
  color: rgba(255, 255, 255, 0.85);
}

/* Same --bs-body-color bug as the landing-card fix above, but app-wide (2026-07-21):
   any plain-text element inside a .card with no color class of its own - most visibly
   <dd> values in the `dl.row` info lists used all over InternalAdmin (Seats, Current
   license, Identity, ...) - inherited the permanently-light #212529 and went nearly
   invisible on a dark card. `[data-theme-mode="dark"] .card` outranks bootstrap.css's
   bare `.card` on specificity, so this doesn't need !important. */
[data-theme-mode="dark"] .card {
  color: var(--default-text-color);
}

[data-theme-mode="dark"] .landing-feature-icon {
  background-color: rgba(var(--brand-accent-rgb), 0.16);
  color: var(--brand-accent);
}

[data-theme-mode="dark"] .trusted-logos img {
  filter: grayscale(100%) invert(0.85);
}

/* Accessibility button na landing/auth stranicama (2026-07-30, zamijenio raniji zaseban
   theme-toggle-btn - light/dark je sad samo jedna od opcija unutar ovog panela, isto kao
   u autenticiranoj app) - fiksiran u gornjem desnom uglu. */
.a11y-toggle-btn {
  position: fixed;
  top: 1rem;
  inset-inline-end: 1rem;
  z-index: 1040;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, 0.1);
  background-color: #fff;
  color: rgb(var(--primary-rgb));
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.1rem;
  cursor: pointer;
}

[data-theme-mode="dark"] .a11y-toggle-btn {
  background-color: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.16);
  color: var(--brand-accent);
}

/* Marketing Landing page only (_LayoutLanding.cshtml sets this modifier class) - the button
   sits over the dark Twilight Indigo navbar there, constant in both themes (see .landing-navbar
   above), so a bare white icon with no circular backdrop reads fine on its own; overrides the
   dark-mode rule above too since the navbar colour doesn't change with the theme toggle. */
.a11y-toggle-btn.a11y-toggle-btn--bare,
[data-theme-mode="dark"] .a11y-toggle-btn.a11y-toggle-btn--bare {
  background-color: transparent;
  border-color: transparent;
  color: #fff;
}

/* Fiksni gumb (gore desno, 2.5rem širok + 1rem od ruba) prekriva Log In/
   Sign Up linkove u landing navbaru na uskim širinama - gurni sadržaj navbara
   ulijevo koliko toggle zauzima da se ne preklapaju. Namjerno bez media queryja:
   Bootstrap .container ima diskretne max-width skokove (540/720/960/1140/1320px)
   pa se preklapanje javljalo iznova malo iznad svakog od tih pragova (npr. 768,
   992, 1200px) kad bi padding bio ograničen na uski raspon širina - konstantan
   padding na svim širinama je jednostavniji i pouzdaniji od gonjenja praga po
   pragu, a na širokom desktopu ostavlja tek neprimjetno malo više razmaka. */
.landing-navbar > .container {
  padding-inline-end: 4rem;
}

/* Areas/Auth/Views/Auth/*.cshtml - centrirana kartica za prijavu/registraciju/itd,
   koristi _LayoutLanding (bez sidebar-a) pa ovdje vertikalno centriramo sadržaj sam. */
.auth-shell {
  min-height: 100vh;
  display: flex;
  align-items: center;
  padding: 3rem 0;
}

.auth-card-wrap {
  width: 100%;
  max-width: 26rem;
  margin-inline: auto;
}

/* Isti stil linka nazad na landing kao .landing-brand, ali izvan tamnog navbara
   (auth kartice sjede direktno na .landing-body pozadini) pa koristi zadanu
   tekst boju umjesto bijele koju .landing-brand nasilno postavlja u headeru. */
.auth-brand {
  color: var(--default-text-color);
}

/* Auth kartice (Login/Register/ForgotPassword/VerifyEmail/InviteAccept/
   AccessDenied) - svijetli Figma stil (2026-07-13): kartica na krem
   .landing-body pozadini, prati light/dark temu kroz theme tokene.
   Zamijenio raniji uvijek-tamni Vanta HALO hero (.auth-hero + #net +
   wwwroot/js/auth-animation.js, obrisan) i .auth-card-glass frosted-glass
   blok s ~15 hardkodiranih bijelo-na-tamnom overridea - stari kod u git
   history. Formama i Choices.js dropdownovima sada je dovoljno defaultno
   vendorsko tematiziranje jer kartica vise nije "uvijek tamna". */
/* Card background is deliberately one step darker than the shared --custom-white token (2026-07-28
   feedback) - --custom-white (#F2F3F5) sits almost flush against .landing-body's Off White
   (#FAFAFB), near-zero contrast for a card that needs to visually separate from the page. Standard
   Cool Gray via --secondary-rgb (#E6E8EB, same Cool Gray already used for card headers/footers) -
   briefly nudged to a custom one-off darker value (2026-07-29, "sign in daj malo tamniju pozadinu
   kartice"), then explicitly put back to the named Cool Gray swatch same day ("na auth ekranima
   stavi cool gray pozadinu cards") rather than keeping the one-off shade. Applies to every Auth
   view via the shared .auth-card class (Login/Register/ForgotPassword/VerifyEmail/InviteAccept/
   InviteConfirm/InviteInvalid/InviteEmailMismatch/AccessDenied), not just Sign in. Light-mode
   only - explicitly reverted to var(--custom-white) below for dark mode - user confirmed dark
   mode already looks right, this must not change it. */
.card.auth-card {
  background-color: rgb(var(--secondary-rgb));
  border-radius: 1rem;
  box-shadow: 0 0.75rem 2rem rgba(43, 42, 40, 0.08);
}

[data-theme-mode="dark"] .card.auth-card {
  background-color: var(--custom-white);
}

/* Linkovi unutar auth kartice i ispod nje ("Sign up", "Forgot your
   password?") - terakota akcent kao na landing stranici. */
.auth-card a,
.auth-card-wrap > p a {
  color: rgb(var(--brand-accent-rgb));
}


/* Isticanje "popularnog" plana u cenovniku - obojeni border i senka da privuku pažnju i sugerišu
   preporučenu opciju. Koristi --brand-accent-rgb (Soft Coral), NE --primary-rgb - primary je u
   light modu Light Coral, ista nijansa kao sama kartica (--custom-white), pa bi border/sjena bili
   nevidljivi da koriste taj token (bio je to slučaj dok su oba dijelila Soft Coral prije
   2026-07-27). Soft Coral kao odvojeni "accent" token radi u oba teme bez posebnog dark override-a
   (koji je zato uklonjen - bio je identičan ovom pravilu). */
/* !important added 2026-08-24 - found while chasing why .plan-card-current wasn't rendering at
   all: the 2026-07-30 ".card { border: none !important; box-shadow: none !important; }" reset
   above (search "makni borders sa svih card") silently killed this rule's border/shadow too,
   since neither had !important of its own to beat it - same root cause, same fix. */
.pricing-card.popular {
  border: 1px solid rgb(var(--brand-accent-rgb)) !important;
  box-shadow: 0 0.5rem 1.5rem rgba(var(--brand-accent-rgb), 0.15) !important;
}

/* Plan/Choose "current plan" card (2026-08-24, "ne vidim koji je current plan koji imam...
   blago povecanje i twilight indigo bordere oko kartice") - first pass relied on the inline
   border-success/border-2/bg-success-transparent utility classes plus a plain box-shadow here,
   but NONE of that actually rendered (confirmed via a live screenshot - the card looked identical
   to its siblings). Root cause: the 2026-07-30 ".card { border: none !important; box-shadow: none
   !important; }" reset above (search "makni borders sa svih card") applies border-STYLE:none to
   every card - Bootstrap's border-color/border-width utilities never touch border-style at all,
   so even a "winning" border-color cascade still draws nothing, and the reset's !important
   box-shadow:none beats this rule's non-important one outright regardless of source order. Fixed
   by taking over the full border shorthand (style+width+color) and box-shadow here directly, with
   !important of our own - same specificity as the reset (.plan-card-current and .card are both
   single-class selectors) so source order decides, and this rule is declared after it. */
.plan-card-current {
  border: 2px solid rgb(var(--success-rgb)) !important;
  /* 2026-08-24 follow-up ("stavi drugaciji background da se vidi da je to current") - 0.08 was
     too close to the flat #ededed card background (see the "makni borders sa svih card" reset
     above) to actually read as different at a glance; bumped to 0.16 so the tint is clearly
     visible without going full-solid-navy (which would fight the card's own dark text). */
  background-color: rgba(var(--success-rgb), 0.16) !important;
  box-shadow: 0 0.75rem 1.75rem rgba(var(--success-rgb), 0.22) !important;
  position: relative;
  z-index: 1;
}
/* The scale-up is md+ only - at the single-column mobile/tablet width (row-cols-md-3) a scaled
   card has no siblings to stand out against and risks clipping against the column's own padding. */
@media (min-width: 768px) {
  .plan-card-current {
    transform: scale(1.04);
  }
}

/* Plan/Choose Monthly/Annual toggle - which price reads as "selected" (2026-08-24, "kada
   promijenim na annual zamijeni mjesta da je veci font na cijeni koja je odabrana, a manjim
   fontom stavi onu koja nije odabrana") - chooseController.js's render() has toggled these two
   classes on .js-price-monthly/.js-price-yearly since 2026-08-21, but nothing ever actually
   styled them, so switching Monthly/Annual had no visual size change at all until now. !important
   because .js-price-monthly already carries its own explicit fs-24 utility class (and
   .js-price-yearly's wrapping div carries fs-13) that this needs to override regardless of the
   two rules' source order. 1.5rem matches fs-24's own value (the size the "always big" monthly
   price used before this toggle existed), so the selected price never looks smaller than it used
   to - only the DESELECTED side now visibly shrinks instead of staying full-size for both. */
.price-selected {
  font-size: 1.5rem !important;
  transition: font-size 0.15s ease, opacity 0.15s ease;
}
.price-deselected {
  font-size: 0.875rem !important;
  opacity: 0.6;
  transition: font-size 0.15s ease, opacity 0.15s ease;
}

/* Veliki, providni znak navodnika u kartici sa preporukom (testimonial) kao dekorativni vizuelni element */
.testimonial-card .ti-quote {
  font-size: 28px;
  color: rgba(var(--primary-rgb), 0.25);
}

/* Linkovi u footeru su providno beli i bez podvlačenja, jer se nalaze na tamnoj pozadini footera */
.landing-footer a {
  color: rgba(255, 255, 255, 0.65);
  text-decoration: none;
}

/* Na hover, link u footeru postaje potpuno beo kao indikacija da je klikabilan */
.landing-footer a:hover {
  color: #fff;
}

/* Krugovi sa ikonicama društvenih mreža u footeru - blago providna pozadina da se uklope u tamni footer, centrirana ikonica unutra */
.landing-footer .social-icon {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background-color: rgba(255, 255, 255, 0.08);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #fff;
}

/* Views/Shared/_ContactsModal.cshtml */
/* Modal "zalijepljen" za dno ekrana umjesto centriran - koristi se za kontakt modal koji se otvara klikom u headeru */
.modal-dialog-bottom {
  position: absolute;
  top: auto;
  bottom: 0;
  left: 0;
  margin: 0;
  min-width: 100%;
}

.modal-dialog-bottom .modal-dialog {
  width: 100%;
  max-width: 100%;
  margin: 0;
}

.modal-dialog-bottom .modal-content {
  border-radius: 1rem 1rem 0 0;
  border: 0;
}

/* Providna (transparent) pozadina sadržaja modala - koristi istu boju kao appina
   pozadina (--body-bg-rgb, krem u light modu), samo malo tamniju nijansu (color-mix
   s crnom) da se modal ipak odvoji od pozadine iza njega. U dark modu koristi
   --body-bg-rgb2 - to JE stvarna pozadina bodyja u dark modu (#2B2A28, vidi
   definicije gore u ovoj datoteci) - bez dodatnog tamnjenja, jer je već tamna.
   backdrop-filter + vidljiv border (--default-border, i on je theme-aware) +
   sjena osiguravaju kontrast/"glass" efekt u oba teme. */
.modal-transparent .modal-content {
  background: color-mix(in srgb, rgb(var(--body-bg-rgb)) 80%, black 20%);
  border: 1px solid var(--default-border);
  border-bottom: 0;
  box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}

[data-theme-mode="dark"] .modal-transparent .modal-content {
  background: rgb(var(--body-bg-rgb2));
}

/* Kontakt "kartice" (badge style) unutar contacts modala - ostaju u jednom redu i na
   mobile (row-cols-3). Modal pozadina je sad krem (light) / ugljen (dark) umjesto
   fiksno tamne, pa su i kartice/tekst theme-aware: tamni "ink" overlay + tamni tekst
   (var(--default-text-color)) na svjetloj krem pozadini u light modu, bijeli overlay +
   bijeli tekst na tamnoj pozadini u dark modu (isti par vrijednosti kao ranije). */
.contact-pill {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .4rem;
  padding: 1rem .5rem .85rem;
  border-radius: 1rem;
  background: rgba(43, 42, 40, 0.05);
  border: 1px solid rgba(43, 42, 40, 0.12);
  box-shadow: 0 2px 10px rgba(43, 42, 40, 0.08);
  color: var(--default-text-color);
  transition: background-color .15s ease, border-color .15s ease, transform .15s ease, box-shadow .15s ease;
}

.contact-pill:hover,
.contact-pill:focus {
  background: rgba(43, 42, 40, 0.09);
  border-color: rgba(43, 42, 40, 0.22);
  color: var(--default-text-color);
  transform: translateY(-3px);
  box-shadow: 0 8px 18px rgba(43, 42, 40, 0.16);
}

[data-theme-mode="dark"] .contact-pill {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.14);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.25);
}

[data-theme-mode="dark"] .contact-pill:hover,
[data-theme-mode="dark"] .contact-pill:focus {
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.3);
  color: #fff;
  box-shadow: 0 8px 18px rgba(0, 0, 0, 0.35);
}

/* Ikona u kružnom "badge"-u, drugačija boja po tipu kontakta - koriste se
   --info/--warning-rgb (dobro kontrastne na kartici u oba teme jer im je nijansa
   dovoljno drugačija od krem/ugljen pozadine modala). Phone ikona namjerno NE
   koristi accent boju (--success-rgb bi bila preblizu neutralnoj krem/ugljen
   podlozi) - umjesto toga koristi isti "ink"/bijeli par kao .contact-pill gore,
   theme-aware, da ostane vidljiva u oba moda. */
.contact-pill-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  font-size: 1.1rem;
}

.contact-pill-icon--mail {
  background: rgba(var(--info-rgb), 0.18);
  color: rgb(var(--info-rgb));
}

.contact-pill-icon--phone {
  background: rgba(43, 42, 40, 0.1);
  color: var(--default-text-color);
}

[data-theme-mode="dark"] .contact-pill-icon--phone {
  background: rgba(255, 255, 255, 0.16);
  color: rgba(255, 255, 255, 0.95);
}

.contact-pill-icon--web {
  background: rgba(var(--warning-rgb), 0.18);
  color: rgb(var(--warning-rgb));
}

.contact-pill-value {
  font-size: .8125rem;
  font-weight: 600;
}

.contact-pill-label {
  font-size: .7rem;
  text-transform: uppercase;
  letter-spacing: .03em;
  opacity: .65;
}

@media (max-width: 575.98px) {
  .contact-pill {
    padding: .75rem .35rem .65rem;
  }

  .contact-pill-icon {
    width: 2.1rem;
    height: 2.1rem;
    font-size: 1rem;
  }

  .contact-pill-value {
    font-size: .6875rem;
  }
}

/* Views/Shared/AccessDenied.cshtml (Error.cshtml i NotFoundPage.cshtml su prešli
   na .error-page-card niže; GlobalError.cshtml je obrisan kao mrtav duplikat) */
/* Blago obojena pozadina kartice na error/not-found/access-denied stranicama (sekundarna
   boja teme, low-opacity) da se kartica odvoji od bijele pozadine layouta - bez ovoga
   kartica nije imala nikakvu pozadinu jer ova klasa do sada nije bila definirana nigdje. */
.bg-fadedSecondary {
  background-color: rgba(var(--secondary-rgb), 0.08);
}

/* Naslov greške - veći i deblji od standardnog paragrafa da privuče pažnju kao naslov */
.error-heading {
  font-size: 1.4rem;
  font-weight: 600;
  color: var(--default-text-color);
}

/* Opis ispod naslova greške - suptilnija (muted) boja da naslov ostane fokus pažnje.
   Mora biti vendorov --text-muted, NE Bootstrapov --bs-secondary-color: vendorov dark
   blok redefinira samo svoje varijable, pa bi bs-secondary ostao taman (nečitljiv)
   u dark modu. */
.error-desc {
  color: var(--text-muted, #6c757d);
  font-size: 0.95rem;
}

/* "Back to previous page" link (2026-07-28) - browser-history back, sits below the Home/Contact
   support buttons. Muted by default (a lower-priority action than the two buttons above it),
   brand-colored on hover/focus so it still reads as clickable. */
.error-back-link {
  color: var(--text-muted, #6c757d);
  font-size: 0.875rem;
  text-decoration: none;
}
.error-back-link:hover,
.error-back-link:focus {
  color: rgb(var(--primary-rgb));
  text-decoration: underline;
}

/* Panel s dijagnostičkim podacima na Error.cshtml (korisnik, URL, poruka, request id) -
   uokviren i lijevo poravnat (umjesto centriranog teksta kartice) da parovi
   labela/vrijednost djeluju kao čitljiva tablica, ne kao centrirani paragraf. */
.error-diag-panel {
  max-width: 700px;
  margin: 0 auto 1.5rem;
  padding: 1rem 1.25rem;
  background-color: var(--custom-white, #fff);
  border: 1px solid var(--default-border);
  border-radius: 0.75rem;
}

.error-diag-fields {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.error-diag-field {
  display: flex;
  justify-content: normal;
  gap: 1rem;
  font-size: 0.8125rem;
}
@media (max-width: 576px) {
  .error-diag-field {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.25rem;
  }
  @media (max-width: 576px) {
    .error-diag-panel {
      padding: 0.75rem 1rem;
    }
  }

  .error-diag-value {
    text-align: left; /* umjesto desno na mobitelu */
  }
}

.error-diag-label {
  /* var(--text-muted) umjesto --bs-secondary-color iz istog razloga kao .error-desc */
  color: var(--text-muted, #6c757d);
  font-weight: 500;
  white-space: nowrap;
}

.error-diag-value {
  font-weight: 500;
  text-align: right;
  word-break: break-word;
}

/* .card-title bold (2026-07-21) - vendor theme only bolds it under the unused
   .custom-card scope (see styles.css), so plain .card cards (all of InternalAdmin)
   rendered card headers at normal weight - hard to tell cards apart at a glance
   when several sit next to each other (e.g. Facility Details' Seats/Members/
   Add member/Pending invites row). Bumping it globally, not per-page. Font-size
   pinned to 0.80rem (2026-07-29) - vendor default read too large next to the
   compact header row height (--card-header's own min-height below). */
.card-title {
  font-weight: 700;
  font-size: 0.80rem;
}

/* .card-header .card-title vertical centering (2026-07-21) - .card-title still carries
   Bootstrap's default margin-bottom (--bs-card-title-spacer-y, 0.5rem) with no matching
   top margin. Every InternalAdmin header already sets d-flex align-items-center to
   center the title in the header row, but flexbox centers the margin box - a
   bottom-only margin pushes the visible text above true center (visible on e.g.
   Facility Details' "License history" header). Only a couple of headers worked
   around this per-instance with an explicit mb-0 (Entitlements/Override's user card).
   Zeroing it for every .card-header .card-title fixes centering app-wide instead of
   requiring mb-0 on each new header. */
.card-header .card-title {
  margin-bottom: 0;
}

/* Consistent card-header height (2026-07-21) - headers with a btn-sm action (e.g.
   Facility Details' "Members" / "Add member") render taller than plain-text-only
   headers (e.g. "Facility info"), since a .card-header only grows to fit its
   tallest child and Bootstrap's default cap padding is too tight to fit a button
   without stretching. Reserving that height on every header up front via min-height
   means a header's height no longer changes depending on whether it happens to have
   a button - text-only headers now match "Members" instead of looking thinner. */
.card-header {
  min-height: 3.25rem;
}

/* Accent card headers (2026-07-21) - opt-in .card-header-accent-{color} modifier for
   screens that stack several plain-white cards next to/under each other (Facility
   Details' license + members&seats tabs, and similar Users/Billing/Entitlements
   screens) where the bold title above still wasn't enough separation. The border-left
   itself was removed 2026-07-30 ("makni left border sa svih card i custom card") -
   the color-coded title text below stays, that alone is enough separation without a
   colored bar down the side of the header. */
.card-header-accent-primary { border-left: none; }
.card-header-accent-primary .card-title { color: rgb(var(--primary-rgb)); }

.card-header-accent-success { border-left: none; }
.card-header-accent-success .card-title { color: rgb(var(--success-rgb)); }

.card-header-accent-warning { border-left: none; }
.card-header-accent-warning .card-title { color: rgb(var(--warning-rgb)); }

.card-header-accent-danger { border-left: none; }
.card-header-accent-danger .card-title { color: rgb(var(--danger-rgb)); }

.card-header-accent-info { border-left: none; }
.card-header-accent-info .card-title { color: rgb(var(--info-rgb)); }

.card-header-accent-secondary { border-left: none; }
.card-header-accent-secondary .card-title { color: rgb(var(--secondary-rgb)); }

/* Dark-mode card-header text: white, bold (2026-07-30 ask - "u dark mode stavi text bijele boje
   sa fontweight 700 u card header"), applied uniformly to every .card-header regardless of
   .custom-card/accent variant. This selector's specificity (3 class-level selectors) beats the
   accent rules above (2 each - .card-header-accent-x .card-title), so it wins in dark mode
   without needing !important - every header's title goes white/bold, hue-coded accent colors
   included, rather than carving out an exception for them. */
[data-theme-mode="dark"] .card-header .card-title {
  color: #ffffff;
  font-weight: 700;
}

/* Suptilna pozadina za <thead> svake tablice po defaultu - vendorski styles.css razlikuje header
   od tijela tablice samo debljinom fonta (nema background-color), pa se teško vizualno odvoje.
   Vendor ima i gotov ".table-light" modifier (opt-in, mora se ručno dodati na <thead>), ali ga
   nijedan ekran u appu stvarno ne koristi - ovdje ga radimo default, bez extra klase. Override ide
   preko --bs-table-bg (ne flat background-color) da ga svaki <th> naslijedi kroz Bootstrap 5.3-ovo
   vlastito pravilo "background-color: var(--bs-table-bg)" po ćeliji - isti mehanizam kao inline
   --bs-table-bg highlight aktivne licence na Facility Details. */
.table > thead {
  --bs-table-bg: rgb(var(--light-rgb));
}

/* Error/404 ekrani (Views/Shared/Error.cshtml + NotFoundPage.cshtml) - zajednička
   "hero" kartica, centrirana u prostoru ispod headera. Sve boje idu preko theme
   tokena (--custom-white, --default-border, --primary-rgb...) pa kartica prati
   light/dark mode bez posebnih override-a. */
.error-page {
  display: flex;
  align-items: center;
  justify-content: center;
  /* dovoljno visine da kartica sjedne optički u sredinu sadržajnog prostora,
     bez izazivanja scrolla na desktopu */
  min-height: min(70vh, 44rem);
  padding: 2rem 1rem;
}

.error-page-card {
  width: 100%;
  max-width: 34rem;
  text-align: center;
  background-color: var(--custom-white, #fff);
  border: 1px solid var(--default-border);
  border-radius: 1.25rem;
  padding: 2.75rem 1.75rem;
  box-shadow: 0 0.75rem 2.5rem rgba(var(--dark-rgb), 0.06);
}

/* Šira varijanta za Error.cshtml - dijagnostički panel (URL, poruka...) treba
   više širine da parovi labela/vrijednost ne lome svaki red. */
.error-page-card--wide {
  max-width: 44rem;
}

/* Kružna ikona iznad koda greške - primary tint za 404, danger tint za error. */
.error-page-icon {
  width: 4.25rem;
  height: 4.25rem;
  margin: 0 auto 1.25rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background-color: rgba(var(--primary-rgb), 0.12);
  color: rgb(var(--primary-rgb));
  font-size: 2rem;
}

.error-page-icon--danger {
  background-color: rgba(var(--danger-rgb), 0.12);
  color: rgb(var(--danger-rgb));
}

/* Veliki statusni kod ("404" / "Oops") - clamp da na mobitelu ne dominira. */
.error-page-code {
  font-size: clamp(3rem, 9vw, 4.5rem);
  font-weight: 700;
  line-height: 1.1;
  margin-bottom: 0.5rem;
  color: rgb(var(--primary-rgb));
}

.error-page-code--danger {
  color: rgb(var(--danger-rgb));
}

/* Traženi URL na 404 stranici - <code> na tintanoj pozadini; token boje umjesto
   Bootstrapove --bs-code-color (dark blok teme je ne redefinira). */
.error-page-url code {
  display: inline-block;
  max-width: 100%;
  padding: 0.35rem 0.75rem;
  border-radius: 0.5rem;
  background-color: rgba(var(--dark-rgb), 0.06);
  color: var(--default-text-color);
  font-size: 0.8125rem;
  word-break: break-all;
}

/* Remix Icon (klasa "ri") koja stoji uz tekst (npr. u dugmićima/linkovima: <i class="ri ri-..."></i> Tekst)
   automatski dobija razmak prema tekstu, kao da je ručno dodana Bootstrap klasa "me-1" - ne treba je
   više pisati u markup-u. Tekst iza ikone je obično čvor teksta (ne element), pa ga :last-child/
   :only-child ne broji - zato se margina primjenjuje uvijek kad je klasa "ri" prisutna. Icon-only
   dugmići/linkovi (bez teksta iza ikone) zato po konvenciji NE dodaju bazu "ri", samo specifičnu
   "ri-..." klasu (vidi npr. Demo/ProductsList.cshtml), pa ovo pravilo na njih ne utječe. */
.ri {
  margin-inline-end: 0.25rem;
}

/* Sidemenu-toggle (hamburger u headeru): .animated-arrow-ova jedina sadržina
   (raspon od 3 crtice) je position:absolute, pa sam <a> element (koji ima
   .header-link { padding: 0 0.5rem } - dakle 0 vertikalnog paddinga) nema
   nijedan element u tijeku (in-flow) koji bi mu dao visinu - box kolabira na
   visinu 0. Vizualno se ikona i dalje vidi (apsolutno pozicionirana), ali
   klikabilna površina gumba svodi se na ~1px traku, pa je gotovo nemoguće
   pogoditi klikom/dodirom - korisnik doživljava kao da collapse ne radi.
   Dajemo gumbu istu visinu kao ostale header-link ikone i re-centriramo
   crtice unutar nje. */
.app-header .sidemenu-toggle.animated-arrow.hor-toggle {
  height: 2rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* .header-element (its flex parent) uses align-items: stretch; a fixed
     height overrides the stretch sizing but the item still falls back to
     flex-start (top) instead, since align-items: stretch only re-centers
     items with an auto cross size. Without this it sits noticeably above
     the vertically-centered logo next to it (most visible on the short
     mobile header). */
  align-self: center;
}

.app-header .sidemenu-toggle.animated-arrow.hor-toggle span {
  top: 50%;
  transform: translateY(-50%);
}

/* Header user-search box: vendor styles.css positions .header-search-icon
   with position:absolute, expecting its containing block to be the
   vendor's own .header-search wrapper (position:relative there). Our
   markup uses a custom .auto-complete-search wrapper instead (never had
   position set), so the icon falls back to the nearest positioned
   ancestor - #header itself (position:fixed also establishes a
   containing block). In vertical nav layout .app-header keeps a
   padding-inline-start reserved for the sidebar, so the icon's absolute
   offset from the header's border-box happens to land close to the
   actual search input by coincidence. Switching to horizontal nav layout
   removes that padding (styles.css: [data-nav-layout=horizontal]
   .app-header { padding-inline-start: 0 !important }), so the header's
   border-box starts at the viewport edge and the icon renders pinned to
   the literal top-left corner of the page instead of over the input. */
.auto-complete-search {
  position: relative;
}

/* Desktop-only: the wrapper otherwise sits flush against the next header
   icon (Help & contacts) since neither has its own spacing. Scoped to
   >=768px so the mobile icon-only/expanded-overlay behavior below is
   untouched. */
@media (min-width: 768px) {
  .auto-complete-search {
    padding-inline-end: 0.75rem;
  }
}

/* Vendor's light-theme header search border (#e6ebf1, styles.css ~L1164) is
   barely visible against the header's white background - darken it slightly
   so the box reads as a distinct control. Scoped to light mode only; dark
   mode's border already contrasts fine against its tinted bg. */
[data-theme-mode="light"] .app-header .header-search-bar {
  border-color: rgba(var(--primary-rgb), 0.35) !important;
}
[data-theme-mode="light"] .app-header .header-search-bar:focus {
  border-color: rgba(var(--primary-rgb), 0.6) !important;
}

/* Mobile header user-search: collapse to an icon-only button instead of
   permanently reserving the vendor's 20rem min-width input (styles.css
   .auto-complete-search .header-search-bar { min-width: 20rem !important }).
   The wrapper now lives as the first <li> in .header-content-right (see
   _main-header.cshtml), right next to the Help & contacts button, so it's
   sized/colored to match that icon group rather than the sidebar-collapse
   toggle: 2rem tap target (matches .avatar.custom-header-avatar and the
   comment on that rule below) and the same 1.2rem/default-link-color glyph
   as .header-content-right .header-link > i (styles.css's own
   [data-header-styles=light] .header-search-icon rule would otherwise tint
   it var(--header-prime-color), which doesn't match its new neighbours).
   Tapping the icon (header-actions.js) adds .search-mobile-open, which
   turns the wrapper into a centered floating box over the header (with a
   close "x" - .header-search-close) so the input and the autoComplete.js
   results list dropped below it are both centered too, rather than
   stretched edge-to-edge. Scoped below Bootstrap's md breakpoint - >=768px
   (tablet/laptop) keeps the original always-visible inline bar untouched,
   just relocated to the right-hand icon group same as mobile. */
@media (max-width: 767.98px) {
  .auto-complete-search {
    width: 2rem;
    height: 2rem;
  }
  .auto-complete-search .header-search-bar,
  .auto-complete-search .header-search-close {
    display: none;
  }
  .auto-complete-search .header-search-icon {
    top: 0;
    inset-inline-start: 0;
    width: 2rem;
    height: 2rem;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    font-size: 1.2rem;
    color: rgba(var(--dark-rgb), var(--bs-link-opacity, 1));
  }

  .auto-complete-search.search-mobile-open {
    position: absolute;
    inset-inline-start: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: calc(100% - 1.5rem);
    max-width: 26rem;
    height: auto;
    z-index: 1030;
    display: flex;
    align-items: center;
  }
  .auto-complete-search.search-mobile-open .header-search-bar {
    display: block;
    /* !important: autoComplete.js's own vendor CSS sets
       .autoComplete_wrapper > input { width: auto !important; } - without
       matching !important here the input stayed at its intrinsic ~13rem
       width, floating left inside the centered box instead of filling it
       (the bug this whole rule exists to fix). */
    width: 100% !important;
    min-width: 0 !important;
    padding-inline-start: 0.75rem !important;
    padding-inline-end: 2.25rem !important;
  }
  .auto-complete-search.search-mobile-open .autoComplete_wrapper {
    display: block;
    width: 100%;
  }
  .auto-complete-search.search-mobile-open .header-search-icon {
    display: none;
  }
  .auto-complete-search.search-mobile-open .header-search-close {
    display: flex;
    position: absolute;
    inset-inline-end: 0.5rem;
    top: 50%;
    transform: translateY(-50%);
    width: 1.75rem;
    height: 1.75rem;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
    cursor: pointer;
  }
}

/* Dugme "scroll to top" - fiksirano u donjem desnom uglu ekrana, sakriveno po defaultu (JS ga prikazuje kad korisnik skroluje na dole), kružni oblik u primary boji */
.scrollToTop {
  display: none;
  position: fixed;
  inset-inline-end: 1.5rem;
  inset-block-end: 1.5rem;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  background-color: rgb(var(--primary-rgb));
  color: #fff;
  align-items: center;
  justify-content: center;
  z-index: 1040;
  cursor: pointer;
}

/* Subscriptions list (iPhone Settings > Subscriptions pattern, 2026-08-21) - a plain list-group
   row per product, tap to expand its own detail in place underneath. Shared between the
   self-service Profile Subscriptions tab and the PtiAdmin Users/Details "Subscription & usage"
   tab, which mirrors the same layout for a PTI admin viewing another user's data. */
.subscription-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  text-align: left;
}

.subscription-row-ico {
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 0.625rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  flex-shrink: 0;
}

.subscription-row-meta {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.subscription-row-name {
  font-weight: 600;
  font-size: 0.875rem;
}

.subscription-row-sub {
  font-size: 0.75rem;
  margin-top: 0.1rem;
}

.subscription-row-chev {
  color: var(--text-muted);
  font-size: 1.1rem;
  flex-shrink: 0;
  transition: transform 0.15s ease;
}

.subscription-row.open .subscription-row-chev {
  transform: rotate(90deg);
}

.subscription-detail {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.25s ease;
  background-color: var(--default-background);
}

/* A large fixed value, not "none" - transitioning to "none" doesn't animate, and the expanded
   detail (credits/generations table included) can run past a smaller cap. */
.subscription-detail.open {
  max-height: 3000px;
}

.subscription-detail-inner {
  padding: 1rem 1.25rem 1.25rem;
}
