/* Data Flywheel office. Material 3 by our design system (tokens.css): colour ROLES, never hex; type ROLES, never a
   raw font size; only the corner scale; depth by tone. Phone first: nav bar on phones, nav rail from 840 px.
   No style attributes are used anywhere in the markup, so everything visual is here. */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  color-scheme: light dark;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--df-sys-color-surface);
  color: var(--df-sys-color-on-surface);
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3,
p,
ul,
dl,
dd,
figure {
  margin: 0;
}

ul {
  padding: 0;
  list-style: none;
}

img,
svg {
  display: block;
  max-width: 100%;
}

a {
  color: inherit;
}

button,
input,
select {
  font: inherit;
  color: inherit;
}

[hidden] {
  display: none !important;
}

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

.skip {
  position: absolute;
  left: 16px;
  top: -64px;
  z-index: 100;
  padding: 12px 20px;
  border-radius: var(--df-sys-shape-corner-full);
  background: var(--df-sys-color-inverse-surface);
  color: var(--df-sys-color-inverse-on-surface);
}

.skip:focus {
  top: 8px;
}

:focus-visible {
  outline: 3px solid var(--df-sys-color-primary);
  outline-offset: 2px;
}

/* ---- type: one rule per role, taken from tokens.css (never a raw font size) ---- */
.page-title {
  font-family: var(--df-sys-typescale-display-small-font);
  font-size: var(--df-sys-typescale-display-small-size);
  line-height: var(--df-sys-typescale-display-small-line-height);
  font-weight: var(--df-sys-typescale-display-small-weight);
  letter-spacing: var(--df-sys-typescale-display-small-tracking);
  font-variation-settings: var(--df-sys-typescale-display-small-axes);
}
.stat-value {
  font-family: var(--df-sys-typescale-headline-large-font);
  font-size: var(--df-sys-typescale-headline-large-size);
  line-height: var(--df-sys-typescale-headline-large-line-height);
  font-weight: var(--df-sys-typescale-headline-large-weight);
  letter-spacing: var(--df-sys-typescale-headline-large-tracking);
  font-variation-settings: var(--df-sys-typescale-headline-large-axes);
}
.t-headline-small,
.empty-title,
.dialog-title {
  font-family: var(--df-sys-typescale-headline-small-font);
  font-size: var(--df-sys-typescale-headline-small-size);
  line-height: var(--df-sys-typescale-headline-small-line-height);
  font-weight: var(--df-sys-typescale-headline-small-weight);
  letter-spacing: var(--df-sys-typescale-headline-small-tracking);
  font-variation-settings: var(--df-sys-typescale-headline-small-axes);
}
.card-title,
.group-title,
.topbar-title {
  font-family: var(--df-sys-typescale-title-large-font);
  font-size: var(--df-sys-typescale-title-large-size);
  line-height: var(--df-sys-typescale-title-large-line-height);
  font-weight: var(--df-sys-typescale-title-large-weight);
  letter-spacing: var(--df-sys-typescale-title-large-tracking);
  font-variation-settings: var(--df-sys-typescale-title-large-axes);
}
.panel-title,
.employee-name,
.env-kind,
.stat-label,
.cost-total {
  font-family: var(--df-sys-typescale-title-medium-font);
  font-size: var(--df-sys-typescale-title-medium-size);
  line-height: var(--df-sys-typescale-title-medium-line-height);
  font-weight: var(--df-sys-typescale-title-medium-weight);
  letter-spacing: var(--df-sys-typescale-title-medium-tracking);
  font-variation-settings: var(--df-sys-typescale-title-medium-axes);
}
.pack-title,
.trend-label {
  font-family: var(--df-sys-typescale-title-small-font);
  font-size: var(--df-sys-typescale-title-small-size);
  line-height: var(--df-sys-typescale-title-small-line-height);
  font-weight: var(--df-sys-typescale-title-small-weight);
  letter-spacing: var(--df-sys-typescale-title-small-tracking);
  font-variation-settings: var(--df-sys-typescale-title-small-axes);
}
body,
.input,
.select {
  font-family: var(--df-sys-typescale-body-large-font);
  font-size: var(--df-sys-typescale-body-large-size);
  line-height: var(--df-sys-typescale-body-large-line-height);
  font-weight: var(--df-sys-typescale-body-large-weight);
  letter-spacing: var(--df-sys-typescale-body-large-tracking);
  font-variation-settings: var(--df-sys-typescale-body-large-axes);
}
.page-sub,
.card-sub,
.employee-desc,
.employee-help,
.group-sub,
.panel-note,
.empty-text,
.dialog-text,
.signin-note,
.metrics th[scope="row"],
.metrics td,
.facts dd,
.cost-lines,
.person,
.banner-text,
.alert,
.muted-text,
.link,
.runs td,
.back,
.topbar-who,
.snackbar-box,
.noscript,
.loading {
  font-family: var(--df-sys-typescale-body-medium-font);
  font-size: var(--df-sys-typescale-body-medium-size);
  line-height: var(--df-sys-typescale-body-medium-line-height);
  font-weight: var(--df-sys-typescale-body-medium-weight);
  letter-spacing: var(--df-sys-typescale-body-medium-tracking);
  font-variation-settings: var(--df-sys-typescale-body-medium-axes);
}
.env-meta,
.run-meta,
.th-sub,
.field-help,
.stat-sub,
.spend-note,
.runs-count,
.env-db,
.dialog-error,
.signin-message,
.spend-of {
  font-family: var(--df-sys-typescale-body-small-font);
  font-size: var(--df-sys-typescale-body-small-size);
  line-height: var(--df-sys-typescale-body-small-line-height);
  font-weight: var(--df-sys-typescale-body-small-weight);
  letter-spacing: var(--df-sys-typescale-body-small-tracking);
  font-variation-settings: var(--df-sys-typescale-body-small-axes);
}
.btn,
.runs th,
.metrics thead th {
  font-family: var(--df-sys-typescale-label-large-font);
  font-size: var(--df-sys-typescale-label-large-size);
  line-height: var(--df-sys-typescale-label-large-line-height);
  font-weight: var(--df-sys-typescale-label-large-weight);
  letter-spacing: var(--df-sys-typescale-label-large-tracking);
  font-variation-settings: var(--df-sys-typescale-label-large-axes);
}
.chip,
.nav-label,
.field-label,
.reason,
.env-pill,
.switch-btn,
.facts dt,
.caps dt {
  font-family: var(--df-sys-typescale-label-medium-font);
  font-size: var(--df-sys-typescale-label-medium-size);
  line-height: var(--df-sys-typescale-label-medium-line-height);
  font-weight: var(--df-sys-typescale-label-medium-weight);
  letter-spacing: var(--df-sys-typescale-label-medium-tracking);
  font-variation-settings: var(--df-sys-typescale-label-medium-axes);
}
.unit {
  font-family: var(--df-sys-typescale-label-small-font);
  font-size: var(--df-sys-typescale-label-small-size);
  line-height: var(--df-sys-typescale-label-small-line-height);
  font-weight: var(--df-sys-typescale-label-small-weight);
  letter-spacing: var(--df-sys-typescale-label-small-tracking);
  font-variation-settings: var(--df-sys-typescale-label-small-axes);
}


