/* Global rules that complement MudBlazor. Component appearance belongs in the Mud theme
   or in the component that owns the exceptional behavior. */

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

body {
  margin: 0;
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
  background: var(--mud-palette-background);
  color: var(--mud-palette-text-primary);
  -webkit-font-smoothing: antialiased;
}

/* The skip link is the first keyboard stop in both shells. Its handler focuses the main
   landmark; scroll clearance keeps it below the fixed AppBar. */
.app-skip-link {
  position: fixed;
  inset: 8px auto auto 16px;
  z-index: 1500;
  padding: 12px 16px;
  border-radius: var(--mud-default-borderradius);
  background: var(--mud-palette-surface);
  transform: translateY(-160%);
}
.app-skip-link:focus { transform: translateY(0); }
#main-content { scroll-margin-top: 72px; }

/* Links within prose need a persistent non-colour cue. Navigation and button links keep
   their own affordances. */
.mud-typography-body1 a.mud-link,
.mud-typography-body2 a.mud-link { text-decoration: underline; text-underline-offset: 3px; }

.app-file-label { display: block; font-weight: 600; margin: 16px 0 8px; }
#import-file { max-width: 100%; }
.import-format summary { min-height: 44px; padding-block: 10px; cursor: pointer; }

.app-scroll-table { min-width: 0; }
.table-scroll-hint {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 4px;
  color: var(--mud-palette-text-secondary);
  font-size: .875rem;
}
.table-scroll-hint[hidden] { display: none; }
.app-scroll-table .mud-table-container:focus-visible {
  outline: 2px solid var(--mud-palette-primary);
  outline-offset: -2px;
}

.report-summary { display: flex; flex-wrap: wrap; gap: 0; margin-bottom: 16px; overflow: hidden; border: 1px solid var(--mud-palette-lines-default); border-radius: 6px; background: var(--mud-palette-surface); }
.report-summary > .mud-paper { flex: 1 1 150px; min-width: 0; border: 0; border-right: 1px solid var(--mud-palette-lines-default); border-radius: 0; margin-bottom: 0 !important; }
.report-total .mud-typography-caption { display: block; font-weight: 600; color: var(--mud-palette-text-secondary); margin-bottom: 6px; }
.report-summary > .report-total:first-child { background: var(--mud-palette-primary-hover); }
.report-summary > .report-total:last-child { border-right: 0; }
.report-summary > .report-total:first-child .mud-typography-h6 { color: var(--mud-palette-primary); }
.report-filter-trigger { display: flex; align-items: center; gap: 12px; margin-left: auto; }
.entries-empty .mud-table-head { display: none; }
.report-empty-message { overflow-wrap: anywhere; }

/* Keep dates and amounts intact; the table's own scroll region handles narrow screens. */
.mud-table-cell.report-value { white-space: nowrap; font-variant-numeric: tabular-nums; }
.report-money { white-space: nowrap; font-variant-numeric: tabular-nums; }
.mud-table-cell.report-group-label { min-width: 10rem; max-width: 24rem; overflow-wrap: anywhere; }
.mud-button-root.report-group-button {
  justify-content: flex-start;
  min-width: 0;
  padding: 4px 0;
  text-align: left;
  text-decoration: underline;
  text-underline-offset: 3px;
  font-weight: inherit;
}
.report-period-range {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex: 0 1 auto;
  white-space: nowrap;
}

@media (max-width: 959.98px) {
  .report-group-table .mud-table-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); padding: 16px; gap: 12px; }
  .report-group-table .mud-table-cell { padding: 0 !important; border: 0 !important; display: flex; flex-direction: column; align-items: flex-start; justify-content: flex-start; gap: 4px; min-width: 0; }
  .report-group-table .mud-table-cell::before { font-size: 11px; color: var(--mud-palette-text-secondary); font-weight: 600; }
  .report-group-table .report-group-label { grid-column: 1 / -1; min-width: 0; }
  .report-group-table .report-group-label::before { display: none; }
}

@media (max-width: 599.98px) {
  .report-period-range {
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr) 44px;
    flex: 1 1 100%;
    text-align: center;
  }
  .report-period-range .mud-typography { white-space: normal; }
  .report-summary > .mud-paper { flex-basis: 45%; padding: 12px !important; border-bottom: 1px solid var(--mud-palette-lines-default); }
  .report-summary > .report-total:first-child { flex-basis: 100%; }
  .report-filter-trigger { width: 100%; justify-content: space-between; }
  .report-group-tabs { gap: 0 !important; }
  .report-group-tabs .mud-button-root { padding-inline: 8px; font-size: 12px; }
  .mud-main-content .mud-button-root { min-height: 44px; }
  .page-header-actions { width: 100%; }
  .invoice-run-history .mud-table-cell { gap: 16px; overflow-wrap: anywhere; }
  .invoice-run-history .mud-table-cell > div { min-width: 0; max-width: 65%; }
}

.app-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.time-period-compact { display: none; }

a {
  color: var(--mud-palette-primary);
}

/* Register editors: field values are body text, not the theme's semibold subtitle.
   Keep this opt-in so compact time-entry controls retain their own density. */
.app-editor-form .mud-input {
  font-weight: var(--mud-typography-body1-weight);
  font-size: var(--mud-typography-body1-size);
  letter-spacing: normal;
}

.app-editor-form .mud-input-label {
  font-weight: 400;
  letter-spacing: normal;
}

.app-editor-form .mud-input-helper-text {
  letter-spacing: normal;
  line-height: 1.5;
}

.app-editor-form .app-editor-option-help {
  margin-left: 44px;
}

.app-directory-table .mud-table-toolbar {
  flex-wrap: wrap;
  gap: 8px 16px;
  height: auto;
  min-height: 80px;
  padding-block: 12px;
}

.directory-search-notice { flex-basis: 100%; }

/* SortScope owns the named column selector and direction control on narrow screens. */
.app-directory-table .mud-table-smalldevices-sortselect { display: none; }

.app-directory-table .mud-table-head {
  background: var(--mud-palette-background);
}

.app-directory-table .mud-table-cell {
  overflow-wrap: anywhere;
}

.app-directory-table .directory-search .mud-input {
  font-weight: 400;
}

.app-directory-table .row-actions .mud-button-root {
  min-width: 44px;
  min-height: 44px;
}

