/* ============================================================
   Smith Product Sense — application layout
   Structure only. Every color, font, radius, spacing and motion
   value comes from tokens.css via var(--...). No raw hex, no raw
   font names, no raw spacing/radius values in this file.
   ============================================================ */

:root {
  /* WCAG 2.5.5 minimum touch target (Spec 7b). An accessibility constant
     rather than a design token, so it lives here and not in tokens.css. */
  --touch-target: 44px;
  --page-max: 1120px;
  --hairline: 1px;
}

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

body {
  margin: 0;
  min-height: 100vh;
}

/* ---------------------------------------------------------------- utilities */

.visually-hidden {
  position: absolute;
  width: var(--hairline);
  height: var(--hairline);
  padding: 0;
  margin: calc(var(--hairline) * -1);
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: var(--space-4);
  top: calc(var(--space-4) * -4);
  z-index: 100;
  padding: var(--space-3) var(--space-4);
  background: var(--bg-surface);
  color: var(--fg-default);
  border: var(--hairline) solid var(--border-strong);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: top var(--duration-fast) var(--ease-out);
}
.skip-link:focus {
  top: var(--space-4);
}

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.spacer {
  flex: 1 1 auto;
}

.empty-state {
  padding: var(--space-8);
  border: var(--hairline) dashed var(--border-default);
  border-radius: var(--radius-md);
  color: var(--fg-muted);
  text-align: center;
}

/* ------------------------------------------------------------------- layout */

.page {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: var(--space-6) var(--space-5) var(--space-24);
}

.site-header {
  border-bottom: var(--hairline) solid var(--border-default);
  background: var(--bg-surface);
  position: sticky;
  top: 0;
  z-index: 20;
}

.site-header__inner {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: var(--space-3) var(--space-5);
  display: flex;
  align-items: center;
  gap: var(--space-5);
  flex-wrap: wrap;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  text-decoration: none;
  color: var(--fg-default);
}
.brand:hover {
  text-decoration: none;
}
.brand__word {
  font-family: var(--font-display);
  font-size: var(--type-h2);
  font-weight: 500;
  letter-spacing: var(--ls-snug);
  line-height: var(--lh-tight);
}

.site-nav {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  /* Four nav items do not fit on a 390px viewport in one line. Without wrapping
     the nav overflows the page by a few pixels and the whole document scrolls
     sideways on every page. */
  flex-wrap: wrap;
}

.site-nav a {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-target);
  padding: 0 var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--ink-700);
  text-decoration: none;
  font-size: var(--type-body-sm);
  font-weight: 500;
  transition: background-color var(--duration-base) var(--ease-out);
}
.site-nav a:hover {
  background: var(--bg-hover);
  text-decoration: none;
}
.site-nav a[aria-current='page'] {
  background: var(--brand-bg);
  color: var(--brand-text);
}

.page-title {
  margin: 0 0 var(--space-2);
}

.page-intro {
  margin: 0 0 var(--space-8);
  color: var(--fg-muted);
  max-width: 60ch;
}

.section {
  margin-bottom: var(--space-12);
}

.section__head {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  flex-wrap: wrap;
}

.section__head h2 {
  margin: 0;
}

/* ------------------------------------------------------------------ buttons */

button,
.btn {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--type-body-sm);
  border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4);
  min-height: var(--touch-target);
  cursor: pointer;
  transition: background-color var(--duration-base) var(--ease-out),
    border-color var(--duration-base) var(--ease-out),
    transform var(--duration-fast) var(--ease-out);
  border: var(--hairline) solid transparent;
  line-height: var(--lh-tight);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  text-decoration: none;
}

button:active,
.btn:active {
  transform: scale(0.99);
}

.btn-primary {
  background: var(--brand);
  color: var(--fg-onbrand);
}
.btn-primary:hover {
  background: var(--brand-hover);
}

.btn-secondary {
  background: var(--bg-surface);
  color: var(--fg-default);
  border-color: var(--border-default);
}
.btn-secondary:hover {
  background: var(--bg-inset);
  border-color: var(--border-strong);
}

.btn-ghost {
  background: transparent;
  color: var(--ink-700);
}
.btn-ghost:hover {
  background: var(--bg-hover);
}

