/* Staff portal viewport helpers — phones, tablets, and narrow windows. */

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  overflow-x: hidden;
}

/*
 * Temporary (phone/tablet) drawer overlay is z-index 1301 and covers the full
 * viewport, including the app bar. ClipMode Always keeps the drawer itself below
 * the app bar, but without this the hamburger still sits under the overlay -- a
 * tap near it closes via the overlay rather than the button, which breaks the
 * toggle affordance and focus. 1350 puts the app bar above both while staying under
 * MudBlazor's dialogs (1400), so a modal still dims and blocks the bar.
 */
.mud-appbar {
  z-index: 1350;
}

/* Routes.razor focuses the page h1 after navigation; a focus ring on a heading reads as a
   glitch rather than a cue, and the tab order continues from it either way. */
h1:focus {
  outline: none;
}

/* Toolbars: title + actions must wrap instead of overflowing. */
.portal-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.portal-toolbar > .mud-typography-h4,
.portal-toolbar > .mud-typography-h5 {
  flex: 1 1 12rem;
  min-width: 0;
}

.portal-toolbar-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

/* Compact table cells: one line each, long text elided (full text lives in the row's
   details dialog). inline-block so max-width applies inside a table cell. */
.portal-cell-ellipsis {
  display: inline-block;
  max-width: 16rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: bottom;
}

.portal-cell-nowrap {
  white-space: nowrap;
}

/* Dashboard disk tile: segmented usage bar with the unused remainder as the track. */
.portal-disk-bar {
  display: flex;
  height: 12px;
  border-radius: 6px;
  overflow: hidden;
  background: rgba(128, 128, 128, 0.18);
}

.portal-disk-bar > div {
  height: 100%;
}

.portal-disk-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin-right: 6px;
  vertical-align: baseline;
}

/* Wide tables/grids scroll horizontally instead of breaking the page. */
.portal-table-scroll {
  width: 100%;
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.portal-table-scroll .mud-table,
.portal-table-scroll .mud-data-grid {
  min-width: 0;
}

/*
 * App bar title swap. The long title needs ~404px; at 768px only ~393px is free once the
 * hamburger, logo, and sign-out button are placed, so it was rendering ellipsised. At
 * 1024px it fit with zero slack -- one longer display name away from clipping again.
 * Swapping at 1280px keeps real headroom; the logo carries the branding below that.
 */
@media (max-width: 1279.95px) {
  .portal-appbar-title-full {
    display: none !important;
  }
}

@media (min-width: 1280px) {
  .portal-appbar-title-short {
    display: none !important;
  }
}

@media (max-width: 599.95px) {
  .mud-main-content {
    padding-left: 0.75rem !important;
    padding-right: 0.75rem !important;
  }

  .mud-container {
    padding-left: 0 !important;
    padding-right: 0 !important;
  }

  .portal-alert-actions {
    flex-direction: column !important;
    align-items: stretch !important;
  }

  .portal-alert-actions .mud-button-root {
    align-self: stretch;
  }
}

/* Sign-in card: generous padding on desktop, but not so much that the fields are
   squeezed into the middle third of a 320px phone. */
.portal-login-card {
  padding: 1.5rem;
}

@media (min-width: 600px) {
  .portal-login-card {
    padding: 2rem;
  }
}

/* Off-screen but still in the accessibility tree -- used by PortalStatusMessage's
   always-present live region. Not display:none, which would remove it entirely. */
.portal-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Avoid horizontal page scroll from dialogs / pickers on small devices. */
.mud-dialog {
  max-width: calc(100vw - 1.5rem);
}

.mud-dialog .mud-dialog-content {
  overflow-x: auto;
}

/* Long till receipts render at full readable width and scroll inside the frame,
   instead of being shrunk to fit 70vh (which made tall receipts unreadably small). */
.portal-receipt-preview-frame {
  max-height: 70vh;
  overflow-y: auto;
  background: #1E2124;
  border-radius: 6px;
}

.portal-receipt-preview {
  width: 100%;
  height: auto;
  display: block;
}

.portal-richtext {
  margin-top: 1rem;
}

.portal-richtext-host .ql-toolbar.ql-snow {
  border-color: var(--mud-palette-lines-default);
  border-radius: 4px 4px 0 0;
}

.portal-richtext-host .ql-container.ql-snow {
  border-color: var(--mud-palette-lines-default);
  border-radius: 0 0 4px 4px;
  font-size: 1rem;
  min-height: 14rem;
}

.portal-richtext-host .ql-editor {
  min-height: 14rem;
}

.portal-page-preview {
  position: sticky;
  top: 5.5rem;
}

.portal-page-preview-frame {
  display: block;
  width: 100%;
  min-height: 75vh;
  height: calc(100vh - 8rem);
  border: 1px solid var(--mud-palette-lines-default);
  border-radius: 4px;
  background: #fff;
}

.portal-hero-preview {
  max-width: 100%;
  max-height: 220px;
  object-fit: cover;
}

.portal-project-thumb {
  max-height: 140px;
}

/* Blazor's circuit-failure banner is injected outside the layout, so it can't be
   styled by MudBlazor components. The layout's ErrorBoundary catches per-page
   exceptions; this only appears when the circuit itself is gone. */
#blazor-error-ui {
  position: fixed;
  inset-block-end: 0;
  inset-inline: 0;
  z-index: 2000;
  display: none;
  padding: 0.75rem 1.25rem;
  background: #FF8C26;
  color: #1E2124;
  font-size: 0.875rem;
  font-weight: 600;
  box-shadow: 0 -1px 3px rgb(0 0 0 / 0.2);
}

