@charset "UTF-8";
:root {
  --primary-color: var(--p-primary-color);
  --primary-contrast-color: var(--p-primary-contrast-color);
  --text-color: var(--p-text-color);
  --text-color-secondary: var(--p-text-muted-color);
  --surface-border: var(--p-content-border-color);
  --surface-card: var(--p-content-background);
  --surface-hover: var(--p-content-hover-background);
  --surface-overlay: var(--p-overlay-popover-background);
  --transition-duration: var(--p-transition-duration);
  --maskbg: var(--p-mask-background);
  --content-border-radius: var(--p-content-border-radius);
  --layout-section-transition-duration: 0.2s;
  --element-transition-duration: var(--p-transition-duration);
  --focus-ring-width: var(--p-focus-ring-width);
  --focus-ring-style: var(--p-focus-ring-style);
  --focus-ring-color: var(--p-focus-ring-color);
  --focus-ring-offset: var(--p-focus-ring-offset);
  --focus-ring-shadow: var(--p-focus-ring-shadow);
}

:root {
  --surface-ground: var(--p-surface-100);
  --code-background: var(--p-surface-900);
  --code-color: var(--p-surface-200);
}

:root[class*=app-dark] {
  --surface-ground: var(--p-surface-950);
  --code-background: var(--p-surface-800);
  --code-color: var(--p-surface-100);
}

.preloader {
  position: fixed;
  z-index: 999999;
  background: #edf1f5;
  width: 100%;
  height: 100%;
}

.preloader-content {
  border: 0 solid transparent;
  border-radius: 50%;
  width: 150px;
  height: 150px;
  position: absolute;
  top: calc(50vh - 75px);
  left: calc(50vw - 75px);
}

.preloader-content:before, .preloader-content:after {
  content: "";
  border: 1em solid var(--primary-color);
  border-radius: 50%;
  width: inherit;
  height: inherit;
  position: absolute;
  top: 0;
  left: 0;
  animation: loader 2s linear infinite;
  opacity: 0;
}

.preloader-content:before {
  animation-delay: 0.5s;
}