.btn-danger {
  background: var(--bg-surface);
  color: var(--error);
  border-color: var(--brick-100);
}
.btn-danger:hover {
  background: var(--error-bg);
  border-color: var(--error);
}

.btn-small {
  font-size: var(--type-caption);
  padding: var(--space-2) var(--space-3);
}

button[disabled] {
  opacity: 0.45;
  cursor: not-allowed;
}

/* ------------------------------------------------------------ badges, chips */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  font-size: var(--type-caption);
  font-weight: 500;
  line-height: var(--lh-tight);
  white-space: nowrap;
}

.dot {
  width: var(--space-2);
  height: var(--space-2);
  border-radius: var(--radius-pill);
  background: currentColor;
  flex: none;
}

.b-info {
  background: var(--info-bg);
  color: var(--info);
}
.b-warn {
  background: var(--warning-bg);
  color: var(--amber-700);
}
.b-error {
  background: var(--error-bg);
  color: var(--error);
}
.b-success {
  background: var(--success-bg);
  color: var(--success);
}
.b-neutral {
  background: var(--bg-inset);
  color: var(--ink-700);
  border: var(--hairline) solid var(--border-default);
}

.chip {
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  font-size: var(--type-caption);
  font-family: var(--font-mono);
  background: var(--bg-inset);
  color: var(--ink-700);
  border: var(--hairline) solid var(--border-default);
  white-space: nowrap;
}

.chip-pending {
  background: var(--warning-bg);
  color: var(--amber-700);
  border-color: var(--amber-100);
}

.division-tag {
  font-size: var(--type-micro);
  font-weight: 600;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--fg-muted);
  text-decoration: none;
}
a.division-tag:hover {
  color: var(--brand);
}

/* -------------------------------------------------------------------- forms */

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}

.field-label {
  font-size: var(--type-caption);
  font-weight: 600;
  color: var(--ink-700);
}

.field-hint {
  font-size: var(--type-caption);
  color: var(--fg-muted);
}

input,
select,
textarea {
  font-family: var(--font-body);
  font-size: var(--type-body-sm);
  color: var(--ink-900);
  background: var(--bg-surface);
  border: var(--hairline) solid var(--border-default);
  border-radius: var(--radius-sm);
  padding: var(--space-3);
  min-height: var(--touch-target);
  line-height: var(--lh-default);
  outline: none;
  width: 100%;
  transition: border-color var(--duration-base) var(--ease-out);
}

textarea {
  min-height: calc(var(--touch-target) * 2);
  resize: vertical;
}

input::placeholder {
  color: var(--ink-300);
}

input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  border-color: var(--brand);
}

.input-error {
  border-color: var(--error);
}

.error-text {
  color: var(--error);
  font-size: var(--type-caption);
}

.page-error {
  padding: var(--space-4);
  border: var(--hairline) solid var(--brick-100);
  background: var(--error-bg);
  color: var(--error);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-6);
}

/* -------------------------------------------------------------------- cards */

.card {
  background: var(--bg-surface);
  border: var(--hairline) solid var(--border-default);
  border-radius: var(--radius-md);
  padding: var(--space-5);
}

/* ------------------------------------------------------- dashboard: this week */

.task-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border: var(--hairline) solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
  overflow: hidden;
}

.task-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: var(--hairline) solid var(--border-subtle);
  flex-wrap: wrap;
}
.task-row:last-child {
  border-bottom: 0;
}

.task-row__check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--touch-target);
  min-height: var(--touch-target);
  margin: 0;
  flex: none;
}

.task-row__check input[type='checkbox'] {
  width: var(--space-5);
  height: var(--space-5);
  min-height: 0;
  accent-color: var(--brand);
  cursor: pointer;
}

.task-row__body {
  flex: 1 1 20ch;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.task-row__title {
  color: var(--ink-900);
  overflow-wrap: anywhere;
}

.task-row.is-done .task-row__title {
  text-decoration: line-through;
  color: var(--fg-muted);
}

.task-row__meta {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  font-size: var(--type-caption);
  color: var(--fg-muted);
}

.task-row__due {
  font-family: var(--font-mono);
  font-size: var(--type-micro);
  color: var(--fg-muted);
  white-space: nowrap;
}

.task-row__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-left: auto;
}

/* ------------------------------------------------------ dashboard: divisions */