/* ---- figures: amounts, counts, dates, ids and codes are Google Sans Code with tabular numbers ---- */
.fig,
.field-name,
.stat-value,
.cost-total {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum';
}

.fig,
.field-name {
  font-family: var(--df-sys-figure-font);
  font-weight: var(--df-sys-figure-weight);
  letter-spacing: var(--df-sys-figure-tracking);
  font-variation-settings: normal;
}

.stat-value .fig,
.cost-total .fig {
  font-weight: var(--df-sys-figure-weight);
}

.fig--none {
  color: var(--df-sys-color-on-surface-variant);
}

.field-name {
  display: inline-block;
  padding: 0 6px;
  border-radius: var(--df-sys-shape-corner-extra-small);
  background: var(--df-sys-color-surface-container-high);
  color: var(--df-sys-color-on-surface);
}

.money {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  white-space: nowrap;
}

.unit {
  color: var(--df-sys-color-on-surface-variant);
  font-family: var(--df-sys-typescale-label-small-font);
}

.muted {
  color: var(--df-sys-color-on-surface-variant);
}

/* ---- icons: Material Symbols Rounded, hidden until the subset font has really loaded ---- */
.icon {
  font-family: 'Material Symbols Rounded';
  font-weight: normal;
  font-style: normal;
  font-size: 24px;
  line-height: 1;
  width: 24px;
  height: 24px;
  display: inline-block;
  flex: none;
  overflow: hidden;
  white-space: nowrap;
  letter-spacing: normal;
  text-transform: none;
  direction: ltr;
  font-feature-settings: 'liga';
  font-variation-settings: 'FILL' var(--df-sys-icon-fill), 'wght' var(--df-sys-icon-weight), 'GRAD' var(--df-sys-icon-grade), 'opsz' 24;
  -webkit-font-smoothing: antialiased;
  opacity: 0;
}

html.icons-ready .icon {
  opacity: 1;
}

/* ---- the frame ---- */
.app {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
}

#rail,
#bottom-nav {
  display: contents;
}

.column {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.main {
  width: 100%;
  max-width: 1280px;
  margin-inline: auto;
  padding: 8px 16px calc(112px + env(safe-area-inset-bottom));
  overflow-wrap: anywhere;
}

.main:focus {
  outline: none;
}

.page-title:focus {
  outline: none;
}

.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--df-sys-color-surface);
  transition: background var(--df-sys-motion-duration-short-4) var(--df-sys-motion-easing-standard);
}

.topbar.is-scrolled {
  background: var(--df-sys-color-surface-container);
}

.topbar-inner {
  display: flex;
  align-items: center;
  gap: 12px;
  height: 64px;
  max-width: 1280px;
  margin-inline: auto;
  padding: 0 16px;
}

.topbar-title {
  margin: 0;
}

.topbar-who {
  display: none;
  color: var(--df-sys-color-on-surface-variant);
}

.spacer {
  flex: 1;
}

.mark {
  display: grid;
  place-items: center;
  flex: none;
  width: 40px;
  height: 40px;
  border-radius: var(--df-sys-shape-corner-medium);
  background: var(--df-brand-blue);
}

.avatar {
  display: grid;
  place-items: center;
  flex: none;
  width: 40px;
  height: 40px;
  border-radius: var(--df-sys-shape-corner-full);
  background: var(--df-brand-blue);
}

/* The blue circle is 2.9:1 against the dark surface; graphics want 3:1, so it gets a ring in dark. */
@media (prefers-color-scheme: dark) {
  .avatar {
    box-shadow: inset 0 0 0 1px var(--df-sys-color-outline-variant);
  }
}