.directory-secondary-details {
  margin-top: 4px;
  color: var(--mud-palette-text-secondary);
  font-size: var(--mud-typography-caption-size);
}

.directory-secondary-details summary {
  cursor: pointer;
  width: fit-content;
}

.directory-secondary-details code {
  white-space: normal;
  overflow-wrap: anywhere;
}

.app-membership-assignment {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(12rem, 1fr) 44px;
  align-items: center;
  gap: 12px;
  padding-block: 12px;
  border-top: 1px solid var(--mud-palette-lines-default);
}

.app-membership-assignment > * { min-width: 0; overflow-wrap: anywhere; }

.app-settings-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px;
  max-width: 1200px;
  align-items: start;
}

.app-settings-grid > .mud-card { min-width: 0; }
.app-settings-grid .mud-card-content { padding: 24px; }
.app-settings-grid .mud-card-actions { padding: 0 24px 24px; justify-content: flex-end; }

@media (max-width: 959.98px) {
  .app-settings-grid { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 599.98px) {
  .app-membership-assignment { grid-template-columns: minmax(0, 1fr) 44px; }
  .app-membership-assignment > :first-child { grid-column: 1 / -1; }
  .app-directory-table .row-actions { gap: 4px; }
  .app-directory-table .mud-table-cell { gap: 12px; }
  .app-directory-table .mud-table-cell::before { flex-shrink: 0; min-width: 5.5rem; }
  .app-settings-grid .mud-card-content { padding: 16px; }
  .app-settings-grid .mud-card-actions { padding: 0 16px 16px; }
}

/* Focus visibility (GOAL 65 / 65.1). MudBlazor 9 removes the browser's own ring outright
   (`button:focus { outline: none }` and `a:focus-visible { outline: none }` in
   MudBlazor.min.css), and focused AppBar controls were measured with no visible indicator in
   the GOAL 65 baseline. One shared rule restores a visible keyboard-focus ring, coloured by
   the theme's primary token — it supplements the library's own focus feedback (input borders,
   labels, tints) and deliberately covers only the suppressed interactive surfaces, so it is
   not the former global focus override (§29). */
a:focus-visible,
button:focus-visible,
[role="button"]:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--mud-palette-primary);
  outline-offset: 2px;
}

/* Tonal application shell (GOAL 70 / 70.1). MudNavLink already publishes `active` and
   `aria-current=page`; this shared class makes that route visually unmistakable without
   changing its navigation semantics. The inset bar supplies a shape cue, while the selected
   container comes from the one MudTheme rather than a parallel CSS palette. */
.mud-navmenu.mud-navmenu-default
  .app-nav-link > .mud-nav-link.active:not(.mud-nav-link-disabled) {
  color: var(--mud-palette-primary);
  background-color: var(--mud-palette-primary-lighten);
  box-shadow: inset 3px 0 0 var(--mud-palette-primary);
}

.mud-navmenu.mud-navmenu-default
  .app-nav-link > .mud-nav-link.active:not(.mud-nav-link-disabled) .mud-nav-link-icon {
  color: var(--mud-palette-primary);
}

@media (hover: hover) and (pointer: fine) {
  .mud-navmenu.mud-navmenu-default
    .app-nav-link > .mud-nav-link.active:not(.mud-nav-link-disabled):hover:not(.mud-nav-link-disabled) {
    background-color: color-mix(
      in srgb,
      var(--mud-palette-primary) 18%,
      var(--mud-palette-drawer-background));
  }
}

.timer-elapsed {
  font-variant-numeric: tabular-nums;
}

/* Today column (GOAL 65 / 65.2). One shared, token-derived selected surface for the
   Organization-local today in the Week matrix — header, body and footer alike, so the
   column reads as one. It is only ever a quiet background tint: the state is carried by
   the visible "Today" caption and aria-current="date" in the header, never by color
   alone, and the tint is too subtle to compete with the cell's own controls. */
.time-today {
  background: color-mix(in srgb, var(--mud-palette-primary) 7%, transparent);
}

/* Compact Week matrix (GOAL 65 / 65.3). Fixed layout with one percentage column grid shared
   by header, body and totals footer: the Project/task column is the flexible readable column,
   the seven day columns are equal and compact, and Total/Actions carry only functional width —
   Total fits one non-wrapping `Nh NNm` value, Actions fits the icon-only timer pair
   (two 40px hit targets plus the stack gap) or the empty-row remove button. Widths are sized
   so the whole matrix fits at 960px of table width — the 960px floor below which the MudTable
   container owns the horizontal scroll, never the page. Editors size to canonical `H:MM`/pcs
   content and are capped at that width (width:100% with max-width in the cell), so nothing
   stretches merely to fill the container, matching the density reference's relative
   allocation, not its pixels. No cell reserves width for a pencil: the field edits directly
   and the row's "Entries (n)" expansion owns full-record changes. */
.time-week-table .mud-table-root {
  table-layout: fixed;
  width: 100%;
  min-width: 960px;
}

/* Selectors carry the table root so they outrank the theme's runtime-injected rules, which
   load after this file and would otherwise win equal-specificity ties on cell padding. */
.time-week-table .mud-table-root .week-col-identity {
  width: 25.5%;
  padding-inline: 8px;
  overflow-wrap: anywhere;
}

.time-week-table .mud-table-root .week-col-day {
  width: 8%;
  padding-inline: 4px;
}

.time-week-table .mud-table-root .week-col-total {
  width: 7.5%;
}

.time-week-table .mud-table-root .week-col-actions {
  width: 11%;
}

.time-week-table .mud-table-root .week-cell-total {
  white-space: nowrap;
}

.time-week-table .mud-table-root .week-cell-identity {
  padding-inline: 8px;
  overflow-wrap: anywhere;
}

.time-week-table .mud-table-root .week-cell-day {
  padding-inline: 4px;
}

.time-week-table .mud-table-root .week-cell-total {
  padding-inline: 4px;
}

.time-week-table .mud-table-root .week-cell-actions {
  padding-inline: 6px;
}

/* Functional-width affordances inside the compact columns: duration-cell buttons (aggregate,
   live timer) keep icon + text but shed generic horizontal padding; the week-row timer
   buttons keep their visible state text on tighter padding. */
.time-week-table .mud-table-root .week-cell-day .mud-button-root {
  padding-inline: 4px;
}