#blazor-error-ui .dismiss {
  cursor: pointer;
  float: inline-end;
}

/* Section headings in the nav drawer. Sized and spaced to read as a label for the run
   below it rather than as another clickable row -- the links themselves are the targets. */
.portal-nav-heading {
  display: block;
  padding: 1rem 1rem 0.25rem;
  color: var(--mud-palette-text-secondary);
  letter-spacing: 0.08em;
  font-weight: 600;
}

.mud-navmenu .portal-nav-heading:first-child {
  padding-top: 0.5rem;
}

/* The Documents page's "Use camera" button. Its input asks for the rear camera, which only
   phones and tablets honour; on a mouse-driven desktop it would be a second file picker. */
.portal-camera-only {
  display: none;
}

@media (pointer: coarse) {
  .portal-camera-only {
    display: inline-flex;
  }
}

/* Ctrl+K quick search dialog. The input is a plain element so it can carry the combobox
   attributes directly; it borrows the outlined-field look from the palette. */
.portal-quick-search {
  padding-top: 0.25rem;
}

.portal-quick-search-input {
  box-sizing: border-box;
  width: 100%;
  padding: 0.75rem 0.875rem;
  border: 1px solid var(--mud-palette-lines-inputs);
  border-radius: var(--mud-default-borderradius);
  background: var(--mud-palette-surface);
  color: var(--mud-palette-text-primary);
  font: inherit;
  font-size: 1rem;
}

.portal-quick-search-input:focus {
  outline: 2px solid var(--mud-palette-primary);
  outline-offset: -1px;
  border-color: var(--mud-palette-primary);
}

.portal-quick-search-status {
  min-height: 1.25rem;
  margin: 0.5rem 0 0.25rem;
  color: var(--mud-palette-text-secondary);
  font-size: 0.8125rem;
}

/* Scrolls inside the dialog so a long result list never pushes the input off screen. */
.portal-quick-search-results,
.portal-quick-search-results ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.portal-quick-search-results {
  max-height: min(60vh, 28rem);
  overflow-y: auto;
}

.portal-quick-search-group {
  padding: 0.75rem 0.5rem 0.25rem;
  color: var(--mud-palette-text-secondary);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.portal-quick-search-note {
  padding: 0.25rem 0.5rem;
  color: var(--mud-palette-text-secondary);
  font-size: 0.875rem;
}

.portal-quick-search-option {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  padding: 0.5rem;
  border-inline-start: 3px solid transparent;
  border-radius: var(--mud-default-borderradius);
  cursor: pointer;
}

.portal-quick-search-option:hover {
  background: var(--mud-palette-action-default-hover);
}

.portal-quick-search-option-active {
  border-inline-start-color: var(--mud-palette-primary);
  background: var(--mud-palette-action-default-hover);
}

.portal-quick-search-title {
  overflow-wrap: anywhere;
  font-weight: 600;
}

.portal-quick-search-detail {
  overflow-wrap: anywhere;
  color: var(--mud-palette-text-secondary);
  font-size: 0.8125rem;
}