.rail {
  display: none;
}

.bottom-nav {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 30;
  display: flex;
  background: var(--df-sys-color-surface-container);
  padding-bottom: env(safe-area-inset-bottom);
}

.app[data-chrome='bare'] .bottom-nav,
.app[data-chrome='bare'] .rail,
.app[data-chrome='bare'] .topbar {
  display: none;
}

.app[data-chrome='bare'] .main {
  padding-bottom: 16px;
}

/* navigation items: icon in a pill over a label (nav bar and rail share them) */
.nav-item {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  min-height: 80px;
  padding: 12px 4px 16px;
  color: var(--df-sys-color-on-surface-variant);
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}

.nav-pill {
  position: relative;
  display: grid;
  place-items: center;
  width: 64px;
  height: 32px;
  border-radius: var(--df-sys-shape-corner-full);
  transition: background var(--df-sys-motion-duration-short-4) var(--df-sys-motion-easing-standard);
}

.nav-pill::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: currentColor;
  opacity: 0;
  transition: opacity var(--df-sys-motion-duration-short-2) var(--df-sys-motion-easing-standard);
}

.nav-item:hover .nav-pill::before {
  opacity: var(--df-sys-state-hover-opacity);
}

.nav-item:active .nav-pill::before {
  opacity: var(--df-sys-state-pressed-opacity);
}

.nav-item[aria-current='page'] {
  color: var(--df-sys-color-on-surface);
}

.nav-item[aria-current='page'] .nav-pill {
  background: var(--df-sys-color-secondary-container);
  color: var(--df-sys-color-on-secondary-container);
}

.nav-item[aria-current='page'] .icon {
  font-variation-settings: 'FILL' 1, 'wght' var(--df-sys-icon-weight), 'GRAD' var(--df-sys-icon-grade), 'opsz' 24;
}

.nav-item:focus-visible {
  outline-offset: -4px;
  border-radius: var(--df-sys-shape-corner-large);
}

/* ---- buttons ---- */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 40px;
  padding: 0 24px;
  border: 0;
  border-radius: var(--df-sys-shape-corner-full);
  background: transparent;
  color: var(--df-sys-color-primary);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: border-radius var(--df-sys-motion-spring-spatial-fast-duration) var(--df-sys-motion-spring-spatial-fast);
}

/* the touch target is 48 even though the button is drawn 40 */
.btn::after {
  content: '';
  position: absolute;
  inset: -4px 0;
}

.btn::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: currentColor;
  opacity: 0;
  transition: opacity var(--df-sys-motion-duration-short-2) var(--df-sys-motion-easing-standard);
}

.btn:hover::before {
  opacity: var(--df-sys-state-hover-opacity);
}

.btn:focus-visible::before {
  opacity: var(--df-sys-state-focus-opacity);
}

.btn:active::before {
  opacity: var(--df-sys-state-pressed-opacity);
}

.btn:active {
  border-radius: var(--df-sys-shape-corner-medium);
}

.btn:has(.icon) {
  padding-inline: 16px 24px;
}

.btn--text {
  padding-inline: 12px;
}

.btn--text:has(.icon) {
  padding-inline: 12px 16px;
}

.btn--filled {
  background: var(--df-sys-color-primary);
  color: var(--df-sys-color-on-primary);
}

.btn--tonal {
  background: var(--df-sys-color-secondary-container);
  color: var(--df-sys-color-on-secondary-container);
}

.btn--outlined {
  box-shadow: inset 0 0 0 1px var(--df-sys-color-outline);
}

.btn--danger {
  color: var(--df-sys-color-error);
}

.btn--danger:not(.btn--outlined) {
  background: var(--df-sys-color-error);
  color: var(--df-sys-color-on-error);
}

.btn:disabled {
  cursor: default;
  background: color-mix(in srgb, var(--df-sys-color-on-surface) 12%, transparent);
  color: color-mix(in srgb, var(--df-sys-color-on-surface) 38%, transparent);
  box-shadow: none;
}

.btn:disabled::before {
  display: none;
}

.link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--df-sys-color-primary);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.link .icon {
  width: 16px;
  height: 16px;
  font-size: 16px;
  font-variation-settings: 'FILL' 0, 'wght' var(--df-sys-icon-weight), 'GRAD' var(--df-sys-icon-grade), 'opsz' 20;
}

.back {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 48px;
  margin-inline: -8px;
  padding-inline: 8px 16px;
  border-radius: var(--df-sys-shape-corner-full);
  color: var(--df-sys-color-primary);
  text-decoration: none;
}

.back:hover {
  background: color-mix(in srgb, var(--df-sys-color-primary) 8%, transparent);
}

/* ---- chips: small status labels (not buttons), roles for meaning ---- */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 24px;
  padding: 2px 10px;
  border-radius: var(--df-sys-shape-corner-small);
  background: var(--df-sys-color-surface-container-high);
  color: var(--df-sys-color-on-surface-variant);
  white-space: nowrap;
}

.chip .icon {
  width: 16px;
  height: 16px;
  font-size: 16px;
  font-variation-settings: 'FILL' 1, 'wght' var(--df-sys-icon-weight), 'GRAD' var(--df-sys-icon-grade), 'opsz' 20;
}

.chip--muted {
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--df-sys-color-outline-variant);
}

.chip--primary {
  background: var(--df-sys-color-primary-container);
  color: var(--df-sys-color-on-primary-container);
}