.time-week-table .mud-table-root .week-cell-day .mud-button-start-icon {
  margin: 0 2px 0 -2px;
}

.time-week-table .mud-table-root .week-cell-actions .mud-button-root {
  padding-inline: 8px;
}

/* The icon-only row timer buttons are compact but keep a usable square hit target (the pair
   plus the stack gap is 2x40+4=84px, inside the Actions track's 960-floor content width of
   ~93.6px); the former text buttons' height is preserved rather than traded away. */
.time-week-table .mud-table-root .week-cell-actions .mud-icon-button {
  min-width: 40px;
  min-height: 40px;
}

/* The duration editor: canonical `H:MM`/pcs content (tabular digits) in a field capped to that
   width by its own component, with the text itself trimmed slightly (the compact track shrinks
   the input's own padding) so the complete value stays visible inside the 8% track. */
.time-week-table .mud-table-root .week-cell-day .mud-input-slot {
  padding-inline: 6px;
}

/* Expanded Time-cell list (GOAL 80 / T-806). Below the 960px floor the Week table scrolls inside
   its container, and the expanded row spans all 960px, so the list's per-row open button sat
   far off-screen. The container is a size container, and the list wrapper stays at most the
   container's visible width (less the cell's 16px side padding) and sticks to the visible left
   edge while the table scrolls. At or above 960px the cap equals the cell's content width, so
   the desktop layout is unchanged. */
.time-week-table .mud-table-container {
  container-type: inline-size;
}

.time-week-table .week-cell-list {
  position: sticky;
  left: 16px;
  box-sizing: border-box;
  width: 100%;
  max-width: calc(100cqw - 32px);
}

/* A MudTooltip popover is a transient hover/focus label, never an interactive surface. Keeping
   it out of pointer hit-testing stops a lingering tooltip under the cursor (typical after a
   row-timer command re-renders a button in place) from intercepting the click a user aims at
   the compact neighbouring action it overlaps - the 65.3 icon-only pair put those neighbours
   one row apart. (GOAL 65 / 65.3) */
.mud-popover.mud-tooltip {
  pointer-events: none;
}

/* The timer's status copy is deliberately quieter than its commands. The running animation is
   carried by the Pause command itself, so a large standalone spinner never competes with elapsed
   time or consumes the summary's shrinking text track. */
.timer-pill {
  display: flex;
  align-items: center;
  gap: 6px;
  width: min(390px, 44vw);
  min-width: 300px;
  border-radius: 12px;
  padding: 3px;
  background: var(--mud-palette-surface);
  border-color: var(--mud-palette-lines-default);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
}

.timer-pill-stop {
  margin-left: 2px;
}

.timer-pill .mud-icon-button {
  width: 40px;
  height: 40px;
  padding: 8px;
}

.timer-descriptive {
  flex: 1 1 auto;
  min-width: 0;
  justify-content: flex-start;
  border-radius: 8px;
}

.timer-descriptive .mud-button-label {
  display: flex;
  width: 100%;
  min-width: 0;
  overflow: hidden;
  text-align: left;
}

.timer-descriptive .mud-stack {
  width: 100%;
  min-width: 0;
  overflow: hidden;
}

.timer-descriptive .mud-typography {
  max-width: 100% !important;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.timer-running-command {
  position: relative;
  display: inline-flex;
  flex: 0 0 auto;
}

.timer-running-ring {
  position: absolute;
  z-index: 2;
  inset: 6px;
  border-radius: 50%;
  pointer-events: none;
}

.timer-running-ring::before {
  content: "";
  position: absolute;
  inset: 0;
  border: 2px solid rgba(255, 255, 255, 0.4);
  border-top-color: #fff;
  border-radius: 50%;
  animation: timer-command-spin 900ms linear infinite;
}

@keyframes timer-command-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .timer-running-ring::before {
    animation: none;
    border-color: rgba(255, 255, 255, 0.8);
  }
}

/* On phones the timer is one deliberate floating dock in both idle and active states. The active
   summary owns all remaining width; its three lines truncate independently before the two large
   touch commands, which never wrap below it. */
.timer-dock {
  position: fixed;
  left: 12px;
  right: 12px;
  bottom: calc(18px + env(safe-area-inset-bottom));
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 72px;
  padding: 10px;
  background: var(--mud-palette-surface);
  border: 1px solid var(--mud-palette-lines-default);
  border-radius: 14px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.18);
  z-index: 1090;
}

.timer-dock-idle {
  justify-content: stretch;
}

.timer-dock-idle .timer-idle-action {
  width: 100%;
  min-height: 48px;
  border-radius: 10px;
  font-weight: 700;
}

.timer-dock-active {
  min-height: 92px;
}

.timer-dock .timer-dock-state {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
}

.timer-dock .timer-descriptive {
  width: 100%;
  min-height: 66px;
  padding: 4px 6px;
  justify-content: flex-start;
  text-align: left;
}

.timer-dock .timer-descriptive .mud-button-label {
  display: block;
  width: 100%;
  min-width: 0;
}

.timer-dock-summary,
.timer-status-line,
.timer-summary-line {
  display: block;
  width: 100%;
  min-width: 0;
}

.timer-dock-summary {
  line-height: 1.28;
}

.timer-status-line {
  white-space: nowrap;
}

.timer-status-line .timer-elapsed {
  font-weight: 800;
}

.timer-summary-line {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.timer-customer {
  margin-top: 2px;
  font-weight: 600;
}

.timer-dock .mud-icon-button {
  flex: 0 0 auto;
  width: 48px;
  height: 48px;
}

.timer-dock .timer-running-ring {
  inset: 5px;
}

.timer-dock-clearance {
  padding-bottom: calc(132px + env(safe-area-inset-bottom));
}

/* GOAL 86: the dock drives the signed-in person's OWN timer, which has no place in another
   member's timesheet - an administrator working there never sees a Start timer call to action
   over that person's rows. The page banner is the marker; the app bar's timer pill remains. */
body:has([data-testid="other-timesheet-banner"]) .timer-dock {
  display: none;
}

body:has([data-testid="other-timesheet-banner"]) .timer-dock-clearance {
  padding-bottom: 0;
}

body:has([data-testid="other-timesheet-banner"]) #mud-snackbar-container {
  bottom: 0;
}