.division-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 30ch), 1fr));
  gap: var(--space-4);
  list-style: none;
  margin: 0;
  padding: 0;
}

.division-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  height: 100%;
  background: var(--bg-surface);
  border: var(--hairline) solid var(--border-default);
  border-radius: var(--radius-md);
  padding: var(--space-5);
  text-decoration: none;
  color: var(--fg-default);
  transition: background-color var(--duration-base) var(--ease-out),
    box-shadow var(--duration-base) var(--ease-out);
}
.division-card:hover {
  background: var(--bg-inset);
  box-shadow: var(--shadow-sm);
  text-decoration: none;
}

.division-card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
}

.division-card__name {
  margin: 0;
}

.division-card__desc {
  margin: 0;
  color: var(--fg-muted);
  font-size: var(--type-body-sm);
}

.division-card__meta {
  margin-top: auto;
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  font-family: var(--font-mono);
  font-size: var(--type-micro);
  /* fg-subtle (ink-400) is 3.6:1 on paper — under AA for this size. */
  color: var(--fg-muted);
}

.division-add {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: calc(var(--touch-target) * 3);
  width: 100%;
  height: 100%;
  border: var(--hairline) dashed var(--border-strong);
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--ink-700);
}
.division-add:hover {
  background: var(--bg-hover);
  border-color: var(--brand);
  color: var(--brand-text);
}

/* ------------------------------------------------- dashboard: innovation lab */

/* Visually distinct from delivery work: dashed, quieter. Unlike Pellucid's
   vision seeds these do carry a status — an experiment has somewhere to go. */
.lab-panel {
  border: var(--hairline) dashed var(--border-strong);
  border-radius: var(--radius-lg);
  background: var(--bg-inset);
  padding: var(--space-6);
}

.experiment-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 28ch), 1fr));
  gap: var(--space-4);
  list-style: none;
  margin: 0;
  padding: 0;
}

.experiment {
  background: var(--bg-surface);
  border: var(--hairline) dashed var(--border-default);
  border-radius: var(--radius-md);
  padding: var(--space-4);
}

.experiment__title {
  margin: 0 0 var(--space-1);
}

.experiment__desc {
  margin: 0;
  color: var(--fg-muted);
  font-size: var(--type-body-sm);
}

/* ---------------------------------------------------------- division detail */

.detail-head {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-8);
}

.file-list,
.detail-task-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.file-item,
.detail-task {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--bg-surface);
  border: var(--hairline) solid var(--border-default);
  border-radius: var(--radius-md);
  flex-wrap: wrap;
}

.file-item__body,
.detail-task__body {
  flex: 1 1 24ch;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.file-item__name {
  font-weight: 600;
  overflow-wrap: anywhere;
}

.file-item__meta {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  font-family: var(--font-mono);
  font-size: var(--type-micro);
  /* fg-subtle (ink-400) is 3.6:1 on paper — under AA for this size. */
  color: var(--fg-muted);
}

.item-actions {
  display: flex;
  gap: var(--space-2);
  margin-left: auto;
  flex-wrap: wrap;
}

.status-filter {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.upload-progress {
  width: 100%;
  height: var(--space-1);
  background: var(--sand-200);
  border-radius: var(--radius-pill);
  overflow: hidden;
  margin-top: var(--space-2);
}

.upload-progress__fill {
  height: 100%;
  background: var(--brand);
  transition: width var(--duration-base) var(--ease-out);
}

.dropzone {
  border: var(--hairline) dashed var(--border-strong);
  border-radius: var(--radius-md);
  padding: var(--space-6);
  text-align: center;
  color: var(--fg-muted);
  background: var(--bg-inset);
}
.dropzone.is-dragover {
  border-color: var(--brand);
  background: var(--brand-bg);
  color: var(--brand-text);
}

/* ------------------------------------------------------------------ roadmap */

.roadmap-toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-6);
}