.chip--secondary {
  background: var(--df-sys-color-secondary-container);
  color: var(--df-sys-color-on-secondary-container);
}

.chip--success {
  background: var(--df-sys-color-success-container);
  color: var(--df-sys-color-on-success-container);
}

.chip--attention {
  background: var(--df-sys-color-tertiary-container);
  color: var(--df-sys-color-on-tertiary-container);
}

.chip--error {
  background: var(--df-sys-color-error-container);
  color: var(--df-sys-color-on-error-container);
}

.pills {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.env-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 24px;
  padding: 2px 10px;
  border-radius: var(--df-sys-shape-corner-small);
  box-shadow: inset 0 0 0 1px var(--df-sys-color-outline-variant);
  color: var(--df-sys-color-on-surface);
}

.env-pill .fig {
  color: var(--df-sys-color-on-surface-variant);
}

.reasons {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.reason {
  padding: 0 8px;
  border-radius: var(--df-sys-shape-corner-small);
  box-shadow: inset 0 0 0 1px var(--df-sys-color-outline-variant);
  color: var(--df-sys-color-on-surface-variant);
  white-space: nowrap;
}

.names {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

/* ---- banner, alert ---- */
#banner {
  width: 100%;
  max-width: 1280px;
  margin-inline: auto;
  padding-inline: 16px;
}

.banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  padding: 10px 16px;
  border-radius: var(--df-sys-shape-corner-medium);
  background: var(--df-sys-color-tertiary-container);
  color: var(--df-sys-color-on-tertiary-container);
}

.banner-text {
  flex: 1 1 auto;
  margin: 0;
  font-weight: 560;
}

.banner-switch {
  display: inline-flex;
  border-radius: var(--df-sys-shape-corner-full);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--df-sys-color-on-tertiary-container) 60%, transparent);
}

/* No overflow: hidden on the pill: it would clip the 48 px touch area below. Each end button rounds its own corner instead. */
.switch-btn {
  position: relative;
  min-height: 32px;
  padding: 0 16px;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
}

.switch-btn:first-child {
  border-start-start-radius: var(--df-sys-shape-corner-full);
  border-end-start-radius: var(--df-sys-shape-corner-full);
}

.switch-btn:last-child {
  border-start-end-radius: var(--df-sys-shape-corner-full);
  border-end-end-radius: var(--df-sys-shape-corner-full);
}

/* the touch target is 48 even though the button is drawn 32 */
.switch-btn::after {
  content: '';
  position: absolute;
  inset: -8px 0;
}

.switch-btn[aria-pressed='true'] {
  background: var(--df-sys-color-on-tertiary-container);
  color: var(--df-sys-color-tertiary-container);
}

.alert {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 12px 16px;
  border-radius: var(--df-sys-shape-corner-medium);
}

.alert--error {
  background: var(--df-sys-color-error-container);
  color: var(--df-sys-color-on-error-container);
}

/* a date or a count in the figure face never breaks in the middle ("2 Mar" / "2026") */
.card-sub .fig,
.page-sub .fig,
.env-meta .fig,
.stat-sub .fig,
.th-sub .fig {
  white-space: nowrap;
}

/* an alert right under the stat tiles (a total that skipped a figure) */
.stats + .alert {
  margin: -8px 0 24px;
}

/* ---- page heads, stats ---- */
.page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 8px 16px;
  padding: 16px 0 12px;
}

.page-head-main {
  min-width: 0;
}

.page-head-side {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}

.page-sub {
  margin-top: 4px;
  color: var(--df-sys-color-on-surface-variant);
}

.stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin: 8px 0 24px;
}

/* three tiles: on a phone the last (the money) takes the whole row */
.stats--3 .stat:last-child {
  grid-column: 1 / -1;
}

.stat {
  padding: 16px;
  border-radius: var(--df-sys-shape-corner-medium);
  background: var(--df-sys-color-surface-container);
  min-width: 0;
}

.stat-label {
  color: var(--df-sys-color-on-surface-variant);
}

.stat-value {
  margin-top: 4px;
  color: var(--df-sys-color-primary);
}

.stat-value .money {
  gap: 6px;
}

.stat-value .unit {
  font-size: var(--df-sys-typescale-title-small-size);
}

.stat-sub {
  margin-top: 4px;
  color: var(--df-sys-color-on-surface-variant);
}

/* ---- cards and grids ---- */
.grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
}

.card {
  position: relative;
  min-width: 0;
  padding: 16px;
  border: 1px solid var(--df-sys-color-outline-variant);
  border-radius: var(--df-sys-shape-corner-medium);
  background: var(--df-sys-color-surface-container-low);
}

.card-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.card-title {
  min-width: 0;
}

.card-link {
  text-decoration: none;
}

/* the whole card is the link */
.card-link::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

.card-link:focus-visible {
  outline: none;
}

.client-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  transition: background var(--df-sys-motion-duration-short-3) var(--df-sys-motion-easing-standard);
}

.client-card:has(.card-link:hover) {
  background: color-mix(in srgb, var(--df-sys-color-on-surface) 6%, var(--df-sys-color-surface-container-low));
}

.client-card:has(.card-link:focus-visible) {
  outline: 3px solid var(--df-sys-color-primary);
  outline-offset: 2px;
}

.card-sub {
  margin-top: -8px;
  color: var(--df-sys-color-on-surface-variant);
}

.facts {
  display: grid;
  gap: 12px;
}

.fact {
  display: grid;
  gap: 4px;
}