@keyframes loader {
  0% {
    transform: scale(0);
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
  100% {
    transform: scale(1);
    opacity: 0;
  }
}
html {
  height: 100%;
  font-size: 14px;
  line-height: 1.2;
}

body {
  font-family: "Lato", sans-serif;
  color: var(--text-color);
  background-color: var(--surface-ground);
  margin: 0;
  padding: 0;
  min-height: 100%;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a {
  text-decoration: none;
}

.layout-wrapper {
  min-height: 100vh;
}

.layout-main-container {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  justify-content: space-between;
  padding: 6rem 2rem 0 2rem;
  transition: margin-left var(--layout-section-transition-duration);
}

.layout-main {
  flex: 1 1 auto;
  padding-bottom: 2rem;
}

.layout-topbar {
  position: fixed;
  height: 4rem;
  z-index: 997;
  left: 0;
  top: 0;
  width: 100%;
  padding: 0 2rem;
  background-color: var(--surface-card);
  transition: left var(--layout-section-transition-duration);
  display: flex;
  align-items: center;
}
.layout-topbar .layout-topbar-logo-container {
  width: 20rem;
  display: flex;
  align-items: center;
}
.layout-topbar .layout-topbar-logo {
  display: inline-flex;
  align-items: center;
  font-size: 1.5rem;
  border-radius: var(--content-border-radius);
  color: var(--text-color);
  font-weight: 500;
  gap: 0.5rem;
}
.layout-topbar .layout-topbar-logo svg {
  width: 3rem;
}
.layout-topbar .layout-topbar-logo:focus-visible {
  outline-width: var(--focus-ring-width);
  outline-style: var(--focus-ring-style);
  outline-color: var(--focus-ring-color);
  outline-offset: var(--focus-ring-offset);
  box-shadow: var(--focus-ring-shadow);
  transition: box-shadow var(--transition-duration), outline-color var(--transition-duration);
}
.layout-topbar .layout-topbar-action {
  display: inline-flex;
  justify-content: center;
  align-items: center;
  border-radius: 50%;
  width: 2.5rem;
  height: 2.5rem;
  color: var(--text-color);
  transition: background-color var(--element-transition-duration);
  cursor: pointer;
  border: none;
  background: transparent;
  -moz-appearance: none;
       appearance: none;
  -webkit-appearance: none;
  font: inherit;
}
.layout-topbar .layout-topbar-action:hover {
  background-color: var(--surface-hover);
}
.layout-topbar .layout-topbar-action:focus-visible {
  outline-width: var(--focus-ring-width);
  outline-style: var(--focus-ring-style);
  outline-color: var(--focus-ring-color);
  outline-offset: var(--focus-ring-offset);
  box-shadow: var(--focus-ring-shadow);
  transition: box-shadow var(--transition-duration), outline-color var(--transition-duration);
}
.layout-topbar .layout-topbar-action i {
  font-size: 1.25rem;
}
.layout-topbar .layout-topbar-action span {
  font-size: 1rem;
  display: none;
}
.layout-topbar .layout-topbar-action.layout-topbar-action-highlight {
  background-color: var(--primary-color);
  color: var(--primary-contrast-color);
}
.layout-topbar .layout-menu-button {
  margin-right: 0.5rem;
}
.layout-topbar .layout-topbar-menu-button {
  display: none;
}
.layout-topbar .layout-topbar-actions {
  margin-left: auto;
  display: flex;
  gap: 1rem;
}
.layout-topbar .layout-topbar-menu-content {
  display: flex;
  gap: 1rem;
}
.layout-topbar .layout-config-menu {
  display: flex;
  gap: 1rem;
}

@media (max-width: 991px) {
  .layout-topbar {
    padding: 0 2rem;
  }
  .layout-topbar .layout-topbar-logo-container {
    width: auto;
  }
  .layout-topbar .layout-menu-button {
    margin-left: 0;
    margin-right: 0.5rem;
  }
  .layout-topbar .layout-topbar-menu-button {
    display: inline-flex;
  }
  .layout-topbar .layout-topbar-menu {
    position: absolute;
    background-color: var(--surface-overlay);
    transform-origin: top;
    box-shadow: 0px 3px 5px rgba(0, 0, 0, 0.02), 0px 0px 2px rgba(0, 0, 0, 0.05), 0px 1px 4px rgba(0, 0, 0, 0.08);
    border-radius: var(--content-border-radius);
    padding: 1rem;
    right: 2rem;
    top: 4rem;
    min-width: 15rem;
    border: 1px solid var(--surface-border);
  }
  .layout-topbar .layout-topbar-menu .layout-topbar-menu-content {
    gap: 0.5rem;
  }
  .layout-topbar .layout-topbar-menu .layout-topbar-action {
    display: flex;
    width: 100%;
    height: auto;
    justify-content: flex-start;
    border-radius: var(--content-border-radius);
    padding: 0.5rem 1rem;
  }
  .layout-topbar .layout-topbar-menu .layout-topbar-action i {
    font-size: 1rem;
    margin-right: 0.5rem;
  }
  .layout-topbar .layout-topbar-menu .layout-topbar-action span {
    font-weight: medium;
    display: block;
  }
  .layout-topbar .layout-topbar-menu-content {
    flex-direction: column;
  }
}
.config-panel .config-panel-label {
  font-size: 0.875rem;
  color: var(--text-secondary-color);
  font-weight: 600;
  line-height: 1;
}
.config-panel .config-panel-colors > div {
  padding-top: 0.5rem;
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  justify-content: space-between;
}
.config-panel .config-panel-colors > div button {
  border: none;
  width: 1.25rem;
  height: 1.25rem;
  border-radius: 50%;
  padding: 0;
  cursor: pointer;
  outline-color: transparent;
  outline-width: 2px;
  outline-style: solid;
  outline-offset: 1px;
}
.config-panel .config-panel-colors > div button.active-color {
  outline-color: var(--primary-color);
}
.config-panel .config-panel-settings {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.layout-sidebar {
  position: fixed;
  width: 20rem;
  height: calc(100vh - 8rem);
  z-index: 999;
  overflow-y: auto;
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
  top: 6rem;
  left: 2rem;
  transition: transform var(--layout-section-transition-duration), left var(--layout-section-transition-duration);
  background-color: var(--surface-overlay);
  border-radius: var(--content-border-radius);
  padding: 0.5rem 1.5rem;
}

.layout-menu {
  margin: 0;
  padding: 0;
  list-style-type: none;
}
.layout-menu .layout-root-menuitem > .layout-menuitem-root-text {
  font-size: 0.857rem;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--text-color);
  margin: 0.75rem 0;
}
.layout-menu .layout-root-menuitem > a {
  display: none;
}
.layout-menu a {
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}
.layout-menu a.active-menuitem > .layout-submenu-toggler {
  transform: rotate(-180deg);
}
.layout-menu li.active-menuitem > a .layout-submenu-toggler {
  transform: rotate(-180deg);
}
.layout-menu ul {
  margin: 0;
  padding: 0;
  list-style-type: none;
}
.layout-menu ul a {
  display: flex;
  align-items: center;
  position: relative;
  outline: 0 none;
  color: var(--text-color);
  cursor: pointer;
  padding: 0.75rem 1rem;
  border-radius: var(--content-border-radius);
  transition: background-color var(--element-transition-duration), box-shadow var(--element-transition-duration);
}
.layout-menu ul a .layout-menuitem-icon {
  margin-right: 0.5rem;
}
.layout-menu ul a .layout-submenu-toggler {
  font-size: 75%;
  margin-left: auto;
  transition: transform var(--element-transition-duration);
}
.layout-menu ul a.active-route {
  font-weight: 700;
  color: var(--primary-color);
}
.layout-menu ul a:hover {
  background-color: var(--surface-hover);
}
.layout-menu ul a:focus {
  outline-offset: -1px;
  box-shadow: inset var(--focus-ring-shadow);
}
.layout-menu ul ul {
  overflow: hidden;
  border-radius: var(--content-border-radius);
}
.layout-menu ul ul li a {
  margin-left: 1rem;
}
.layout-menu ul ul li li a {
  margin-left: 2rem;
}
.layout-menu ul ul li li li a {
  margin-left: 2.5rem;
}
.layout-menu ul ul li li li li a {
  margin-left: 3rem;
}
.layout-menu ul ul li li li li li a {
  margin-left: 3.5rem;
}
.layout-menu ul ul li li li li li li a {
  margin-left: 4rem;
}

.layout-submenu-enter-from,
.layout-submenu-leave-to {
  max-height: 0;
}

.layout-submenu-enter-to,
.layout-submenu-leave-from {
  max-height: 1000px;
}

.layout-submenu-leave-active {
  overflow: hidden;
  transition: max-height 0.45s cubic-bezier(0, 1, 0, 1);
}

.layout-submenu-enter-active {
  overflow: hidden;
  transition: max-height 1s ease-in-out;
}

.layout-footer {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem 0 1rem 0;
  gap: 0.5rem;
  border-top: 1px solid var(--surface-border);
}

@media screen and (min-width: 1960px) {
  .layout-main,
  .landing-wrapper {
    width: 1504px;
    margin-left: auto !important;
    margin-right: auto !important;
  }
}
@media (min-width: 992px) {
  .layout-wrapper.layout-overlay .layout-main-container {
    margin-left: 0;
    padding-left: 2rem;
  }
  .layout-wrapper.layout-overlay .layout-sidebar {
    transform: translateX(-100%);
    left: 0;
    top: 0;
    height: 100vh;
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    border-right: 1px solid var(--surface-border);
    transition: transform 0.4s cubic-bezier(0.05, 0.74, 0.2, 0.99), left 0.4s cubic-bezier(0.05, 0.74, 0.2, 0.99);
    box-shadow: 0px 3px 5px rgba(0, 0, 0, 0.02), 0px 0px 2px rgba(0, 0, 0, 0.05), 0px 1px 4px rgba(0, 0, 0, 0.08);
  }
  .layout-wrapper.layout-overlay.layout-overlay-active .layout-sidebar {
    transform: translateX(0);
  }
  .layout-wrapper.layout-static .layout-main-container {
    margin-left: 22rem;
  }
  .layout-wrapper.layout-static.layout-static-inactive .layout-sidebar {
    transform: translateX(-100%);
    left: 0;
  }
  .layout-wrapper.layout-static.layout-static-inactive .layout-main-container {
    margin-left: 0;
    padding-left: 2rem;
  }
  .layout-wrapper .layout-mask {
    display: none;
  }
}
@media (max-width: 991px) {
  .blocked-scroll {
    overflow: hidden;
  }
  .layout-wrapper .layout-main-container {
    margin-left: 0;
    padding-left: 2rem;
  }
  .layout-wrapper .layout-sidebar {
    transform: translateX(-100%);
    left: 0;
    top: 0;
    height: 100vh;
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    transition: transform 0.4s cubic-bezier(0.05, 0.74, 0.2, 0.99), left 0.4s cubic-bezier(0.05, 0.74, 0.2, 0.99);
  }
  .layout-wrapper .layout-mask {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 998;
    width: 100%;
    height: 100%;
    background-color: var(--maskbg);
  }
  .layout-wrapper.layout-mobile-active .layout-sidebar {
    transform: translateX(0);
  }
  .layout-wrapper.layout-mobile-active .layout-mask {
    display: block;
  }
}
/* Utils */
.clearfix:after {
  content: " ";
  display: block;
  clear: both;
}

/* Horizontal gutter shared by every page's content edge, so ONE left/right line runs through
   list titles + toolbars + grid columns AND detail headers, tab labels, form fields and
   in-tab grid toolbars. Change it here to move every screen's side indent together; list and
   detail stay aligned. (Only the side gutter — vertical card padding stays the base 2rem.) */
.card {
  background: var(--surface-card);
  padding: 2rem;
  margin-bottom: 2rem;
  border-radius: var(--content-border-radius);
}
.card:last-child {
  margin-bottom: 0;
}

/* Tabbed detail cards (Company/Person/User/Role/… detail):
   - fill the content area to the viewport bottom in every module, so the card is
     always full-height; a short grid sits at the top, a tall one scrolls INSIDE
     the tab (the page itself never scrolls). Fixed calc height, NOT flex:1, because
     .layout-main-container uses min-height:100vh so % heights don't resolve.
     8rem = 6rem topbar pad + 2rem page bottom pad (.layout-main-container/.layout-main).
   - the header, tab labels and content all keep the shared side gutter
     ($fire-content-gutter) so they line up on one left/right edge; grid ROWS still run
     edge-to-edge under that (only the first/last column content is indented).
   Applies to EVERY tabbed detail card, host and package (incl. the device-detail
   module) — one boilerplate-wide contract, no per-view scoped duplicates.
   Vertical-tab cards (.settings-vertical-tabs — left tab list, right panel) manage
   their own layout and must NOT be forced into this column/edge-to-edge contract. */
.card:has(> .p-tabs):not(:has(> .settings-vertical-tabs)) {
  height: calc(100vh - 8rem);
  min-height: 0;
  margin-bottom: 0;
  padding-left: 0;
  padding-right: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.card:has(> .p-tabs):not(:has(> .settings-vertical-tabs)) > .fire-detail-header {
  flex: none;
  padding-left: 1.5rem;
  padding-right: 1.5rem;
}
.card:has(> .p-tabs):not(:has(> .settings-vertical-tabs)) .p-tabs {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.card:has(> .p-tabs):not(:has(> .settings-vertical-tabs)) .p-tablist {
  flex: none;
  padding-left: 0;
  padding-right: 0;
}
.card:has(> .p-tabs):not(:has(> .settings-vertical-tabs)) {
  /* Shift the tab strip in so the FIRST tab's label lands on the shared gutter, lining up
     with the header + content below. Aura pads each tab by 1.125rem, so the inner tab row
     only needs (gutter − 1.125rem). Padding the INNER .p-tablist-tab-list (not the root)
     moves the tabs AND their active-bar together, while the tablist's full-width bottom
     divider — which sits on an ancestor — stays edge-to-edge. */
}
.card:has(> .p-tabs):not(:has(> .settings-vertical-tabs)) .p-tablist-tab-list {
  padding-left: 0.375rem;
}
.card:has(> .p-tabs):not(:has(> .settings-vertical-tabs)) .p-tabpanels {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding-left: 0;
  padding-right: 0;
}
.card:has(> .p-tabs):not(:has(> .settings-vertical-tabs)) {
  /* the active tab body fills the rest; tall content scrolls here */
}
.card:has(> .p-tabs):not(:has(> .settings-vertical-tabs)) .p-tabpanel {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
}
.card:has(> .p-tabs):not(:has(> .settings-vertical-tabs)) {
  /* Give the CONTENT the shared side gutter so form fields / grid controls line up with the
     header + tab labels — but keep the grid ROWS running edge-to-edge:
     - form tabs (no grid): indent the whole panel;
     - grid tabs: indent the toolbar AND the grid's first/last column (rule below); the row
       stripes stay full-width. The toolbar is either the grid's own `.fire-grid-toolbar`
       (host list-in-tab) OR a tab's custom `*-toolbar` placed outside the grid
       (device-detail's per-tab toolbars), so match both via the `-toolbar` suffix.
     - dashboard tabs: excluded — a dashboard manages its own edge spacing (the widget grid
       sits at its own offset), so the panel runs edge-to-edge like grids. */
}
.card:has(> .p-tabs):not(:has(> .settings-vertical-tabs)) .p-tabpanel:not(:has(.fire-grid)):not(:has(.device-dashboard)) {
  padding-left: 1.5rem;
  padding-right: 1.5rem;
}
.card:has(> .p-tabs):not(:has(> .settings-vertical-tabs)) .p-tabpanel:has(.fire-grid) [class$=-toolbar] {
  padding-left: 1.5rem;
  padding-right: 1.5rem;
}
.card:has(> .p-tabs):not(:has(> .settings-vertical-tabs)) {
  /* an embedded grid's OUTER columns align to the same gutter (mirrors the list-page rule):
     only the first/last cell is indented, the row stripes keep bleeding to the card edge */
}
.card:has(> .p-tabs):not(:has(> .settings-vertical-tabs)) .p-tabpanel .p-datatable-thead > tr > th:first-child,
.card:has(> .p-tabs):not(:has(> .settings-vertical-tabs)) .p-tabpanel .p-datatable-tbody > tr > td:first-child {
  padding-left: 1.5rem;
}
.card:has(> .p-tabs):not(:has(> .settings-vertical-tabs)) .p-tabpanel .p-datatable-thead > tr > th:last-child,
.card:has(> .p-tabs):not(:has(> .settings-vertical-tabs)) .p-tabpanel .p-datatable-tbody > tr > td:last-child {
  padding-right: 1.5rem;
}

/* Dashboard tab runs its own tinted canvas full-bleed: the .p-tabpanels default vertical
   padding (Aura ~.875rem/1.125rem) and the card's 2rem bottom padding would frame that
   canvas in white top + bottom. Drop them WHILE the dashboard tab is active (scoped to the
   active panel so form/grid tabs keep their spacing), so the canvas meets the tab strip and
   the card's bottom edge with no gap — the vertical analogue of the grid card's flush pager. */
.card:has(> .p-tabs):has(.p-tabpanel-active > .device-dashboard) {
  padding-bottom: 0;
}
.card:has(> .p-tabs):has(.p-tabpanel-active > .device-dashboard) > .p-tabs > .p-tabpanels {
  padding-top: 0;
  padding-bottom: 0;
}

/* Root-wrapper full-height for multi-card / master-detail pages that don't fit the
   single-card .form-body contract (Role detail, Profile, Groups). The wrapper becomes a
   viewport-tall flex column (same 8rem offset as every other screen); each view decides
   which of its cards stays pinned and which grows + scrolls internally, so the page
   itself never scrolls. Views set their own overflow + per-card flex in scoped styles. */
.page-fill {
  height: calc(100vh - 8rem);
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* Plain form-detail cards (User/Role/Profile/Group detail — no tabs, no grid) fill the
   viewport too, so a form screen is as tall as every list/tabbed screen (same 8rem
   offset). The header stays pinned; the fields + action bar scroll inside .form-body —
   identical behaviour to a tabbed detail's General tab, just without the tab strip.
   Marker is a direct .form-body child, so any form view opts in by wrapping its
   sections + .form-actions in <div class="form-body">. */
.card:has(> .form-body) {
  height: calc(100vh - 8rem);
  min-height: 0;
  margin-bottom: 0;
  /* same shared side gutter as the tabbed + list cards, so a plain form screen's header and
     fields line up with every other screen; vertical padding stays the base 2rem */
  padding-left: 1.5rem;
  padding-right: 1.5rem;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.card:has(> .form-body) > .fire-detail-header {
  flex: none;
}
.card:has(> .form-body) > .form-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
}

/* List-page grid cards fill the viewport too (same 8rem offset): the title + search
   toolbar stay pinned, the table body scrolls internally, and the paginator stays at
   the card bottom — the page itself never scrolls. Only top-level list grids match
   (.fire-grid.card); embedded grids inside tabs/dialogs are untouched. */
.fire-grid.card {
  height: calc(100vh - 8rem);
  min-height: 0;
  margin-bottom: 0;
  /* Content gutter: title + search toolbar keep the shared side gutter while the grid rows
     run edge-to-edge. The paginator is the card's footer, so drop the base 2rem bottom
     padding too — it sits flush at the card edge instead of leaving dead space below the
     pager. */
  padding-left: 0;
  padding-right: 0;
  padding-bottom: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.fire-grid.card > .fire-page-title,
.fire-grid.card > .fire-detail-header,
.fire-grid.card > .fire-grid-toolbar {
  flex: none;
  padding-left: 1.5rem;
  padding-right: 1.5rem;
}
.fire-grid.card {
  /* flex:0 1 auto = hug content (natural height) when short, so a few-row grid's
     pager sits right under the rows near the top; only shrink + scroll the body
     internally once the rows would exceed the card. */
}
.fire-grid.card .p-datatable {
  flex: 0 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.fire-grid.card .p-datatable-table-container {
  flex: 0 1 auto;
  min-height: 0;
  overflow: auto;
}
.fire-grid.card .p-datatable-paginator-bottom {
  flex: none;
}
.fire-grid.card {
  /* Align the table's OUTER content with the shared gutter used by the title, search box and
     "new" button, while the row stripes / header underline keep bleeding to the card edge
     (that full-width feel is why the grid card drops its own L/R padding above). Each cell
     already carries ~1rem side padding, so only the first and last columns need nudging: the
     first column ("Name") sits directly under the title + search box, and the last column
     lines up under the "new" button. */
}
.fire-grid.card .p-datatable-thead > tr > th:first-child,
.fire-grid.card .p-datatable-tbody > tr > td:first-child {
  padding-left: 1.5rem;
}
.fire-grid.card .p-datatable-thead > tr > th:last-child,
.fire-grid.card .p-datatable-tbody > tr > td:last-child {
  padding-right: 1.5rem;
}

.p-toast.p-toast-top-right, .p-toast.p-toast-top-left, .p-toast.p-toast-top-center {
  top: 100px;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  margin: 1.5rem 0 1rem 0;
  font-family: inherit;
  font-weight: 700;
  line-height: 1.5;
  color: var(--text-color);
}
h1:first-child,
h2:first-child,
h3:first-child,
h4:first-child,
h5:first-child,
h6:first-child {
  margin-top: 0;
}

h1 {
  font-size: 2.5rem;
}

h2 {
  font-size: 2rem;
}

h3 {
  font-size: 1.75rem;
}

h4 {
  font-size: 1.5rem;
}

h5 {
  font-size: 1.25rem;
}

h6 {
  font-size: 1rem;
}

mark {
  background: #fff8e1;
  padding: 0.25rem 0.4rem;
  border-radius: var(--content-border-radius);
  font-family: monospace;
}

blockquote {
  margin: 1rem 0;
  padding: 0 2rem;
  border-left: 4px solid #90a4ae;
}

hr {
  border-top: solid var(--surface-border);
  border-width: 1px 0 0 0;
  margin: 1rem 0;
}

p {
  margin: 0 0 1rem 0;
  line-height: 1.5;
}
p:last-child {
  margin-bottom: 0;
}

/* ---- minimal utility shim (Sakai layout markup uses a few tailwind names) ---- */
.hidden {
  display: none !important;
}

.relative {
  position: relative;
}

@media (min-width: 1024px) {
  .lg\:block {
    display: block !important;
  }
}
.animate-fadein {
  animation: fadein 0.15s linear;
}

.animate-fadeout {
  animation: fadeout 0.15s linear;
}

.animate-scalein {
  animation: scalein 0.15s linear;
}

@keyframes fadein {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes fadeout {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}
@keyframes scalein {
  from {
    opacity: 0;
    transform: scaleY(0.8);
  }
  to {
    opacity: 1;
    transform: scaleY(1);
  }
}
/* ---- splash ---- */
.fire-splash {
  height: 100vh;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  align-items: center;
  justify-content: center;
  color: var(--text-color-secondary);
  background: var(--surface-ground);
}

/* ---- topbar brand ---- */
.fire-logo-badge {
  width: 2rem;
  height: 2rem;
  border-radius: 8px;
  background: var(--primary-color);
  color: var(--primary-contrast-color);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.fire-logo-image {
  height: 2rem;
  width: auto;
  max-width: 160px;
  -o-object-fit: contain;
     object-fit: contain;
}

/* app name beside the badge — shown only when no logo image is configured.
   (.layout-topbar-logo is inline-flex with gap:.5rem, so no extra margin here) */
.fire-logo-text {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--text-color);
  white-space: nowrap;
}

/* user menu = just the avatar, a clean circular icon button like the other topbar
   actions (the full name shows on hover via tooltip + inside the popup header) */
.fire-user-action {
  padding: 0 !important;
  /* the base .layout-topbar-action hides child <span>s (icon-button text labels);
     the avatar's initials live in a <span class="p-avatar-label">, so keep it shown */
}
.fire-user-action .p-avatar-label {
  display: flex !important;
}

.fire-topbar-avatar {
  background: color-mix(in srgb, var(--primary-color) 16%, transparent);
  color: var(--primary-color);
  font-weight: 700;
}

.fire-user-menu-header {
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--surface-border);
}
.fire-user-menu-header .name {
  font-weight: 600;
}
.fire-user-menu-header .mail {
  font-size: 0.8rem;
  color: var(--text-color-secondary);
}

/* ---- page primitives ---- */
.fire-page-title {
  margin: 0 0 1.25rem;
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--text-color);
}

.fire-card {
  background: var(--surface-card);
  border-radius: var(--content-border-radius);
  padding: 1.5rem;
}

.fire-stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1.25rem;
  margin-bottom: 1.25rem;
}

.fire-stat {
  display: flex;
  align-items: center;
  gap: 1rem;
}
.fire-stat .stat-icon {
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.2rem;
}
.fire-stat .stat-value {
  font-size: 1.4rem;
  font-weight: 700;
  color: var(--text-color);
  line-height: 1.2;
}
.fire-stat .stat-label {
  font-size: 0.82rem;
  color: var(--text-color-secondary);
}

/* search hit highlight (the core's yellow `.marked`): settings tabs + grid cells */
.marked,
.p-tab.marked {
  background: #fff59d;
  border-radius: 4px;
}

/* ---- detail page header (back button + title + actions, inside the card) ---- */
.fire-detail-header {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1.25rem;
}
.fire-detail-header .fire-page-title {
  margin-bottom: 0;
}
.fire-detail-header .spacer {
  flex: 1;
}

/* ---- grid ---- */
/* NB: the detail-header title must NOT get a bottom margin — it lives in a flex row
   (align-items:center) next to the back button, and any margin-bottom offsets its text
   upward so the arrow no longer lines up. Header spacing is handled by
   .fire-detail-header's own margin-bottom. */
.fire-grid .fire-page-title,
.card > .fire-page-title {
  margin-bottom: 1rem;
}

.fire-grid-toolbar {
  display: flex;
  /* one shared baseline: search, funnel and filter controls align at the
     bottom; the FilterBar's floating labels + clear badge hang into the
     reserved headroom (min-height), so opening filters never shifts the grid */
  align-items: flex-end;
  gap: 0.75rem;
  margin-bottom: 1rem;
  min-height: 3.25rem;
}
.fire-grid-toolbar .spacer {
  flex: 1;
}

/* Mobile (same 991px breakpoint the layout uses to collapse the sidebar — below it the app
   is already in "mobile view", so the grid chrome must switch over at the same width).
   The toolbar is a single non-wrapping row on desktop, which on a narrow screen cannot
   shrink below its controls' intrinsic widths and pushes the page into a sideways scroll.
   Let it wrap, and keep search + funnel + the filters toggle together on the first row;
   only the FilterBar's opened panel takes a line of its own. `min-width: 0` is what
   actually allows a flex child to shrink past its content, and the reserved headroom is
   dropped since nothing hangs into it once the rows are stacked. */
@media (max-width: 991px) {
  /* the title row is the same non-wrapping pattern: let a long title keep its action
     buttons on screen by wrapping them onto the next line instead of overflowing */
  .fire-detail-header {
    flex-wrap: wrap;
  }
  .fire-detail-header .fire-page-title {
    min-width: 0;
    overflow-wrap: anywhere;
  }
  .fire-grid-toolbar {
    flex-wrap: wrap;
    align-items: center;
    min-height: 0;
    gap: 0.5rem;
  }
  .fire-grid-toolbar > * {
    min-width: 0;
  }
  .fire-grid-toolbar {
    /* Search shares the first row with the funnel + filters toggle, taking only the
       width they leave. `flex-basis: 0` is load-bearing: with `auto` the search's
       hypothetical size is the input's intrinsic width (~210px), and a wrapping flex
       container breaks the line BEFORE it shrinks anything — so the toggle dropped to
       a second row. At basis 0 the search claims no width up front, all three fit on
       one line, and the input then grows into whatever is left. */
  }
  .fire-grid-toolbar > .p-iconfield {
    flex: 1 1 0;
    min-width: 0;
  }
  .fire-grid-toolbar > .p-iconfield .p-inputtext {
    width: 100%;
    min-width: 0;
  }
  .fire-grid-toolbar {
    /* the spacer would otherwise force a phantom row between wrapped items */
  }
  .fire-grid-toolbar .spacer {
    flex: 0 0 auto;
  }
  /* Dashboards: stack every widget in one full-width column, top to bottom.
     grid-layout-plus positions items with inline `position:absolute` +
     `transform: translate3d(x,y,0)` + a pixel width, and sets an inline height on the
     container — so each of those is overridden here and the items simply flow in DOM
     order. Doing it in CSS deliberately: the library's own reflow (responsive mode /
     col-num) would rewrite the layout array and fire `layout-updated`, which persists
     positions — a phone visit would then overwrite the desktop arrangement. This way the
     saved layout is never touched. The inline HEIGHT is left alone so each widget keeps
     the height it was given. */
  .vgl-layout {
    height: auto !important;
  }
  .vgl-item {
    position: relative !important;
    inset: auto !important;
    width: 100% !important;
    transform: none !important;
    margin-bottom: 1rem;
  }
  /* drag placeholder + resize handles are meaningless once stacked (drag/resize are
     also switched off in the dashboard components on mobile) */
  .vgl-item--placeholder,
  .vgl-item__resizer {
    display: none !important;
  }
}
/* ---- grid reload overlay ----
   The DataTable loading mask reuses PrimeVue's global `.p-overlay-mask` (the dark modal
   backdrop), which is far too heavy for an inline grid refresh. Soften it into a light
   frosted veil (adapts to dark mode via --surface-card) with a primary-coloured spinner. */
.p-datatable-mask {
  background: color-mix(in srgb, var(--surface-card, #ffffff) 55%, transparent) !important;
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  transition: opacity 0.15s ease;
}

.p-datatable-loading-icon {
  color: var(--primary-color, #3b82f6);
  font-size: 1.75rem;
}

/* ---- edit-form bodies (useEditForm / EditFormHost) — shared field layout ----
   Every form-body component wraps its fields in `.form-grid`, so these primitives
   live here once instead of being repeated in each component's \3c style scoped>.
   Scoped under .form-grid so `.p-error` doesn't clash with PrimeVue's global one. */
.form-grid {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.form-grid .two-col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}
.form-grid .field label {
  display: block;
  margin-bottom: 0.35rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--p-text-muted-color, #475569);
}
.form-grid .field-inline {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.form-grid .field-inline label {
  font-size: 0.9rem;
}
.form-grid .hint {
  display: block;
  margin-top: 0.35rem;
  color: var(--p-text-muted-color, #64748b);
}
.form-grid .p-error {
  display: block;
  margin-top: 0.35rem;
  color: var(--p-red-500, #ef4444);
  font-size: 0.8rem;
}

/* ---- line-item tables inside form bodies (repeated rows: formula variables,
   thresholds, mappings, …) — the tabular counterpart of `.form-grid`. Row gap
   comes from border-spacing, so cell padding and column alignment stay intact.
   Column widths stay in each component's scoped style. Intentionally compact
   tables (widget-config swatch tables) do NOT use this class. */
.form-lines {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0 0.5rem;
}
.form-lines th {
  text-align: left;
  font-size: 0.74rem;
  font-weight: 600;
  color: var(--p-text-muted-color, #64748b);
  padding: 0 0.4rem;
}
.form-lines td {
  padding: 0 0.4rem;
  vertical-align: top;
}

/* ---- dashboard widget config dialogs (*WidgetConfig.vue) — shared field layout ---- */
.widget-config .field {
  margin-bottom: 1rem;
}
.widget-config .field label {
  display: block;
  margin-bottom: 0.35rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--p-text-muted-color, #475569);
}
.widget-config .field-inline {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.widget-config .field-inline label {
  font-size: 0.9rem;
}
.widget-config .row-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}
.widget-config .hint {
  display: block;
  margin-top: 0.35rem;
  color: var(--p-text-muted-color, #64748b);
  font-size: 0.8rem;
}