.toggle-group {
  display: inline-flex;
  border: var(--hairline) solid var(--border-default);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.toggle-group button {
  border-radius: 0;
  border: 0;
  background: var(--bg-surface);
  color: var(--ink-700);
}
.toggle-group button + button {
  border-left: var(--hairline) solid var(--border-default);
}
.toggle-group button[aria-pressed='true'] {
  background: var(--brand);
  color: var(--fg-onbrand);
}

.roadmap-scroll {
  overflow-x: auto;
  border: var(--hairline) solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
  max-width: 100%;
  /* Without paint containment the wide grid inflates the document's scroll width
     and the whole page scrolls sideways on a phone — overflow-x alone does not
     stop it. Containment keeps the horizontal scroll inside this region, which is
     what Section 7b asks for. Sticky lane names still resolve against this
     element, so they keep working. */
  contain: paint;
}

.roadmap-grid {
  display: grid;
  /* Sized against the container, not its own content. Under an intrinsic width
     (max-content) a 1fr track resolves to the longest unwrapped task title —
     ~600px per column, so barely two columns fit on a laptop. Sizing to 100%
     lets 1fr share the available width, while the minmax() minimums still
     overflow a phone and make .roadmap-scroll scroll. */
  width: 100%;
}

/* Track widths are set by grid-template-columns in roadmap.js; item min-widths
   would fight with it, so they are deliberately not set here. */
.roadmap-cell,
.lane__name,
.roadmap-colhead {
  border-bottom: var(--hairline) solid var(--border-subtle);
  border-right: var(--hairline) solid var(--border-subtle);
  padding: var(--space-3);
  min-width: 0;
}

/* Lane label stays visible while the columns scroll horizontally. */
.lane__name {
  position: sticky;
  left: 0;
  z-index: 2;
  background: var(--bg-inset);
  font-weight: 600;
  font-size: var(--type-body-sm);
  display: flex;
  align-items: center;
}

.lane__name a {
  color: var(--fg-default);
  text-decoration: none;
}
.lane__name a:hover {
  color: var(--brand);
}

.roadmap-colhead {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--bg-inset);
  font-family: var(--font-mono);
  font-size: var(--type-micro);
  color: var(--fg-muted);
  text-transform: uppercase;
  letter-spacing: var(--ls-wide);
}

.roadmap-colhead.is-corner {
  left: 0;
  z-index: 3;
}

.roadmap-colhead.is-unscheduled,
.roadmap-cell.is-unscheduled {
  background: var(--bg-inset);
}

.roadmap-cell {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  vertical-align: top;
}

.roadmap-task {
  display: block;
  width: 100%;
  text-align: left;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  border: var(--hairline) solid var(--border-default);
  background: var(--bg-surface);
  font-size: var(--type-caption);
  color: var(--ink-700);
  min-height: var(--touch-target);
  line-height: var(--lh-default);
  overflow-wrap: anywhere;
  /* These read as cards, not inline links — the global underline is noise here. */
  text-decoration: none;
}
.roadmap-task:hover {
  background: var(--bg-inset);
  border-color: var(--border-strong);
}
.roadmap-task.is-done {
  text-decoration: line-through;
  color: var(--fg-muted);
}

.roadmap-task__status {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--type-micro);
  /* fg-subtle (ink-400) is 3.6:1 on paper — under AA for this size. */
  color: var(--fg-muted);
  margin-top: var(--space-1);
}

/* ------------------------------------------------------------------ dialogs */

dialog {
  border: var(--hairline) solid var(--border-default);
  border-radius: var(--radius-lg);
  background: var(--bg-surface);
  color: var(--fg-default);
  padding: 0;
  width: min(52ch, calc(100% - var(--space-8)));
  box-shadow: var(--shadow-md);
}

dialog::backdrop {
  background: rgb(20 24 28 / 0.32);
}

.dialog__form {
  padding: var(--space-6);
}

.dialog__title {
  margin: 0 0 var(--space-5);
}

.dialog__actions {
  display: flex;
  gap: var(--space-3);
  justify-content: flex-end;
  margin-top: var(--space-6);
  flex-wrap: wrap;
}

/* ------------------------------------------------- banners: offline, update */

.offline-indicator,
.update-banner {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  font-size: var(--type-body-sm);
  flex-wrap: wrap;
}

.offline-indicator {
  background: var(--warning-bg);
  color: var(--amber-700);
  border-bottom: var(--hairline) solid var(--amber-100);
}

.update-banner {
  background: var(--brand-bg);
  color: var(--brand-text);
  border-bottom: var(--hairline) solid var(--peach-300);
}

.update-banner button {
  min-height: var(--touch-target);
}