.facts dt,
.caps dt {
  color: var(--df-sys-color-on-surface-variant);
}

.people {
  display: grid;
  gap: 6px;
}

.person {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 8px;
}

.person-name {
  min-width: 0;
}

.card-foot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-top: auto;
  padding-top: 12px;
  border-top: 1px solid var(--df-sys-color-outline-variant);
}

.card-foot-label {
  color: var(--df-sys-color-on-surface-variant);
}

/* ---- client screen ---- */
.layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
  margin-top: 8px;
}

.panel {
  min-width: 0;
  padding: 16px;
  border: 1px solid var(--df-sys-color-outline-variant);
  border-radius: var(--df-sys-shape-corner-medium);
  background: var(--df-sys-color-surface-container-low);
}

.panel-title {
  margin-bottom: 12px;
}

.panel-note {
  margin-top: 12px;
  color: var(--df-sys-color-on-surface-variant);
}

.panel .card {
  background: var(--df-sys-color-surface-container);
}

.envs {
  display: grid;
  gap: 12px;
}

.employees {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  gap: 12px;
}

.env {
  padding: 12px 0;
  border-top: 1px solid var(--df-sys-color-outline-variant);
}

.env:first-child {
  padding-top: 0;
  border-top: 0;
}

.env-head {
  display: flex;
  align-items: center;
  gap: 8px;
}

.env-head .icon {
  color: var(--df-sys-color-on-surface-variant);
}

.env-version {
  margin-left: auto;
  padding: 0 8px;
  border-radius: var(--df-sys-shape-corner-small);
  background: var(--df-sys-color-primary-container);
  color: var(--df-sys-color-on-primary-container);
}

.env-meta {
  margin-top: 4px;
  color: var(--df-sys-color-on-surface-variant);
}

.env-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 16px;
  margin-top: 6px;
}

/* a link in running text is at least 24 px to hit (WCAG 2.2) */
.env-links .link {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
}

.env-db {
  color: var(--df-sys-color-on-surface-variant);
}

.pack + .pack {
  margin-top: 16px;
}

.pack-title {
  margin-bottom: 8px;
  color: var(--df-sys-color-on-surface-variant);
}

.employee {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.employee-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

.employee-who {
  flex: 1;
  min-width: 0;
}

.employee-desc {
  margin-top: 2px;
  color: var(--df-sys-color-on-surface-variant);
}

.employee-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 6px;
}

.card-head .employee-chips {
  justify-content: flex-end;
  margin-top: 0;
}

.employee-help {
  color: var(--df-sys-color-on-surface-variant);
}

.employee--stopped {
  border-color: var(--df-sys-color-error);
}

.employee-actions {
  display: flex;
  margin-top: auto;
}

.caps {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.cost-lines {
  display: grid;
}

.cost-lines li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px solid var(--df-sys-color-outline-variant);
}

.cost-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-top: 12px;
}

/* ---- spend against the cap ---- */
.spend {
  display: grid;
  gap: 8px;
}

.spend-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}

.spend-of {
  color: var(--df-sys-color-on-surface-variant);
}

.spend-share {
  color: var(--df-sys-color-on-surface-variant);
}

.spend--near .spend-share,
.spend--near .spend-note {
  color: var(--df-sys-color-tertiary);
}

.spend--over .spend-share,
.spend--over .spend-note {
  color: var(--df-sys-color-error);
}

.spend-note {
  font-weight: 560;
}

.bar {
  appearance: none;
  -webkit-appearance: none;
  display: block;
  width: 100%;
  height: 8px;
  border: 0;
  border-radius: var(--df-sys-shape-corner-full);
  background: var(--df-sys-color-surface-container-highest);
  box-shadow: inset 0 0 0 1px var(--df-sys-color-outline-variant);
  overflow: hidden;
  color: transparent;
  font-size: 0;
}

.bar::-webkit-progress-bar {
  background: var(--df-sys-color-surface-container-highest);
  border-radius: var(--df-sys-shape-corner-full);
}

.bar::-webkit-progress-value {
  background: var(--df-sys-color-primary);
  border-radius: var(--df-sys-shape-corner-full);
}

.bar::-moz-progress-bar {
  background: var(--df-sys-color-primary);
  border-radius: var(--df-sys-shape-corner-full);
}

.bar--near::-webkit-progress-value {
  background: var(--df-sys-color-tertiary);
}

.bar--near::-moz-progress-bar {
  background: var(--df-sys-color-tertiary);
}

.bar--over::-webkit-progress-value {
  background: var(--df-sys-color-error);
}

.bar--over::-moz-progress-bar {
  background: var(--df-sys-color-error);
}

/* ---- control room ---- */
.score-cards {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 440px), 1fr));
}

.group {
  margin-top: 32px;
}

.group-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}

.group-sub {
  color: var(--df-sys-color-on-surface-variant);
}

/* A scorecard is its own container: it lays itself out by the room it has, not by the screen. One card alone on a wide
   screen spreads into two columns (the table, then the spend and the chart); two or three share the row. */
.score {
  display: flex;
  flex-direction: column;
  gap: 16px;
  container: score / inline-size;
}

.score-body {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}

@container score (min-width: 640px) {
  .score-body {
    display: grid;
    grid-template-columns: minmax(0, 640px) minmax(240px, 360px);
    grid-template-rows: auto 1fr;
    gap: 16px 48px;
    align-items: start;
  }

  .score-body > .metrics {
    grid-column: 1;
    grid-row: 1 / span 2;
  }

  .score-body > .spend,
  .score-body > .muted {
    grid-column: 2;
    grid-row: 1;
  }

  .score-body > .trend-wrap {
    grid-column: 2;
    grid-row: 2;
  }
}