/* Timer dock notification band (GOAL 65 / 65.4). The dock is the one fixed control in the
   bottom strip, and every timer command answers with a Snackbar from the bottom-right - without
   this the transient notification would sit ON the dock's Pause/Resume/Stop row and swallow
   clicks into it for as long as it shows (indefinitely while a mouse rests over it, which
   pauses MudBlazor's auto-hide). Where the dock's own clearance marker exists - the same
   render pass that renders the dock - the whole snackbar stack is lifted clear of the dock.
   Browsers without :has keep the former placement, where the dock simply reclaims the strip a
   few seconds later. */
body:has(.timer-dock-clearance) #mud-snackbar-container {
  bottom: calc(132px + env(safe-area-inset-bottom));
}

/* Period navigation and Day cards use explicit phone composition. Generic flex wrapping made the
   arrows read as unrelated controls and MudTable's default responsive cells squeezed labels,
   project identity and values into one unreadable line. */
.time-toolbar-layout,
.time-period-navigation,
.time-toolbar-actions {
  display: flex;
  align-items: center;
}

.time-view-toggle { flex: none; }

.time-toolbar-layout {
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

.time-period-navigation {
  gap: 8px;
}

.time-toolbar-actions {
  gap: 8px;
  margin-left: auto;
  max-width: 100%;
  flex-wrap: wrap;
}

@media (min-width: 601px) and (max-width: 959.98px) {
  .time-toolbar-actions { flex: 1 1 100%; margin-left: 0; }
  .time-toolbar-actions .time-teammate-select { flex: 1 1 15rem; }
  .time-period-return { margin-left: auto; }
}

/* GOAL 86: the administrator's teammate picker sits with the other toolbar controls. */
.time-teammate-select {
  width: 15rem;
  flex: 0 1 15rem;
}

.other-timesheet-banner-title {
  font-weight: 600;
}

.time-day-work,
.time-day-value {
  min-width: 0;
}

/* A saved Day row opens its editor on a click anywhere (Time.razor OnRowClick), so it shows the
   hand cursor. The named activation button stays for the keyboard and assistive technology: no
   icon, transparent, parked in the work block's corner; the row draws the focus ring for it. */
.time-day-entries .mud-table-body .time-day-entry-row {
  cursor: pointer;
}

.time-day-work {
  position: relative;
}

.time-day-entry-activation {
  position: absolute;
  top: 0;
  left: 0;
  width: 28px;
  height: 28px;
}

.time-day-entry-activation button {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  opacity: 0;
}

.time-day-entries .mud-table-body .mud-table-row:has(.time-day-entry-activation button:focus-visible) {
  outline: 2px solid var(--mud-palette-primary);
  outline-offset: -2px;
}

/* One timer per screen (GOAL 65.4 "one timer, two shapes"): below the layout's narrow breakpoint
   (MudBlazor Xs/Sm, under 960px, see MainLayout) the timer is the docked bar, so the Day view's own
   live-session card would be a second copy of it and is not shown. The dock carries Pause, Resume
   and Stop there. From 960px up the AppBar pill and the card both show. */
@media (max-width: 959.98px) {
  .live-session-row {
    display: none;
  }
}

/* Day entry rows: one tidy, vertically centred line per entry. The hours field has its own column,
   so the fields line up from row to row, and the saved duration and indicators sit beside it. The
   Reported column shrinks to its content instead of floating mid-row. Scoped to the entries table:
   the prepared/pieces/timer context table keeps its own layout. */
.time-day-entries .mud-table-root .mud-table-cell {
  vertical-align: middle;
  padding-block: 8px;
}

.time-day-entries .time-day-reported {
  width: 1%;
  white-space: nowrap;
}

.time-day-entries .time-day-value {
  display: grid;
  /* Fixed text column: every row's grid is its own, so the field only lines up between rows when the
     text column has the same width in each (it fits "Non-billable" and "Billable Invoiced"). */
  grid-template-columns: 4.75rem 10.5rem;
  align-items: center;
  justify-content: end;
  column-gap: 12px;
}

/* Running timer / nothing saved: one plain value, not the field-and-text grid. */
.time-day-entries .time-day-value.time-day-value-plain {
  display: flex;
  justify-content: flex-end;
}

@media (max-width: 600px) {
  .time-day-entries .time-day-value {
    grid-template-columns: 4.75rem 9.25rem;
  }
}

.time-day-entries .time-day-value-text {
  display: flex;
  align-items: baseline;
  gap: 6px;
  text-align: left;
  white-space: nowrap;
}

/* GOAL 86: a Day row with no timer (another member's timesheet) has nothing to put in its
   Actions cell; the stacked phone layout drops the empty labelled cell instead of showing it. */
@media (max-width: 959.98px) {
  .time-day-entries td.time-day-actions-empty {
    display: none;
  }
}

/* Duration fields (Week cells, single-entry Day rows): the time is centered in its box. */
.duration-field input {
  text-align: center;
}

/* The outlined box fills its (centered) control, so it lines up with the column header. */
.duration-field.mud-input-control {
  width: 4.25rem !important;
  max-width: 4.25rem !important;
}

.duration-field .mud-input,
.duration-field .mud-input-control-input-container {
  width: 100% !important;
}

/* Saved pieces row (QuantityEntryDetails): quantity and time spent never wrap; the row wraps
   instead, and on narrow screens the note takes its own full-width line. */
.pieces-entry-main {
  flex-wrap: wrap;
  min-width: 0;
}

.pieces-entry-value {
  white-space: nowrap;
}

.pieces-entry-actions {
  flex: none;
}

/* Expanded Pieces detail in the Week grid (GOAL 80 / T-822). Below the 960px floor the table
   scrolls inside its container and the expanded cell spans all 960px, which put Edit and Delete
   far off-screen. Same technique as .week-cell-list above: the region stays at most the
   container's visible width (less the cell's 16px side padding) and sticks to the visible left
   edge while the table scrolls. At or above 960px the cap equals the cell's content width, so
   the desktop layout is unchanged. */
.time-week-table .pieces-detail-region {
  position: sticky;
  left: 16px;
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
  max-width: calc(100cqw - 32px);
}

@media (max-width: 600px) {
  /* The utility classes MudStack renders are !important, so the narrow layout needs it too:
     the entry's facts and notes take the full width and the actions sit on their own line below,
     with touch targets of at least 40x40px. */
  .pieces-detail-region .time-entry-detail-row {
    flex-direction: column !important;
    align-items: stretch !important;
    justify-content: flex-start !important;
    min-width: 0;
  }

  .pieces-detail-region .pieces-entry-actions {
    justify-content: flex-end !important;
  }

  .pieces-detail-region .pieces-entry-actions .mud-icon-button {
    min-width: 40px;
    min-height: 40px;
  }

  .time-workspace-toolbar {
    padding: 12px !important;
  }

  .time-toolbar-layout {
    flex-wrap: wrap;
    gap: 8px;
  }

  .time-period-navigation {
    flex: 0 0 100%;
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr) 44px;
    gap: 4px;
  }

  .time-period-label {
    min-width: 0 !important;
    font-size: 0.875rem;
    white-space: nowrap;
  }

  .time-period-full { display: none; }
  .time-period-compact { display: inline; }

  .time-toolbar-actions {
    display: contents;
  }

  .time-period-return {
    order: 2;
    min-width: 80px;
  }

  .time-teammate-select {
    order: 1;
    flex: 1 1 100%;
    width: 100%;
  }

  .time-copy-week {
    order: 4;
    flex: 0 0 100%;
    min-width: 0;
  }

  .time-view-toggle {
    order: 3;
    margin-left: auto;
  }

  .pieces-entry-main {
    flex: 1 1 auto;
    max-width: 100%;
  }

  .pieces-entry-note {
    flex: 1 1 100%;
    min-width: 0;
  }

  .time-day-table .mud-table-root .mud-table-body .mud-table-row {
    display: grid !important;
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
    padding: 16px;
  }

  .time-day-table .mud-table-root .mud-table-cell {
    display: grid !important;
    grid-template-columns: 88px minmax(0, 1fr);
    align-items: center;
    width: 100% !important;
    min-width: 0;
    padding: 0 !important;
    border: 0;
  }

  .time-day-table .mud-table-root .mud-table-cell::before {
    width: auto !important;
    min-width: 0 !important;
    font-weight: 600;
    text-align: left;
  }

  .time-day-table .time-day-identity {
    align-items: start;
  }

  .time-day-work {
    overflow: hidden;
  }

  .time-day-work .mud-typography {
    overflow-wrap: anywhere;
  }

  .time-day-work .mud-button-root {
    margin-left: -8px;
  }

  .time-day-value,
  .time-day-action-controls {
    justify-self: end;
  }

  .time-day-table .mud-table-root .time-day-actions-active {
    display: none !important;
  }
}