/* --------------------------------------------------------- auth-only screens */

.auth-shell {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-6);
}

.auth-card {
  width: min(46ch, 100%);
  background: var(--bg-surface);
  border: var(--hairline) solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: var(--space-8);
}

.auth-card__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-6);
}

.auth-note {
  margin-top: var(--space-5);
  color: var(--fg-muted);
  font-size: var(--type-caption);
}

.auth-success {
  padding: var(--space-4);
  border: var(--hairline) solid var(--olive-100);
  background: var(--success-bg);
  color: var(--success);
  border-radius: var(--radius-md);
  margin-top: var(--space-4);
}

/* ------------------------------------------------------------- narrow screens */

@media (max-width: 40rem) {
  .page {
    padding: var(--space-5) var(--space-4) var(--space-16);
  }

  .site-header__inner {
    padding: var(--space-3) var(--space-4);
    gap: var(--space-3);
  }

  .division-grid,
  .experiment-grid {
    grid-template-columns: 1fr;
  }

  /* Forms with several fields become a bottom sheet, not a cramped modal. */
  dialog {
    width: 100%;
    max-width: none;
    max-height: 92vh;
    margin: auto auto 0;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    border-bottom: 0;
  }

  .dialog__form {
    padding: var(--space-5);
    overflow-y: auto;
    max-height: 92vh;
  }

  .dialog__actions button {
    flex: 1 1 14ch;
  }

  .task-row__actions,
  .item-actions {
    margin-left: 0;
    width: 100%;
  }
}

/* ------------------------------------------------------------ reduced motion */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  button:active,
  .btn:active {
    transform: none;
  }
}


/* ============================================================
   SPS-only: pipeline, money, engagements, compliance
   ============================================================ */

/* ---------------------------------------------------------------- money tiles */

.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 22ch), 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

.stat {
  background: var(--bg-surface);
  border: var(--hairline) solid var(--border-subtle);
  border-top: var(--rule-strong) solid var(--brand-decor);
  padding: var(--space-5);
}

.stat__label {
  font-family: var(--font-mono);
  font-size: var(--type-micro);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--fg-muted);
  margin-bottom: var(--space-2);
}

.stat__value {
  font-family: var(--font-display);
  font-size: var(--type-display-m);
  font-weight: 300;
  line-height: var(--lh-tight);
  color: var(--ink-900);
}

.stat__note {
  font-size: var(--type-caption);
  color: var(--fg-muted);
  margin-top: var(--space-2);
}

.stat.is-alert {
  border-top-color: var(--error);
}
.stat.is-alert .stat__value {
  color: var(--error);
}

/* Money reads as data, not prose — tabular figures keep columns aligned. */
.money {
  font-variant-numeric: tabular-nums;
}

.money-unset {
  color: var(--fg-muted);
  font-style: italic;
}

/* ------------------------------------------------------------------ pipeline */

.pipeline {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 26ch), 1fr));
  gap: var(--space-4);
  align-items: start;
}

.pipeline-col {
  background: var(--bg-inset);
  border: var(--hairline) solid var(--border-subtle);
  padding: var(--space-4);
  min-height: var(--space-24);
}

.pipeline-col__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
  padding-bottom: var(--space-2);
  border-bottom: var(--hairline) solid var(--border-subtle);
}

.pipeline-col__title {
  font-family: var(--font-mono);
  font-size: var(--type-micro);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--fg-muted);
}

.pipeline-col__count {
  font-family: var(--font-mono);
  font-size: var(--type-micro);
  color: var(--fg-muted);
}

.pipeline-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.client-card {
  display: block;
  background: var(--bg-surface);
  border: var(--hairline) solid var(--border-default);
  padding: var(--space-4);
  text-decoration: none;
  color: var(--fg-default);
  transition: background-color var(--duration-base) var(--ease-out),
    border-color var(--duration-base) var(--ease-out);
}
.client-card:hover {
  background: var(--bg-cream);
  border-color: var(--border-strong);
  text-decoration: none;
}

.client-card__name {
  font-family: var(--font-display);
  font-size: var(--type-h3);
  font-weight: 400;
  line-height: var(--lh-snug);
  margin-bottom: var(--space-1);
}

.client-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  font-size: var(--type-caption);
  color: var(--fg-muted);
  margin-top: var(--space-2);
}