.metrics {
  width: 100%;
  border-collapse: collapse;
}

.metrics th,
.metrics td {
  padding: 8px 0;
  border-bottom: 1px solid var(--df-sys-color-outline-variant);
  vertical-align: middle;
}

.metrics thead th {
  text-align: right;
  color: var(--df-sys-color-on-surface);
  vertical-align: bottom;
}

.metrics thead th:first-child {
  width: 36%;
}

.metrics th[scope='row'] {
  padding-right: 8px;
  text-align: left;
  font-weight: 400;
  color: var(--df-sys-color-on-surface-variant);
}

.metrics td {
  text-align: right;
}

.metrics tbody tr:last-child th,
.metrics tbody tr:last-child td {
  border-bottom: 0;
}

.th-sub {
  display: block;
  color: var(--df-sys-color-on-surface-variant);
  font-weight: 400;
}

.split {
  display: inline-grid;
  gap: 4px;
  justify-items: end;
}

.statebar {
  width: 72px;
  height: 8px;
  overflow: hidden;
  border-radius: var(--df-sys-shape-corner-full);
}

.seg--prepared {
  fill: var(--df-sys-color-success);
}

.seg--look {
  fill: var(--df-sys-color-tertiary);
}

.seg--stop {
  fill: var(--df-sys-color-error);
}

.trend-wrap {
  display: grid;
  gap: 8px;
}

.trend-label {
  color: var(--df-sys-color-on-surface-variant);
}

.trend {
  width: 100%;
  max-width: 240px;
  height: auto;
  overflow: visible;
}

.trend-bar--earlier {
  fill: var(--df-sys-color-outline);
}

.trend-bar--current {
  fill: var(--df-sys-color-primary);
}

.trend-bar--none {
  /* "no decisions": a dotted baseline, so it cannot be mistaken for a week at 0% (a small solid bar) */
  fill: none;
  stroke: var(--df-sys-color-outline);
  stroke-width: 1.2;
  stroke-dasharray: 1.6 2.2;
}

.trend-bar--current.trend-bar--none {
  stroke: var(--df-sys-color-primary);
}

.trend-note {
  color: var(--df-sys-color-on-surface-variant);
}

/* ---- runs ---- */
.filters {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin: 8px 0 16px;
  align-items: end;
}

.field {
  position: relative;
  display: grid;
  gap: 6px;
  min-width: 0;
}

.field-label {
  color: var(--df-sys-color-on-surface-variant);
}

.field-help {
  color: var(--df-sys-color-on-surface-variant);
}

.input,
.select {
  width: 100%;
  min-height: 48px;
  padding: 0 16px;
  border: 1px solid var(--df-sys-color-outline);
  border-radius: var(--df-sys-shape-corner-extra-small);
  background: var(--df-sys-color-surface);
  appearance: none;
  -webkit-appearance: none;
}

.input:hover,
.select:hover {
  border-color: var(--df-sys-color-on-surface);
}

.input:focus-visible,
.select:focus-visible {
  outline: none;
  border-color: var(--df-sys-color-primary);
  box-shadow: inset 0 0 0 1px var(--df-sys-color-primary);
}

.select {
  padding-right: 40px;
  text-overflow: ellipsis;
}

.field--select::after {
  content: '';
  position: absolute;
  right: 14px;
  bottom: 14px;
  width: 20px;
  height: 20px;
  background: var(--df-sys-color-on-surface-variant);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 10l5 5 5-5z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 10l5 5 5-5z'/%3E%3C/svg%3E") center / contain no-repeat;
  pointer-events: none;
}

.filters-clear {
  grid-column: 1 / -1;
  justify-self: start;
  margin-inline-start: -12px;
}

.runs-count {
  margin: 0 0 12px;
  color: var(--df-sys-color-on-surface-variant);
}

.runs {
  width: 100%;
}

.runs thead {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

.runs tbody {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
}

.runs tr.run {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr);
  grid-template-areas:
    'client client when'
    'employee employee ms'
    'status status cost'
    'changed changed changed'
    'why why why';
  align-items: center;
  column-gap: 8px;
  padding: 12px 16px;
  border: 1px solid var(--df-sys-color-outline-variant);
  border-radius: var(--df-sys-shape-corner-medium);
  background: var(--df-sys-color-surface-container-low);
}

.runs td {
  padding: 3px 0;
  min-width: 0;
}

.run-meta,
.c-client {
  overflow-wrap: anywhere;
}

.runs td:empty {
  display: none;
}

.c-client {
  grid-area: client;
  font-weight: 560;
}

/* The client's name is the one link in a card, so its touch target is 48 tall; the negative margin keeps the card compact. */
.c-client .link {
  display: inline-flex;
  align-items: center;
  min-height: 48px;
  margin-block: -14px;
}

.c-when {
  grid-area: when;
  text-align: right;
  white-space: nowrap;
  color: var(--df-sys-color-on-surface-variant);
}

.c-employee {
  grid-area: employee;
  display: grid;
}

.c-ms {
  grid-area: ms;
  text-align: right;
  color: var(--df-sys-color-on-surface-variant);
}

.c-status {
  grid-area: status;
  padding-top: 6px;
}