/* Administrator entries toolbar (GOAL 69 / 69.3). A table toolbar is a MudToolBar with a
   fixed 4rem height. Whenever the Entries table carries the administrator selection bar, the
   toolbar's content can stand two or three lines tall — search and actions stacking, and at a
   promoted selection the Move-blocked sentence wrapping under the buttons — and the fixed box
   pushed every wrapped line over the table header below. The height becomes a min-height:
   one-line toolbars (the search-only drill-downs, the idle Entries view) keep the exact box
   they shipped with, and only a wrapping selection grows it. The selector carries the table
   root class so it outranks the theme's runtime-injected toolbar rules, which load after
   this file and would otherwise win equal-specificity ties. */
.entries-selection-toolbar .mud-table-toolbar {
  height: auto;
  min-height: 4rem;
}

/* Keep selection available when the wide Entries table is scrolled over to its Edit column.
   Without this, the first-column checkboxes disappear outside the table's scroll viewport. */
.entries-selectable .mud-table-root tr > :first-child {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--mud-palette-surface);
  box-shadow: 1px 0 0 var(--mud-palette-lines-default);
}

.entries-selectable .mud-table-root thead tr > :first-child {
  z-index: 2;
}

.muted {
  color: var(--mud-palette-text-secondary);
}

.muted a {
  text-decoration: underline;
}

.detail-sections { display: grid; gap: 24px; min-width: 0; }
.detail-section { padding: 24px; min-width: 0; }
.detail-section-heading {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 20px;
}
.detail-section-heading > div { min-width: 0; }
.detail-section-heading .mud-button-root { flex-shrink: 0; }
.meta-list, .detail-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px 32px;
  margin: 0;
}
.meta-list > div, .detail-grid > div { min-width: 0; }
.detail-field-wide { grid-column: 1 / -1; }
.detail-grid.invoice-start-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.meta-list dt, .detail-grid dt {
  margin: 0 0 4px;
  font-size: .875rem;
  color: var(--mud-palette-text-secondary);
}
.meta-list dd, .detail-grid dd {
  margin: 0;
  color: var(--mud-palette-text-primary);
  overflow-wrap: anywhere;
}
.detail-multiline { white-space: pre-wrap; }
.meta-list .mud-chip { margin: 0; }
@media (max-width: 959px) {
  .meta-list, .detail-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 599px) {
  .detail-sections { gap: 16px; }
  .detail-section { padding: 16px; }
  .meta-list, .detail-grid { grid-template-columns: minmax(0, 1fr); gap: 16px; }
}


/* ======================================================================================
   GOAL 87 - harmonized navigation, page layout, tables, row actions, loading and colour.
   Everything below reads the one MudTheme palette (--mud-palette-*); no colour is hard-coded.
   ====================================================================================== */

:root {
  --page-form-width: 720px;
}

/* Navigation: one section label, equal 44px rows, first label on the page title's top line
   (AppBar 64px + the 24px main-content padding = the drawer's first content line). */
.mud-drawer-content > .app-nav:first-of-type {
  padding-top: 24px;
}

.app-nav + .app-nav {
  margin-top: 8px;
}

.app-nav-section {
  padding: 24px 23px 8px;
  font-size: 10px;
  font-weight: 600;
  line-height: 1.33;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--mud-palette-text-secondary);
}

.app-nav .app-nav-section:first-child {
  padding-top: 0;
}

.app-nav .mud-nav-link {
  min-height: 44px;
  padding: 0 14px;
  border-radius: 6px;
  font-size: 14px;
  align-items: center;
}

.app-nav .app-nav-link { padding: 0 10px; margin-block: 2px; }
.app-nav .mud-nav-link-icon { width: 20px; height: 20px; }