/* --------------------------------------------------------------- engagements */

.engagement-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.engagement {
  background: var(--bg-surface);
  border: var(--hairline) solid var(--border-default);
  border-left: var(--rule-strong) solid var(--brand-decor);
  padding: var(--space-4);
}

.engagement__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.engagement__name {
  font-family: var(--font-display);
  font-size: var(--type-h3);
  font-weight: 400;
}

.engagement__terms {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-top: var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--type-micro);
  color: var(--fg-muted);
}

/* A contract that is not yet signed is the single most consequential gap on the
   page, so it is called out rather than left as one chip among many. */
.engagement.is-unsigned {
  border-left-color: var(--error);
}

.contract-warning {
  margin-top: var(--space-3);
  padding: var(--space-3);
  background: var(--error-bg);
  color: var(--error);
  font-size: var(--type-body-sm);
  border: var(--hairline) solid var(--error);
}

.renewal-warning {
  margin-top: var(--space-3);
  padding: var(--space-3);
  background: var(--warning-bg);
  color: var(--warning);
  font-size: var(--type-body-sm);
  border: var(--hairline) solid var(--warning);
}

/* ------------------------------------------------------------------ invoices */

.invoice-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--type-body-sm);
}

.invoice-table caption {
  text-align: left;
  font-family: var(--font-mono);
  font-size: var(--type-micro);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--fg-muted);
  padding-bottom: var(--space-3);
}

.invoice-table th,
.invoice-table td {
  text-align: left;
  padding: var(--space-3);
  border-bottom: var(--hairline) solid var(--border-subtle);
}

.invoice-table th {
  font-family: var(--font-mono);
  font-size: var(--type-micro);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--fg-muted);
  font-weight: 500;
}

.invoice-table td.amount {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.table-scroll {
  overflow-x: auto;
  max-width: 100%;
  contain: paint;
}

/* --------------------------------------------------------- compliance facts */

.fact-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 30ch), 1fr));
  gap: var(--space-3);
}

.fact {
  background: var(--bg-surface);
  border: var(--hairline) solid var(--border-subtle);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.fact__label {
  font-weight: 600;
  font-size: var(--type-body-sm);
}

.fact__value {
  font-family: var(--font-mono);
  font-size: var(--type-caption);
  color: var(--fg-muted);
  overflow-wrap: anywhere;
}

/* ------------------------------------------- roadmap: engagement span ribbons */

/* A retainer runs for months, so it renders as a ribbon across every column it
   covers rather than as a point like a task. */
.span-ribbon {
  display: block;
  background: var(--brand-bg);
  border: var(--hairline) solid var(--brand);
  border-left: 0;
  border-right: 0;
  color: var(--brand-text);
  font-size: var(--type-micro);
  padding: var(--space-2) var(--space-3);
  margin-bottom: var(--space-2);
  text-decoration: none;
  overflow-wrap: anywhere;
}
.span-ribbon:hover {
  background: var(--peach-50);
  text-decoration: none;
}
.span-ribbon.is-start {
  border-left: var(--rule-strong) solid var(--brand);
}
.span-ribbon.is-end {
  border-right: var(--rule-strong) solid var(--brand);
}

.span-ribbon__continues {
  font-family: var(--font-mono);
  /* No opacity here — dimming brand-text on brand-bg drops it under AA. The
     continuation marker is quieter by being mono and short, not by being faint. */
  color: var(--brand-text);
}

/* ------------------------------------------------------------- narrow screens */

@media (max-width: 40rem) {
  .stat__value {
    font-size: var(--type-h1);
  }

  .pipeline {
    grid-template-columns: 1fr;
  }

  .fact-list {
    grid-template-columns: 1fr;
  }
}


/* ------------------------------------------------------- manual update check */

/* Browsers only look for a new service worker on navigation, and at most about
   once a day. This gives the update a deliberate trigger instead of leaving it
   to chance after a deploy. */
.update-check {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.update-check__status {
  font-size: var(--type-caption);
  color: var(--fg-muted);
}

@media (max-width: 40rem) {
  /* On a phone the status text would push the header controls onto another line
     mid-interaction, so it drops below rather than shoving things sideways. */
  .update-check {
    width: 100%;
    justify-content: flex-start;
  }
}