/* The state and the decision are two chips in one cell, side by side when there is room and stacked when there is not:
   they cannot run into each other, because they are in a flex row that wraps, not in two cells that can be too narrow. */
.status-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}

.c-cost {
  grid-area: cost;
  text-align: right;
  padding-top: 6px;
  justify-self: end;
}

.c-changed {
  grid-area: changed;
  padding-top: 6px;
}

.c-why {
  grid-area: why;
  padding-top: 6px;
}

.run-meta {
  color: var(--df-sys-color-on-surface-variant);
}

/* The model and the versions are two pieces that never break inside: in a card they sit on one line when there is room and
   on two when there is not, and a name is never cut in the middle or left with a dot at the start of a line. */
.run-model,
.run-versions {
  display: inline-block;
  white-space: nowrap;
}

.run-model {
  margin-inline-end: 0.7em;
}

/* The text cells that span columns must not make those columns wider than the chips need: their own width counts as zero
   when the grid is sized, and they then fill the area they were given. (A long run-meta line would otherwise squeeze the
   date into a sliver.) The chips cell is the exception: its width is what the first two columns are sized by. */
.c-client,
.c-employee,
.c-changed,
.c-why {
  contain: inline-size;
}

/* A phone narrower than 380 cannot hold the chips, the date and the cost side by side: the date goes beside the time it took,
   and the cost drops to its own line. */
@media (max-width: 379px) {
  .runs tr.run {
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas:
      'client client'
      'when ms'
      'employee employee'
      'status status'
      'cost cost'
      'changed changed'
      'why why';
  }

  .c-when {
    text-align: left;
  }

  .c-cost {
    justify-self: start;
    text-align: left;
  }
}

/* ---- empty, loading ---- */
.empty {
  display: grid;
  justify-items: center;
  gap: 8px;
  max-width: 480px;
  margin: 48px auto;
  padding: 0 8px;
  text-align: center;
}

.empty .icon {
  width: 48px;
  height: 48px;
  font-size: 48px;
  margin-bottom: 8px;
  color: var(--df-sys-color-on-surface-variant);
  font-variation-settings: 'FILL' 0, 'wght' var(--df-sys-icon-weight), 'GRAD' var(--df-sys-icon-grade), 'opsz' 48;
}

.empty-text {
  color: var(--df-sys-color-on-surface-variant);
}

.empty .btn {
  margin-top: 8px;
}

.loading {
  display: grid;
  justify-items: center;
  gap: 12px;
  margin: 96px auto;
  color: var(--df-sys-color-on-surface-variant);
}

/* the flywheel's turn, kept as the loading animation */
.loading-ring {
  width: 40px;
  height: 40px;
  border: 4px solid var(--df-sys-color-primary-container);
  border-top-color: var(--df-sys-color-primary);
  border-radius: var(--df-sys-shape-corner-full);
  animation: spin 900ms linear infinite;
}

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

/* ---- sign in ---- */
.signin {
  display: grid;
  place-items: center;
  min-height: calc(100dvh - 32px);
}

.signin-card {
  display: grid;
  gap: 16px;
  width: 100%;
  max-width: 440px;
  padding: 0 0 24px;
  overflow: hidden;
  border-radius: var(--df-sys-shape-corner-extra-large);
  background: var(--df-sys-color-surface-container-low);
  border: 1px solid var(--df-sys-color-outline-variant);
}

.signin-card > *:not(.signin-hero) {
  margin-inline: 24px;
}

.signin-hero {
  display: grid;
  place-items: center;
  padding: 32px;
  background: var(--df-brand-blue);
}

.signin-form {
  display: grid;
  gap: 12px;
}

.signin-form .btn {
  justify-self: start;
}

.signin-message {
  min-height: 1rem;
  color: var(--df-sys-color-error);
}

.signin-note {
  color: var(--df-sys-color-on-surface-variant);
}

/* ---- dialog and snackbar: the things that float have shadows ---- */
.dialog {
  width: min(560px, calc(100vw - 32px));
  max-height: calc(100dvh - 32px);
  padding: 24px;
  border: 0;
  border-radius: var(--df-sys-shape-corner-extra-large);
  background: var(--df-sys-color-surface-container-high);
  color: var(--df-sys-color-on-surface);
  box-shadow: var(--df-sys-elevation-level3);
}

.dialog::backdrop {
  background: color-mix(in srgb, var(--df-sys-color-scrim) 32%, transparent);
}

.dialog-body {
  display: grid;
  gap: 16px;
  justify-items: start;
}

.dialog-body .field {
  width: 100%;
}

.dialog-icon .icon {
  width: 32px;
  height: 32px;
  font-size: 32px;
  font-variation-settings: 'FILL' 1, 'wght' var(--df-sys-icon-weight), 'GRAD' var(--df-sys-icon-grade), 'opsz' 40;
}

.dialog-icon--error {
  color: var(--df-sys-color-error);
}

.dialog-icon--primary {
  color: var(--df-sys-color-primary);
}

.dialog-text {
  color: var(--df-sys-color-on-surface-variant);
}

.dialog-error {
  min-height: 1rem;
  color: var(--df-sys-color-error);
}

.dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 8px;
}

.snackbar {
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: calc(96px + env(safe-area-inset-bottom));
  z-index: 60;
  display: flex;
  justify-content: center;
  pointer-events: none;
  visibility: hidden;
}

.snackbar.is-open {
  visibility: visible;
}