@media (min-width: 960px) {
  .app-content-container { padding-inline: 32px; }
}

/* Entity-specific columns. Shared directory presentation lives in DirectoryTable.razor.css. */
.directory-eyebrow { font-size: 12px; color: var(--mud-palette-text-secondary); margin-bottom: 8px; }
.entity-directory-page h1 { font-size: 28px; font-weight: 700; }
.entity-directory-page .mud-typography-body1 { font-size: 14px; }
.customer-directory-table .directory-identity-cell { width: 48%; }
.project-directory-table .directory-identity-cell { width: 32%; }
.project-directory-table .directory-customer-cell { width: 22%; }
.directory-identity { display: flex; align-items: center; gap: 12px; min-width: 0; }
.directory-entity-icon { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 36px; height: 36px; border: 1px solid var(--mud-palette-lines-default); border-radius: 6px; color: var(--mud-palette-text-secondary); background: var(--mud-palette-background); }
.directory-identity-text { min-width: 0; overflow-wrap: anywhere; }
.app-directory-table .directory-entity-name { font-size: 14px; font-weight: 600; }
button.directory-entity-name { background: transparent; text-align: left; cursor: pointer; font-family: inherit; }
.directory-entity-description { font-size: 12px; color: var(--mud-palette-text-secondary); margin-top: 4px; }
.directory-classification { font-size: 12px; color: var(--mud-palette-info); }
.directory-customer-cell { overflow-wrap: anywhere; }
.app-directory-table .directory-count-cell { text-align: right; font-variant-numeric: tabular-nums; }
.directory-count-link { display: inline-flex; align-items: center; gap: 4px; }
.directory-status { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-width: 140px; }
.directory-status .mud-chip { margin: 0; border-radius: 5px; height: 24px; font-size: 11px; }
.directory-entity-actions { display: flex; gap: 6px; justify-content: flex-end; align-items: center; }
.directory-entity-actions .mud-button { border-color: var(--mud-palette-lines-default); font-size: 12px; min-width: 68px; min-height: 32px; }
.directory-entity-actions .mud-button-icon-start .mud-icon-root { font-size: 16px; }
#projects { scroll-margin-top: 80px; }

@media (max-width: 599.98px) {
  .entity-directory-page h1 { font-size: 24px; }
  .app-directory-table.mud-sm-table .mud-table-body .directory-identity-cell { justify-content: flex-start; padding-top: 16px; }
  .app-directory-table .directory-identity-cell::before { display: none; }
  .app-directory-table .directory-status { justify-content: flex-end; min-width: 0; }
  .app-directory-table .directory-entity-actions { margin-left: auto; }
  .directory-entity-actions .mud-button-root { min-height: 44px; min-width: 44px; }
}

.app-nav .mud-nav-link .mud-nav-link-icon,
.app-nav .mud-nav-link .mud-nav-link-text {
  align-self: center;
}

/* Fortnox child group: children keep the 44px row with compact labels and align below
   the parent label. The parent of the current child is marked without the inset bar,
   which stays exclusive to the active row. */
.app-nav .app-nav-child > .mud-nav-link {
  padding-inline-start: 34px; /* inset row plus text margin aligns beneath the parent label */
  font-size: 13px;
}

/* A child has no icon but MudBlazor still gives its text a 12px start margin, leaving about
   160px for the label in the 236px drawer. The library's active rule sets weight 500 with
   !important, which widens "Synchronization history" past that and wrapped the current row to
   two lines (52.5px). The current child keeps the regular weight so every child stays one
   40px line; its fill, colour and inset bar still mark it. */
.app-nav .app-nav-child > .mud-nav-link.active:not(.mud-nav-link-disabled) {
  font-weight: 400 !important;
}

.app-nav .app-nav-parent-current > .mud-nav-link:not(.active) {
  color: var(--mud-palette-primary);
  font-weight: 600;
}

/* Page width presets. Standard is the full content width; forms stop at one readable column. */
.page-width-form {
  max-width: var(--page-form-width);
}

.page-width-standard {
  max-width: none;
}

.page-back-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-bottom: 8px;
  font-size: 0.875rem;
  color: var(--mud-palette-text-secondary);
}

.page-back-link:hover {
  color: var(--mud-palette-primary);
}

/* GOAL 91.3: local tabs. A labelled row of real links under the page header; the current tab
   carries aria-current="page" and a 2px bar. Theme variables only. */
.local-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  border-bottom: 1px solid var(--mud-palette-lines-default);
}

.local-tab {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding-inline: 16px;
  margin-bottom: -1px;
  border-bottom: 2px solid transparent;
  font-weight: 500;
  color: var(--mud-palette-text-secondary);
}

.local-tab:hover {
  color: var(--mud-palette-text-primary);
}

.local-tab[aria-current] {
  border-bottom-color: var(--mud-palette-primary);
  color: var(--mud-palette-primary);
}

.local-tab:focus-visible {
  outline: 2px solid var(--mud-palette-primary);
  outline-offset: -2px;
  border-radius: 4px;
}

/* Cards and table surfaces: one outlined treatment instead of elevated here and outlined there. */
.mud-card,
.app-data-table.mud-table,
.app-simple-table.mud-table,
.app-simple-table.mud-simple-table {
  box-shadow: none;
  border: 1px solid var(--mud-palette-lines-default);
  border-radius: 8px;
}

/* Directory tables: the search sits on the table's left padding, the footer divider spans the
   full width, and the last row does not double the divider. */
.app-data-table .mud-table-toolbar {
  padding-inline: 16px;
}

.directory-search {
  width: 100%;
  max-width: 24rem;
}

/* The divider belongs to the table body, not the pager: the pager's own top edge was painted
   under its rows-per-page block and showed up only to the right of it. */
.app-data-table .mud-table-container {
  border-bottom: 1px solid var(--mud-palette-lines-default);
}

.app-data-table .mud-table-pagination,
.app-data-table .mud-table-pagination-toolbar,
.app-data-table .mud-table-pagination .mud-toolbar {
  border-top: 0;
}

.app-data-table .mud-table-body .mud-table-row:last-child > .mud-table-cell {
  border-bottom: 0;
}

/* Simple (hand-paged) tables share the directory header weight and row rhythm. */
.app-simple-table .mud-table-head .mud-table-cell,
.app-simple-table th {
  font-weight: 600;
}