.snackbar-box {
  max-width: 560px;
  padding: 14px 16px;
  border-radius: var(--df-sys-shape-corner-extra-small);
  background: var(--df-sys-color-inverse-surface);
  color: var(--df-sys-color-inverse-on-surface);
  box-shadow: var(--df-sys-elevation-level3);
  animation: rise var(--df-sys-motion-duration-medium-2) var(--df-sys-motion-easing-emphasized-decelerate);
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
}

.noscript {
  margin: 48px 0;
  text-align: center;
}

/* ---- from 600: a little more air ---- */
@media (min-width: 600px) {
  /* The nav bar's three items sit together in the middle, not 250 px apart across a tablet. */
  .bottom-nav {
    justify-content: center;
    gap: 24px;
  }

  .bottom-nav .nav-item {
    flex: 0 0 144px;
  }

  /* As many cards side by side as fit at 345 px or more: that is the least a card needs for its chips, date and cost. */
  .runs tbody {
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 345px), 1fr));
  }

  .stats {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .stats--3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .stats--3 .stat:last-child {
    grid-column: auto;
  }

  .filters {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .topbar-who {
    display: block;
  }
}

/* ---- from 840: the nav rail replaces the nav bar ---- */
@media (min-width: 840px) {
  .app {
    flex-direction: row;
  }

  .bottom-nav {
    display: none;
  }

  .rail {
    position: sticky;
    top: 0;
    z-index: 25;
    display: flex;
    flex: none;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    width: 96px;
    height: 100dvh;
    padding: 24px 0;
  }

  .rail .mark {
    margin-bottom: 20px;
  }

  .rail .nav-item {
    flex: none;
    width: 96px;
    min-height: 0;
    padding: 4px 0;
  }

  .topbar-mark {
    display: none;
  }

  .topbar-inner,
  #banner {
    padding-inline: 32px;
  }

  .main {
    padding: 8px 32px 48px;
  }

  .snackbar {
    bottom: 24px;
  }

  .cards {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .layout {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .panel--wide {
    grid-column: 1 / -1;
  }

  .stats--4 {
    gap: 16px;
  }
}

@media (min-width: 1100px) {
  .cards {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* from 1280: runs become a real table, with fixed column widths so a long name wraps instead of widening the page.
   (Below that the cards are used: 1200 px leaves the table 1040 px, and eight columns of chips and figures need about 1080.) */
@media (min-width: 1280px) {
  .runs {
    table-layout: fixed;
    border-collapse: separate;
    border-spacing: 0;
    border: 1px solid var(--df-sys-color-outline-variant);
    border-radius: var(--df-sys-shape-corner-medium);
    background: var(--df-sys-color-surface-container-low);
    overflow: hidden;
  }

  .runs thead {
    position: static;
    width: auto;
    height: auto;
    overflow: visible;
    clip-path: none;
  }

  .runs tbody {
    display: table-row-group;
  }

  .runs tr.run {
    display: table-row;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
  }

  /* Every column has a width in pixels, wide enough for what it holds: the longest chip, "Needs a look", is about 104 px;
     the longest reason, "Foreign currency", about 140; the model name, 17 letters of the figure face, about 125. Any room
     beyond their sum is shared out, so the table fills the page. The state and the decision are one column: chips that
     stack when it is narrow and sit side by side when it is not. */
  .runs th:nth-child(1) { width: 132px; }
  .runs th:nth-child(2) { width: 172px; }
  .runs th:nth-child(3) { width: 150px; }
  .runs th:nth-child(4) { width: 148px; }
  .runs th:nth-child(5) { width: 120px; }
  .runs th:nth-child(6) { width: 164px; }
  .runs th:nth-child(7) { width: 116px; }
  .runs th:nth-child(8) { width: 80px; }

  .runs th,
  .runs td {
    padding: 12px 12px;
    text-align: left;
    vertical-align: top;
    border-top: 1px solid var(--df-sys-color-outline-variant);
  }

  .runs thead th {
    border-top: 0;
    background: var(--df-sys-color-surface-container);
    color: var(--df-sys-color-on-surface-variant);
  }

  .runs td:empty {
    display: table-cell;
  }

  .runs .num,
  .runs td.c-cost,
  .runs td.c-ms {
    text-align: right;
  }

  .c-cost,
  .c-ms {
    white-space: nowrap;
  }

  /* In the table the name is read in a row of text, not tapped as a card: 24 px is the target, and it may wrap. */
  .c-client .link {
    display: inline;
    min-height: 0;
    margin-block: 0;
    padding-block: 2px;
  }

  .runs td.c-cost,
  .runs td.c-ms,
  .c-when,
  .c-client,
  .c-employee,
  .c-status,
  .c-changed,
  .c-why {
    padding-top: 12px;
  }

  /* table cells size themselves: the card layout's "count as zero" trick is for grid items only */
  .runs td.c-client,
  .runs td.c-employee,
  .runs td.c-changed,
  .runs td.c-why {
    contain: none;
  }

  .c-employee {
    display: table-cell;
  }

  .run-employee,
  .run-meta,
  .run-model,
  .run-versions {
    display: block;
  }

  /* in the table the model and the versions are two lines */
  .run-model {
    margin-inline-end: 0;
  }

  .c-when {
    text-align: left;
    white-space: nowrap;
  }

  .runs tbody tr:first-child td {
    border-top: 0;
  }
}

/* ---- motion: reduced motion means no springs and no ambient movement ---- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }

  .loading-ring {
    animation: none;
  }
}