/* Sync history is intentionally a wide, hand-paged table. Keep its columns readable on
   phones and let the named region own horizontal scrolling instead of squeezing every cell. */
.fortnox-sync-history-page {
  min-width: 0;
  max-width: 100%;
  overflow-x: clip;
}

.fortnox-sync-history-scroll {
  width: 100%;
  max-width: 100%;
  min-width: 0;
  overflow-x: auto;
  box-sizing: border-box;
}

.fortnox-sync-history-table .mud-table-container {
  width: max-content;
  min-width: 100%;
  overflow-x: visible;
}

.fortnox-sync-history-table {
  width: max-content;
  min-width: 100%;
}

.fortnox-sync-history-table .mud-table-container > table {
  min-width: 1345px;
}

.simple-pager {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 8px;
  padding: 6px 8px;
  border: 1px solid var(--mud-palette-lines-default);
  border-radius: 8px;
  background: var(--mud-palette-surface);
}

.simple-pager-position {
  margin-inline-start: auto;
  padding-inline: 8px;
}

/* Row actions: one right-aligned, vertically centered, non-wrapping group; equal minimum width
   so left edges line up row to row, the role-change button wide enough for its longest label. */
.row-actions-cell {
  text-align: right;
  white-space: nowrap;
}

.row-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  flex-wrap: nowrap;
}

.row-actions .mud-button-root {
  min-width: 5.5rem;
  white-space: nowrap;
}

.row-actions .mud-button-root.row-action-wide {
  min-width: 10rem;
}

@media (max-width: 599.98px) {
  .row-actions {
    flex-wrap: wrap;
  }

  .row-actions .mud-button-root,
  .row-actions .mud-button-root.row-action-wide {
    min-width: 0;
  }
}

/* Reserve one status line and its bar; feedback is readable without animation or color. */
.app-inline-loading { display: inline-flex; align-items: center; gap: 0.5rem; }
/* Only the time data region reloads; keep space below the persistent period toolbar. */
.time-workspace-content { min-height: 20rem; }
.section-loading {
  min-height: 28px;
  width: 100%;
  border-radius: 2px;
}

.section-loading .mud-progress-linear {
  height: 4px;
}

/* Status chips are tonal, not solid: a light tint of the role colour with the role colour as
   text, so Active/Billable/Invoiced read as quiet labels instead of the loudest thing in a row.
   The roles stay the theme's (Success, Info, Warning, Error, Primary). */
.mud-chip.mud-chip-filled,
.mud-chip.mud-chip-filled[class*="mud-chip-color-"] {
  --chip-tone: var(--mud-palette-text-primary);
  background-color: color-mix(in srgb, var(--chip-tone) 13%, var(--mud-palette-surface));
  color: color-mix(in srgb, var(--chip-tone) 88%, black);
}

.mud-chip.mud-chip-filled.mud-chip-color-primary { --chip-tone: var(--mud-palette-primary); }
.mud-chip.mud-chip-filled.mud-chip-color-success { --chip-tone: var(--mud-palette-success); }
.mud-chip.mud-chip-filled.mud-chip-color-info { --chip-tone: var(--mud-palette-info); }
.mud-chip.mud-chip-filled.mud-chip-color-warning { --chip-tone: var(--mud-palette-warning); }
.mud-chip.mud-chip-filled.mud-chip-color-error { --chip-tone: var(--mud-palette-error); }

.mud-chip.mud-chip-filled .mud-chip-content,
.mud-chip.mud-chip-filled .mud-icon-root {
  color: inherit;
}

.chip-busy .mud-chip-icon {
  animation: chip-spin 1s linear infinite;
}

@keyframes chip-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .chip-busy .mud-chip-icon {
    animation: none;
  }
}

/* Stepper (Import, Invoicing): content and the first/last step sit on the container's own edges
   instead of being inset another 24px. */
.mud-stepper .mud-stepper-content {
  padding-inline: 0;
}

.mud-stepper .mud-stepper-nav > .mud-step:first-child {
  padding-inline-start: 0;
}

.mud-stepper .mud-stepper-nav > .mud-step:last-child {
  padding-inline-end: 0;
}

/* Card actions line up with the card's text (16px), not 8px in from it. */
.mud-card .mud-card-actions {
  padding-inline: 16px;
}

/* The native file chooser button matches the other outlined buttons. */
input[type="file"]::file-selector-button {
  margin-inline-end: 12px;
  padding: 6px 14px;
  font: inherit;
  font-weight: 550;
  color: var(--mud-palette-text-primary);
  background: var(--mud-palette-surface);
  border: 1px solid var(--mud-palette-lines-inputs);
  border-radius: var(--mud-default-borderradius);
  cursor: pointer;
}

/* Phone: only the current step shows its label, so the stepper never clips "Pro...". */
@media (max-width: 599.98px) {
  .mud-stepper .mud-stepper-nav .mud-step:not(.active) .mud-step-label-content {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  .mud-stepper .mud-stepper-nav .mud-step:not(.active) {
    padding-inline: 8px;
  }
}

/* Duration fields: the error is shown ONCE, as the red outline plus the toast. The helper text stays
   in the DOM for assistive technology (aria-describedby) but is not drawn: in a narrow day column it
   wrapped one word per line and pushed the row open (GOAL 87 follow-up). */
.duration-field .mud-input-helper-text {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* A locked day in the Week matrix has the footprint of an editable field: same width, a read-only
   tonal surface, the value centered, the lock inside the box on the right. */
.locked-duration {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  width: 4.25rem;
  height: 2.5rem;
  padding-inline: 4px 2px;
  border: 1px solid var(--mud-palette-lines-default);
  border-radius: var(--mud-default-borderradius);
  background: color-mix(in srgb, var(--mud-palette-text-primary) 4%, var(--mud-palette-surface));
  font-variant-numeric: tabular-nums;
}

.locked-duration-value {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0;
  border: 0;
  background: transparent;
  font: inherit;
  font-weight: 550;
  text-align: center;
  color: var(--mud-palette-text-primary);
}

button.locked-duration-value {
  cursor: pointer;
}

.locked-duration-empty {
  color: var(--mud-palette-text-secondary);
  font-weight: 400;
}

.locked-duration .invoice-period-notice summary {
  min-width: 1.25rem;
  min-height: 1.25rem;
}

.locked-duration .invoice-period-notice .mud-icon-root {
  font-size: 0.95rem;
}

@page { size: A4 portrait; margin: 16mm 14mm; }
@media print {
  body:has(.report-print-layout) { background: white !important; }
}

/* Pieces fields share the time field's box (same width and height, see .duration-field); the number sits
   against the unit so "5 pcs" reads as one value. */
.pieces-field input {
  text-align: right;
  padding-right: 4px;
}

.pieces-field .mud-input-adornment-end {
  margin-left: 4px;
  font-size: 0.8125rem;
}

/* The time a pieces entry took: a small, muted line under the pieces (it is part of the Time total). */
.week-pieces-time {
  margin-top: 2px;
  color: var(--mud-palette-text-secondary);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.week-cell-total .week-pieces-time {
  text-align: right;
}

/* The return-to-current-period button sits beside the period arrows and never wraps its label. */
.time-current-period {
  white-space: nowrap;
  flex: none;
}

/* Fortnox history: the long explanations sit behind a native disclosure so the records come first. */
.history-notes summary {
  cursor: pointer;
  color: var(--mud-palette-text-secondary);
  font-size: 0.875rem;
}

/* Header actions wrap inside the page width on a phone and keep every label on one line. */
.page-header-actions {
  flex-shrink: 0;
  max-width: 100%;
}

.page-header-actions .mud-button-root {
  white-space: nowrap;
}

/* One menu activator survives viewport changes. Wide screens show name + chevron;
   compact screens show only the account icon, with the full name inside the menu. */
.account-menu { max-width: 180px; }
.account-menu > button {
  max-width: 100%;
  min-height: 44px;
}
.account-menu .mud-button-label {
  position: relative;
  display: block;
  padding-right: 28px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.account-menu .mud-button-icon-start { display: none; }
.account-menu .mud-button-icon-end {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  margin: 0;
}

/* Equal side tracks center the brand against the full bar, regardless of drawer or timer state.
   Keep one timer in its existing desktop/dock sites; only constrain its descriptive text track. */
.app-header-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  width: 100%;
  gap: 12px;
}
.app-header-navigation { min-width: 0; }
.app-header-brand {
  display: block;
  width: 112px;
  height: auto;
}
.app-header-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  min-width: 0;
}
.app-header-actions .timer-pill {
  flex: 0 1 390px;
  min-width: 0;
}
.app-header-actions > .mud-menu {
  flex: 0 0 auto;
  max-width: 180px;
}
.app-header-actions > .mud-menu > button { max-width: 100%; }
.app-header-actions [data-testid="signin"] { white-space: nowrap; }
@media (max-width: 1279.98px) {
  .account-menu > button {
    width: 44px;
    min-width: 44px;
    height: 44px;
    padding: 0;
  }
  .account-menu .mud-button-label {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    font-size: 0;
  }
  .account-menu .mud-button-icon-start { display: inline-flex; margin: 0; }
  .account-menu .mud-button-icon-end { display: none; }
}
@media (max-width: 599.98px) {
  .app-header-grid { gap: 8px; }
  .app-header-brand { width: 96px; }
  .app-header-actions [data-testid="signin"] .mud-button-icon-start { display: none; }
}

/* The native file chooser button matches the outlined buttons of the rest of the app. */
#import-file::file-selector-button {
  margin-right: 12px;
  padding: 5px 16px;
  border: 1px solid var(--mud-palette-lines-inputs, currentColor);
  border-radius: var(--mud-default-borderradius, 4px);
  background: transparent;
  color: var(--mud-palette-text-primary);
  font: inherit;
  font-weight: 500;
  cursor: pointer;
}

#import-file::file-selector-button:hover {
  background: var(--mud-palette-action-default-hover, rgba(0, 0, 0, 0.04));
}

/* Keep invoice progress visible while reading a long run. */
.invoice-run-summary {
  position: sticky;
  top: 64px;
  z-index: 2;
  background: var(--mud-palette-surface);
  padding: 12px 0;
  border-bottom: 1px solid var(--mud-palette-divider);
}
.invoice-progress-region:focus { outline: none; }
@media (max-width: 599.98px) {
  /* Mobile status rows must fit their card, including long names and action menus. */
  .invoice-run-summary { position: static; }
  .invoice-progress-table .mud-table-root { table-layout: fixed; }
  .invoice-progress-table .mud-table-body .mud-table-cell {
    display: grid;
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.5fr);
    gap: 8px;
    text-align: left;
    white-space: normal;
  }
  .invoice-progress-table .mud-table-body .mud-table-cell::before {
    width: auto;
    min-width: 0;
    margin: 0;
    padding: 0;
  }
  .invoice-progress-table .mud-table-cell > div { min-width: 0; overflow-wrap: anywhere; }
  .invoice-progress-table .mud-chip { max-width: 100%; margin-inline: 0; height: auto; min-height: 32px; }
  .invoice-progress-table .mud-chip-content { white-space: normal; }
  .invoice-progress-table .invoice-row-actions { display: flex; flex-wrap: wrap; align-items: center; }
}

.app-detail-panel.mud-dialog { margin: 0; width: 500px; max-width: 100vw; height: 100dvh; max-height: 100dvh; border-radius: 0; }
.mud-dialog-container:has(> .app-detail-panel) { padding: 0; }
.app-detail-panel .mud-dialog-content { padding: 20px 24px; }
.app-detail-panel .mud-dialog-title { padding: 24px; }
.app-detail-panel .user-membership { padding: 14px; border: 1px solid var(--mud-palette-lines-default); border-radius: 6px; }
.directory-tabs { display: flex; flex-wrap: wrap; gap: 16px; padding: 0 20px; border-bottom: 1px solid var(--mud-palette-lines-default); }
.directory-tabs .mud-button-root { border-radius: 0; padding: 14px 4px; border-bottom: 2px solid transparent; }
.directory-tabs [aria-pressed="true"] { border-bottom-color: var(--mud-palette-primary); font-weight: 600; }
.directory-alternate-sort { margin-left: 12px; font-size: 11px; }
@media (max-width: 599.98px) {
  .app-detail-panel.mud-dialog { width: 100vw; }
  .directory-tabs { gap: 8px; padding-inline: 12px; }
  .directory-tabs .mud-button-root { font-size: 12px; }
}
