/* ==========================================================================
   Beetzee — plain-language UX layer
   --------------------------------------------------------------------------
   Styles for the reworked everyday screens: the time clock, leave filing and
   the leave inbox. Everything here uses the design tokens in tokens.css so it
   stays in step with the rest of the system.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. The time clock card
   -------------------------------------------------------------------------- */

.bz-clock-card {
  background:
    radial-gradient(120% 140% at 12% 0%, rgba(139, 92, 246, 0.16), transparent 60%),
    var(--bz-bg-surface-raised);
  border: 1px solid var(--bz-border-default);
  border-radius: var(--bz-radius-xl);
  box-shadow: var(--bz-shadow-md);
  display: grid;
  gap: var(--bz-space-5);
  padding: var(--bz-space-8);
  position: relative;
}

/* Was a hard green/blue/yellow rail down the left edge. That reads as a
   framework alert component, not as this product. The state now shows as a
   faint wash across the whole card, with the badge carrying the word. */
.bz-clock-working {
  background:
    radial-gradient(120% 140% at 12% 0%, rgba(52, 211, 153, 0.10), transparent 62%),
    var(--bz-bg-surface-raised);
}

.bz-clock-break {
  background:
    radial-gradient(120% 140% at 12% 0%, rgba(251, 191, 36, 0.10), transparent 62%),
    var(--bz-bg-surface-raised);
}

.bz-clock-done {
  background:
    radial-gradient(120% 140% at 12% 0%, rgba(56, 189, 248, 0.09), transparent 62%),
    var(--bz-bg-surface-raised);
}

.bz-clock-top {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--bz-space-3);
  justify-content: space-between;
}

.bz-clock-date {
  color: var(--bz-text-tertiary);
  font-size: var(--bz-text-supporting);
  font-weight: 600;
  letter-spacing: 0.08em;
  margin: 0;
  text-transform: uppercase;
}

.bz-clock-headline {
  color: var(--bz-text-primary);
  font-size: clamp(26px, 4vw, 38px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin: 0 0 var(--bz-space-2);
}

.bz-clock-detail {
  color: var(--bz-text-secondary);
  font-size: 15px;
  margin: 0;
}

.bz-clock-actions {
  align-items: flex-end;
  display: flex;
  flex-wrap: wrap;
  gap: var(--bz-space-4);
}

.bz-clock-form {
  align-items: flex-end;
  display: flex;
  flex-wrap: wrap;
  gap: var(--bz-space-3);
  margin: 0;
}

/* The primary button is deliberately oversized. This is the single control
   most people press every day, often on a phone, sometimes in a hurry. */
.bz-clock-button {
  align-items: center;
  border: 1px solid transparent;
  border-radius: var(--bz-radius-lg);
  cursor: pointer;
  display: inline-flex;
  font-family: var(--bz-font-body);
  font-size: 18px;
  font-weight: 700;
  gap: var(--bz-space-3);
  justify-content: center;
  letter-spacing: -0.01em;
  min-height: 64px;
  min-width: 220px;
  padding: 0 var(--bz-space-8);
  transition: transform 0.12s ease, box-shadow 0.12s ease, background-color 0.12s ease;
}

.bz-clock-button svg {
  height: 22px;
  width: 22px;
}

.bz-clock-button:hover { transform: translateY(-1px); }
.bz-clock-button:active { transform: translateY(1px); }

.bz-clock-button:focus-visible {
  outline: 3px solid var(--bz-focus-ring);
  outline-offset: 3px;
}

.bz-clock-button-in {
  background: var(--bz-brand-gradient);
  box-shadow: 0 10px 26px rgba(139, 92, 246, 0.32);
  color: #fff;
}

.bz-clock-button-in:hover {
  box-shadow: 0 14px 32px rgba(139, 92, 246, 0.42);
}

/* Was solid mint green - a colour that appears nowhere else in the product.
   Time Out is the same weight of action as Time In, so it wears the same
   brand gradient; the headline and badge already say which one you are on. */
.bz-clock-button-out {
  background: var(--bz-brand-gradient);
  box-shadow: 0 10px 26px rgba(139, 92, 246, 0.32);
  color: #fff;
}

.bz-clock-button-out:hover {
  box-shadow: 0 14px 32px rgba(139, 92, 246, 0.42);
}

.bz-clock-button-ghost {
  background: var(--bz-bg-surface-hover);
  border-color: var(--bz-border-default);
  color: var(--bz-text-primary);
  font-size: 15px;
  min-height: 48px;
  min-width: 0;
  padding: 0 var(--bz-space-5);
}

.bz-clock-button-ghost:hover {
  background: var(--bz-bg-surface);
  border-color: var(--bz-border-strong);
}

.bz-clock-secondary {
  border-left: 1px solid var(--bz-border-subtle);
  padding-left: var(--bz-space-4);
}

.bz-clock-break-pick {
  display: grid;
  gap: var(--bz-space-1);
}

.bz-clock-break-pick > span {
  color: var(--bz-text-tertiary);
  font-size: var(--bz-text-supporting);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.bz-clock-break-pick select {
  background: var(--bz-bg-input);
  border: 1px solid var(--bz-border-default);
  border-radius: var(--bz-radius-sm);
  color: var(--bz-text-primary);
  font-family: var(--bz-font-body);
  font-size: 14px;
  min-height: 48px;
  padding: 0 var(--bz-space-3);
}

.bz-clock-alt {
  border-top: 1px solid var(--bz-border-subtle);
  color: var(--bz-text-tertiary);
  font-size: 13px;
  margin: 0;
  padding-top: var(--bz-space-4);
}

.bz-clock-alt a {
  color: var(--bz-text-secondary);
  text-underline-offset: 3px;
}

/* On a phone the button should span the full width and stay thumb-reachable. */
@media (max-width: 720px) {
  .bz-clock-card {
    padding: var(--bz-space-5);
  }

  .bz-clock-actions,
  .bz-clock-form {
    width: 100%;
  }

  .bz-clock-button {
    min-height: 68px;
    width: 100%;
  }

  .bz-clock-secondary {
    border-left: 0;
    border-top: 1px solid var(--bz-border-subtle);
    padding-left: 0;
    padding-top: var(--bz-space-4);
  }

  .bz-clock-break-pick {
    width: 100%;
  }

  .bz-clock-break-pick select {
    width: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .bz-clock-button {
    transition: none;
  }

  .bz-clock-button:hover,
  .bz-clock-button:active {
    transform: none;
  }
}

/* The state chip must carry its own colour: the shared .badge tones are muted
   by design elsewhere, which read as "nothing is happening" on this card. */
.bz-clock-card .badge {
  border-radius: var(--bz-radius-pill);
  font-size: var(--bz-text-supporting);
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 6px 14px;
  text-transform: none;
}

.bz-clock-working .badge {
  background: var(--bz-success-soft);
  border: 1px solid rgba(52, 211, 153, 0.35);
  color: var(--bz-success);
}

.bz-clock-break .badge {
  background: var(--bz-warning-soft);
  border: 1px solid rgba(251, 191, 36, 0.35);
  color: var(--bz-warning);
}

.bz-clock-done .badge {
  background: var(--bz-info-soft);
  border: 1px solid rgba(56, 189, 248, 0.35);
  color: var(--bz-info);
}

.bz-clock-ready .badge {
  background: var(--bz-brand-soft);
  border: 1px solid rgba(139, 92, 246, 0.35);
  color: #c4b5fd;
}

/* --------------------------------------------------------------------------
   2. Leave — filing and the manager inbox
   -------------------------------------------------------------------------- */

.visually-hidden {
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

.nav-notification-count {
  align-items: center;
  background: linear-gradient(135deg, #a855f7, #ec4899);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 999px;
  color: #fff;
  display: inline-flex;
  font-size: 11px;
  font-weight: 900;
  justify-content: center;
  line-height: 1;
  margin-left: 6px;
  min-height: 18px;
  min-width: 18px;
  padding: 3px 5px;
  vertical-align: middle;
}

.bz-user-qr-dock {
  bottom: 18px;
  left: max(18px, calc(220px + 18px));
  position: fixed;
  z-index: 70;
}

.bz-user-qr-dock--client {
  bottom: calc(10px + env(safe-area-inset-bottom, 0px));
  left: 16px;
  z-index: 230;
}

.bz-user-qr-dock-trigger {
  align-items: center;
  appearance: none;
  background: rgba(255, 255, 255, 0.96);
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 14px;
  box-shadow: 0 14px 36px rgba(15, 23, 42, 0.14);
  color: #111827;
  cursor: pointer;
  display: inline-flex;
  height: 48px;
  justify-content: center;
  padding: 0;
  width: 48px;
}

.bz-user-qr-dock-icon {
  align-items: center;
  background: #eef4ff;
  border-radius: 10px;
  color: #0f172a;
  display: inline-flex;
  height: 30px;
  justify-content: center;
  width: 30px;
}

.bz-user-qr-dock-icon .command-icon {
  height: 19px;
  width: 19px;
}

.bz-user-qr-dock-trigger:hover,
.bz-user-qr-dock-trigger:focus-visible {
  outline: none;
  transform: translateY(-1px);
}

.bz-user-qr-overlay {
  align-items: center;
  background: rgba(2, 6, 23, 0.72);
  display: flex;
  inset: 0;
  justify-content: center;
  padding: 18px;
  position: fixed;
  z-index: 260;
}

.bz-user-qr-overlay[hidden] {
  display: none;
}

.bz-user-qr-panel {
  align-items: center;
  background: #fff;
  border: 1px solid rgba(209, 217, 230, 0.95);
  border-radius: 18px;
  box-shadow: 0 24px 60px rgba(15, 23, 42, 0.24);
  color: #111827;
  display: grid;
  gap: 12px;
  justify-items: center;
  max-width: calc(100vw - 32px);
  padding: 16px;
  position: relative;
  text-align: center;
  width: min(420px, 92vw);
}

.bz-user-qr-close {
  align-items: center;
  appearance: none;
  background: #fff;
  border: 1px solid rgba(209, 217, 230, 0.95);
  border-radius: 10px;
  color: #111827;
  cursor: pointer;
  display: inline-flex;
  font: 800 0.82rem/1 Inter, Arial, sans-serif;
  justify-content: center;
  justify-self: end;
  min-height: 38px;
  padding: 0 14px;
}

.bz-user-qr-frame {
  position: relative;
  width: min(330px, 78vw);
}

.bz-user-qr-code {
  display: block;
  height: auto;
  width: 100%;
}

.bz-user-qr-avatar {
  align-items: center;
  background: #eef4ff;
  border: 6px solid #fff;
  border-radius: 999px;
  box-shadow: 0 8px 18px rgba(15, 23, 42, 0.18);
  color: #0f172a;
  display: inline-flex;
  font-size: 0.9rem;
  font-weight: 900;
  height: 54px;
  justify-content: center;
  left: 50%;
  overflow: hidden;
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 54px;
}

.bz-user-qr-avatar img {
  display: block;
  height: 100%;
  object-fit: cover;
  width: 100%;
}

.bz-user-qr-panel strong {
  color: #111827;
  font-size: 17px;
}

.bz-user-qr-panel code {
  background: rgba(15, 23, 42, 0.06);
  border-radius: 8px;
  color: #475569;
  font: 800 13px/1.2 ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  padding: 8px 10px;
}

.bz-live-notification-toast {
  animation: bz-notification-arrive 180ms ease-out;
  background: linear-gradient(135deg, rgba(23, 20, 46, 0.99), rgba(8, 15, 29, 0.99));
  border: 2px solid rgba(192, 132, 252, 0.72);
  border-radius: 8px;
  box-shadow: 0 22px 64px rgba(0, 0, 0, 0.56), 0 0 28px rgba(168, 85, 247, 0.2);
  color: var(--bz-text);
  display: grid;
  gap: 7px;
  max-width: min(400px, calc(100vw - 32px));
  padding: 17px 46px 17px 18px;
  position: fixed;
  right: 18px;
  top: 82px;
  z-index: 1500;
}

@keyframes bz-notification-arrive {
  from { opacity: 0; transform: translateY(-10px) scale(0.98); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

a.has-unread-notifications,
button.has-unread-notifications {
  border-color: rgba(192, 132, 252, 0.68);
  box-shadow: 0 0 0 3px rgba(168, 85, 247, 0.14);
}

.bz-live-notification-toast strong {
  color: #fff;
  font-size: 14px;
}

.bz-live-notification-toast p {
  color: var(--bz-text-secondary);
  font-size: 13px;
  line-height: 1.4;
  margin: 0;
}

.bz-live-notification-toast a {
  color: #d8b4fe;
  font-size: 13px;
  font-weight: 900;
  text-decoration: none;
}

.bz-live-notification-toast button {
  align-items: center;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 50%;
  color: #fff;
  cursor: pointer;
  display: inline-flex;
  height: 26px;
  justify-content: center;
  padding: 0;
  position: absolute;
  right: 10px;
  top: 10px;
  width: 26px;
}

@media (max-width: 980px) {
  .bz-user-qr-dock {
    bottom: 14px;
    left: 14px;
  }
}

@media (max-width: 560px) {
  .bz-user-qr-dock-trigger {
    height: 46px;
    width: 46px;
  }

  .bz-live-notification-toast {
    left: 14px;
    right: 14px;
    top: 70px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .bz-live-notification-toast {
    animation: none;
  }
}

.equipment-image-zoom {
  --equipment-zoom-x: 50%;
  --equipment-zoom-y: 50%;
  background: #fff;
  border-radius: 8px;
  cursor: zoom-in;
  overflow: hidden;
  position: relative;
}

.equipment-image-zoom:focus-visible {
  outline: 3px solid #a855f7;
  outline-offset: 3px;
}

.equipment-image-zoom > img {
  display: block;
  transform-origin: var(--equipment-zoom-x) var(--equipment-zoom-y);
  transition: transform 160ms ease-out;
}

.equipment-image-zoom.is-zoomed {
  cursor: zoom-out;
}

.equipment-image-zoom.is-zoomed > img {
  transform: scale(2.35);
}

.equipment-image-zoom-hint {
  background: rgba(9, 13, 24, 0.78);
  border-radius: 999px;
  bottom: 10px;
  color: #fff;
  font-size: 11px;
  font-weight: 800;
  left: 50%;
  opacity: 0;
  padding: 6px 10px;
  pointer-events: none;
  position: absolute;
  transform: translateX(-50%);
  transition: opacity 140ms ease;
  white-space: nowrap;
}

.equipment-image-zoom:hover .equipment-image-zoom-hint,
.equipment-image-zoom:focus-visible .equipment-image-zoom-hint {
  opacity: 1;
}

.equipment-image-zoom.is-zoomed .equipment-image-zoom-hint {
  opacity: 0;
}

.crp-main-image-zoom {
  align-self: center;
  height: 280px;
  width: 100%;
}

.crp-main-image-zoom > .crp-main-image {
  height: 100%;
}

.equipment-profile-hero-zoom {
  max-height: 440px;
  width: 100%;
}

.equipment-profile-hero-zoom > img {
  height: auto;
  max-height: 440px;
  object-fit: contain;
  width: 100%;
}

@media (max-width: 720px) {
  .crp-main-image-zoom {
    height: 220px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .equipment-image-zoom > img,
  .equipment-image-zoom-hint {
    transition: none;
  }
}

.equipment-edit-card summary {
  align-items: center;
  cursor: pointer;
  display: flex;
  font-weight: 800;
  gap: 10px;
}

.equipment-edit-card summary::-webkit-details-marker {
  display: none;
}

.equipment-edit-card[open] summary {
  margin-bottom: 14px;
}

.equipment-profile-heading-actions {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: flex-end;
}

/* Equipment profile actions are controls, not equal-height dashboard cards. */
.equipment-actions-stack {
  align-content: start;
  align-self: start;
  grid-auto-rows: max-content;
}

.equipment-detail-grid {
  align-items: start;
}

.equipment-detail-grid > .equipment-profile {
  align-content: start;
  align-self: start;
  grid-auto-rows: max-content;
  height: auto;
}

.equipment-detail-grid > .equipment-profile > img {
  height: auto;
  max-height: 440px;
  object-fit: contain;
}

.equipment-media-tools {
  gap: 16px;
  padding: 16px;
}

.equipment-profile-qr-card {
  align-items: center;
  background: rgba(8, 13, 26, 0.62);
  border: 1px solid rgba(148, 163, 184, 0.16);
  border-radius: 10px;
  display: grid;
  gap: 18px;
  grid-template-columns: minmax(0, 1fr) 190px;
  padding: 16px;
}

.equipment-profile-qr-card h3,
.equipment-profile-qr-card p {
  margin: 0;
}

.equipment-profile-qr-card h3 {
  font-size: 1.2rem;
  margin-top: 4px;
}

.equipment-profile-qr-card code {
  color: #d8b4fe;
  display: inline-block;
  font-weight: 800;
  margin-top: 10px;
}

.equipment-profile-qr-card > img {
  aspect-ratio: 1;
  background: #fff;
  border-radius: 10px;
  height: auto;
  justify-self: end;
  padding: 10px;
  width: min(100%, 190px);
}

.equipment-profile-qr-empty {
  align-items: center;
  color: var(--muted);
  display: flex;
  flex-direction: column;
  gap: 8px;
  justify-content: center;
  min-height: 150px;
  text-align: center;
}

.equipment-profile-qr-empty svg {
  height: 42px;
  width: 42px;
}

.equipment-photo-gallery {
  align-content: start;
  align-items: start;
  grid-auto-rows: max-content;
}

.equipment-photo-gallery > a,
.equipment-photo-gallery > .equipment-photo-add-tile {
  align-self: start;
  aspect-ratio: 1;
  height: auto;
  min-height: 0;
}

.equipment-photo-gallery > a img {
  height: 100%;
  object-fit: cover;
  width: 100%;
}

.equipment-photo-gallery .equipment-photo-add-tile {
  background: rgba(255, 255, 255, 0.025);
  border: 1px dashed rgba(196, 181, 253, 0.48);
  border-radius: 10px;
  display: block;
  overflow: hidden;
  padding: 0;
}

.equipment-photo-add-picker {
  align-items: center;
  cursor: pointer;
  display: flex;
  height: 100%;
  justify-content: center;
  min-height: 64px;
  padding: 8px;
  position: relative;
  width: 100%;
}

.equipment-photo-add-picker:hover {
  background: rgba(139, 92, 246, 0.1);
}

.equipment-photo-add-tile[aria-busy="true"] {
  opacity: 0.7;
  pointer-events: none;
}

.equipment-photo-add-picker input {
  height: 1px;
  opacity: 0;
  overflow: hidden;
  position: absolute;
  width: 1px;
}

.equipment-photo-gallery .equipment-photo-add-copy {
  align-items: center;
  background: transparent;
  color: #ddd6fe;
  display: flex;
  flex-direction: column;
  font-size: 0.72rem;
  gap: 5px;
  inset: auto;
  letter-spacing: 0;
  padding: 0;
  position: static;
  text-transform: none;
}

.equipment-photo-add-copy svg {
  height: 22px;
  width: 22px;
}

#equipment-location-form {
  align-content: start;
  align-items: end;
  gap: 14px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  padding: 16px;
}

#equipment-location-form > label {
  gap: 7px;
}

#equipment-location-form textarea {
  min-height: 84px;
}

#equipment-location-form .equipment-location-submit {
  border-radius: 8px;
  min-height: 42px;
  padding: 9px 16px;
  width: auto;
}

.equipment-actions-stack > details.settings-readiness-card {
  gap: 0;
  overflow: hidden;
  padding: 0;
}

.equipment-actions-stack > details.settings-readiness-card > summary {
  align-items: center;
  cursor: pointer;
  display: flex;
  font-weight: 800;
  gap: 10px;
  list-style: none;
  padding: 16px;
}

.equipment-actions-stack > details.settings-readiness-card > summary::-webkit-details-marker {
  display: none;
}

.equipment-actions-stack > details.settings-readiness-card[open] > summary {
  background: rgba(255, 255, 255, 0.025);
  border-bottom: 1px solid rgba(148, 163, 184, 0.14);
  margin-bottom: 0;
}

.equipment-actions-stack > details.settings-readiness-card > .compact-form {
  background: transparent;
  border: 0;
  border-radius: 0;
  gap: 12px;
  padding: 16px;
}

.equipment-actions-stack > .equipment-edit-card > .compact-form {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.equipment-actions-stack > .equipment-edit-card[open] > .compact-form {
  max-height: min(70vh, 760px);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-gutter: stable;
}

.equipment-actions-stack > .equipment-delete-card > .compact-form {
  grid-template-columns: 1fr;
}

.equipment-delete-warning {
  color: var(--muted);
  margin: 0;
}

.equipment-delete-confirm {
  align-items: center;
  display: flex;
  gap: 10px;
}

.equipment-delete-confirm input {
  flex: 0 0 auto;
  height: 20px;
  margin: 0;
  width: 20px;
}

.equipment-delete-confirm span {
  line-height: 1.4;
}

.equipment-delete-card .danger-button {
  border-radius: 8px;
  min-height: 42px;
  padding: 9px 16px;
  width: auto;
}

.equipment-lightbox-actions .equipment-delete-action {
  background: rgba(251, 113, 133, 0.08);
  border-color: rgba(251, 113, 133, 0.42);
  border-radius: var(--bz-radius-pill);
  color: #fecdd3;
  font-weight: 800;
}

.equipment-lightbox-actions .equipment-delete-action:hover,
.equipment-lightbox-actions .equipment-delete-action:focus-visible {
  background: rgba(251, 113, 133, 0.16);
  border-color: rgba(251, 113, 133, 0.7);
}

@media (max-width: 720px) {
  #equipment-location-form {
    grid-template-columns: 1fr;
  }

  .equipment-profile-qr-card {
    grid-template-columns: 1fr;
  }

  .equipment-profile-qr-card > img {
    justify-self: center;
    width: min(70vw, 220px);
  }

  .equipment-actions-stack > .equipment-edit-card > .compact-form {
    grid-template-columns: 1fr;
  }

}

.equipment-existing-photo-picker {
  border: 1px solid rgba(148, 163, 184, 0.22);
  border-radius: 8px;
  padding: 12px;
}

.equipment-existing-photo-picker legend {
  color: rgba(226, 232, 240, 0.78);
  font-size: 0.78rem;
  font-weight: 800;
  padding: 0 6px;
  text-transform: uppercase;
}

.equipment-existing-photo-picker > small {
  color: rgba(226, 232, 240, 0.68);
  display: block;
  margin-bottom: 10px;
}

.equipment-existing-photo-picker > div {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(108px, 1fr));
}

.equipment-existing-photo-picker label {
  align-items: start;
  background: rgba(15, 23, 42, 0.52);
  border: 1px solid rgba(148, 163, 184, 0.2);
  border-radius: 8px;
  cursor: pointer;
  display: grid;
  gap: 8px;
  grid-template-columns: 1fr;
  min-width: 0;
  padding: 8px;
}

.equipment-existing-photo-picker label:has(input:checked) {
  background: rgba(127, 29, 29, 0.22);
  border-color: rgba(251, 113, 133, 0.55);
}

.equipment-existing-photo-picker input {
  height: 1px;
  overflow: hidden;
  opacity: 0;
  position: absolute;
  width: 1px;
}

.equipment-existing-photo-picker label:has(input:focus-visible) {
  outline: 2px solid #c084fc;
  outline-offset: 2px;
}

.equipment-existing-photo-picker img {
  aspect-ratio: 1 / 1;
  border-radius: 6px;
  grid-column: 1 / -1;
  object-fit: cover;
  width: 100%;
}

.equipment-existing-photo-picker .equipment-photo-name {
  color: rgba(226, 232, 240, 0.82);
  font-size: 0.78rem;
  font-weight: 800;
}

.equipment-photo-remove-action,
.equipment-photo-remove-pending {
  align-items: center;
  border-radius: 7px;
  display: flex;
  font-size: 0.76rem;
  font-weight: 800;
  gap: 6px;
  justify-content: center;
  min-height: 34px;
  padding: 6px 8px;
}

.equipment-photo-remove-action {
  background: rgba(251, 113, 133, 0.08);
  border: 1px solid rgba(251, 113, 133, 0.36);
  color: #fecdd3;
}

.equipment-photo-remove-pending {
  background: rgba(251, 113, 133, 0.18);
  color: #fff;
  display: none;
}

.equipment-existing-photo-picker input:checked ~ img {
  filter: grayscale(0.9);
  opacity: 0.38;
}

.equipment-existing-photo-picker input:checked ~ .equipment-photo-remove-action {
  display: none;
}

.equipment-existing-photo-picker input:checked ~ .equipment-photo-remove-pending {
  display: flex;
}

/* The "you have decisions waiting" banner. Loud on purpose: an unanswered
   leave request is somebody not knowing whether they can book a flight. */
.bz-leave-alert {
  align-items: center;
  background: linear-gradient(135deg, rgba(251, 191, 36, 0.14), rgba(251, 191, 36, 0.04));
  border: 1px solid rgba(251, 191, 36, 0.32);
  border-radius: var(--bz-radius-lg);
  display: flex;
  flex-wrap: wrap;
  gap: var(--bz-space-4);
  justify-content: space-between;
  padding: var(--bz-space-5) var(--bz-space-6);
}

.bz-leave-alert-body strong {
  color: var(--bz-text-primary);
  display: block;
  font-size: 17px;
  margin-bottom: 2px;
}

.bz-leave-alert-body p {
  color: var(--bz-text-secondary);
  font-size: 14px;
  margin: 0;
}

.bz-leave-alert-action {
  align-items: center;
  background: var(--bz-warning);
  border-radius: var(--bz-radius-md);
  color: #2a1c00;
  display: inline-flex;
  font-weight: 700;
  gap: var(--bz-space-2);
  min-height: 44px;
  padding: 0 var(--bz-space-5);
  text-decoration: none;
}

.bz-leave-alert-action:hover { background: #fcd34d; }

.bz-leave-person {
  margin-bottom: var(--bz-space-5);
  max-width: 420px;
}

.bz-leave-person label {
  color: var(--bz-text-secondary);
  display: grid;
  font-size: 14px;
  font-weight: 600;
  gap: var(--bz-space-2);
}

.bz-leave-person select {
  background: var(--bz-bg-input);
  border: 1px solid var(--bz-border-default);
  border-radius: var(--bz-radius-md);
  color: var(--bz-text-primary);
  font-family: var(--bz-font-body);
  font-size: 15px;
  min-height: 48px;
  padding: 0 var(--bz-space-3);
}

.bz-leave-balance-intro {
  color: var(--bz-text-secondary);
  font-size: 14px;
  margin: 0 0 var(--bz-space-3);
}

/* Balance chips: the answer to "can I even take this?" at a glance. */
.bz-balance-strip {
  display: grid;
  gap: var(--bz-space-3);
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  list-style: none;
  margin: 0 0 var(--bz-space-6);
  padding: 0;
}

.bz-balance-chip {
  background: var(--bz-bg-surface);
  border: 1px solid var(--bz-border-subtle);
  border-radius: var(--bz-radius-md);
  display: grid;
  gap: 2px;
  padding: var(--bz-space-3) var(--bz-space-4);
}

.bz-balance-chip.is-empty { opacity: 0.55; }

.bz-balance-name {
  color: var(--bz-text-tertiary);
  font-size: var(--bz-text-supporting);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.bz-balance-value {
  color: var(--bz-text-primary);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.bz-balance-chip small {
  color: var(--bz-text-tertiary);
  font-size: 12px;
}

/* One screen, no wizard. */
.bz-leave-form {
  display: grid;
  gap: var(--bz-space-4);
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

.bz-leave-field { display: grid; gap: var(--bz-space-2); }
.bz-leave-field-wide { grid-column: 1 / -1; }

.bz-leave-field > label {
  color: var(--bz-text-primary);
  font-size: 15px;
  font-weight: 600;
}

.bz-optional {
  color: var(--bz-text-tertiary);
  font-size: 13px;
  font-weight: 400;
}

.bz-leave-field input,
.bz-leave-field select,
.bz-leave-field textarea {
  background: var(--bz-bg-input);
  border: 1px solid var(--bz-border-default);
  border-radius: var(--bz-radius-md);
  color: var(--bz-text-primary);
  font-family: var(--bz-font-body);
  font-size: 15px;
  padding: var(--bz-space-3);
  width: 100%;
}

.bz-leave-field input,
.bz-leave-field select { min-height: 48px; }

.bz-leave-field input:focus-visible,
.bz-leave-field select:focus-visible,
.bz-leave-field textarea:focus-visible {
  border-color: var(--bz-brand);
  outline: 2px solid var(--bz-focus-ring);
  outline-offset: 1px;
}

.bz-leave-hint { color: var(--bz-text-tertiary); font-size: 13px; }
.bz-leave-hint.is-bad { color: var(--bz-danger); font-weight: 600; }

.bz-leave-submit { align-self: end; grid-column: 1 / -1; }

/* Inbox */
.bz-leave-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--bz-space-2);
  margin-bottom: var(--bz-space-4);
}

.bz-leave-tab {
  align-items: center;
  background: var(--bz-bg-surface);
  border: 1px solid var(--bz-border-subtle);
  border-radius: var(--bz-radius-pill);
  color: var(--bz-text-secondary);
  display: inline-flex;
  font-size: 14px;
  font-weight: 600;
  gap: var(--bz-space-2);
  min-height: 42px;
  padding: 0 var(--bz-space-4);
  text-decoration: none;
}

.bz-leave-tab:hover {
  background: var(--bz-bg-surface-hover);
  color: var(--bz-text-primary);
}

.bz-leave-tab.is-active {
  background: var(--bz-brand-soft);
  border-color: rgba(139, 92, 246, 0.45);
  color: #ddd2ff;
}

.bz-leave-tab b {
  background: rgba(255, 255, 255, 0.08);
  border-radius: var(--bz-radius-pill);
  font-size: 12px;
  min-width: 22px;
  padding: 2px 7px;
  text-align: center;
}

.bz-leave-tab.is-active b { background: rgba(139, 92, 246, 0.32); }

.bz-leave-search { display: block; margin-bottom: var(--bz-space-4); }

.bz-leave-search input {
  background: var(--bz-bg-input);
  border: 1px solid var(--bz-border-default);
  border-radius: var(--bz-radius-md);
  color: var(--bz-text-primary);
  font-family: var(--bz-font-body);
  font-size: 15px;
  min-height: 48px;
  padding: 0 var(--bz-space-4);
  width: 100%;
}

.bz-leave-list { display: grid; gap: var(--bz-space-3); }

.bz-leave-card {
  background: var(--bz-bg-surface);
  border: 1px solid var(--bz-border-subtle);
  border-radius: var(--bz-radius-md);
  display: grid;
  gap: var(--bz-space-3);
  padding: var(--bz-space-4) var(--bz-space-5);
}

/* Status used to be a coloured bar welded to the left edge. A light wash over
   the whole card says the same thing without the alert-box look. */
.bz-leave-card.is-pending  { background: rgba(251, 191, 36, 0.05); border-color: rgba(251, 191, 36, 0.16); }
.bz-leave-card.is-approved { background: rgba(52, 211, 153, 0.055); border-color: rgba(52, 211, 153, 0.16); }
.bz-leave-card.is-declined { background: rgba(251, 113, 133, 0.055); border-color: rgba(251, 113, 133, 0.16); }
.bz-leave-card.is-cancelled { opacity: 0.7; }

.bz-leave-card-main {
  align-items: center;
  display: grid;
  gap: var(--bz-space-4);
  grid-template-columns: minmax(160px, 1.2fr) minmax(180px, 1.4fr) auto;
}

.bz-leave-who strong,
.bz-leave-when strong {
  color: var(--bz-text-primary);
  display: block;
  font-size: 15px;
}

.bz-leave-who small,
.bz-leave-when small {
  color: var(--bz-text-tertiary);
  display: block;
  font-size: 13px;
  margin-top: 2px;
}

.bz-leave-status { justify-self: end; }

.bz-leave-pill {
  border-radius: var(--bz-radius-pill);
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  padding: 5px 12px;
}

.bz-leave-pill.is-pending  { background: var(--bz-warning-soft); color: var(--bz-warning); }
.bz-leave-pill.is-approved { background: var(--bz-success-soft); color: var(--bz-success); }
.bz-leave-pill.is-declined { background: var(--bz-danger-soft); color: var(--bz-danger); }
.bz-leave-pill.is-cancelled { background: rgba(255, 255, 255, 0.06); color: var(--bz-text-tertiary); }

.bz-leave-reason {
  color: var(--bz-text-secondary);
  font-size: 14px;
  margin: 0;
}

.bz-leave-note {
  align-items: flex-start;
  background: rgba(255, 255, 255, 0.03);
  border-radius: var(--bz-radius-sm);
  color: var(--bz-text-secondary);
  display: flex;
  font-size: 13px;
  gap: var(--bz-space-2);
  margin: 0;
  padding: var(--bz-space-2) var(--bz-space-3);
}

.bz-leave-note svg { flex: none; height: 15px; margin-top: 2px; width: 15px; }

.bz-leave-actions {
  align-items: center;
  border-top: 1px solid var(--bz-border-subtle);
  display: flex;
  flex-wrap: wrap;
  gap: var(--bz-space-2);
  margin: 0;
  padding-top: var(--bz-space-3);
}

.bz-leave-note-input {
  background: var(--bz-bg-input);
  border: 1px solid var(--bz-border-default);
  border-radius: var(--bz-radius-sm);
  color: var(--bz-text-primary);
  flex: 1 1 220px;
  font-family: var(--bz-font-body);
  font-size: 14px;
  min-height: 44px;
  padding: 0 var(--bz-space-3);
}

.bz-leave-actions button {
  align-items: center;
  border: 1px solid transparent;
  border-radius: var(--bz-radius-sm);
  cursor: pointer;
  display: inline-flex;
  font-family: var(--bz-font-body);
  font-size: 14px;
  font-weight: 700;
  gap: var(--bz-space-2);
  min-height: 44px;
  padding: 0 var(--bz-space-4);
}

.bz-leave-actions button svg { height: 16px; width: 16px; }

.bz-leave-approve { background: var(--bz-success); color: #05231a; }
.bz-leave-approve:hover { background: #4ade9f; }

.bz-leave-decline {
  background: var(--bz-danger-soft);
  border-color: rgba(251, 113, 133, 0.4);
  color: var(--bz-danger);
}
.bz-leave-decline:hover { background: rgba(251, 113, 133, 0.22); }

.bz-leave-cancel {
  background: transparent;
  border-color: var(--bz-border-default);
  color: var(--bz-text-secondary);
}
.bz-leave-cancel:hover { background: var(--bz-bg-surface-hover); color: var(--bz-text-primary); }

.bz-leave-actions button:focus-visible {
  outline: 2px solid var(--bz-focus-ring);
  outline-offset: 2px;
}

@media (max-width: 760px) {
  .bz-leave-card-main { grid-template-columns: 1fr; gap: var(--bz-space-2); }
  .bz-leave-status { justify-self: start; }
  .bz-leave-actions button { flex: 1 1 auto; justify-content: center; }
  .bz-leave-alert { flex-direction: column; align-items: flex-start; }
  .bz-leave-alert-action { width: 100%; justify-content: center; }
}

/* `display: grid` on the field wrapper beats the browser's default `hidden`
   styling, so the conditional "how many hours?" input stayed visible. */
.bz-leave-field[hidden],
.bz-leave-list [hidden],
[data-leave-row][hidden] {
  display: none !important;
}

/* --------------------------------------------------------------------------
   3. Entry point to the front-desk time-in station
   -------------------------------------------------------------------------- */

.attendance-task-card-station {
  background: linear-gradient(135deg, rgba(139, 92, 246, 0.16), rgba(217, 70, 239, 0.06));
  border-color: rgba(139, 92, 246, 0.4);
}

.attendance-task-card-station:hover {
  border-color: rgba(139, 92, 246, 0.6);
}

/* --------------------------------------------------------------------------
   4. Sign-in
   -------------------------------------------------------------------------- */

/* Caps Lock is the quiet cause of most "it won't let me in" support calls. */
.login-capslock {
  align-items: center;
  background: var(--bz-warning-soft);
  border: 1px solid rgba(251, 191, 36, 0.35);
  border-radius: var(--bz-radius-sm);
  color: var(--bz-warning);
  display: flex;
  font-size: 13px;
  font-weight: 600;
  gap: var(--bz-space-2);
  margin: 0;
  padding: var(--bz-space-2) var(--bz-space-3);
}

.login-capslock[hidden] { display: none; }
.login-capslock svg { flex: none; height: 16px; width: 16px; }

/* --------------------------------------------------------------------------
   5. System-wide table and typography repairs
   -------------------------------------------------------------------------- */

/* The codebase's standard "primary value + supporting note" cell is written as
   <td><strong>Name</strong><small>note</small></td>. `small` is inline by
   default, so these ran together as "Backup Staff4 completed tasks measured".
   A handful of tables patched this individually; most did not. One rule fixes
   every table at once. */
table td > small,
table th > small,
table td > strong + small,
.mini-record > small,
.mini-record > strong + small {
  color: var(--bz-text-tertiary);
  display: block;
  font-size: 12px;
  line-height: 1.35;
  margin-top: 2px;
}

/* Same shape, same problem, outside tables. */
.attendance-record-row div > small,
.bz-leave-who > small,
.bz-leave-when > small {
  display: block;
}

/* --------------------------------------------------------------------------
   6. Touch targets
   -------------------------------------------------------------------------- */

/* A finger needs about 44px. Checkboxes shipped at 16px, which makes every
   "tick the box" interaction on a phone a game of chance. */
input[type="checkbox"],
input[type="radio"] {
  height: 20px;
  min-height: 20px;
  min-width: 20px;
  width: 20px;
}

/* Give the box a comfortable hit area. Deliberately does NOT set `display`:
   many of these labels are already flex or grid items and forcing inline-flex
   here re-wrapped their contents (it broke the calendar filter list). */
label:has(> input[type="checkbox"]),
label:has(> input[type="radio"]) {
  align-items: center;
  min-height: 44px;
}

/* Links used as the primary way into a row were 19-23px tall. 6px of padding
   took them to 28px, which is still under the 44px floor for something you
   press with a thumb. */
.row-link,
.client-name-link,
.project-name-link {
  align-items: center;
  display: inline-flex;
  min-height: 44px;
  padding-block: 6px;
}

/* Searchable selects keep a native <select> for keyboard and no-JS use. It is
   already visually hidden in app.css; make sure it is also out of the tab
   order so nobody lands on a control they cannot see. */
select.is-searchable-native {
  visibility: hidden !important;
}

/* An inline-flex form is as wide as its contents. The bulk-edit rows behind
   the <details> on bank_accounts and supplier_bills came out 492px, 593px and
   857px wide on a 390px phone, and because body is overflow-x: hidden they did
   not scroll - the last field and the Save button were cut off with no way to
   get at them. A form is never wider than the thing it sits in. */
.inline-form,
.compact-form,
.status-form,
.inline-payment {
  flex-wrap: wrap;
  max-width: 100%;
  min-width: 0;
}

.inline-form > *,
.compact-form > *,
.status-form > *,
.inline-payment > * {
  min-width: 0;
}

.inline-form :is(input, select, textarea),
.compact-form :is(input, select, textarea),
.status-form :is(input, select, textarea),
.inline-payment :is(input, select, textarea) {
  max-width: 100%;
  min-width: 0;
}

/* --------------------------------------------------------------------------
   7. Keyboard focus
   -------------------------------------------------------------------------- */

/* Anything you can reach with Tab must show where you are. */
/* THE focus ring. 3px of #c4b5fd sitting 2px clear of the control, so it is
   drawn on the page background: 10.5:1 there, 8.3:1 over a button. It used to
   be declared 2px here and 3px in components.css, and eight other rules
   switched it off again - a keyboard user could not see where they were. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible,
[role="button"]:focus-visible,
[role="link"]:focus-visible,
[role="tab"]:focus-visible,
[role="menuitem"]:focus-visible,
[role="option"]:focus-visible {
  outline: 3px solid var(--bz-focus-ring);
  outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   8. Calendar repairs
   -------------------------------------------------------------------------- */

/* "Search" was wrapping to "Sear / ch": the button is a flex item with no
   nowrap, so it shrank below its own text. */
.cal-search button,
.cal-search-clear {
  flex: none;
  white-space: nowrap;
}

/* Same cause in the calendar filter list - the calendar's name ("Project")
   broke across two lines while its description was clipped. Let the name hold
   its width and give the description the leftover room. */
.cal-filter-list label {
  flex-wrap: wrap;
  gap: var(--bz-space-2);
}

.cal-filter-list label > strong {
  flex: none;
  white-space: nowrap;
}

.cal-filter-list label > span:not(.cal-dot) {
  color: var(--bz-text-tertiary);
  flex: 1 1 100%;
  font-size: 12px;
  min-width: 0;
}

/* --------------------------------------------------------------------------
   9. Words that must never break
   -------------------------------------------------------------------------- */

/* A status badge that wraps ("Pa/id") reads as two different states. */
.badge,
.bz-leave-pill,
.status-pill,
.pill {
  white-space: nowrap;
}

/* Column headers stay on one line - the table already scrolls horizontally
   inside .table-wrap, so there is nothing to gain by squeezing them. */
.table-wrap th {
  white-space: nowrap;
}

/* Role and person names are identifiers; breaking them mid-word makes them
   hard to scan down a column. */
.staff-role,
.role-name,
h3 > .staff-role,
.mini-record > strong {
  overflow-wrap: break-word;
  word-break: normal;
}

/* Reference codes are scanned, not read as prose. Breaking them across three
   lines in a table made every row 82px tall for no benefit. */
.row-link,
.receipt-code,
.reference-code {
  overflow-wrap: normal;
  white-space: nowrap;
}

.table-wrap .row-link {
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: bottom;
}

/* Filter chips and segmented controls were 31px tall - fine with a mouse,
.filter-chip,
.segment-link,
.cal-segments a,
.bz-leave-tab {
  align-items: center;
  display: inline-flex;
  min-height: 40px;
}

/* --------------------------------------------------------------------------
   10. Buttons keep their label on one line
   -------------------------------------------------------------------------- */

/* Two-word buttons were wrapping ("Add / member", "See / workload") because
   they sit in flex rows with no nowrap and shrink below their own text. */
button,
.primary-button,
.secondary-button,
.bz-button,
a.primary-button,
a.secondary-button {
  white-space: nowrap;
}

/* ...but a control that genuinely holds a sentence still needs to wrap. */
.bz-clock-button,
.station-start,
button.allow-wrap,
.attendance-task-card,
.attendance-task-card * {
  white-space: normal;
}

/* Buttons must not be squeezed narrower than their label. */
.staff-hero-actions > *,
.section-heading .inline-actions > * {
  flex: none;
}

/* --------------------------------------------------------------------------
   11. Subscription — your plan, and changing it
   -------------------------------------------------------------------------- */

.bz-sub-hero {
  align-items: flex-start;
  background:
    radial-gradient(120% 140% at 8% 0%, rgba(139, 92, 246, 0.15), transparent 62%),
    var(--bz-bg-surface-raised);
  border: 1px solid var(--bz-border-default);
  border-radius: var(--bz-radius-xl);
  display: flex;
  flex-wrap: wrap;
  gap: var(--bz-space-6);
  justify-content: space-between;
  padding: var(--bz-space-8);
}

.bz-sub-hero h2 {
  font-size: clamp(24px, 3.2vw, 34px);
  letter-spacing: -0.02em;
  margin: 0 0 var(--bz-space-2);
}

.bz-sub-price {
  color: var(--bz-text-primary);
  font-size: 24px;
  font-weight: 700;
  margin: 0 0 var(--bz-space-1);
}

.bz-sub-price span {
  color: var(--bz-text-tertiary);
  font-size: 14px;
  font-weight: 500;
}

.bz-sub-hero-main { flex: 1 1 320px; min-width: 0; }

.bz-sub-hero-side {
  display: grid;
  flex: 0 0 auto;
  gap: var(--bz-space-3);
  justify-items: end;
  text-align: right;
}

.bz-sub-branch {
  display: grid;
  gap: 2px;
  margin: 0;
}

.bz-sub-branch > span {
  color: var(--bz-text-tertiary);
  font-size: var(--bz-text-supporting);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.bz-sub-branch > strong { font-size: 16px; }
.bz-sub-branch > small { color: var(--bz-text-tertiary); font-size: 12px; }

/* Plan comparison */
.bz-plan-grid {
  display: grid;
  gap: var(--bz-space-4);
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}

.bz-plan-card {
  background: var(--bz-bg-surface);
  border: 1px solid var(--bz-border-subtle);
  border-radius: var(--bz-radius-lg);
  display: grid;
  gap: var(--bz-space-3);
  grid-template-rows: auto auto auto 1fr auto;
  padding: var(--bz-space-6);
  position: relative;
}

.bz-plan-card.is-current {
  background: var(--bz-brand-soft);
  border-color: rgba(139, 92, 246, 0.5);
}

.bz-plan-flag {
  background: var(--bz-brand);
  border-radius: var(--bz-radius-pill);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 4px 12px;
  position: absolute;
  right: var(--bz-space-4);
  top: calc(var(--bz-space-4) * -0.5);
  text-transform: uppercase;
}

.bz-plan-card h3 {
  font-size: 19px;
  letter-spacing: -0.01em;
  margin: 0;
}

.bz-plan-price {
  color: var(--bz-text-primary);
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.02em;
  margin: 0;
}

.bz-plan-blurb {
  color: var(--bz-text-secondary);
  font-size: 14px;
  margin: 0;
}

.bz-plan-features {
  display: grid;
  gap: var(--bz-space-2);
  list-style: none;
  margin: 0;
  padding: 0;
}

.bz-plan-features li {
  align-items: flex-start;
  display: flex;
  font-size: 14px;
  gap: var(--bz-space-2);
}

.bz-plan-features i {
  flex: none;
  font-size: 14px;
  font-style: normal;
  font-weight: 800;
  line-height: 1.45;
  width: 16px;
}

.bz-plan-features .is-yes i { color: var(--bz-success); }
.bz-plan-features .is-yes span { color: var(--bz-text-primary); }
.bz-plan-features .is-no i { color: var(--bz-text-tertiary); }
.bz-plan-features .is-no span { color: var(--bz-text-tertiary); }

.bz-plan-choose {
  background: var(--bz-brand-gradient);
  border: 0;
  border-radius: var(--bz-radius-md);
  color: #fff;
  cursor: pointer;
  font-family: var(--bz-font-body);
  font-size: 15px;
  font-weight: 700;
  min-height: 48px;
  width: 100%;
}

.bz-plan-choose:hover { filter: brightness(1.08); }

.bz-plan-note {
  color: var(--bz-text-tertiary);
  font-size: 13px;
  margin: 0;
  text-align: center;
}

@media (max-width: 720px) {
  .bz-sub-hero { padding: var(--bz-space-5); }
  .bz-sub-hero-side { justify-items: start; text-align: left; }
}

/* --------------------------------------------------------------------------
   12. Earnings (formerly "Staff Money")
   -------------------------------------------------------------------------- */

.bz-earn-hero {
  background:
    radial-gradient(120% 140% at 10% 0%, rgba(52, 211, 153, 0.12), transparent 62%),
    var(--bz-bg-surface-raised);
  border: 1px solid var(--bz-border-default);
  border-radius: var(--bz-radius-xl);
  display: grid;
  gap: var(--bz-space-5);
  padding: var(--bz-space-8);
}

.bz-earn-hero-head h2 {
  font-size: clamp(24px, 3.2vw, 32px);
  letter-spacing: -0.02em;
  margin: 0 0 var(--bz-space-2);
}

/* Three tiles, biggest question first. */
.bz-earn-tiles {
  display: grid;
  gap: var(--bz-space-4);
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  list-style: none;
  margin: 0;
  padding: 0;
}

.bz-earn-tile {
  background: var(--bz-bg-surface);
  border: 1px solid var(--bz-border-subtle);
  border-radius: var(--bz-radius-md);
  display: grid;
  gap: var(--bz-space-1);
  padding: var(--bz-space-4) var(--bz-space-5);
}

/* Kept deliberately faint - enough to separate the three at a glance, not
   enough to look like three different alert boxes. */
.bz-earn-tile.is-paid { background: rgba(52, 211, 153, 0.055); border-color: rgba(52, 211, 153, 0.16); }
.bz-earn-tile.is-approved { background: rgba(56, 189, 248, 0.055); border-color: rgba(56, 189, 248, 0.16); }
.bz-earn-tile.is-waiting { background: rgba(251, 191, 36, 0.05); border-color: rgba(251, 191, 36, 0.16); }

.bz-earn-tile-label {
  color: var(--bz-text-tertiary);
  font-size: var(--bz-text-supporting);
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.bz-earn-tile-value {
  color: var(--bz-text-primary);
  font-size: 28px;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
}

.bz-earn-tile small {
  color: var(--bz-text-tertiary);
  font-size: 12px;
}

.bz-earn-hero-foot {
  border-top: 1px solid var(--bz-border-subtle);
  color: var(--bz-text-secondary);
  font-size: 14px;
  margin: 0;
  padding-top: var(--bz-space-4);
}

/* The claim form: six questions in plain words, replacing a thirteen-field
   form that asked for period start, period end, due date and a category. */
.bz-earn-form {
  display: grid;
  gap: var(--bz-space-4);
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}

.bz-earn-field { display: grid; gap: var(--bz-space-2); }
.bz-earn-field-wide { grid-column: 1 / -1; }

.bz-earn-field > label {
  color: var(--bz-text-primary);
  font-size: 15px;
  font-weight: 600;
}

.bz-earn-field input,
.bz-earn-field select,
.bz-earn-field textarea {
  background: var(--bz-bg-input);
  border: 1px solid var(--bz-border-default);
  border-radius: var(--bz-radius-md);
  color: var(--bz-text-primary);
  font-family: var(--bz-font-body);
  font-size: 15px;
  padding: var(--bz-space-3);
  width: 100%;
}

.bz-earn-field input,
.bz-earn-field select { min-height: 48px; }

.bz-earn-hint { color: var(--bz-text-tertiary); font-size: 13px; }
.bz-earn-submit { grid-column: 1 / -1; }

@media (max-width: 720px) {
  .bz-earn-hero { padding: var(--bz-space-5); }
}

.bz-earn-hero-foot a {
  color: #c4b5fd;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.bz-earn-hero-foot a:hover { color: #ddd2ff; }

/* --------------------------------------------------------------------------
   13. Client home
   -------------------------------------------------------------------------- */

/* The hero copy column was losing the width fight with the artwork, so a short
   headline broke across six lines ("Turn your / Google / Drive folder / into a
   / beautiful / Gallery."). Give the words the larger share. */
.cgd-hero {
  grid-template-columns: minmax(340px, 1.3fr) minmax(220px, 0.85fr);
}

.cgd-hero-copy h2 {
  font-size: clamp(1.9rem, 2.9vw, 3.2rem);
  text-wrap: balance;
}

/* Names and emails were being cut off ("Cora Consu...", "consumer@beetz...").
   A customer's own name should never be an ellipsis on their own home page -
   let it wrap onto a second line instead. */
.cgd-account-person h3,
.cgd-account-person p {
  overflow: visible;
  overflow-wrap: break-word;
  text-overflow: clip;
  white-space: normal;
}

/* "Things waiting for you" - replaces a second copy of the hero's call to
   action with the question a customer actually arrives with. */
.bz-client-todo {
  background: var(--bz-bg-surface-raised);
  border: 1px solid var(--bz-border-default);
  border-radius: var(--bz-radius-lg);
  display: grid;
  gap: var(--bz-space-3);
  padding: var(--bz-space-5);
}

.bz-client-todo h3 {
  font-size: 17px;
  letter-spacing: -0.01em;
  margin: 0;
}

.bz-client-todo.is-clear p {
  color: var(--bz-text-tertiary);
  font-size: 14px;
  margin: 0;
}

.bz-client-todo ul {
  display: grid;
  gap: var(--bz-space-2);
  list-style: none;
  margin: 0;
  padding: 0;
}

.bz-client-todo li a {
  align-items: center;
  background: var(--bz-bg-surface);
  border: 1px solid var(--bz-border-subtle);
  border-radius: var(--bz-radius-md);
  display: flex;
  gap: var(--bz-space-3);
  min-height: 56px;
  padding: var(--bz-space-3) var(--bz-space-4);
  text-decoration: none;
}

.bz-client-todo li a:hover { background: var(--bz-bg-surface-hover); }

.bz-client-todo li.tone-amber a { background: rgba(251, 191, 36, 0.05); border-color: rgba(251, 191, 36, 0.16); }
.bz-client-todo li.tone-violet a { background: rgba(139, 92, 246, 0.07); border-color: rgba(139, 92, 246, 0.18); }
.bz-client-todo li.tone-green a { background: rgba(52, 211, 153, 0.055); border-color: rgba(52, 211, 153, 0.16); }

.bz-client-todo li b {
  color: var(--bz-text-primary);
  font-size: 24px;
  font-weight: 800;
  line-height: 1;
  min-width: 24px;
}

.bz-client-todo li strong {
  color: var(--bz-text-primary);
  display: block;
  font-size: 14px;
}

.bz-client-todo li small {
  color: var(--bz-text-tertiary);
  display: block;
  font-size: 12px;
  margin-top: 2px;
}

/* --------------------------------------------------------------------------
   14. Modal dialogs
   --------------------------------------------------------------------------
   Forms that are an occasional errand — asking for overtime, claiming money
   back — do not belong permanently on the page. They open on request so the
   page itself stays short and readable.
   -------------------------------------------------------------------------- */

.bz-dialog {
  background: var(--bz-bg-surface-raised);
  border: 1px solid var(--bz-border-default);
  border-radius: var(--bz-radius-xl);
  box-shadow: var(--bz-shadow-lg);
  color: var(--bz-text-primary);
  max-height: min(88vh, 900px);
  max-width: min(760px, calc(100vw - 32px));
  overflow: auto;
  padding: var(--bz-space-8);
  position: relative;
  width: 100%;
}

.bz-dialog::backdrop {
  backdrop-filter: blur(3px);
  background: rgba(3, 5, 10, 0.72);
}

.bz-dialog:not([open]) { display: none; }

.bz-dialog-head { margin-bottom: var(--bz-space-6); padding-right: var(--bz-space-8); }

.bz-dialog-head h2 {
  font-size: clamp(21px, 2.6vw, 27px);
  letter-spacing: -0.02em;
  margin: 0 0 var(--bz-space-2);
}

.bz-dialog-head .muted { margin: 0; }

.bz-dialog-dismiss {
  margin: 0;
  position: absolute;
  right: var(--bz-space-4);
  top: var(--bz-space-4);
}

.bz-dialog-dismiss button {
  background: var(--bz-bg-surface-hover);
  border: 1px solid var(--bz-border-subtle);
  border-radius: var(--bz-radius-pill);
  color: var(--bz-text-secondary);
  cursor: pointer;
  font-size: 22px;
  height: 40px;
  line-height: 1;
  padding: 0;
  width: 40px;
}

.bz-dialog-dismiss button:hover {
  background: var(--bz-bg-surface);
  color: var(--bz-text-primary);
}

.bz-dialog-actions {
  align-items: center;
  border-top: 1px solid var(--bz-border-subtle);
  display: flex;
  flex-wrap: wrap;
  gap: var(--bz-space-3);
  grid-column: 1 / -1;
  justify-content: flex-end;
  margin-top: var(--bz-space-2);
  padding-top: var(--bz-space-5);
}

.bz-dialog-cancel {
  background: transparent;
  border: 1px solid var(--bz-border-default);
  border-radius: var(--bz-radius-md);
  color: var(--bz-text-secondary);
  cursor: pointer;
  font-family: var(--bz-font-body);
  font-size: 15px;
  font-weight: 600;
  min-height: 48px;
  padding: 0 var(--bz-space-5);
}

.bz-dialog-cancel:hover {
  background: var(--bz-bg-surface-hover);
  color: var(--bz-text-primary);
}

.bz-dialog .bz-clock-button { min-width: 0; }

/* Attendance corrections use a month, not an ever-growing select menu.
   Recorded days can be corrected; blank days can be selected for missing-day
   requests and approved by an admin. */
.bz-correction-calendar {
  border: 1px solid var(--bz-border-subtle);
  border-radius: var(--bz-radius-lg);
  display: grid;
  gap: 12px;
  padding: 16px;
}

.bz-correction-calendar-head,
.bz-correction-month-controls,
.bz-correction-selected {
  align-items: center;
  display: flex;
  gap: 10px;
  justify-content: space-between;
}

.bz-correction-calendar-head > div:first-child,
.bz-correction-selected {
  align-items: flex-start;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.bz-correction-calendar-head small,
.bz-correction-selected small {
  color: var(--bz-text-tertiary);
  font-size: 0.78rem;
}

.bz-correction-month-controls input[type="month"] {
  min-height: 40px;
  width: 160px;
}

.bz-correction-month-controls .secondary-button {
  min-height: 40px;
  min-width: 40px;
  padding: 0;
}

.bz-correction-weekdays,
.bz-correction-calendar-grid {
  display: grid;
  gap: 6px;
  grid-template-columns: repeat(7, minmax(0, 1fr));
}

.bz-correction-weekdays span {
  color: var(--bz-text-tertiary);
  font-size: 0.68rem;
  font-weight: 800;
  text-align: center;
  text-transform: uppercase;
}

.bz-correction-calendar-day,
.bz-correction-calendar-grid > .is-outside {
  aspect-ratio: 1 / 0.9;
  min-height: 54px;
}

.bz-correction-calendar-day {
  align-content: center;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 10px;
  color: var(--bz-text-tertiary);
  display: grid;
  gap: 2px;
  justify-items: center;
  padding: 5px;
}

.bz-correction-calendar-day.is-disabled {
  color: rgba(148, 163, 184, 0.32);
  cursor: not-allowed;
  opacity: 0.55;
}

button.bz-correction-calendar-day.has-time {
  background: rgba(139, 92, 246, 0.13);
  border-color: rgba(167, 139, 250, 0.42);
  color: var(--bz-text-primary);
  cursor: pointer;
}

button.bz-correction-calendar-day.can-add-missing {
  background: rgba(255, 255, 255, 0.025);
  border-color: rgba(148, 163, 184, 0.16);
  cursor: pointer;
}

button.bz-correction-calendar-day.can-add-missing:hover,
button.bz-correction-calendar-day.can-add-missing:focus-visible {
  background: rgba(139, 92, 246, 0.14);
  border-color: rgba(167, 139, 250, 0.48);
  color: var(--bz-text-primary);
  outline: none;
}

button.bz-correction-calendar-day.has-time:hover,
button.bz-correction-calendar-day.has-time:focus-visible,
button.bz-correction-calendar-day.is-selected {
  background: linear-gradient(135deg, rgba(124, 58, 237, 0.8), rgba(219, 39, 119, 0.68));
  border-color: rgba(216, 180, 254, 0.9);
  outline: none;
}

.bz-correction-calendar-day b { font-size: 0.9rem; }
.bz-correction-calendar-day small { font-size: 0.64rem; white-space: nowrap; }
.bz-correction-calendar-day i {
  color: #fcd34d;
  font-size: 0.58rem;
  font-style: normal;
  font-weight: 800;
  text-transform: uppercase;
}

.bz-correction-selected {
  background: rgba(255, 255, 255, 0.025);
  border-radius: 10px;
  padding: 10px 12px;
}

.bz-correction-missing {
  background: none;
  border: 0;
  color: #c4b5fd;
  cursor: pointer;
  justify-self: start;
  padding: 2px 0;
  text-decoration: underline;
  text-underline-offset: 3px;
}

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

.bz-correction-time-pair label {
  display: grid;
  gap: 6px;
}

/* The two big entry points on the Earnings page. */
.bz-earn-hero-actions {
  border-top: 1px solid var(--bz-border-subtle);
  display: grid;
  gap: var(--bz-space-3);
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  padding-top: var(--bz-space-5);
}

.bz-earn-action {
  align-items: center;
  background: var(--bz-bg-surface);
  border: 1px solid var(--bz-border-subtle);
  border-radius: var(--bz-radius-md);
  color: var(--bz-text-primary);
  cursor: pointer;
  display: flex;
  font-family: var(--bz-font-body);
  gap: var(--bz-space-3);
  min-height: 68px;
  padding: var(--bz-space-3) var(--bz-space-4);
  text-align: left;
  transition: background-color 0.12s ease, border-color 0.12s ease;
}

.bz-earn-action:hover {
  background: var(--bz-bg-surface-hover);
  border-color: rgba(139, 92, 246, 0.45);
}

.bz-earn-action svg {
  color: #c4b5fd;
  flex: none;
  height: 22px;
  width: 22px;
}

.bz-earn-action strong { display: block; font-size: 15px; }

.bz-earn-action small {
  color: var(--bz-text-tertiary);
  display: block;
  font-size: 13px;
  margin-top: 2px;
}

@media (max-width: 720px) {
  .bz-dialog {
    border-radius: var(--bz-radius-lg);
    max-height: 92vh;
    padding: var(--bz-space-5);
  }

  .bz-dialog-actions > * { flex: 1 1 auto; justify-content: center; }

  .bz-correction-calendar-head { align-items: stretch; flex-direction: column; }
  .bz-correction-month-controls { justify-content: stretch; }
  .bz-correction-month-controls input[type="month"] { flex: 1 1 auto; width: auto; }
  .bz-correction-calendar-day,
  .bz-correction-calendar-grid > .is-outside { min-height: 42px; }
  .bz-correction-calendar-day small { display: none; }
  .bz-correction-time-pair { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   15. Flat main menu
   --------------------------------------------------------------------------
   The sidebar used to be collapsible sections. Every destination is now a
   top-level item, so the list is longer and must scroll comfortably and stay
   scannable.
   -------------------------------------------------------------------------- */

.nav-flat {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.nav-flat a {
  align-items: center;
  padding-block: 9px;
  border-radius: var(--bz-radius-pill);
  color: #bdb9c6;
  display: flex;
  font-size: 14px;
  font-weight: 700;
  gap: 10px;
  min-height: 38px;
  padding: 8px 12px;
  text-decoration: none;
}

.nav-flat a:hover {
  background: rgba(148, 163, 184, 0.1);
  color: #f7f1ff;
}

.nav-flat a.active {
  background: rgba(139, 92, 246, 0.18);
  color: #fff;
}

/* Longer, self-describing labels ("Equipment Maintenance") must not be cut off
   into "Equipment Maintena". Let them use a second line instead. */
.nav-flat a > span {
  line-height: 1.25;
  min-width: 0;
  overflow-wrap: break-word;
  white-space: normal;
}

.nav-flat a svg {
  flex: none;
  height: 18px;
  width: 18px;
}

/* A long flat list has to scroll on its own rather than pushing the account
   card off the bottom of the screen. */
.sidebar nav {
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: thin;
}

/* --------------------------------------------------------------------------
   16. Project summary card — make it editable
   -------------------------------------------------------------------------- */

.project-summary-edit {
  align-items: center;
  background: rgba(139, 92, 246, 0.16);
  border: 1px solid rgba(139, 92, 246, 0.4);
  border-radius: var(--bz-radius-md);
  color: #ddd2ff;
  cursor: pointer;
  display: inline-flex;
  font-family: var(--bz-font-body);
  font-size: 13px;
  font-weight: 700;
  gap: var(--bz-space-2);
  justify-content: center;
  margin-top: var(--bz-space-2);
  min-height: 40px;
  padding: 0 var(--bz-space-4);
}

.project-summary-edit:hover {
  background: rgba(139, 92, 246, 0.26);
  color: #fff;
}

.project-summary-edit svg { height: 15px; width: 15px; }

/* The project editor is a wide form; give it more room than the default. */
#project-details-dialog { max-width: min(880px, calc(100vw - 32px)); }

#project-details-dialog .form-grid {
  display: grid;
  gap: var(--bz-space-4);
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}

#project-details-dialog .form-grid > label { display: grid; gap: var(--bz-space-2); }
#project-details-dialog .form-grid > label.full,
#project-details-dialog .form-help { grid-column: 1 / -1; }

#project-details-dialog input,
#project-details-dialog select,
#project-details-dialog textarea {
  background: var(--bz-bg-input);
  border: 1px solid var(--bz-border-default);
  border-radius: var(--bz-radius-md);
  color: var(--bz-text-primary);
  font-family: var(--bz-font-body);
  font-size: 15px;
  padding: var(--bz-space-3);
  width: 100%;
}

#project-details-dialog input,
#project-details-dialog select { min-height: 48px; }

/* --------------------------------------------------------------------------
   17. Project people
   -------------------------------------------------------------------------- */

.solo-people-row {
  align-items: center;
  border-top: 1px solid var(--bz-border-subtle);
  display: flex;
  flex-wrap: wrap;
  gap: var(--bz-space-3);
  justify-content: space-between;
  margin-top: var(--bz-space-5);
  padding-top: var(--bz-space-4);
}

.solo-people-row p {
  color: var(--bz-text-secondary);
  font-size: 14px;
  margin: 0;
}

.solo-people-row strong { color: var(--bz-text-primary); }

#project-people-dialog { max-width: min(760px, calc(100vw - 32px)); }

#project-people-dialog .form-grid {
  display: grid;
  gap: var(--bz-space-5);
}

#project-people-dialog .form-label {
  color: var(--bz-text-primary);
  display: block;
  font-size: 15px;
  font-weight: 600;
  margin-bottom: var(--bz-space-2);
}

#project-people-dialog .project-member-search input,
#project-people-dialog select {
  background: var(--bz-bg-input);
  border: 1px solid var(--bz-border-default);
  border-radius: var(--bz-radius-md);
  color: var(--bz-text-primary);
  font-family: var(--bz-font-body);
  font-size: 15px;
  min-height: 48px;
  padding: 0 var(--bz-space-3);
  width: 100%;
}

#project-people-dialog .project-member-picker {
  display: grid;
  gap: var(--bz-space-2);
  margin-top: var(--bz-space-3);
  max-height: 260px;
  overflow-y: auto;
}

#project-people-dialog .project-member-picker label {
  align-items: center;
  background: var(--bz-bg-surface);
  border: 1px solid var(--bz-border-subtle);
  border-radius: var(--bz-radius-md);
  cursor: pointer;
  display: flex;
  gap: var(--bz-space-3);
  padding: var(--bz-space-3) var(--bz-space-4);
}

#project-people-dialog .project-member-picker label:hover {
  border-color: rgba(139, 92, 246, 0.45);
}

#project-people-dialog .project-member-picker label[hidden] { display: none; }

#project-people-dialog .project-member-picker strong { display: block; font-size: 14px; }

#project-people-dialog .project-member-picker small {
  color: var(--bz-text-tertiary);
  display: block;
  font-size: 12px;
}

#project-people-dialog .project-member-search-empty {
  color: var(--bz-text-tertiary);
  font-size: 13px;
  margin: var(--bz-space-2) 0 0;
}

/* --------------------------------------------------------------------------
   18. Workforce rules — salary
   -------------------------------------------------------------------------- */

/* Monthly salary shared a cell with "hours per day" and had no label, so it
   read as a second unexplained hours box. It has its own column now. */
.workforce-salary-cell small {
  color: var(--bz-text-tertiary);
  display: block;
  font-size: 12px;
  margin-top: 4px;
}

/* --------------------------------------------------------------------------
   19. Staff dashboard — team list
   --------------------------------------------------------------------------
   Rows were resolving to five implicit grid tracks instead of three, which
   pushed the avatar onto its own line and let the "Team" chip land on top of
   the person's name ("Backup Staff" reading as "Backup / StaffTeam").
   -------------------------------------------------------------------------- */

.staff-team-list a {
  align-items: center;
  column-gap: var(--bz-space-3);
  display: grid;
  grid-auto-flow: row;
  grid-template-columns: 34px minmax(0, 1fr) auto;
  padding: var(--bz-space-2) 0;
  row-gap: 0;
}

.staff-team-list a > :first-child {
  grid-column: 1;
  grid-row: 1;
}

.staff-team-list a > span {
  grid-column: 2;
  grid-row: 1;
  min-width: 0;
}

.staff-team-list a > em {
  grid-column: 3;
  grid-row: 1;
  justify-self: end;
  white-space: nowrap;
}

.staff-team-list strong {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.staff-team-list small {
  color: var(--bz-text-tertiary);
  display: block;
  font-size: 12px;
}

/* Value and label ran together as "0%early/on time". */
.performance-pair span {
  display: grid;
  gap: 2px;
}

.performance-pair small {
  color: var(--bz-text-tertiary);
  display: block;
  font-size: 12px;
}

/* Five tiles in a rigid three-column grid left a ragged empty slot on the
   second row. Let them size to the row instead. */
.staff-metrics {
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}

/* ==========================================================================
   20. Staff dashboard arrangement

   The old staff home led with five equal metric tiles, then repeated the same
   numbers again in a payroll strip and a second attendance panel. Nothing on
   the page told you what to do first. This lays it out the way the day
   actually runs: who you are and what date it is, the clock, anything blocking
   your pay, then your work.
   ========================================================================== */

.sd-shell {
  display: grid;
  gap: var(--bz-space-5);
}

/* Staff Home has no separate page-title bar, so the global 104px account-menu
   clearance plus the shell's 24px top padding left a conspicuous empty band.
   Keep enough room for the floating account control, then start the greeting
   where the clock card can be seen without a page of air above it. */
.staff-control-dashboard.sd-shell {
  padding-top: 12px;
}

@media (min-width: 761px) {
  body:not(.login-screen) .main:has(> .staff-control-dashboard.sd-shell) {
    padding-top: 72px;
  }
}

/* --- Greeting ------------------------------------------------------------ */

.sd-greeting {
  align-items: flex-end;
  display: flex;
  flex-wrap: wrap;
  gap: var(--bz-space-4);
  justify-content: space-between;
}

.sd-greeting-text h2 {
  font-size: var(--bz-text-page-title);
  line-height: 1.2;
  margin: 0;
}

.sd-greeting-text p {
  color: var(--bz-text-secondary);
  margin: 4px 0 0;
}

.sd-date {
  color: var(--bz-text-tertiary);
  display: flex;
  gap: 8px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.12em;
  margin: 0;
  text-transform: uppercase;
}

.sd-date i {
  color: var(--bz-text-tertiary);
  font-style: normal;
}

/* --- Clock row: the card, with today's four numbers beside it ------------ */

.sd-clock-row {
  /* The stat aside is gone; the clock owns the row. */
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}

/* With two side panels removed, the right column must hug its content
   instead of stretching panels across the leftover height. */
.staff-side-column { align-content: start; }
.staff-side-column > .staff-panel { height: auto; align-self: start; }

.sd-clock-row > .bz-clock-card {
  margin: 0;
}

.sd-stat-block {
  background: var(--bz-bg-surface-raised);
  border: 1px solid var(--bz-border-subtle);
  border-radius: var(--bz-radius-lg);
  display: grid;
  gap: 1px;
  grid-template-columns: 1fr 1fr;
  overflow: hidden;
}

.sd-stat-block .sd-stat {
  background: var(--bz-bg-surface);
  padding: var(--bz-space-4);
}

.sd-stat-label {
  color: var(--bz-text-tertiary);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.1em;
  margin: 0 0 6px;
  text-transform: uppercase;
}

.sd-stat strong {
  display: block;
  font-size: 22px;
  line-height: 1.15;
}

.sd-stat small {
  color: var(--bz-text-tertiary);
  display: block;
  font-size: 12px;
  margin-top: 2px;
}

.sd-stat.is-warn strong {
  color: var(--bz-warning);
}

/* --- Blocking alert ------------------------------------------------------ */

.sd-alert {
  align-items: center;
  background: var(--bz-danger-soft);
  border: 1px solid var(--bz-danger);
  border-radius: var(--bz-radius-md);
  display: flex;
  flex-wrap: wrap;
  gap: var(--bz-space-3);
  padding: var(--bz-space-4);
}

.sd-alert > i {
  align-items: center;
  color: var(--bz-danger);
  display: inline-flex;
  flex: 0 0 auto;
}

.sd-alert > i svg {
  height: 20px;
  width: 20px;
}

.sd-alert > div {
  flex: 1 1 260px;
}

.sd-alert strong {
  display: block;
}

.sd-alert p {
  color: var(--bz-text-secondary);
  margin: 2px 0 0;
}

/* --- Notices that are waiting on you ------------------------------------- */
/*
 * "float the actionable items" - a notice asking you to do something was
 * sitting in date order among notices that were only telling you things, and
 * every one of them offered the same word, Open.
 */
.bz-notify-actionable {
  border: 1px solid rgba(255, 255, 255, 0.24);
  border-radius: var(--bz-radius-md);
  margin-bottom: var(--bz-space-4);
  padding: var(--bz-space-3) var(--bz-space-3) var(--bz-space-4);
}

.bz-notify-actionable > .bz-notify-day {
  margin-top: 0;
}

.notification.is-actionable {
  border-left: 3px solid rgba(255, 255, 255, 0.52);
}

/* Notifications are already dense with status labels and action buttons.
   Neutral borders keep that information legible without outlining every row
   in neon purple. Unread still has a stronger left edge, just in soft white. */
.bz-notifications-page .notification,
.bz-notifications-page .notification.unread {
  border-color: rgba(255, 255, 255, 0.24);
}

.bz-notifications-page .notification.unread {
  box-shadow: inset 3px 0 0 rgba(255, 255, 255, 0.52);
}

/* --- The hours worked, as the biggest thing on the card ------------------ */
/*
 * "Since 4:26 PM - 0h 00m so far today" was grey sub-text under a heading
 * that repeated the badge in the corner. The one number somebody opens this
 * card to see was the smallest thing on it.
 */
.bz-clock-figure {
  display: grid;
  gap: 2px;
  margin: 0 0 var(--bz-space-2);
}

.bz-clock-figure strong {
  color: var(--bz-text-primary);
  font-size: clamp(2.6rem, 8vw, 4rem);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1;
}

.bz-clock-figure span {
  color: var(--bz-text-secondary);
  font-size: 0.95rem;
  line-height: 1.4;
}

/* With a figure above it, the sentence is no longer the headline. */
.bz-clock-figure + .bz-clock-headline {
  font-size: 1.05rem;
  font-weight: 600;
  margin: 0 0 var(--bz-space-2);
}

/* --- An alert that says what is actually wrong --------------------------- */
/*
 * The payroll alert used to be one grey sentence and a button that led
 * nowhere. It now carries the list of what is missing, so it needs room to
 * breathe and the list needs to read as a list rather than as more prose.
 */
.sd-alert-detailed {
  align-items: flex-start;
}

.sd-alert-list {
  color: var(--bz-text-primary);
  display: grid;
  gap: 4px;
  list-style: none;
  margin: var(--bz-space-3) 0 0;
  padding: 0;
}

.sd-alert-list li {
  align-items: baseline;
  display: flex;
  gap: var(--bz-space-2);
  line-height: 1.45;
}

.sd-alert-list li::before {
  background: var(--bz-danger);
  border-radius: 50%;
  content: "";
  flex: 0 0 auto;
  height: 6px;
  transform: translateY(-1px);
  width: 6px;
}

.sd-alert-who {
  border-top: 1px solid color-mix(in srgb, var(--bz-danger) 30%, transparent);
  margin-top: var(--bz-space-3) !important;
  padding-top: var(--bz-space-3);
}

/* --- Attendance and payroll ---------------------------------------------- */

.sd-head-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.sd-attendance-stats {
  display: grid;
  gap: var(--bz-space-3);
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  margin-bottom: var(--bz-space-4);
}

.sd-attendance-stats .sd-stat {
  background: var(--bz-bg-surface-raised);
  border-radius: var(--bz-radius-md);
  padding: var(--bz-space-3) var(--bz-space-4);
}

.sd-cutoff-top {
  color: var(--bz-text-secondary);
  display: flex;
  flex-wrap: wrap;
  gap: var(--bz-space-2);
  justify-content: space-between;
  margin-bottom: 6px;
}

.sd-cutoff .muted {
  margin: 6px 0 0;
}

/* --- Body columns -------------------------------------------------------- */

.sd-pair {
  display: grid;
  gap: var(--bz-space-4);
  grid-template-columns: 1fr 1fr;
}

/* --- Time-today donut ---------------------------------------------------- */

.sd-donut-wrap {
  align-items: center;
  display: flex;
  gap: var(--bz-space-4);
}

.sd-donut {
  align-items: center;
  aspect-ratio: 1;
  background: conic-gradient(var(--bz-brand) var(--sd-fill, 0%), var(--bz-bg-surface-raised) 0);
  border-radius: 50%;
  display: flex;
  flex: 0 0 auto;
  justify-content: center;
  position: relative;
  width: 116px;
}

.sd-donut::after {
  background: var(--bz-bg-surface);
  border-radius: 50%;
  content: "";
  inset: 11px;
  position: absolute;
}

.sd-donut > span {
  position: relative;
  text-align: center;
  z-index: 1;
}

.sd-donut b {
  display: block;
  font-size: 18px;
}

.sd-donut small {
  color: var(--bz-text-tertiary);
  font-size: 12px;
}

.sd-donut-legend {
  display: grid;
  gap: var(--bz-space-3);
  margin: 0;
}

.sd-donut-legend dt {
  color: var(--bz-text-tertiary);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.sd-donut-legend dd {
  font-size: 16px;
  margin: 2px 0 0;
}

/* --- Empty states --------------------------------------------------------
   "No assigned projects yet." on its own told a new hire nothing about who
   fills the list or where to look meanwhile. Each empty state now names the
   thing, says who puts it there, and offers the one place worth going. */

.sd-empty {
  align-items: center;
  border: 1px dashed var(--bz-border-default);
  border-radius: var(--bz-radius-md);
  display: grid;
  gap: 6px;
  justify-items: center;
  padding: var(--bz-space-8) var(--bz-space-4);
  text-align: center;
}

.sd-empty-sm {
  padding: var(--bz-space-5) var(--bz-space-4);
}

.sd-empty > i {
  align-items: center;
  background: var(--bz-bg-surface-raised);
  border-radius: 50%;
  color: var(--bz-text-tertiary);
  display: inline-flex;
  height: 40px;
  justify-content: center;
  margin-bottom: 2px;
  width: 40px;
}

.sd-empty > i svg {
  height: 20px;
  width: 20px;
}

.sd-empty strong {
  font-size: 15px;
}

.sd-empty p {
  color: var(--bz-text-tertiary);
  margin: 0;
  max-width: 42ch;
}

.sd-empty .btn {
  margin-top: 6px;
}

@media (max-width: 1100px) {
  .sd-clock-row,
  .sd-pair {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 640px) {
  .sd-greeting {
    align-items: flex-start;
    flex-direction: column;
  }

  .sd-donut-wrap {
    flex-direction: column;
    align-items: flex-start;
  }

  .sd-donut-legend {
    grid-auto-flow: column;
    gap: var(--bz-space-6);
  }
}

/* The side column is gone (My team and Deadline score were removed on the
   owner's call), so Home is one clean full-width column at every size. */
.sd-body.staff-layout {
  grid-template-columns: minmax(0, 1fr);
}

/* Four numbers stacked to the clock card's full height left holes between
   them. Sit them at the top of each cell. */
.sd-stat-block .sd-stat {
  align-content: start;
  display: grid;
}

.sd-stat-block .sd-stat {
  align-content: center;
}

.sd-head-actions .secondary-button {
  font-size: 13px;
  padding: 6px 12px;
}

/* ==========================================================================
   21. YouTube in the video gallery

   The video product only accepted Google Drive file links. YouTube links now
   render as embeds; these rules give the iframe the same frame the <video>
   element and the Drive preview already had, so a mixed gallery does not have
   one card sized differently from its neighbours.
   ========================================================================== */

.client-gallery-youtube,
.client-cinema-youtube,
.gallery-drive-video-player iframe {
  aspect-ratio: 16 / 9;
  background: #000;
  border: 0;
  display: block;
  height: auto;
  width: 100%;
}

.client-cinema-youtube {
  border-radius: var(--bz-radius-md);
}

/* Says which of the two link types you pasted, before you submit. */
.cgd-video-source-hint {
  color: var(--bz-text-tertiary);
  display: block;
  font-size: 12px;
  margin-top: 6px;
}

.cgd-video-source-hint.is-ok {
  color: var(--bz-success);
}

.cgd-video-source-hint.is-warn {
  color: var(--bz-warning);
}

/* ==========================================================================
   22. Client cinema sidebar repairs
   ========================================================================== */

/* The four Quick Action links had no flex gap and their SVGs were shrinkable,
   so the bell icon sat on top of the word "Notifications" and the plus sign
   overlapped "Gallery Link". */
.client-gallery-quick-card > div,
.client-gallery-link-card > div {
  /* Two fixed columns were ~104px wide in a 216px sidebar card, narrower than
     the word "Notifications". centre-justified content then overflowed both
     edges and the icon landed on top of the label. Let the row drop to one
     column when two will not fit. */
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

.client-gallery-quick-card > div a,
.client-gallery-link-card > div a {
  align-items: center;
  display: flex;
  gap: 8px;
  justify-content: flex-start;
  line-height: 1.25;
  min-width: 0;
  padding: 9px 11px;
  text-align: left;
}

.client-gallery-quick-card > div a svg,
.client-gallery-link-card > div a svg {
  flex: 0 0 auto;
  height: 16px;
  width: 16px;
}

/* "beetzee + linked video" was clipped to "beetzee + li..." because the value
   column was locked to one line. Let it wrap - the card has the room. */
.client-gallery-info-card dd {
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
}

/* "Large video warningIf the file is very large..." - the heading and the
   supporting line ran together with no break. */
.gallery-drive-video-create-warning span {
  display: grid;
  gap: 2px;
}

/* ==========================================================================
   23. No status rails

   Green, blue and yellow bars welded to the left edge of a card are a generic
   framework alert pattern - they read as somebody else's design system
   dropped into this one. Everywhere one of those bars carried a meaning, the
   meaning now lives in a faint wash across the whole card plus the words and
   badge already on it.
   ========================================================================== */

/* Service cards outlined themselves in full-strength blue, pink and orange.
   Same card, same accent, but as a tint rather than a hard rule. */
.cgd-service-card {
  border-color: color-mix(in srgb, var(--cgd-service-accent, #7c3aed) 22%, transparent);
}

.cgd-service-card:hover,
.cgd-service-card:focus-within {
  border-color: color-mix(in srgb, var(--cgd-service-accent, #7c3aed) 40%, transparent);
}

/* Notice, flash and callout strips that used the same left-bar idiom. */
.settings-sync-blocker {
  background: var(--bz-bg-surface-raised);
  border: 1px solid var(--bz-border-subtle);
  border-left: 0;
  border-radius: var(--bz-radius-sm);
  padding: var(--bz-space-3) var(--bz-space-4);
}

/* The success banner was a green wash. Confirmations are not a separate
   brand - the app is purple, so a confirmation reads purple. Errors keep red
   because an error genuinely has to look like one. */
body:not(.login-screen) .alert.success,
body:not(.login-screen) .bz-alert.success {
  background: var(--bz-brand-soft);
  border-color: rgba(139, 92, 246, 0.24);
  color: var(--bz-text-primary);
}

/* ==========================================================================
   24. Rentals
   ========================================================================== */

.rental-next-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--bz-space-3);
}

/* An empty state living inside a table cell must not inherit the cell's
   left alignment or its cramped padding. */
.rental-active-table .sd-empty {
  border: 0;
  margin: 0;
}

/* ==========================================================================
   25. Wizard step rail

   The step chips were near-white (rgba(226, 232, 240, 0.9)) chevrons on a dark
   app - a light-theme component sitting in a dark product. Same shape, dark
   surface, brand for the step you are on.
   ========================================================================== */

.bz-wizard-step {
  background: var(--bz-bg-surface-raised);
  color: var(--bz-text-tertiary);
}

.bz-wizard-step.is-current {
  background: var(--bz-brand-gradient);
  color: #fff;
}

.bz-wizard-step.is-complete {
  background: var(--bz-brand-soft);
  color: var(--bz-text-secondary);
}

/* "Step 1 of 6: Renter" sat above a progress bar that said the same thing,
   under a chevron rail that said it a third time. The words and the rail stay;
   the bar goes. */
.bz-wizard-dialog [data-cpgee-step-progress],
.bz-wizard-dialog .cpgee-step-progress {
  display: none;
}

/* ==========================================================================
   26. "Everything about <person>"

   A staff member's page listed their projects and tasks and stopped there.
   Their pay, schedule, attendance and leave each lived on a page this one
   never linked to - setting somebody's salary meant already knowing that
   "Workforce Rules" is where salaries live.
   ========================================================================== */

.bz-person-admin-grid {
  display: grid;
  gap: var(--bz-space-3);
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}

.bz-person-admin-grid a {
  align-items: center;
  background: var(--bz-bg-surface-raised);
  border: 1px solid var(--bz-border-subtle);
  border-radius: var(--bz-radius-md);
  display: flex;
  gap: var(--bz-space-3);
  padding: var(--bz-space-4);
  text-decoration: none;
}

.bz-person-admin-grid a:hover {
  background: var(--bz-bg-surface-hover);
  border-color: var(--bz-border-strong);
}

.bz-person-admin-grid i {
  align-items: center;
  background: var(--bz-brand-soft);
  border-radius: var(--bz-radius-sm);
  color: var(--bz-brand);
  display: inline-flex;
  flex: 0 0 auto;
  height: 38px;
  justify-content: center;
  width: 38px;
}

.bz-person-admin-grid strong { display: block; }

.bz-person-admin-grid small {
  color: var(--bz-text-tertiary);
  display: block;
  font-size: 12px;
}

/* ==========================================================================
   27. Project discussion

   The project conversation used to be a thread of directed messages: you chose
   one recipient and only the two of you could read it. It is a comment section
   now - one thread per project, everybody on the project in it.
   ========================================================================== */

.bz-discussion-compose {
  align-items: flex-start;
  background: var(--bz-bg-surface-raised);
  border: 1px solid var(--bz-border-subtle);
  border-radius: var(--bz-radius-lg);
  display: flex;
  gap: var(--bz-space-3);
  margin-bottom: var(--bz-space-5);
  padding: var(--bz-space-4);
}

.bz-discussion-compose > div { flex: 1 1 auto; min-width: 0; }

.bz-discussion-compose textarea,
.bz-discussion-reply textarea {
  background: var(--bz-bg-input);
  border: 1px solid var(--bz-border-default);
  border-radius: var(--bz-radius-md);
  color: var(--bz-text-primary);
  font-family: var(--bz-font-body);
  font-size: 15px;
  padding: var(--bz-space-3);
  resize: vertical;
  width: 100%;
}

.bz-discussion-compose-actions {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--bz-space-3);
  justify-content: space-between;
  margin-top: var(--bz-space-3);
}

.bz-discussion-compose-actions small { color: var(--bz-text-tertiary); }

/* Use profile photos when available; initials remain the resilient fallback. */
.bz-discussion-avatar {
  align-items: center;
  background: var(--bz-bg-surface-hover);
  border-radius: 50%;
  color: var(--bz-text-secondary);
  display: inline-flex;
  flex: 0 0 auto;
  font-size: 12px;
  font-weight: 700;
  height: 36px;
  justify-content: center;
  object-fit: cover;
  overflow: hidden;
  width: 36px;
}

.bz-discussion-avatar.is-you {
  background: var(--bz-brand-soft);
  color: var(--bz-brand);
}

.bz-discussion-people {
  align-items: center;
  display: flex;
  gap: 4px;
}

.bz-discussion-people .bz-discussion-avatar {
  height: 28px;
  font-size: 12px;
  margin-right: -8px;
  outline: 2px solid var(--bz-bg-surface);
  width: 28px;
}

.bz-discussion-people small {
  color: var(--bz-text-tertiary);
  margin-left: 14px;
  white-space: nowrap;
}

.bz-discussion-list,
.bz-discussion-replies {
  display: grid;
  gap: var(--bz-space-4);
  list-style: none;
  margin: 0;
  padding: 0;
}

.bz-discussion-replies {
  border-left: 2px solid var(--bz-border-subtle);
  margin-top: var(--bz-space-4);
  padding-left: var(--bz-space-4);
}

.bz-discussion-item {
  display: flex;
  gap: var(--bz-space-3);
}

.bz-discussion-item.is-removed { opacity: 0.55; }

.bz-discussion-item.is-highlighted .bz-discussion-body {
  background: var(--bz-brand-soft);
  border-radius: var(--bz-radius-md);
  padding: var(--bz-space-3);
}

.bz-discussion-body { flex: 1 1 auto; min-width: 0; }

.bz-discussion-meta {
  align-items: baseline;
  display: flex;
  flex-wrap: wrap;
  gap: var(--bz-space-2);
  margin: 0 0 2px;
}

.bz-discussion-meta span {
  color: var(--bz-text-tertiary);
  font-size: 12px;
}

.bz-discussion-text {
  line-height: 1.55;
  overflow-wrap: break-word;
}

.bz-discussion-actions {
  display: flex;
  gap: var(--bz-space-3);
  margin-top: var(--bz-space-2);
}

.bz-discussion-actions button {
  align-items: center;
  background: none;
  border: 0;
  color: var(--bz-text-tertiary);
  cursor: pointer;
  display: inline-flex;
  font-family: var(--bz-font-body);
  font-size: 13px;
  gap: 5px;
  padding: 4px 0;
}

.bz-discussion-actions button:hover { color: var(--bz-text-primary); }

.bz-discussion-actions svg { height: 14px; width: 14px; }

.bz-discussion-reply {
  display: grid;
  gap: var(--bz-space-2);
  justify-items: start;
  margin-top: var(--bz-space-3);
}

/* display:grid beats the browser default [hidden]{display:none}, so every
   reply box on the page was open before anybody clicked Reply. */
.bz-discussion-reply[hidden] { display: none; }

/* Messages posted before this became a thread stay readable, folded away. */
.bz-discussion-archive summary {
  color: var(--bz-text-tertiary);
  cursor: pointer;
  font-size: 13px;
  /* A <details> heading is a button. These were 23px tall. Padding rather
     than a flex box, because display:flex on a summary removes the browser's
     disclosure triangle. */
  min-height: 44px;
  padding-block: 10px;
}

@media (max-width: 640px) {
  .bz-discussion-compose { flex-direction: column; }
  .bz-discussion-replies { padding-left: var(--bz-space-3); }
}

/* ==========================================================================
   28. Empty states

   181 of them across the product, nearly all a single flat sentence sitting
   flush against the left edge of whatever container they were dropped in -
   "No activity yet." reads like something failed to load rather than like a
   list that is simply empty. This gives every one of them room, a centred
   position and a softer weight, without touching a single call site.
   ========================================================================== */

.empty-state {
  color: var(--bz-text-tertiary);
  padding: var(--bz-space-8) var(--bz-space-4);
  text-align: center;
}

/* Inside a table cell the browser's own alignment wins, so restate it. */
td > .empty-state,
td.empty-state {
  text-align: center;
}

/* A paragraph-level empty state inside a compact panel should not shove the
   panel to twice its height. */
.mc-activity .empty-state,
.mc-schedule .empty-state,
.ecd-list .empty-state,
.staff-team-list .empty-state {
  padding: var(--bz-space-5) var(--bz-space-3);
}

/* The rich version, used where there is a genuine next step to offer. */
.bz-empty {
  align-items: center;
  border: 1px dashed var(--bz-border-default);
  border-radius: var(--bz-radius-md);
  display: grid;
  gap: 6px;
  justify-items: center;
  padding: var(--bz-space-8) var(--bz-space-4);
  text-align: center;
}

.bz-empty > i {
  align-items: center;
  background: var(--bz-bg-surface-raised);
  border-radius: 50%;
  color: var(--bz-text-tertiary);
  display: inline-flex;
  height: 40px;
  justify-content: center;
  margin-bottom: 2px;
  width: 40px;
}

.bz-empty > i svg { height: 20px; width: 20px; }

.bz-empty strong { font-size: 15px; }

.bz-empty p {
  color: var(--bz-text-tertiary);
  margin: 0;
  max-width: 44ch;
}

.bz-empty .secondary-button,
.bz-empty .primary-button { margin-top: 8px; }

/* ==========================================================================
   29. Contracts

   The list printed every contract's full legal text inline. Nine contracts
   made a page 434,000 pixels tall with 1,555 headings in it - you scrolled
   for minutes to reach the second one. The wording is one click away now,
   still on the same page, so you can read before signing exactly as before.
   ========================================================================== */

.contract-readable-toggle {
  border-top: 1px solid var(--bz-border-subtle);
  margin-top: var(--bz-space-4);
  padding-top: var(--bz-space-4);
}

.contract-readable-toggle > summary {
  align-items: center;
  cursor: pointer;
  display: flex;
  font-weight: 600;
  gap: var(--bz-space-2);
  list-style: none;
  padding: var(--bz-space-2) 0;
}

.contract-readable-toggle > summary::-webkit-details-marker { display: none; }

.contract-readable-toggle > summary svg { height: 16px; width: 16px; }

.contract-readable-toggle > summary::after {
  color: var(--bz-text-tertiary);
  content: "Show";
  font-size: 13px;
  font-weight: 500;
  margin-left: auto;
}

.contract-readable-toggle[open] > summary::after { content: "Hide"; }

/* These agreements run to about 50,000 characters - roughly twenty printed
   pages, a thousand paragraphs. Rendered at full height one of them measures
   47,000 pixels, so anything below it on the page was unreachable in practice.
   The contract scrolls inside its own box instead. */
.contract-readable-body {
  max-height: 60vh;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-right: var(--bz-space-3);
}

/* Printing must still produce the whole thing. */
@media print {
  .contract-readable-body {
    max-height: none;
    overflow: visible;
  }
}

/* Rental request decisions stay grouped in the queue instead of becoming a
   row of unrelated controls. The destructive choice remains secondary until
   its required reason is opened. */
.rental-request-actions {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  min-width: 260px;
}

.rental-request-actions form {
  margin: 0;
}

.rental-request-actions > form {
  align-items: end;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.rental-hold-length {
  color: var(--bz-text-tertiary, #9ca3af);
  display: grid;
  font-size: 11px;
  font-weight: 700;
  gap: 3px;
}

.rental-hold-length select {
  min-height: 38px;
  min-width: 118px;
}

.rental-payment-deadline {
  color: var(--bz-warning, #fbbf24);
  display: block;
  margin-top: 5px;
  white-space: nowrap;
}

.rental-request-cancel {
  flex-basis: 100%;
  font-size: 12px;
}

.rental-request-cancel > summary {
  color: var(--bz-text-tertiary, #9ca3af);
  cursor: pointer;
  width: max-content;
}

.rental-request-cancel form {
  align-items: end;
  display: grid;
  gap: 8px;
  grid-template-columns: minmax(180px, 1fr) auto;
  margin-top: 8px;
}

.rental-request-cancel label,
.rental-request-cancel textarea {
  width: 100%;
}

.crp-payment-request {
  align-items: center;
  background: linear-gradient(135deg, rgba(124, 58, 237, .16), rgba(219, 39, 119, .10));
  border: 1px solid rgba(168, 85, 247, .45);
  border-radius: 12px;
  display: flex;
  margin: 16px 0;
  padding: 16px;
}

.crp-payment-request small,
.crp-payment-request strong,
.crp-payment-request p {
  display: block;
}

.crp-payment-request small {
  color: #c4b5fd;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.crp-payment-request strong {
  font-size: 18px;
  margin-top: 3px;
}

.crp-payment-request p {
  color: var(--bz-text-secondary, #cbd5e1);
  line-height: 1.45;
  margin: 6px 0 0;
}

@media (max-width: 720px) {
  .rental-request-cancel form {
    grid-template-columns: 1fr;
  }
}

/* The template name and its code ran together as one string - "Beetzee Client
   Services AgreementBZ-CLIENT-SA · v1.0" - because the <small> was inline
   inside the <span>. */
.contract-template-link > span {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.contract-template-link > span small {
  color: var(--bz-text-tertiary);
  display: block;
  font-size: 12px;
}

/* The contract card sat wider than the column holding it, so its title and the
   table's Value column were cut off at the right edge. */
.contracts-grid-layout,
.contract-table-card,
.contract-document-card {
  min-width: 0;
}

.contract-document-card h2 {
  overflow-wrap: break-word;
}

.contract-table-wrap {
  overflow-x: auto;
}

/* The signing card sat wider than the column it lives in, so the contract
   title and the table's Value column were clipped by the sidebar. */
.contracts-grid-layout > * { min-width: 0; max-width: 100%; }

.contract-document-card,
.contract-table-card,
.contract-table-wrap,
.contract-table { max-width: 100%; }

/* A 40px title is bigger than the thing it names. */
.contract-document-card h2 {
  font-size: clamp(20px, 2.2vw, 28px);
  line-height: 1.2;
}

/* ==========================================================================
   30. Bulk settings behind a toggle

   Some settings screens list every record with an editable form beside it.
   Accounting Settings put 588 input fields and 18,000 pixels on one page that
   way, which buried the six settings anybody actually changes.
   ========================================================================== */

.bz-bulk-settings {
  border: 1px solid var(--bz-border-subtle);
  border-radius: var(--bz-radius-md);
  margin-top: var(--bz-space-4);
}

.bz-bulk-settings > summary {
  align-items: center;
  cursor: pointer;
  display: flex;
  font-weight: 600;
  gap: var(--bz-space-2);
  list-style: none;
  padding: var(--bz-space-4);
}

.bz-bulk-settings > summary::-webkit-details-marker { display: none; }

.bz-bulk-settings > summary svg { height: 16px; width: 16px; }

.bz-bulk-settings > summary::after {
  color: var(--bz-text-tertiary);
  content: "Open";
  font-size: 13px;
  font-weight: 500;
  margin-left: auto;
}

.bz-bulk-settings[open] > summary::after { content: "Close"; }

.bz-bulk-settings[open] > summary {
  border-bottom: 1px solid var(--bz-border-subtle);
}

.bz-bulk-settings > *:not(summary) {
  max-height: 70vh;
  overflow-y: auto;
  padding: var(--bz-space-4);
}

/* ==========================================================================
   31. Wide tables

   Project budgets, workforce rules and the invoice screens all render tables
   wider than the panel holding them. The overflow was clipped, so the last
   columns were unreadable with nothing to say they existed.
   ========================================================================== */

.bz-table-scroll {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  position: relative;
  width: 100%;
}

.bz-table-scroll:focus-visible {
  outline: 2px solid var(--bz-focus-ring);
  outline-offset: 2px;
}

/* A soft fade on the right edge is the only honest way to say "there is more
   over here" without adding furniture to every table. */
.bz-table-scroll.has-more,
.main .table-wrap.has-more {
  position: relative;
}

.bz-table-scroll.has-more::after,
.main .table-wrap.has-more::after {
  background: linear-gradient(90deg, transparent, var(--bz-bg-surface));
  bottom: 0;
  content: "";
  pointer-events: none;
  position: sticky;
  right: 0;
  top: 0;
  width: 36px;
  float: right;
  height: 100%;
  margin-left: -36px;
}

/* ==========================================================================
   32. Staff home on a phone

   The whole screen ran to 6,937px on a 390px-wide phone - about nine screens
   of scrolling to reach the bottom. Most of it was the project cards, each
   showing a full-width photo roughly as tall as it was wide. On a phone you
   want to know which jobs are yours and how far along they are; the picture
   is decoration.
   ========================================================================== */

@media (max-width: 640px) {
  .staff-project-grid { gap: var(--bz-space-2); }

  .staff-project-card {
    align-items: center;
    display: grid;
    gap: 2px var(--bz-space-3);
    grid-template-columns: 56px minmax(0, 1fr);
    padding: var(--bz-space-3);
  }

  .staff-project-card img {
    border-radius: var(--bz-radius-sm);
    grid-column: 1;
    grid-row: 1 / span 3;
    height: 56px;
    object-fit: cover;
    width: 56px;
  }

  .staff-project-card > strong,
  .staff-project-card > small,
  .staff-project-card > em,
  .staff-project-card > p,
  .staff-project-card > .mc-progress { grid-column: 2; }

  /* The stage chip and the "Due:" line say the same thing twice on a screen
     this narrow. Progress and the due date are what matter. */
  .staff-project-card > em { display: none; }

  .staff-project-card > small:first-of-type { display: none; }

  .staff-project-card > p {
    margin: 0;
    font-size: 12px;
  }

  .staff-project-card .mc-progress { margin-top: 2px; }
}

@media (max-width: 640px) {
  /* Each task row stacked five separate lines - title, project, date,
     priority, status - so six tasks filled the screen twice over. Group them
     the way you read them: what it is, then when and how urgent. */
  .staff-task-row {
    align-items: start;
    column-gap: var(--bz-space-3);
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    padding: var(--bz-space-3);
    row-gap: 4px;
  }

  .staff-task-row .staff-task-action { grid-column: 1; grid-row: 1 / span 2; }

  .staff-task-row .staff-task-title { grid-column: 2; grid-row: 1; }

  .staff-task-row > span,
  .staff-task-row > b,
  .staff-task-row > em {
    font-size: 12px;
    grid-column: 2;
    grid-row: 2;
    justify-self: start;
  }

  /* Put the three small facts on one line instead of three. */
  .staff-task-row > span { justify-self: start; }
  .staff-task-row > b { justify-self: center; }
  .staff-task-row > em { justify-self: end; }

  .staff-task-row {
    grid-template-areas:
      "act title title title"
      "act when prio status";
    grid-template-columns: auto auto auto 1fr;
  }

  .staff-task-row .staff-task-action { grid-area: act; }
  .staff-task-row .staff-task-title { grid-area: title; }
  .staff-task-row > span { grid-area: when; }
  .staff-task-row > b { grid-area: prio; }
  .staff-task-row > em { grid-area: status; }

  /* "In Progress" and "Queued #4" were wrapping onto two lines inside their
     chip, which made every row taller than the text in it. */
  .staff-task-row > em,
  .staff-task-row > b {
    white-space: nowrap;
    font-size: 12px;
    padding: 3px 8px;
  }
}

@media (max-width: 640px) {
  /* The hero is a two-column grid; on a phone the art column kept its width
     and sat entirely off the right edge, painted but never seen. It is
     decoration - the sentence beside it is the message - so on a phone it
     goes away properly instead of hiding out of frame. */
  .cgd-hero-art { display: none; }

  .cgd-hero { grid-template-columns: minmax(0, 1fr); }
}

/* ==========================================================================
   33. Critical attention strip

   The markup for this row exists and is sensible - icon, count, title, detail -
   but no stylesheet ever described it{
  display: grid;
  gap: var(--bz-space-3);
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  margin-top: var(--bz-space-3);
}

.mc-critical-item {
  align-items: center;
  background: var(--bz-bg-surface-raised);
  border: 1px solid var(--bz-border-subtle);
  border-radius: var(--bz-radius-md);
  display: flex;
  gap: var(--bz-space-3);
  padding: var(--bz-space-3) var(--bz-space-4);
  text-decoration: none;
}

.mc-critical-item:hover {
  background: var(--bz-bg-surface-hover);
  border-color: var(--bz-border-strong);
}

.mc-critical-item > i {
  align-items: center;
  background: var(--bz-bg-surface);
  border-radius: var(--bz-radius-sm);
  color: var(--bz-text-tertiary);
  display: inline-flex;
  flex: 0 0 auto;
  height: 34px;
  justify-content: center;
  width: 34px;
}

.mc-critical-item > i svg { height: 17px; width: 17px; }

.mc-critical-item > span {
  display: grid;
  gap: 1px;
  min-width: 0;
}

.mc-critical-item strong {
  font-size: 20px;
  line-height: 1.1;
}

/* The title inherited the tone colour, so "Equipment repairs" sat there in
   alarm orange while reading zero. The icon carries the tone; the words stay
   the same colour as every other label on the page. */
.mc-critical-item b,
.mc-critical-item strong {
  color: var(--bz-text-primary);
}

.mc-critical-item b {
  font-size: 13px;
  font-weight: 600;
}

.mc-critical-item.is-clear b,
.mc-critical-item.is-clear strong {
  color: var(--bz-text-secondary);
}

.mc-critical-item small {
  color: var(--bz-text-tertiary);
  font-size: 12px;
}

/* Nothing wrong is the normal state, and a screen full of shouting zeros
   teaches you to ignore the whole row. Zero recedes; a real number does not. */
.mc-critical-item.tone-danger > i { background: var(--bz-danger-soft); color: var(--bz-danger); }
.mc-critical-item.tone-warning > i,
.mc-critical-item.tone-amber > i { background: var(--bz-warning-soft); color: var(--bz-warning); }
.mc-critical-item.tone-info > i,
.mc-critical-item.tone-blue > i { background: var(--bz-info-soft); color: var(--bz-info); }
.mc-critical-item.tone-success > i,
.mc-critical-item.tone-green > i { background: var(--bz-success-soft); color: var(--bz-success); }

.mc-critical-item.is-clear { opacity: 0.62; }
.mc-critical-item.is-clear > i { background: var(--bz-bg-surface); color: var(--bz-text-disabled); }

/* ==========================================================================
   34. Money in a metric tile

   "PHP 655,600.00" was breaking across two lines mid-number - the tile showed
   "PHP 655,600.0" then "0" underneath, which reads as a different amount at a
   glance. An owner should never have to double-take at their own revenue.
   The figure stays exact; it just gets room and refuses to break.
   ========================================================================== */

.mc-metric-card strong,
.staff-metric strong,
.client-gallery-metric strong {
  font-size: clamp(18px, 1.6vw, 26px);
  line-height: 1.15;
  overflow-wrap: normal;
  word-break: keep-all;
}

/* A long currency string gets the whole tile width rather than sharing a row
   with the icon, and shrinks to fit rather than wrapping. Two lines is still
   two lines even when the break lands between words. */
/* Measured: the value box is 164px and "PHP 655,600.00" needs 187px at 21px
   type. Clipping it would hide digits, so the type comes down instead - a
   currency figure is worth less space than a two-digit count, not more. */
.mc-metric-card strong {
  display: block;
  font-size: clamp(15px, 1.25vw, 21px);
  white-space: nowrap;
}

/* ==========================================================================
   35. Project header

   The header is a flex row: description on the left, the summary card on the
   right. A short description left roughly 250px of empty space below it while
   the card ran to full height, so the page opened with a large blank area
   between the project name and its first tab.
   ========================================================================== */

.project-hero {
  align-items: flex-start;
}

.project-hero > *:first-child {
  min-width: 0;
}

/* The summary card sets the height of the row. Nothing gains from the empty
   column beside it stretching to match. */
.project-hero .project-summary,
.project-hero > aside,
.project-hero > .project-summary-card {
  align-self: flex-start;
}

.project-hero-main {
  display: grid;
  gap: var(--bz-space-3);
  align-content: start;
}

.project-hero-main h2 { margin: 0; }

.project-hero-main > p { margin: 0; }

.project-hero-progress {
  display: grid;
  gap: 6px;
  margin-top: var(--bz-space-2);
  max-width: 460px;
}

.project-hero-progress-top {
  align-items: baseline;
  display: flex;
  gap: var(--bz-space-3);
  justify-content: space-between;
}

.project-hero-progress-top span {
  color: var(--bz-text-tertiary);
  font-size: 13px;
}

.project-hero-facts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--bz-space-5);
  margin: var(--bz-space-2) 0 0;
}

.project-hero-facts > div { display: grid; gap: 2px; }

.project-hero-facts dt {
  color: var(--bz-text-tertiary);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.project-hero-facts dd {
  font-size: 20px;
  font-weight: 600;
  margin: 0;
}

.project-hero-facts .is-late dd { color: var(--bz-danger); }

/* ==========================================================================
   36. Project board

   Two boards, fourteen columns, and every card in the first one. The stage a
   project sits in is stored in a column that is created with DEFAULT
   'Inquiry' - the first column of the sales board - and nothing writes to it
   except an admin dragging a card. So a shoot that was filmed, edited,
   delivered and paid for still sat under "Someone asked, nothing agreed yet",
   and the whole Productions board was seven empty columns.

   The placement is now worked out from the project's own progress when nobody
   has moved the card (see project_effective_board_stage in index.php). Three
   things here follow from that: a card that was placed rather than moved says
   so, every column carries a plain sentence saying what it means, and a column
   with nothing in it stops competing for attention with the ones that have
   work in them.
   ========================================================================== */

/* What the column means, under its name. Small and quiet - it is there to be
   read once, not every time. */
.board-column-meaning {
  display: block;
  margin: 2px 0 0;
  font-size: 12px;
  line-height: 1.35;
  font-weight: 500;
  /* #6b7280 measured 3.4:1 on the board's near-black card. Small text needs
     4.5:1, so the fallback is lightened - the token still wins where one is
     defined. */
  color: var(--bz-text-tertiary);
  max-width: 22ch;
}

/* An empty column still needs to be a drop target, so it keeps its width and
   its outline. It just stops shouting: no tone fill, paler heading. */
.board-column.is-empty {
  opacity: 0.62;
}

.board-column.is-empty:hover,
.board-column.is-empty:focus-within,
.board-column.is-empty.is-drop-target {
  opacity: 1;
}

.board-empty {
  margin: 0;
  padding: 14px 10px;
  text-align: center;
  font-size: 12px;
  color: var(--bz-text-tertiary);
  border: 1px dashed var(--bz-border-default);
  border-radius: 10px;
}

/* "Not moved yet" is a statement about the board, not about the project, so it
   is outlined rather than filled - it must not read like a status the client
   would see. */
.board-pill.is-inferred {
  background: transparent;
  border: 1px dashed var(--bz-border-strong, #cbd5e1);
  color: var(--bz-text-tertiary);
  font-weight: 600;
  cursor: help;
}

/* The column head became a two-part block on the production board to make room
   for the sentence; keep the count aligned to the top next to it. */
.board-column-head {
  align-items: flex-start;
}

/* Why a card cannot be moved, on the card. Amber rather than red: nothing has
   gone wrong, there is simply paperwork outstanding. */
.board-card-locked {
  display: flex;
  gap: 6px;
  align-items: flex-start;
  margin: 8px 0 0;
  padding: 7px 9px;
  border-radius: 8px;
  /* Fixed translucent amber rather than a theme token: the board is dark and
     the token's light-theme value produced amber text on olive, about 3:1.
     A wash over whatever the card is sitting on works in both themes. */
  background: rgba(245, 158, 11, 0.16);
  border: 1px solid rgba(245, 158, 11, 0.42);
  color: #fcd34d;
  font-size: 12px;
  line-height: 1.4;
}

/* The light-theme override that used to live here was wrong twice over: the
   product does not set data-theme at all, so `:root:not([data-theme='dark'])`
   matched the dark board and painted #92400e - brown on near-black, 2.3:1,
   which is below the 4.5:1 that small text needs. The amber above works on
   both, so the override is gone rather than corrected. */

.board-card-locked svg {
  flex: 0 0 auto;
  width: 13px;
  height: 13px;
  margin-top: 1px;
}

.board-card-locked a {
  display: block;
  margin-top: 3px;
  color: inherit;
  font-weight: 700;
  text-decoration: underline;
}

/* A disabled stage picker must not look like an ordinary one, or it reads as a
   broken control rather than a locked one. */
.board-move-form select[disabled] {
  opacity: 0.55;
  cursor: not-allowed;
}

/* app.css sets `.board-inline-remove-form .board-pill { font: inherit }` to
   drop the browser's default button font. The shorthand also throws away the
   10px the pill itself set, so the Archive button rendered at body size - the
   largest, loudest thing on every card, for the one action that takes a
   project off the board. It is a pill like the others again. */
.board-inline-remove-form .board-pill,
.board-card-foot button.board-pill {
  font-family: inherit;
  font-size: 12px;
  line-height: 1.2;
  font-weight: 600;
  padding: 3px 6px;
}

/* ==========================================================================
   37. My Tasks

   The ten view tabs on this page carried the class `button-tabs`, and no
   stylesheet in the product defined it. They rendered as bare links with a
   space between them, so on a phone the row read as one run-on sentence:
   "Assigned to me Collaborating Due today Overdue Upcoming In progress For
   review Blocked Completed All visible". Nothing looked clickable and nothing
   looked selected.

   They wrap rather than scroll sideways. Ten tabs in a horizontal scroller
   means the last five are off-screen with no sign they exist; wrapped, every
   view is visible at once on any width.
   ========================================================================== */

.button-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 18px;
}

.button-tabs a {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 0 14px;
  border: 1px solid var(--line, rgba(148, 163, 184, 0.28));
  border-radius: 999px;
  background: rgba(15, 23, 42, 0.55);
  color: var(--text, inherit);
  font-weight: 700;
  font-size: 13px;
  text-decoration: none;
  white-space: nowrap;
}

.button-tabs a:hover,
.button-tabs a:focus-visible {
  border-color: rgba(160, 98, 255, 0.55);
}

/* The selected view has to be obvious at a glance - it decides what the whole
   list below is showing. */
.button-tabs a.active {
  background: linear-gradient(135deg, rgba(141, 77, 255, 0.34), rgba(255, 63, 183, 0.18));
  border-color: rgba(160, 98, 255, 0.62);
  color: #ffffff;
}

/* Accept / complete now happen from the list itself. The form must not add a
   margin inside a table cell. */
.task-next-action {
  margin: 0 0 4px;
}

.task-next-action .primary-button {
  min-height: 38px;
  padding: 0 12px;
  font-size: 13px;
  white-space: nowrap;
}

/* ==========================================================================
   38. A page's annex

   When two pages are merged, the second one's content ends up appended below
   the first. Calendar swallowed Schedule and came to 5,903px on a desktop and
   12,381px on a phone: three dashboards and a table of every project sitting
   under a calendar. The calendar - the reason anyone opens the page - was one
   screen in nine.

   An annex is the second page, folded. It is not a settings toggle like
   section 30; it holds whole sections, so it opens full width with no inner
   padding of its own and lets the sections inside keep their own spacing.
   ========================================================================== */

.bz-page-annex {
  border: 1px solid var(--bz-border-subtle);
  border-radius: var(--bz-radius-md);
  margin-top: var(--bz-space-5);
}

.bz-page-annex > summary {
  align-items: center;
  cursor: pointer;
  display: flex;
  gap: var(--bz-space-3);
  list-style: none;
  padding: var(--bz-space-4) var(--bz-space-5);
}

.bz-page-annex > summary::-webkit-details-marker { display: none; }

.bz-page-annex > summary svg {
  flex: 0 0 auto;
  height: 18px;
  width: 18px;
}

/* Heading and explanation stack, so the fold says what is inside it rather
   than making you open it to find out. */
.bz-page-annex > summary span {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.bz-page-annex > summary b {
  font-size: 15px;
  font-weight: 700;
}

.bz-page-annex > summary small {
  color: var(--bz-text-tertiary);
  font-size: 12px;
}

.bz-page-annex > summary::after {
  color: var(--bz-text-tertiary);
  content: "Show";
  flex: 0 0 auto;
  font-size: 13px;
  font-weight: 600;
  margin-left: auto;
}

.bz-page-annex[open] > summary::after { content: "Hide"; }

.bz-page-annex[open] > summary {
  border-bottom: 1px solid var(--bz-border-subtle);
}

/* The sections inside already carry their own margins; the annex only needs to
   stop the first one from doubling up against the summary border. */
.bz-page-annex-body > :first-child { margin-top: var(--bz-space-4); }

/* ==========================================================================
   39. Invoices and payments

   The cash-payment wizard sits in a two-column grid beside the list of open
   balances. Grid items stretch by default, so the wizard box grew to the
   height of the taller column - 650px for 543px of content - and the browser
   spread the extra 107px between its four rows. The result was a step rail,
   then a gap, then a progress bar floating in the middle of nothing, then the
   one field you actually had to fill in, 250px further down.

   The wizard is now its own height and the space stays at the bottom of the
   column where it does no harm.
   ========================================================================== */

.cashier-mode-panel .two-column-section {
  align-items: start;
}

.bz-inline-wizard {
  align-content: start;
}

/* One line of text - "Step 1 of 3: Invoice" - was being given 97px. */
.cashier-payment-wizard .cpgee-step-meta {
  align-self: start;
}

/* ==========================================================================
   40. Equipment value tile

   "PHP 210,000.00" needs 259px at 28.8px type. The tile it sits in is 214px
   wide and clips its overflow, so the page showed "PHP 210,000" with the last
   83px - the centavos and part of the thousands - cut off at the card edge.
   A figure that is silently truncated is worse than no figure: it reads as a
   smaller number rather than as a mistake.

   Same treatment as the revenue tile in section 34: the type comes down until
   the whole amount fits. An amount is worth less space than a two-digit count,
   not more.
   ========================================================================== */

.ecd-kpis article strong {
  /* The value shares its row with the tile's icon, which is why only 176px of
     the 214px card was available to it. Given the whole width it needs less
     shrinking, and the icon moves up beside the label where it belongs. */
  display: block;
  grid-column: 1 / -1;
  max-width: 100%;
  font-size: clamp(13px, 1.2vw, 24px);
  line-height: 1.15;
  white-space: nowrap;
  overflow-wrap: normal;
  word-break: keep-all;
}

/* ==========================================================================
   41. Things a thumb has to hit

   A finger needs about 44px to hit something reliably, and a lot less than
   that was on offer: the board's action pills were 18px tall, and the
   contract template's eighty placeholder buttons were 30px. On a desktop with
   a mouse those are fine; on a phone they are a guess.

   Only on touch, and only where the control is genuinely pressed - the pills
   that are just labels ("Not moved yet", the priority badge) keep their size,
   because making a label finger-sized would push the real actions off the
   card.
   ========================================================================== */

@media (hover: none) and (pointer: coarse) {
  .board-card-foot a.board-pill,
  .board-card-foot button.board-pill,
  .board-card-foot summary.board-pill {
    min-height: 34px;
    padding: 0 10px;
    align-items: center;
  }

  .board-move-form select {
    min-height: 38px;
  }

  .contract-template-variable-list button {
    min-height: 38px;
    padding: 0 12px;
  }

  /* Anything that reads as a button gets a floor, without touching the
     decorative badges beside them. */
  .inline-actions button,
  .inline-actions .primary-button,
  .inline-actions .secondary-button,
  .button-row button,
  .form-actions button {
    min-height: 40px;
  }
}

/* ==========================================================================
   42. Two colours that were a whisker under

   A contrast sweep over every page as an owner and as a client found nine
   places where text sat below the ratio it needs. Seven were on Gallery
   Branding, which paints its own white cards but was still inheriting the
   product's dark-theme text colours - "Mandatory" was rendering at 1.37:1,
   which is to say invisible. Those are fixed in that screen's own stylesheet.

   These two are the last of them: both close, both fixable by nudging one
   colour rather than redesigning anything.
   ========================================================================== */

/* White on #8b5cf6 measured 4.23:1 against the 4.5:1 small text needs. A
   slightly deeper violet carries the same badge at 5.1:1. */
.bz-plan-flag {
  background: #7c3aed;
}

/* The purple link colour is right on body text but sits at 4.15:1 on the
   darker card these help links live on, beside a field label. */
.cgd-create-field-head a {
  color: #c4a5fb;
}

/* ==========================================================================
   43. The projects table and its side panel

   The projects list sits beside a "Today" panel in a two-column grid, and the
   panel takes a fixed 260-300px. The table itself needs about 910px for its
   seven columns. Below 1320px the layout already stacks, but between 1320px
   and roughly 1520px the panel is present and the table is left with 800px -
   so on a 1440px laptop, the most common screen there is, the last two
   columns (Progress and Actions) were pushed off into a sideways scroll.

   The panel is a summary; the table is the page. It stacks below the list
   until the window is wide enough to hold both properly.
   ========================================================================== */

@media (max-width: 1520px) {
  .project-northstar-main {
    grid-template-columns: minmax(0, 1fr);
  }

  .project-northstar-table-wrap {
    contain: none;
  }
}

/* Same fault as section 43, on Contracts: a 320px side card beside a table
   that needs 1,112px for its nine columns. The layout stacks below 1,180px,
   but between there and about 1,470px the card is present and the table gets
   784px - so on a 1440px laptop three columns sat off the right edge. */
@media (max-width: 1470px) {
  .contracts-grid-layout {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Manage Users: eight columns, 1,670px, in a 1,076px page. Two of the columns
   are multi-select lists that can be narrower without losing anything, and the
   whole row is a form rather than a reading table. */
.managed-users-table select[multiple] {
  min-width: 0;
  max-width: 180px;
}

.managed-users-table .managed-user-access-form {
  min-width: 0;
}

/* ==========================================================================
   44. Opening a photo

   A photo in the gallery grid could not be opened. There was no link on it and
   no viewer, so the only way to see a shot at full size was to go and find the
   file. The thumbnail is now a button that opens the same dialog the equipment
   pages use - already keyboard-closable, already moves focus to the close
   button - and the dialog offers the original in a new tab.
   ========================================================================== */

.media-preview-button {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  border-radius: inherit;
  overflow: hidden;
}

.media-preview-button img {
  display: block;
  width: 100%;
}

/* The hint stays out of the way until the photo is pointed at or focused, so
   it never sits on top of the picture while somebody is looking through them. */
.media-preview-hint {
  position: absolute;
  inset: auto 8px 8px auto;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  border-radius: 999px;
  background: rgba(9, 12, 20, 0.78);
  color: #f1f5f9;
  font-size: 12px;
  font-weight: 700;
  opacity: 0;
  transition: opacity 120ms ease;
}

.media-preview-button:hover .media-preview-hint,
.media-preview-button:focus-visible .media-preview-hint {
  opacity: 1;
}

/* On a touch screen there is no hover, so the hint is always there. */
@media (hover: none) {
  .media-preview-hint { opacity: 1; }
}

.media-preview-hint svg {
  width: 12px;
  height: 12px;
}

.media-lightbox .equipment-lightbox-media img {
  max-height: 78vh;
  width: auto;
  max-width: 100%;
  object-fit: contain;
}

/* ------------------------------------------------------------------ *
 * 45. Search in the menu
 *
 * The top bar is hidden on twenty-two pages, the dashboard among them,
 * so the only "find anything" box on the product did not exist on the
 * page everybody lands on. An owner with ninety-four menu entries had
 * no way to type what he wanted. This puts the same box at the top of
 * the sidebar, which is on every page.
 * ------------------------------------------------------------------ */

.sidebar .global-search.global-search-sidebar {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
  width: calc(100% - 24px);
  min-width: 0;
  max-width: calc(100% - 24px);
  height: auto;
  min-height: 40px;
  margin: 4px 12px 10px;
  padding: 0 10px;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.055);
  border: 1px solid rgba(255, 255, 255, 0.09);
  box-sizing: border-box;
}

.sidebar .global-search.global-search-sidebar:focus-within {
  /* The ring lives on the box, not the borderless input inside it. The old
     focus state was a border going from 9% to 24% white, which measured
     2.1:1; this is 10.5:1 against the sidebar. */
  border-color: var(--bz-focus-ring);
  background: rgba(255, 255, 255, 0.085);
  box-shadow: 0 0 0 3px var(--bz-focus-ring);
}

.sidebar .global-search-sidebar > svg,
.sidebar .global-search-sidebar .command-icon {
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  opacity: 0.72;
}

.sidebar .global-search-sidebar input[type="search"] {
  flex: 1 1 auto;
  width: 100%;
  min-width: 0;
  height: 38px;
  min-height: 38px;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
  color: inherit;
  font-size: 0.86rem;
}

/* The visible box around this input shows the focus ring (see the
   :focus-within rule above), so the input does not draw a second one inside
   it - the sidebar clips anything that overflows. */
.sidebar .global-search-sidebar input[type="search"]:focus,
.sidebar .global-search-sidebar input[type="search"]:focus-visible {
  outline: none;
  box-shadow: none;
}

.sidebar .global-search-sidebar input[type="search"]::placeholder {
  color: rgba(255, 255, 255, 0.55);
}

/* The panel is wider than the sidebar on purpose - a page name plus its
   section does not fit in 200px, and a truncated result is no result. */
.sidebar .global-search-sidebar .global-search-results {
  left: 0;
  right: auto;
  top: calc(100% + 6px);
  width: max(100%, 268px);
  min-width: 0;
  max-height: min(58vh, 460px);
  overflow-y: auto;
  z-index: 140;
}

/* ------------------------------------------------------------------ *
 * 46. Pay, on the person's own page
 *
 * One figure and one button, sized like something you press rather
 * than one cell of a nine-column grid.
 * ------------------------------------------------------------------ */

.bz-person-pay-form {
  display: block;
}

.bz-person-pay-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
}

.bz-person-pay-row > label {
  font-weight: 600;
  flex: 0 0 auto;
}

.bz-person-pay-input {
  display: flex;
  align-items: stretch;
  flex: 0 1 300px;
  min-width: 0;
}

.bz-person-pay-input b {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 12px;
  min-height: 48px;
  border: 1px solid var(--bz-border-strong);
  border-right: 0;
  border-radius: 10px 0 0 10px;
  background: rgba(255, 255, 255, 0.05);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  opacity: 0.85;
}

.bz-person-pay-input input {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 48px;
  margin: 0;
  border-radius: 0 10px 10px 0;
  font-size: 1.15rem;
  font-weight: 600;
}

.bz-person-pay-form button {
  min-height: 48px;
  flex: 0 0 auto;
}

.bz-person-pay-help {
  margin: 10px 0 0;
  font-size: 0.85rem;
  opacity: 0.75;
}

.bz-person-pay .form-help {
  margin-top: 14px;
}

@media (max-width: 640px) {
  .bz-person-pay-row { align-items: stretch; flex-direction: column; }
  .bz-person-pay-input { flex: 1 1 auto; }
  .bz-person-pay-form button { width: 100%; justify-content: center; }
}

/* ------------------------------------------------------------------ *
 * 47. Time & Pay - one page for a worker
 *
 * Attendance, Calendar and Leaves were three menu entries answering one
 * question. The merged page leads with three plain things: am I timed
 * in, when do I work, how many days off do I have left. Everything else
 * folds.
 * ------------------------------------------------------------------ */

.bz-week-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.bz-week-day {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px 16px;
  padding: 10px 14px;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.07);
  background: rgba(255, 255, 255, 0.025);
}

.bz-week-day.is-today {
  border-color: rgba(167, 139, 250, 0.45);
  background: rgba(167, 139, 250, 0.08);
}

.bz-week-day-name {
  flex: 0 0 132px;
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
}

.bz-week-day-name b {
  font-size: 0.95rem;
}

.bz-week-day-name small {
  opacity: 0.6;
}

.bz-week-day-what {
  flex: 0 0 auto;
  font-size: 0.92rem;
}

.bz-week-day.is-rest .bz-week-day-what,
.bz-week-day.is-leave .bz-week-day-what {
  opacity: 0.72;
}

.bz-week-day.is-leave .bz-week-day-what {
  color: #6ee7b7;
  opacity: 1;
}

.bz-week-day-events {
  flex: 1 1 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding-left: 148px;
}

.bz-week-day-events a {
  font-size: 0.8rem;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.05);
  text-decoration: none;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bz-week-day-events a:hover {
  border-color: rgba(255, 255, 255, 0.3);
}

@media (max-width: 640px) {
  .bz-week-day-name { flex-basis: 100%; }
  .bz-week-day-events { padding-left: 0; }
}

/* Days off: one number you can read across the room. */

.bz-timeoff-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 18px;
}

.bz-timeoff-figure {
  display: flex;
  align-items: baseline;
  gap: 12px;
  min-width: 0;
}

.bz-timeoff-figure strong {
  font-size: 2.4rem;
  line-height: 1;
  font-weight: 700;
}

.bz-timeoff-figure span {
  font-size: 0.95rem;
  opacity: 0.8;
  max-width: 260px;
}

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

.bz-timeoff-side .primary-button {
  min-height: 44px;
}

.bz-timeoff-pending {
  margin: 0;
  font-size: 0.85rem;
  color: #fbbf24;
}

.bz-timeoff-all {
  font-size: 0.85rem;
  opacity: 0.85;
}

@media (max-width: 640px) {
  .bz-timeoff-side { width: 100%; }
  .bz-timeoff-side .primary-button { width: 100%; justify-content: center; }
}

/* ------------------------------------------------------------------ *
 * 48. Time & Pay round two: photo clock, warnings, proofs, history,
 * balances-as-rows, and the way back.
 * ------------------------------------------------------------------ */

/* The way back, on pages reached from Time & Pay that hide the top bar. */
.bz-back-strip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 10px 0 6px;
  padding: 10px 16px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.05);
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: none;
  min-height: 40px;
}

.bz-back-strip:hover {
  border-color: rgba(255, 255, 255, 0.3);
}

/* Clock warnings: late, and the overtime line. */
.bz-clock-warning {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 10px 0 0;
  padding: 10px 14px;
  border-radius: 10px;
  font-size: 0.9rem;
  line-height: 1.45;
  max-width: 640px;
}

/* display:flex would beat the hidden attribute; the warning must truly hide
   until its moment comes. */
.bz-clock-warning[hidden] {
  display: none;
}

.bz-clock-warning svg {
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  margin-top: 2px;
}

.bz-clock-warning.is-late {
  background: rgba(251, 191, 36, 0.1);
  border: 1px solid rgba(251, 191, 36, 0.3);
  color: #fcd34d;
}

.bz-clock-warning.is-overtime {
  background: rgba(251, 191, 36, 0.1);
  border: 1px solid rgba(251, 191, 36, 0.3);
  color: #fcd34d;
}

.bz-clock-warning.is-overtime.is-over {
  background: rgba(251, 113, 133, 0.1);
  border-color: rgba(251, 113, 133, 0.35);
  color: #fda4af;
}

.bz-clock-warning a {
  color: inherit;
  text-decoration: underline;
}

/* The photo Time In. */
.bz-clock-photo {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}

.bz-clock-camera {
  width: 220px;
  max-width: 100%;
  border-radius: 14px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.14);
}

.bz-clock-camera video {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  background: #000;
}

.bz-clock-photo-status {
  font-size: 0.8rem;
  opacity: 0.7;
  max-width: 420px;
}

.bz-clock-plainlink {
  border: 0;
  background: none;
  padding: 4px 0;
  color: inherit;
  opacity: 0.65;
  font-size: 0.8rem;
  text-decoration: underline;
  cursor: pointer;
  min-height: 32px;
  text-align: left;
}

.bz-clock-plainlink:hover {
  opacity: 0.95;
}

/* Photo proofs for the manager. */
.bz-proof-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 12px;
}

.bz-proof-card {
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 12px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.025);
  min-width: 0;
}

.bz-proof-card img {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  background: #000;
}

.bz-proof-meta {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 12px;
  min-width: 0;
}

.bz-proof-meta strong {
  font-size: 0.88rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bz-proof-meta small,
.bz-proof-meta a {
  font-size: 0.76rem;
}

.bz-proof-meta .badge {
  font-size: 0.75rem;
  padding: 1px 8px;
}

.bz-proof-nogeo {
  opacity: 0.6;
}

/* A worker's history: one line per day, inside the card. */
.bz-timesheet-filter {
  align-items: end;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 18px;
}

.bz-timesheet-filter label {
  display: grid;
  gap: 6px;
  min-width: 170px;
}

.bz-timesheet-filter input {
  min-height: 42px;
}

.bz-timesheet-summary {
  border-top: 1px solid var(--bz-border-subtle);
  display: flex;
  flex-wrap: wrap;
  gap: 16px 34px;
  margin-top: 20px;
  padding-top: 18px;
}

.bz-timesheet-summary span {
  display: grid;
  gap: 2px;
  min-width: 120px;
}

.bz-timesheet-summary b {
  font-size: 1.3rem;
}

.bz-timesheet-summary small {
  color: var(--bz-text-tertiary);
}

.bz-timesheet-summary .is-warning b {
  color: #fcd34d;
}

/* Pay is the answer people come to a timesheet for, not footnote copy. Keep
   each figure in its own readable card and make the amount earned so far the
   strongest item in the group. */
.payroll-cutoff-panel .payroll-cutoff-grid {
  display: grid;
  gap: 12px;
  grid-template-columns: minmax(0, 1.45fr) repeat(3, minmax(0, 1fr));
}

.payroll-cutoff-panel .payroll-cutoff-grid > article {
  align-content: start;
  background: rgba(255, 255, 255, 0.025);
  border: 1px solid var(--bz-border-subtle);
  border-radius: 12px;
  display: grid;
  gap: 7px;
  min-width: 0;
  padding: 18px;
}

.payroll-cutoff-panel .payroll-cutoff-grid > article > span:first-child {
  color: var(--bz-text-tertiary);
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.payroll-cutoff-panel .payroll-cutoff-grid > article > strong {
  font-size: 1.25rem;
  line-height: 1.15;
}

.payroll-cutoff-panel .payroll-cutoff-grid > article:first-child > strong {
  color: var(--bz-text-primary);
  font-size: clamp(1.65rem, 2.5vw, 2.25rem);
}

.payroll-cutoff-panel .payroll-cutoff-grid > article > small {
  color: var(--bz-text-tertiary);
  line-height: 1.45;
}

@media (max-width: 1100px) {
  .payroll-cutoff-panel .payroll-cutoff-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 640px) {
  .payroll-cutoff-panel .payroll-cutoff-grid {
    grid-template-columns: 1fr;
  }
}

.bz-history-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.bz-history-day {
  display: block;
  padding: 0;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.07);
  background: rgba(255, 255, 255, 0.025);
  min-width: 0;
  overflow: hidden;
}

.bz-history-edit-row {
  align-items: baseline;
  appearance: none;
  background: transparent;
  border: 0;
  color: inherit;
  cursor: pointer;
  display: flex;
  flex-wrap: wrap;
  font: inherit;
  gap: 6px 16px;
  padding: 10px 14px;
  text-align: left;
  width: 100%;
}

.bz-history-edit-row:hover,
.bz-history-edit-row:focus-visible {
  background: rgba(139, 92, 246, 0.12);
  outline: none;
}

.bz-history-edit-row:focus-visible {
  box-shadow: inset 0 0 0 2px rgba(167, 139, 250, 0.8);
}

.bz-history-date {
  flex: 0 0 132px;
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.bz-history-date small {
  opacity: 0.6;
}

.bz-history-what {
  flex: 1 1 320px;
  font-size: 0.92rem;
  min-width: 0;
}

.bz-history-action {
  align-items: center;
  color: #c4b5fd;
  display: inline-flex;
  font-size: 0.78rem;
  font-weight: 700;
  gap: 5px;
  margin-left: auto;
  white-space: nowrap;
}

.bz-history-action svg {
  height: 14px;
  width: 14px;
}

.bz-history-day.is-open .bz-history-what {
  color: #fcd34d;
}

.bz-history-day.is-note .bz-history-what {
  opacity: 0.7;
}

@media (max-width: 640px) {
  .bz-timesheet-filter > * { width: 100%; }
  .bz-history-date { flex-basis: 100%; }
}

/* Leave balances: rows with a little bar, not a wall of cards. */
.bz-balance-rows {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0 0 6px;
}

.bz-balance-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 14px;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.07);
  background: rgba(255, 255, 255, 0.025);
  min-width: 0;
}

.bz-balance-row-name {
  flex: 0 0 190px;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.bz-balance-row-name b {
  font-size: 0.92rem;
}

.bz-balance-row-name small {
  opacity: 0.6;
  font-size: 0.76rem;
}

.bz-balance-row-meter {
  flex: 1 1 auto;
  height: 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.07);
  overflow: hidden;
  min-width: 40px;
}

.bz-balance-row-meter i {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, #34d399, #6ee7b7);
}

.bz-balance-row-days {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  font-size: 0.9rem;
  white-space: nowrap;
}

.bz-balance-row-days strong {
  font-size: 1.05rem;
}

.bz-balance-row-days small {
  color: #fbbf24;
  font-size: 0.75rem;
  white-space: normal;
  text-align: right;
}

.bz-balance-row-days.is-unlimited {
  opacity: 0.75;
}

.bz-balance-none {
  margin: 2px 0 14px;
  font-size: 0.82rem;
  opacity: 0.6;
}

@media (max-width: 640px) {
  .bz-balance-row { flex-wrap: wrap; }
  .bz-balance-row-name { flex-basis: 100%; }
  .bz-balance-row-meter { order: 3; flex-basis: 100%; }
}

/* ------------------------------------------------------------------ *
 * 49. Leave in a lightbox: ask fast, decide fast.
 * ------------------------------------------------------------------ */

.bz-earn-field-split {
  display: flex;
  gap: 12px;
}

.bz-earn-field-split > span {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

/* A field the script has hidden must actually hide, whatever display the
   class sets. */
.bz-earn-field[hidden] {
  display: none;
}

/* The approve/deny queue. */
.bz-approve-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.bz-approve-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px 20px;
  padding: 14px 16px;
  border-radius: 12px;
  border: 1px solid rgba(251, 191, 36, 0.22);
  background: rgba(251, 191, 36, 0.05);
  min-width: 0;
}

.bz-approve-who {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  flex: 1 1 340px;
}

.bz-approve-who strong {
  font-size: 1rem;
}

.bz-approve-who span {
  font-size: 0.9rem;
}

.bz-approve-who em {
  font-size: 0.88rem;
  font-style: italic;
  opacity: 0.85;
}

.bz-approve-who small {
  font-size: 0.78rem;
  opacity: 0.65;
}

.bz-approve-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 0 0 auto;
}

.bz-approve-actions .primary-button,
.bz-approve-actions .secondary-button {
  min-height: 44px;
}

@media (max-width: 640px) {
  .bz-approve-actions { width: 100%; }
  .bz-approve-actions form { flex: 1 1 auto; }
  .bz-approve-actions .primary-button { width: 100%; justify-content: center; }
}

/* ------------------------------------------------------------------ *
 * 50. The owner's dashboard, made honest: one decision list, project
 * rows instead of posters, and lightboxes for the worker's extras.
 * ------------------------------------------------------------------ */

.bz-needs-panel {
  margin: 4px 0 14px;
}

.bz-needs-clear {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  padding: 14px 16px;
  border-radius: 10px;
  background: rgba(52, 211, 153, 0.08);
  border: 1px solid rgba(52, 211, 153, 0.22);
  color: #6ee7b7;
  font-size: 0.95rem;
}

.bz-needs-clear svg { width: 16px; height: 16px; flex: 0 0 auto; }

.bz-needs-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 8px;
}

.bz-needs-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 14px;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.03);
  text-decoration: none;
  min-height: 56px;
}

.bz-needs-row:hover { border-color: rgba(255, 255, 255, 0.28); }

.bz-needs-row strong {
  flex: 0 0 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 40px;
  border-radius: 10px;
  font-size: 1.1rem;
  background: rgba(255, 255, 255, 0.06);
}

.bz-needs-row.tone-red strong { background: rgba(251, 113, 133, 0.14); color: #fda4af; }
.bz-needs-row.tone-amber strong { background: rgba(251, 191, 36, 0.13); color: #fcd34d; }
.bz-needs-row.tone-blue strong { background: rgba(96, 165, 250, 0.13); color: #93c5fd; }
.bz-needs-row.tone-pink strong { background: rgba(244, 114, 182, 0.13); color: #f9a8d4; }
.bz-needs-row.tone-muted strong { opacity: 0.8; }

.bz-needs-row span { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; }
.bz-needs-row span b { font-size: 0.92rem; }
.bz-needs-row span small { font-size: 0.78rem; opacity: 0.65; }
.bz-needs-row > i { flex: 0 0 auto; opacity: 0.5; }
.bz-needs-row > i svg { width: 14px; height: 14px; }

/* Projects as status rows. */
.bz-project-rows { display: flex; flex-direction: column; gap: 6px; }

.bz-project-row {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 10px 14px;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.07);
  background: rgba(255, 255, 255, 0.025);
  text-decoration: none;
  min-height: 54px;
  min-width: 0;
}

.bz-project-row:hover { border-color: rgba(255, 255, 255, 0.28); }

.bz-project-row-name { flex: 1 1 220px; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.bz-project-row-name strong { font-size: 0.92rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bz-project-row-name small { font-size: 0.76rem; opacity: 0.6; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.bz-project-row-stage {
  flex: 0 0 auto;
  font-size: 0.76rem;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.05);
  white-space: nowrap;
}

.bz-project-row-progress { flex: 0 1 180px; display: flex; align-items: center; gap: 8px; min-width: 90px; }
.bz-project-row-progress i { flex: 1 1 auto; height: 7px; border-radius: 999px; background: rgba(255, 255, 255, 0.07); overflow: hidden; }
.bz-project-row-progress em { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, #8b5cf6, #d946ef); }
.bz-project-row-progress b { font-size: 0.8rem; flex: 0 0 auto; }

.bz-project-row-due { flex: 0 0 84px; text-align: right; font-size: 0.8rem; opacity: 0.75; white-space: nowrap; }
.bz-project-row-due.is-late { color: #fda4af; opacity: 1; font-weight: 600; }

@media (max-width: 720px) {
  .bz-project-row { flex-wrap: wrap; }
  .bz-project-row-progress { flex-basis: 100%; }
}

/* Bottom pair. */
.bz-bottom-two { grid-template-columns: 1fr 1fr; }
@media (max-width: 980px) { .bz-bottom-two { grid-template-columns: 1fr; } }

.bz-money-note { margin: 2px 0 8px; font-size: 0.84rem; opacity: 0.75; }

.bz-team-load { display: flex; flex-direction: column; gap: 10px; }
.bz-team-load a { display: flex; align-items: center; gap: 10px; text-decoration: none; min-height: 34px; }
.bz-team-load a span { flex: 0 0 130px; font-size: 0.86rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bz-team-load a .bz-load-track { flex: 1 1 auto; height: 7px; border-radius: 999px; background: rgba(255, 255, 255, 0.07); overflow: hidden; display: block; text-decoration: none; }
.bz-team-load a .bz-load-track b { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, #60a5fa, #818cf8); }
.bz-team-load a .mc-avatar { flex: 0 0 auto; }
.bz-team-load a em { flex: 0 0 auto; font-size: 0.78rem; opacity: 0.75; font-style: normal; white-space: nowrap; }

/* The worker's "more" row: two buttons that open lightboxes. */
.bz-more-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 10px;
  padding: 0;
  background: none;
  border: 0;
}

.bz-more-row button {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.09);
  background: rgba(255, 255, 255, 0.03);
  color: inherit;
  text-align: left;
  cursor: pointer;
  min-height: 64px;
}

.bz-more-row button:hover { border-color: rgba(255, 255, 255, 0.3); }
.bz-more-row button i { flex: 0 0 auto; display: flex; }
.bz-more-row button i svg { width: 18px; height: 18px; opacity: 0.8; }
.bz-more-row button span { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.bz-more-row button span b { font-size: 0.95rem; }
.bz-more-row button span small { font-size: 0.78rem; opacity: 0.65; }

/* A lightbox big enough to hold a whole section. */
.bz-dialog.bz-dialog-wide {
  width: min(1020px, 96vw);
  max-height: 88vh;
  overflow-y: auto;
}

.bz-dialog.bz-dialog-wide .visual-page-shell {
  padding: 0;
  border: 0;
  background: none;
  box-shadow: none;
}

/* Notifications grouped by day. */
.bz-notify-day {
  margin: 14px 0 2px;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.55;
}

.notification-list .bz-notify-day:first-child { margin-top: 0; }

/* ------------------------------------------------------------------ *
 * 51. Hubs: a family of tools on one page, one sentence each.
 * ------------------------------------------------------------------ */

.bz-hub-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 10px;
}

.bz-hub-card {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 16px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.03);
  text-decoration: none;
  min-height: 68px;
}

.bz-hub-card:hover { border-color: rgba(255, 255, 255, 0.3); }
.bz-hub-card i { flex: 0 0 auto; display: flex; margin-top: 2px; }
.bz-hub-card i svg { width: 17px; height: 17px; opacity: 0.8; }
.bz-hub-card span { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.bz-hub-card span b { font-size: 0.95rem; }
.bz-hub-card span small { font-size: 0.8rem; opacity: 0.68; line-height: 1.4; }

/* Creative Suite: the owner sees six products first, then four plain questions. */
.creative-suite-admin__heading { align-items: flex-start; }

.creative-suite-admin__summary {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
}

.creative-suite-admin__summary article {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 16px;
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.035);
}

.creative-suite-admin__summary span,
.creative-suite-admin__summary small,
.creative-suite-product small { color: var(--muted, #a8a7b6); }
.creative-suite-admin__summary span { font-size: 0.76rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; }
.creative-suite-admin__summary strong { font-size: 1.35rem; }
.creative-suite-admin__summary small { font-size: 0.76rem; line-height: 1.35; }

.creative-suite-products {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}

.creative-suite-product {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: 1fr auto;
  gap: 12px;
  min-width: 0;
  padding: 18px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 16px;
  background: linear-gradient(145deg, rgba(139, 92, 246, 0.11), rgba(255, 255, 255, 0.025));
}

.creative-suite-product__icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 12px;
  color: #fff;
  background: linear-gradient(135deg, #8b5cf6, #d91c8c);
}

.creative-suite-product__icon svg { width: 20px; height: 20px; }
.creative-suite-product h3 { margin: 0 0 5px; font-size: 1.05rem; }
.creative-suite-product p { margin: 0 0 8px; line-height: 1.45; }
.creative-suite-product small { display: block; line-height: 1.4; }
.creative-suite-product .secondary-button { grid-column: 1 / -1; justify-content: center; width: 100%; }

.creative-suite-settings {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

.creative-suite-settings__group { margin: 0; }
.creative-suite-settings__group .bz-hub-grid { grid-template-columns: 1fr; }
.creative-suite-settings__title { display: flex; align-items: flex-start; gap: 12px; margin-bottom: 16px; }
.creative-suite-settings__title > span {
  display: grid;
  flex: 0 0 38px;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: rgba(139, 92, 246, 0.18);
  color: #c4b5fd;
  font-weight: 800;
}
.creative-suite-settings__title h2 { margin: 0 0 4px; font-size: 1.08rem; }
.creative-suite-settings__title p { margin: 0; line-height: 1.45; }

@media (max-width: 1050px) {
  .creative-suite-products { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .creative-suite-admin__summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 720px) {
  .creative-suite-products,
  .creative-suite-settings,
  .creative-suite-admin__summary { grid-template-columns: 1fr; }
  .creative-suite-product { padding: 15px; }
}

/* Photos / Videos switch on the merged media page. */
.bz-media-tabs {
  display: flex;
  gap: 8px;
  margin: 4px 0 14px;
}

.bz-media-tabs a,
.bz-media-tabs button {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.04);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.9rem;
  min-height: 42px;
  width: auto;
  height: auto;
  color: inherit;
  font-family: inherit;
  line-height: 1.2;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  box-shadow: none;
}

.bz-media-tabs a.active,
.bz-media-tabs button.active {
  background: rgba(139, 92, 246, 0.18);
  border-color: rgba(167, 139, 250, 0.5);
}

.bz-media-tabs a svg,
.bz-media-tabs button svg { width: 15px; height: 15px; flex: 0 0 auto; }

/* ------------------------------------------------------------------ *
 * 52. Calendar: filter chips in plain sight, and phone feeds.
 * ------------------------------------------------------------------ */

.bz-cal-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 10px 0 4px;
}

/* app.css gives calendar cards display:flex, which beats the browser's
   [hidden]{display:none} - so the kind-filter chips looked like they did
   nothing. Hidden means hidden. */
[data-calendar-card][hidden] { display: none !important; }

/* Worker calendar: the date-jump form is replaced by the plain range label. */
.cal-range-plain {
  align-self: center;
  font-weight: 700;
  padding: 0 10px;
  white-space: nowrap;
}

.bz-cal-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.04);
  color: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  min-height: 38px;
  opacity: 0.45;
}

.bz-cal-chip.is-on { opacity: 1; }
.bz-cal-chip:hover { border-color: rgba(255, 255, 255, 0.3); }

.bz-week-actions { display: flex; gap: 10px; flex-wrap: wrap; }

.bz-feed-block {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0 0 14px;
  padding: 14px 16px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.09);
  background: rgba(255, 255, 255, 0.03);
}

.bz-feed-block > b { font-size: 0.95rem; }
.bz-feed-block > small { opacity: 0.7; }

.bz-feed-copy { display: flex; gap: 8px; margin-top: 6px; }
.bz-feed-copy input {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 0.78rem;
  font-family: ui-monospace, monospace;
  min-height: 42px;
}
.bz-feed-copy .secondary-button { flex: 0 0 auto; min-height: 42px; }

/* ------------------------------------------------------------------ *
 * 53. One person's schedule, in the owner's words.
 * ------------------------------------------------------------------ */

.bz-sched-editor { margin-top: 18px; padding-top: 16px; border-top: 1px solid rgba(255, 255, 255, 0.08); }

.bz-sched-summary { margin: 0 0 14px; font-size: 0.92rem; opacity: 0.85; }

.bz-sched-form { display: flex; flex-direction: column; gap: 16px; }

.bz-sched-row { display: flex; flex-direction: column; gap: 8px; }

.bz-sched-label { font-weight: 600; font-size: 0.88rem; }

.bz-sched-modes { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 10px; max-width: 560px; }

.bz-sched-mode {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.03);
  cursor: pointer;
}

.bz-sched-mode:has(input:checked) { border-color: rgba(167, 139, 250, 0.6); background: rgba(139, 92, 246, 0.1); }
.bz-sched-mode input { margin-top: 3px; }
.bz-sched-mode span { display: flex; flex-direction: column; gap: 2px; }
.bz-sched-mode small { opacity: 0.65; font-size: 0.78rem; }

.bz-sched-times { display: flex; gap: 14px; flex-wrap: wrap; }
.bz-sched-times label { display: flex; flex-direction: column; gap: 4px; font-size: 0.82rem; }
.bz-sched-times input { min-height: 44px; }

.bz-sched-hours { max-width: 130px; min-height: 44px; font-size: 1.05rem; font-weight: 600; }

.bz-sched-days { display: flex; gap: 8px; flex-wrap: wrap; }

.bz-sched-day { position: relative; cursor: pointer; }
.bz-sched-day input { position: absolute; opacity: 0; pointer-events: none; }
.bz-sched-day span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 52px;
  min-height: 44px;
  padding: 0 12px;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.03);
  font-weight: 600;
  font-size: 0.86rem;
  opacity: 0.45;
}
.bz-sched-day input:checked + span {
  opacity: 1;
  border-color: rgba(110, 231, 183, 0.55);
  background: rgba(52, 211, 153, 0.1);
}

.bz-sched-actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.bz-sched-actions .primary-button { min-height: 46px; }
.bz-sched-actions small { opacity: 0.65; }

/* ------------------------------------------------------------------ *
 * 54. What one person can open - sentences and checkboxes.
 * ------------------------------------------------------------------ */

.bz-access-form { display: flex; flex-direction: column; gap: 10px; }

.bz-access-mode {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.03);
  cursor: pointer;
  max-width: 560px;
}

.bz-access-mode:has(input:checked) { border-color: rgba(167, 139, 250, 0.6); background: rgba(139, 92, 246, 0.1); }
.bz-access-mode input { margin-top: 3px; }
.bz-access-mode span { display: flex; flex-direction: column; gap: 2px; }
.bz-access-mode small { opacity: 0.65; font-size: 0.78rem; }

.bz-access-areas {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 8px;
  margin: 4px 0 4px 24px;
}

.bz-access-area {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.09);
  background: rgba(255, 255, 255, 0.02);
  cursor: pointer;
}

.bz-access-area:has(input:checked) { border-color: rgba(110, 231, 183, 0.5); background: rgba(52, 211, 153, 0.07); }
.bz-access-area input { margin-top: 3px; }
.bz-access-area span { display: flex; flex-direction: column; gap: 2px; }
.bz-access-area b { font-size: 0.9rem; }
.bz-access-area small { opacity: 0.62; font-size: 0.76rem; line-height: 1.35; }

@media (max-width: 640px) { .bz-access-areas { margin-left: 0; } }

/* ------------------------------------------------------------------ *
 * 55. Final delivery: the one link that ends a project, floated on the
 *     project hero for staff and client alike.
 * ------------------------------------------------------------------ */

.bz-final-delivery {
  align-items: center;
  border: 1px solid rgba(167, 139, 250, 0.35);
  background: rgba(139, 92, 246, 0.1);
  border-radius: 14px;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 14px;
  padding: 12px 16px;
}

.bz-final-delivery.is-unset {
  background: rgba(255, 255, 255, 0.03);
  border-color: rgba(255, 255, 255, 0.12);
  border-style: dashed;
}

.bz-final-delivery-link {
  align-items: center;
  display: inline-flex;
  flex: 1 1 auto;
  gap: 12px;
  min-width: 0;
  text-decoration: none;
}

.bz-final-delivery-link svg {
  background: rgba(139, 92, 246, 0.22);
  border-radius: 10px;
  flex: 0 0 auto;
  height: 34px;
  padding: 8px;
  width: 34px;
}

.bz-final-delivery-link span {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.bz-final-delivery-link strong { font-size: 0.98rem; }

.bz-final-delivery-link small {
  font-size: 0.78rem;
  opacity: 0.68;
}

.bz-final-delivery-link:hover strong { text-decoration: underline; }

.bz-final-delivery-empty {
  align-items: center;
  display: inline-flex;
  flex: 1 1 auto;
  gap: 10px;
  font-size: 0.88rem;
  opacity: 0.72;
}

.bz-final-delivery-empty svg { height: 16px; width: 16px; }

.bz-final-delivery .secondary-button { flex: 0 0 auto; }

/* ------------------------------------------------------------------ *
 * 56. My Galleries: the three products (FlipGallery, Lightbox Gallery,
 *     VidPlay) offered side by side, not FlipGallery alone.
 * ------------------------------------------------------------------ */

.client-my-galleries-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.client-my-galleries-empty-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  margin-top: 12px;
}

/* ------------------------------------------------------------------ *
 * 57. Hidden means hidden - everywhere.
 *
 * The browser's default [hidden]{display:none} loses to ANY authored
 * display value, so every element that pairs the hidden attribute with
 * display:flex/grid rendered anyway. This bit the clock form, the
 * dashboard project filter, the access areas, the calendar cards, the
 * leave fields... one rule ends the whole class of bug.
 * ------------------------------------------------------------------ */

[hidden] {
  display: none !important;
}

/* ------------------------------------------------------------------ *
 * 57b. Public product landing page.
 *
 * The bare index used to send every visitor directly to a sign-in form.
 * Show the six things Beetzee makes first, then give Upload Link its own
 * clear explanation instead of copying the client dashboard's service pitch.
 * ------------------------------------------------------------------ */

body.bz-public-home {
  background:
    radial-gradient(circle at 50% 6%, rgba(107, 55, 132, 0.34), transparent 34rem),
    linear-gradient(180deg, #0a0810 0%, #05070c 55%, #040509 100%);
  color: #f7f5fb;
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  margin: 0;
  min-height: 100vh;
}

.bz-public-landing {
  margin: 0 auto;
  max-width: 1280px;
  padding: 0 32px 32px;
}

.bz-public-nav {
  align-items: center;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  display: flex;
  justify-content: space-between;
  min-height: 92px;
}

.bz-public-brand {
  display: inline-flex;
  margin: 0;
}

.bz-public-brand img {
  display: block;
  height: auto;
  width: 82px;
}

.bz-public-nav nav,
.bz-public-upload__actions {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.bz-public-nav nav a,
.bz-public-upload__actions a,
.bz-public-footer a {
  margin: 0;
}

.bz-public-hero {
  display: grid;
  gap: 28px;
  padding: 76px 0 28px;
}

.bz-public-hero__head {
  max-width: 760px;
}

.bz-public-hero__head h1,
.bz-public-hero__head p {
  margin: 0;
}

.bz-public-hero__head h1 {
  color: #fff;
  font-size: clamp(2.7rem, 6vw, 5rem);
  letter-spacing: -0.058em;
  line-height: 0.98;
}

.bz-public-hero__head > p:last-child {
  color: #bbb6c5;
  font-size: clamp(1rem, 1.6vw, 1.12rem);
  line-height: 1.6;
  margin-top: 18px;
  max-width: 690px;
}

.bz-public-product-grid {
  gap: 18px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.bz-public-product-card {
  min-height: 410px;
}

/* The generated artwork is the card background, not a thumbnail. Keep it
 * visible through the full service while the lower veil protects the copy. */
.bz-public-product-card > img {
  object-position: center;
}

.bz-public-product-card .cgd-product-card__shade {
  background: linear-gradient(
    180deg,
    rgba(5, 7, 13, 0.04) 0%,
    rgba(5, 7, 13, 0.34) 42%,
    rgba(5, 7, 13, 0.82) 72%,
    rgba(5, 7, 13, 0.92) 100%
  );
}

/* Signed-in service offers use their generated art in the same full-card
 * treatment instead of reading like a small image attached to a dark box. */
.client-gallery-dashboard .cgd-service-card {
  background:
    linear-gradient(90deg, rgba(10, 13, 20, 0.84) 0%, rgba(10, 13, 20, 0.58) 50%, rgba(10, 13, 20, 0.2) 100%),
    var(--cgd-service-bg, linear-gradient(135deg, #1b1229, #0a0f19));
  background-position: center;
  background-size: cover;
}

/* Keep every product row on the same typographic rails even when an eyebrow
 * or description wraps differently. Without these reserved rows, a two-line
 * eyebrow pushed its title below the title beside it. */
.bz-public-product-card .cgd-product-card__body {
  grid-template-rows: 42px minmax(2.2em, auto) minmax(1.65rem, auto) minmax(5.8em, auto) auto;
}

.bz-public-product-card .cgd-product-card__body > i {
  margin-bottom: 0;
}

.bz-public-product-card .cgd-product-card__body > small {
  align-items: flex-end;
  display: flex;
  min-height: 2.2em;
}

.bz-public-product-card .cgd-product-card__body > strong {
  align-self: start;
}

.bz-public-product-card .cgd-product-card__body > em {
  align-self: start;
  min-height: 5.8em;
}

.bz-public-product-card .cgd-product-card__body > span:last-child {
  align-self: end;
}

.bz-public-product-card .cgd-product-card__body > span:last-child svg {
  height: 16px;
  width: 16px;
}

.bz-public-upload {
  background: #0b0f18;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 10px;
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(380px, 1.1fr);
  margin: 34px 0 64px;
  min-height: 470px;
  overflow: hidden;
}

.bz-public-upload__content {
  align-content: center;
  display: grid;
  padding: clamp(30px, 5vw, 64px);
  position: relative;
  z-index: 1;
}

.bz-public-upload__content h2 {
  color: #fff;
  font-size: clamp(2rem, 4vw, 3.35rem);
  letter-spacing: -0.05em;
  line-height: 1.02;
  margin: 8px 0 16px;
  max-width: 10ch;
}

.bz-public-upload__content > p:not(.eyebrow) {
  color: #bbb6c5;
  line-height: 1.6;
  margin: 0;
  max-width: 52ch;
}

.bz-public-upload__content ol {
  display: grid;
  gap: 12px;
  list-style: none;
  margin: 28px 0;
  padding: 0;
}

.bz-public-upload__content li {
  align-items: center;
  display: grid;
  gap: 14px;
  grid-template-columns: 42px 1fr;
}

.bz-public-upload__content li > strong {
  align-items: center;
  background: rgba(139, 92, 246, 0.16);
  border: 1px solid rgba(196, 181, 253, 0.24);
  border-radius: 7px;
  color: #d8b4fe;
  display: inline-flex;
  font-size: 0.72rem;
  height: 36px;
  justify-content: center;
  letter-spacing: 0.08em;
  width: 36px;
}

.bz-public-upload__content li span {
  display: grid;
  gap: 2px;
}

.bz-public-upload__content li b {
  color: #fff;
  font-size: 0.92rem;
}

.bz-public-upload__content li small {
  color: #8f8a9d;
  font-size: 0.78rem;
  line-height: 1.4;
}

.bz-public-upload__art {
  min-height: 100%;
  margin: 0;
  overflow: hidden;
  position: relative;
}

.bz-public-upload__art::after {
  background: linear-gradient(90deg, #0b0f18 0%, rgba(11, 15, 24, 0.76) 17%, transparent 50%);
  content: "";
  inset: 0;
  pointer-events: none;
  position: absolute;
}

.bz-public-upload__art img {
  display: block;
  height: 100%;
  object-fit: cover;
  object-position: 62% center;
  width: 100%;
}

.bz-public-footer {
  align-items: center;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  color: #777381;
  display: flex;
  font-size: 0.78rem;
  justify-content: space-between;
  padding: 24px 0 0;
}

.bz-public-footer a {
  color: #c4b5fd;
  text-decoration: none;
}

@media (max-width: 900px) {
  .bz-public-product-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .bz-public-upload {
    grid-template-columns: 1fr;
  }

  .bz-public-upload__art {
    min-height: 360px;
    order: -1;
  }

  .bz-public-upload__art::after {
    background: linear-gradient(180deg, transparent 52%, #0b0f18 100%);
  }
}

@media (max-width: 760px) {
  .bz-public-landing {
    padding: 0 18px 24px;
  }

  .bz-public-nav {
    min-height: 76px;
  }

  .bz-public-brand img {
    width: 66px;
  }

  .bz-public-nav .primary-button {
    display: none;
  }

  .bz-public-hero {
    padding-top: 48px;
  }

  .bz-public-product-grid {
    grid-template-columns: 1fr;
  }

  .bz-public-product-card {
    min-height: 420px;
  }

  .bz-public-product-card .cgd-product-card__body {
    grid-template-rows: auto;
  }

  .bz-public-product-card .cgd-product-card__body > small,
  .bz-public-product-card .cgd-product-card__body > em {
    min-height: 0;
  }

  .bz-public-upload {
    margin-bottom: 44px;
  }
}

@media (max-width: 520px) {
  .bz-public-upload__art {
    min-height: 270px;
  }

  .bz-public-upload__content {
    padding: 26px 22px 30px;
  }

  .bz-public-upload__actions {
    align-items: stretch;
    flex-direction: column;
  }

  .bz-public-upload__actions a {
    justify-content: center;
  }
}

/* Missing pictures get the quiet placeholder from the global handler. */
img.bz-img-fallback {
  object-fit: contain;
  opacity: 0.8;
}

/* ------------------------------------------------------------------ *
 * 58. Workforce roster: one readable line per person instead of a
 *     nine-column grid of raw inputs.
 * ------------------------------------------------------------------ */

.bz-wf-roster {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.bz-wf-row {
  align-items: center;
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.025);
  border-radius: 12px;
  display: grid;
  gap: 14px;
  grid-template-columns: minmax(160px, 1.2fr) minmax(0, 2fr) minmax(120px, 0.8fr) 28px;
  padding: 12px 16px;
  text-decoration: none;
}

.bz-wf-row:hover {
  border-color: rgba(167, 139, 250, 0.45);
  background: rgba(139, 92, 246, 0.08);
}

.bz-wf-row span {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.bz-wf-row small {
  font-size: 0.76rem;
  opacity: 0.65;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bz-wf-row b {
  font-size: 0.9rem;
}

.bz-wf-pay-unset {
  color: #fbbf24;
}

.bz-wf-open {
  align-items: center;
  justify-content: center;
  opacity: 0.5;
}

.bz-wf-open svg { width: 16px; height: 16px; }

@media (max-width: 760px) {
  .bz-wf-row {
    grid-template-columns: 1fr;
    gap: 6px;
  }

  .bz-wf-open { display: none; }
}

/* Rental wizard: the by-hand item picker folds under the scanner. */
.bz-rental-find-fold {
  border: 1px dashed rgba(255, 255, 255, 0.14);
  border-radius: 12px;
  padding: 10px 14px;
}

.bz-rental-find-fold > summary {
  align-items: center;
  cursor: pointer;
  display: flex;
  gap: 8px;
  font-size: 0.88rem;
  font-weight: 600;
  opacity: 0.8;
}

.bz-rental-find-fold > summary svg { width: 15px; height: 15px; }

.bz-rental-find-fold[open] { padding-bottom: 14px; }

/* ------------------------------------------------------------------ *
 * 59. Contracts hub: All / Signed / Templates tabs, sortable signed
 *     list, templates grouped by use.
 * ------------------------------------------------------------------ */

.bz-contract-hub-tabs { margin: 2px 0 16px; }

.bz-signed-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.bz-signed-row {
  align-items: center;
  background: rgba(255, 255, 255, 0.025);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  display: grid;
  gap: 14px;
  grid-template-columns: minmax(0, 2fr) minmax(140px, 1.2fr) minmax(110px, 1fr) minmax(110px, 0.8fr);
  padding: 12px 16px;
  text-decoration: none;
}

.bz-signed-row:hover {
  border-color: rgba(167, 139, 250, 0.45);
  background: rgba(139, 92, 246, 0.08);
}

.bz-signed-row span {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.bz-signed-row small {
  font-size: 0.75rem;
  opacity: 0.62;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bz-signed-row b { font-size: 0.88rem; }

.bz-template-group { margin-bottom: 18px; }

.bz-template-group > h3 {
  font-size: 0.95rem;
  margin: 0 0 8px;
  opacity: 0.85;
}

@media (max-width: 760px) {
  .bz-signed-row { grid-template-columns: 1fr; gap: 6px; }
}

/* --------------------------------------------------------------------------
   45. Repairs to section 7 and the 12px floor, 21 August 2026
   --------------------------------------------------------------------------
   The pass that raised every control to 44px and gave everything one focus
   ring was checked by measuring numbers and never by looking at a screen.
   Three things went out looking wrong. All three are one mistake repeated:
   a rule was written for a control on its own, without asking what the
   control sits inside.
   -------------------------------------------------------------------------- */

/* 45.1  A chip must never be stretched by a taller neighbour.
   The tab strips are flex rows and were left at the default alignment, which
   stretches every item to the height of the tallest. On a window where one
   chip wrapped to two lines, every other chip grew with it - and because
   these chips are drawn with a 999px corner radius, a 42px pill became a
   140px ellipse. Pin them to their own height instead. */
.button-tabs,
.bz-media-tabs,
.bz-home-tabs,
.project-detail-tabs,
.client-nav-tabs,
.bz-tab-strip {
  align-items: center;
}

.button-tabs > a,
.button-tabs > button,
.bz-media-tabs > a,
.bz-media-tabs > button,
.bz-home-tabs > a,
.bz-home-tabs > button,
.project-detail-tabs > a,
.project-detail-tabs > button,
.client-nav-tabs > a,
.client-nav-tabs > button,
.bz-tab-strip > a,
.bz-tab-strip > button {
  align-self: center;
  flex: 0 0 auto;
}

/* 45.2  One focus ring, not two.
   Some fields are drawn as a box with a borderless input inside it, and the
   box already lights up when the field is focused. Section 7 then drew a
   second ring on the input itself, so the sign-in fields showed two hard
   rings, one inside the other. Where the box carries the ring, the input
   must not. Every wrapper listed here is checked below to still show a ring
   of its own - the ring is moved, never removed. */
.login-input-wrap input:focus-visible,
.global-search input:focus-visible,
.global-search-sidebar input:focus-visible,
.project-member-search input:focus-visible,
.cal-search input:focus-visible,
.contract-search input:focus-visible,
.mc-search input:focus-visible,
.client-gallery-search input:focus-visible {
  outline: none;
}

/* 45.3  And the ring the box does draw was a flat slab of pale lilac laid
   over the brand. Keep it clearly visible - the 1px edge is the full ring
   colour, which is what carries the contrast - but let the glow behind it be
   the brand purple rather than a second opaque band. */
.login-input-wrap:focus-within,
.global-search:focus-within,
.global-search-sidebar:focus-within,
.project-member-search:focus-within {
  border-color: var(--bz-focus-ring);
  box-shadow: 0 0 0 3px rgba(160, 61, 255, 0.42), 0 8px 24px rgba(92, 44, 180, 0.22);
}

/* 45.4  Tick boxes and radios were left as the browser draws them, which on a
   near-black page is a pale grey slab with no relation to anything else on
   screen - clearly visible in the sign-in screenshot. Draw them properly:
   an empty box with a visible edge, the brand colour and a tick when on.
   The 44px press target still lives on the surrounding label. */
input[type="checkbox"],
input[type="radio"] {
  appearance: none;
  -webkit-appearance: none;
  background: var(--bz-bg-input, #151519);
  border: 1.5px solid rgba(255, 255, 255, 0.34);
  cursor: pointer;
  display: inline-grid;
  flex: none;
  height: 20px;
  margin: 0;
  place-content: center;
  position: relative;
  transition: background 0.14s ease, border-color 0.14s ease;
  width: 20px;
}

input[type="checkbox"] { border-radius: 6px; }
input[type="radio"] { border-radius: 50%; }

input[type="checkbox"]:hover:not(:disabled),
input[type="radio"]:hover:not(:disabled) {
  border-color: rgba(255, 255, 255, 0.55);
}

input[type="checkbox"]:checked,
input[type="radio"]:checked {
  background: var(--bz-brand-500, #8740ff);
  border-color: var(--bz-brand-500, #8740ff);
}

/* The tick is drawn rather than typed, so it lines up at any size. */
input[type="checkbox"]:checked::after {
  border: solid #fff;
  border-width: 0 2px 2px 0;
  content: "";
  height: 9px;
  margin-top: -2px;
  transform: rotate(45deg);
  width: 5px;
}

input[type="radio"]:checked::after {
  background: #fff;
  border-radius: 50%;
  content: "";
  height: 8px;
  width: 8px;
}

input[type="checkbox"]:indeterminate {
  background: var(--bz-brand-500, #8740ff);
  border-color: var(--bz-brand-500, #8740ff);
}

input[type="checkbox"]:indeterminate::after {
  background: #fff;
  content: "";
  height: 2px;
  width: 10px;
}

input[type="checkbox"]:disabled,
input[type="radio"]:disabled {
  cursor: not-allowed;
  opacity: 0.45;
}

/* A tick box and its words should sit on the same line, centred against each
   other. Several were floating above their own label. */
label:has(> input[type="checkbox"]),
label:has(> input[type="radio"]) {
  align-items: center;
}

/* 45.5  Date, time and file pickers were also left as the browser draws them:
   black-on-white boxes reading "mm/dd/yyyy" in the middle of a dark form, and
   a grey "Choose File" button. Give them the same skin as every other field. */
input[type="date"],
input[type="datetime-local"],
input[type="time"],
input[type="month"],
input[type="week"],
input[type="file"] {
  background: var(--bz-bg-input, #151519);
  border: 1px solid var(--bz-border-default, rgba(255, 255, 255, 0.11));
  border-radius: var(--bz-radius-md, 10px);
  color: var(--bz-text-primary, #f4f2f7);
  font: inherit;
  font-size: var(--bz-text-body, 14px);
  min-height: var(--bz-control-height, 44px);
  /* 48.10  A date field carries its own idea of how narrow it may be - about
     257px in this browser - and that beats the 100% below. In a three-column
     form on a laptop each column is 237px, so the right-hand 20px of every
     "Starts at" and "Expires at" field, the part with the little calendar in
     it, was drawn outside the field and under whatever came next. */
  min-width: 0;
  padding: 0 12px;
  width: 100%;
}

input[type="file"] {
  align-items: center;
  display: flex;
  padding: 0 12px;
}

/* The browser's own "Choose File" button inside a file field. */
input[type="file"]::file-selector-button {
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid var(--bz-border-default, rgba(255, 255, 255, 0.14));
  border-radius: 8px;
  color: var(--bz-text-primary, #f4f2f7);
  cursor: pointer;
  font: inherit;
  font-size: 13px;
  margin-right: 12px;
  min-height: 32px;
  padding: 0 12px;
}

input[type="file"]::file-selector-button:hover {
  background: rgba(255, 255, 255, 0.14);
}

/* The small calendar and clock glyphs the browser draws are black by default,
   which is invisible on this background. */
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="datetime-local"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator,
input[type="month"]::-webkit-calendar-picker-indicator,
input[type="week"]::-webkit-calendar-picker-indicator {
  cursor: pointer;
  filter: invert(1) brightness(1.6);
  opacity: 0.75;
}

/* 45.6  A form inside a lightbox was still laid out in three columns, so on a
   dialog narrower than the page the last column ran off the right-hand edge -
   the corrected-time-in field was cut in half. Inside a dialog the form
   follows the dialog's width, not the window's. */
dialog .form-grid,
dialog .settings-grid,
dialog .bz-form-grid {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
}

dialog .form-grid > *,
dialog .settings-grid > *,
dialog .bz-form-grid > * {
  min-width: 0;
}

dialog input,
dialog select,
dialog textarea {
  max-width: 100%;
}

/* --------------------------------------------------------------------------
   46. What a look at every page turned up, 21 August 2026
   --------------------------------------------------------------------------
   A crawl of every page as all six kinds of account, at desktop and phone
   width, opening every lightbox, found 1,709 things that measured fine and
   looked wrong. They fall into six groups, and each group is one rule.
   -------------------------------------------------------------------------- */

/* 46.1  The logo at the top of the menu was 120px tall on every page.
   It sits in a full-height flex column, so with nothing telling it otherwise
   it stretched to fill whatever space was going. Found 618 times - once on
   every page, for every account, at every width. */
.brand,
.brand-logo-only {
  align-self: center;
  flex: none;
}

/* 46.2  The same fault on ordinary buttons. A row of buttons is a flex row,
   so the moment one of them wrapped to two lines the rest grew to match -
   and a button drawn with a 999px corner became an ellipse. Seen at 98x111
   and 74x134 on the projects pages. A button is as tall as its own words
   plus its own padding, never as tall as its neighbour. */
.primary-button,
.secondary-button,
.bz-btn,
.row-action,
.chip-button {
  align-self: center;
}

/* A button that is meant to fill its row says so, and keeps doing it. */
.primary-button.full,
.secondary-button.full,
.bz-btn.full,
.form-actions > .full {
  align-self: stretch;
}

/* 46.3  Dropdowns were left as the browser draws them: its own arrow, its own
   idea of spacing, and on some machines its own background. Give them the
   same skin as every other field, with the arrow drawn in rather than
   inherited. (A dropdown that is deliberately hidden behind a search box
   keeps its own rules - those are hidden from sight, not styled.) */
select:not(.is-searchable-native) {
  appearance: none;
  -webkit-appearance: none;
  background-color: var(--bz-bg-input, #151519);
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5 6 6.5l5-5' stroke='%23b9b4c4' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-position: right 12px center;
  background-repeat: no-repeat;
  background-size: 12px 8px;
  border: 1px solid var(--bz-border-default, rgba(255, 255, 255, 0.14));
  border-radius: var(--bz-radius-md, 10px);
  color: var(--bz-text-primary, #f4f2f7);
  cursor: pointer;
  font: inherit;
  font-size: var(--bz-text-body, 14px);
  padding-right: 34px;
}

/* The list that drops down is drawn by the browser, not by this stylesheet,
   so the only way to make it dark is to tell the browser the page is dark.
   That is set once on :root; this repeats it for the control itself, because
   a few browsers only look at the element. */
select:not(.is-searchable-native),
select:not(.is-searchable-native) option {
  color-scheme: dark;
}

select:not(.is-searchable-native) option {
  background: var(--bz-bg-surface, #1b1b1f);
  color: var(--bz-text-primary, #f4f2f7);
}

/* 46.4  Things running off the edge of a lightbox.
   A lightbox is narrower than the page, and content built for the page did
   not know that: the step markers along the top of the contract wizard ran
   80px past the edge, and the quotation items table 83px. Let the steps wrap
   and give a wide table its own sideways scroll, inside the box. */
dialog .bz-wizard,
dialog .bz-wizard-steps,
dialog .wizard-steps {
  flex-wrap: wrap;
  row-gap: var(--bz-space-3, 8px);
}

dialog .bz-wizard-step {
  flex: 0 1 auto;
  max-width: 100%;
}

dialog table {
  max-width: 100%;
}

dialog .table-wrap,
dialog .bz-table-scroll {
  max-width: 100%;
  overflow-x: auto;
}

/* A long word with nowhere to break - a file path, an email address - was
   pushing the whole box wider rather than wrapping. */
dialog p,
dialog li,
dialog td,
dialog th,
dialog label {
  overflow-wrap: break-word;
}

/* 46.5  A tick box floating above the words it belongs to. The label is a
   flex row; without an alignment it lines up on the text baseline, which
   puts a 20px box 14px too high next to two lines of text. */
label:has(input[type="checkbox"]),
label:has(input[type="radio"]),
.check-row,
.check-card {
  align-items: center;
}

/* 46.6  The search results panel in the menu was wider than the menu, so its
   right-hand edge was cut off by the sidebar. Found on 100 page views. */
.global-search-results,
#sidebar-search-results {
  box-sizing: border-box;
  max-width: 100%;
}

.global-search-results a {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 46.7  A table heading sitting past the end of its own row, which clipped
   the last column's title. The heading had padding added to it after its
   width was worked out. */
table th,
table td {
  box-sizing: border-box;
}

/* --------------------------------------------------------------------------
   47. A round thing must be round, 21 August 2026
   --------------------------------------------------------------------------
   The pass that made every press target at least 44px tall checked its work
   at phone width and nowhere else. On a phone the small month grid gives each
   day about 50px of width, so a 44px height is a circle. On a desktop the
   same grid sits in a narrow column and gives each day 33px - and 33 wide by
   44 tall, drawn with a 999px corner, is an oval. Today's date has been an
   egg on every desktop since.

   The rule is the general one: a control drawn as a circle must take its
   height from its width, not from a number typed somewhere else.
   -------------------------------------------------------------------------- */
.cal-mini-month b,
.cal-mini-month a {
  align-items: center;
  aspect-ratio: 1;
  display: flex;
  justify-content: center;
  /* Width decides height now, so the height floor would only fight it. The
     press target is still comfortable: this grid is never narrower than the
     column it sits in, which is 33px on a desktop and about 50px on a phone. */
  min-height: 0;
  padding-top: 0;
}

.cal-mini-month a {
  flex-direction: column;
  gap: 1px;
}

/* On a phone there is room, so take it - back over the 44px mark. */
@media (max-width: 900px) {
  .cal-mini-month b,
  .cal-mini-month a {
    min-height: 44px;
  }
}

/* 47.1  A tick box in a grid was being stretched sideways to fill its column -
   26px wide by 20 tall, so a square box was a rectangle - and sat 14px above
   the words next to it, because the label is a two-row grid and the box was
   pinned to the first row. Hold it to its own size and centre it against the
   whole label. */
input[type="checkbox"],
input[type="radio"] {
  align-self: center;
  justify-self: center;
  max-width: 20px;
  min-width: 20px;
}

/* ==========================================================================
   48. The middle widths, 22 August 2026

   Every earlier look at this site was taken at two sizes: a wide desktop and a
   phone. A laptop window sits between them, and between them is where the
   page tore. At 1024-1280px the menu is still open and still 224px wide, so
   the page has around 780px to work in - and the top of the team page insists
   on 941px, because a search box in it has a hard 360px floor and the buttons
   beside it are forbidden to shrink. Nothing was allowed to give, so the whole
   dark panel slid off the right edge and took the tiles, the calendar button
   and half the "Projects" count with it. The heading was crushed into a 200px
   gutter and broke into four lines: "Team / workload / and / assignments".

   The rule underneath it: a row that cannot shrink must be allowed to wrap.
   ========================================================================== */

/* 48.1  A single-column grid gets an invisible column sized to its widest
   child, and that column ignores the width of the box it is in. One oversized
   thing inside therefore pushes the entire page sideways. minmax(0, 1fr) says
   the column may be as narrow as the page needs. */
.team-command-page,
.staff-control-dashboard {
  grid-template-columns: minmax(0, 1fr);
}

/* 48.2  The title and the buttons beside it sat on one unbreakable line. Let
   the buttons drop underneath when the line runs out, and give the title room
   to be a title - it needs about 320px before it starts stacking words. */
.staff-hero {
  flex-wrap: wrap;
}

/* Stated as a width, not as a flex-basis. Below 900px this row is turned into
   a column, and in a column a flex-basis is a HEIGHT - so "320px" there meant a
   320px-tall title block with a gulf of empty space under the words. A minimum
   width means the same thing in both directions. */
.staff-hero > :first-child {
  min-width: min(320px, 100%);
}

/* The row of buttons takes whatever width is left. Without this it shrank to
   fit its own content and then wrapped inside itself while empty space sat
   beside it - two buttons stacked with room for four. */
.staff-hero-actions {
  flex: 1 1 auto;
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* 48.3  The search box asked for 360px and would not go below it, so on a
   laptop it took the room the two buttons needed and pushed them onto lines of
   their own. It may now shrink, but it does not grab spare room either: the
   three of them fit on one line together, which is the point of putting them
   on one line. Section 11 stops the buttons being squeezed narrower than their
   labels; that still holds, because they wrap rather than shrink. */
.staff-search {
  min-width: min(320px, 100%);
}

/* 48.4  The hint at the end of that box said "Find a person Directory" with
   nothing between the two, in a different typeface, so it read as one broken
   sentence. It is a hint about where the link goes, so make it look like a
   hint and sit it at the far end. */
.staff-search kbd {
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: var(--bz-radius-xs, 4px);
  color: var(--bz-text-tertiary, #a9a8b7);
  font-family: inherit;
  font-size: 11px;
  letter-spacing: 0.04em;
  margin-left: auto;
  padding: 2px 7px;
  text-transform: uppercase;
  white-space: nowrap;
}

/* 48.5  A staff card in the team directory is a two-column grid: a picture,
   then the name and what they are doing. The picture column was fixed at 38px
   and the picture is 58px, so every face overlapped the name beside it by 20px.
   The column now takes the size of whatever is in it. */
.team-directory-card {
  grid-template-columns: auto minmax(0, 1fr);
}

/* The two counts now sit together on their own line under the name, instead of
   being dealt into the grid one per column. */
.team-directory-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  grid-column: 1 / -1;
}

.team-directory-tags em {
  white-space: nowrap;
}

/* 48.6  The little ring-and-bars charts. The ring is a fixed 132px circle and
   the bars sat beside it in whatever was left - 160px on a laptop - while the
   bars themselves refuse to go under 268px. So the bar and the number beside
   it were drawn 108px outside the panel: the reader saw a label, a line
   running off the edge, and no figure at all. Let the bars drop under the ring
   when the two do not fit, and let the columns give when they must. */
.visual-donut-wrap {
  flex-wrap: wrap;
}

.visual-lines {
  /* A minimum WIDTH, not a flex-basis. Below 900px this wrap is turned into a
     column, where a basis is a height - so the bars were given 240px of height
     and only 135px of width, and the labels went back to being cut off. The
     same mistake this file warns about in section 48.27, made here first. */
  flex: 1 1 auto;
  min-width: min(240px, 100%);
}

.visual-lines > span {
  grid-template-columns: minmax(0, 0.65fr) minmax(40px, 1fr) auto;
}

/* 48.7  The four counts across the top of Projects. Each one is a 44px icon
   and whatever is left, and on a laptop what is left is 94px - so every label
   was cut off with three dots: "Active proje...", "Due this we...", "Needs
   appr...", "Behind sch...". A row of numbers whose labels you cannot read is
   a row of numbers. Two short lines say the whole word, so let them wrap.
   The same for the date range under "Due this week", which was the one place
   the cut hid real information rather than a word you could guess. */
.project-northstar-kpi small,
.project-northstar-kpi em {
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
}

/* Below about a 900px window the tiles are already two across and there is
   room again, so this only changes the crowded middle. */

/* 48.8  The filter row above the projects table. Between 821px and 1320px it
   was switched from a wrapping row into a fixed six-column grid whose columns
   add up to more than the row is ever given once the menu is open: a search box
   held at 320px, three dropdowns held at 132px each - and the dropdowns
   themselves insist on 136px, so each one hung 4px over its own column. The
   last column collapsed to nothing and the "Filters" button was pushed off the
   right-hand edge, where it could not be pressed.

   A row of controls should wrap, which is what it does at every other width.
   The rule that measured the window forgot the 224px of menu beside it. */
@media (min-width: 821px) and (max-width: 1320px) {
  .project-northstar-toolbar {
    display: flex;
    flex-wrap: wrap;
  }

  .project-northstar-search {
    flex: 1 1 260px;
  }

  .project-northstar-count {
    justify-self: auto;
    margin-left: auto;
  }
}

/* 48.9  A button must look like a button wherever it is put.

   About fifteen rules in the stylesheet say "every link inside this list is a
   two-column grid: a picture, then the words". That is right for the rows of
   the list. It is wrong for the button that sits underneath the list when the
   list is empty, and that button is a link too. On the projects page it made
   "Open the calendar" 98px wide with its label dealt into a 58px picture
   column and told never to wrap - so the button read "Open the c" and the rest
   was drawn over whatever was beside it.

   Buttons are declared inline-flex where they are defined. This puts them back
   to that, after any list rule has had its say. */
/* Written twice over so it outranks the list rules, which are one class more
   specific than a plain button class on its own. */
body :is(.primary-button, .secondary-button, .danger-button, .bz-button):is(.primary-button, .secondary-button, .danger-button, .bz-button) {
  display: inline-flex;
  grid-template-columns: none;
}

/* 48.11  A button in a form is given its width by the column it lands in, not
   by how long its label is. Buttons are told never to wrap, so "Save rental
   branch profile" - which needs 249px - was drawn inside a 237px pill: the
   little disc icon sat outside the pill on the left and the word "profile" ran
   out the right-hand side. Same for "Archive plan permanently".

   Everywhere else a button sizes itself, and nowrap is right there. Here the
   column decides, so the label must be allowed a second line. It only takes
   one when it does not fit. */
.form-grid > button,
.form-grid > .primary-button,
.form-grid > .secondary-button,
.form-grid > .danger-button {
  grid-column: 1 / -1;
  justify-self: start;
}

/* Anywhere the width still comes from outside the button, a second line is
   better than a label drawn outside its own pill. */
.form-grid > label > button {
  white-space: normal;
}

/* 48.12  Every heading row on the site is a title on the left and buttons on
   the right, on one line that was not allowed to break. Below about 1300px,
   with the menu taking 224px, there is no longer room for both, and it is
   always the title that gives: "Recent checklist items" was pressed into 153px
   and came out as four stacked words, and "Beetzee Gallery Branding" into
   264px. The buttons never gave an inch, because a button that shrinks stops
   reading as a button.

   So let the row break instead. The title keeps at least 260px - about six or
   seven words on a line - and the buttons drop underneath when that is all
   there is. Below 760px they already stack; this covers everything above it. */
/* Named by what they are rather than one by one, because there are dozens of
   them across the site and they were written by different hands: -head,
   -header, -heading, -hero, in both dash and double-underscore spellings. */
.acd-hero,
.acd-panel-head,
.board-card-dialog-head,
.board-column-head,
.board-dialog-panel-head,
.bz-page-header,
.bz-section-header,
.bz-sub-hero,
.bz-wizard-head,
.cal-modal-head,
.cgd-create-field-head,
.cgd-section-head,
.client-gallery-info-head,
.contract-client-list-head,
.contract-document-head,
.contract-side-head,
.contract-template-editor-head,
.cpgee-chat-embed-head,
.cpgee-production-card-head,
.drive-preview-head,
.equipment-lightbox-head,
.equipment-selected-heading,
.gallery-branding-manager__hero,
.gallery-branding-manager__section-heading,
.gallery-color-manager__hero,
.gallery-color-manager__section-heading,
.gallery-template-manager__hero,
.gallery-template-manager__section-heading,
.google-map-picker__head,
.mc-hero,
.payment-panel-head,
.project-hero,
.project-hero-progress-top,
.project-northstar-header,
.project-northstar-rail-head,
.project-northstar-rail-subhead,
.project-stage-panel-head,
.quotation-card-head,
.rental-equipment-qr-head,
.section-heading,
.settings-hero,
.signature-module-head,
.staff-panel-head,
.studio-section-head,
.visual-panel-head,
.workspace-panel-head {
  /* align-content decides what happens to the space between wrapped lines. Left
     alone it is "stretch", which pulls two lines apart to fill whatever height
     the box has and leaves a hole down the middle. Keep them together. */
  align-content: flex-start;
  flex-wrap: wrap;
}

/* The title side keeps 240px before the row breaks - roughly five or six words
   on a line. It is stated as a minimum WIDTH rather than a flex-basis, because
   several of these rows are turned into columns on a phone, and in a column a
   flex-basis is a height. It is not allowed to grow either, so nothing that
   fits today moves. Only a block holding the words gets the floor; a row that
   starts with an icon or a photograph is left alone.

   Named one by one rather than by a pattern in the name: a first pass used
   [class*="-hero"], which also caught .mc-hero-actions - a row of buttons with
   no title in it at all - and left a 380px hole under it on a phone. */
.acd-hero > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.acd-panel-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.board-card-dialog-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.board-column-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.board-dialog-panel-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.bz-page-header > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.bz-section-header > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.bz-sub-hero > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.bz-wizard-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.cal-modal-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.cgd-create-field-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.cgd-section-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.client-gallery-info-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.contract-client-list-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.contract-document-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.contract-side-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.contract-template-editor-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.cpgee-chat-embed-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.cpgee-production-card-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.drive-preview-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.equipment-lightbox-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.equipment-selected-heading > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.gallery-branding-manager__hero > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.gallery-branding-manager__section-heading > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.gallery-color-manager__hero > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.gallery-color-manager__section-heading > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.gallery-template-manager__hero > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.gallery-template-manager__section-heading > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.google-map-picker__head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.mc-hero > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.payment-panel-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.project-hero > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.project-hero-progress-top > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.project-northstar-header > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.project-northstar-rail-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.project-northstar-rail-subhead > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.project-stage-panel-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.quotation-card-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.rental-equipment-qr-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.section-heading > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.settings-hero > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.signature-module-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.staff-panel-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.studio-section-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.visual-panel-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]),
.workspace-panel-head > :first-child:is(div, hgroup, header):not([class*="icon"]):not([class*="avatar"]) {
  min-width: min(240px, 100%);
}

/* 48.13  Two buttons side by side in a two-column panel were each given
   172px, and "Open page=payments" needs 176 - so three pixels of the last
   letter were drawn outside the button. Same cause as 48.11: the column sets
   the width, so the label must be free to take a second line. */
:is(.responsive-grid, .bz-grid, .two-column-section) > :is(button, .primary-button, .secondary-button, .danger-button) {
  white-space: normal;
}

/* 48.14  A small button was left as plain inline text with padding around it.
   Padding on inline text does not push the lines apart, so the button was
   drawn over the line above it - the "Not done" button sat on top of the word
   "Search". Small buttons are buttons. */
:is(.primary-small, .secondary-small, .danger-small) {
  align-items: center;
  display: inline-flex;
  gap: 6px;
  justify-content: center;
  vertical-align: middle;
}

/* 48.15  The single commonest way this site tore sideways.

   When a box is a grid and nobody says how many columns it has, the browser
   makes one - and that one column is as wide as the widest thing inside it,
   whatever the box itself measures. So a card 169px wide, holding a line of
   text 219px wide, quietly draws that line 50px into the card beside it. Two
   headings on top of each other, a price written over a name, a panel sliding
   off the right of the page: all the same thing.

   This says the invented column may be as narrow as the box that holds it. It
   changes nothing about a grid whose columns are written down - only the ones
   the browser had to guess, which is where the guess was wrong. */
main :where(*) {
  grid-auto-columns: minmax(0, auto);
}

/* 48.16  What a button should do when there is not enough room, decided once.

   Section 10 stopped buttons wrapping, because in a row of buttons they were
   being squashed narrower than their own words: "Add member" came out as
   "Add / member". That was the right problem and the wrong cure. Never
   wrapping means that when something else decides the width - a form column,
   a two-across panel - the label is simply drawn outside the button, and half
   a dozen pages had a word hanging off the end of its pill.

   The two cases want opposite things, and they can be told apart:

     in a row  - refuse to be squashed, and the label then always fits
     in a cell - fill the cell, and take a second line if the words need it

   flex-shrink is only read in a row; white-space is what matters in a cell.
   So both are stated, and each applies where it means something. */
button,
.primary-button,
.secondary-button,
.danger-button,
.bz-button,
a.primary-button,
a.secondary-button {
  flex-shrink: 0;
  white-space: normal;
}

/* Anything built to hold a whole sentence keeps wrapping, as before. */
.bz-clock-button,
.station-start,
button.allow-wrap {
  flex-shrink: 1;
}

/* 48.17  The "there is nothing here yet" block is a stack: a circle, a line
   saying what is missing, a sentence explaining it, and a button. Where one of
   these sits inside a list that is itself laid out in columns, it inherited
   those columns and dealt its four parts across them - so on the equipment page
   the button landed in a 117px column and wrapped, with 567px of empty room
   beside it. It is always one column. */
/* Written twice over: the list rules that caught it are a class more specific
   than a single class name on its own. */
.bz-empty.bz-empty {
  grid-template-columns: minmax(0, 1fr);
}

/* 48.18  On a phone the account chip and the "Menu" button were both pinned to
   the top of the screen, and the chip was allowed to stretch to within 76px of
   the left edge - straight over the Menu button, which is 115px wide. The
   result on every page was your own name written across the menu button and no
   photo visible at all. Leave the button its corner. */
@media (max-width: 520px) {
  body:not(.login-screen) .topbar-account-floating {
    max-width: calc(100vw - 152px);
  }
}

/* 48.19  The step strip of a wizard shown inside a side panel - "1 Invoice,
   2 Cash, 3 Receipt" - is 446px of chevrons in a 361px panel, so it became a
   thing you had to scroll sideways to read, and step 3 was a bare number with
   no word next to it. In a dialog these already wrap onto a second line.
   Do the same here: two rows you can read beat one row you cannot. */
.bz-inline-wizard .bz-wizard-steps {
  flex-wrap: wrap;
  overflow-x: visible;
  row-gap: var(--bz-space-2, 6px);
}

/* 48.20  A form is three columns wide, and drops to one below a 760px window.
   That measurement is of the window, and the menu takes 224px of it, so on a
   768px screen a form was still three columns - of 126px each. A tick box and
   the words beside it need more than that, and "Promotions enabled" came out
   with the last letters over the edge.

   Two columns fills the gap. Above 1000px nothing changes. */
@media (max-width: 1000px) {
  .form-grid,
  .compact-form-grid,
  .bz-form-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* 48.21  A tick box row is a box and a label on one line, and it stays on one
   line. Letting it wrap put the box on a line of its own with a 123px hole
   under it, which is worse than the five pixels it was meant to save. The
   words wrap inside their own half instead. */
.check-row > * {
  min-width: 0;
}

/* 48.22  The date line under a project - "No due date / Schedule pending" -
   was told never to wrap, in a 96px column. The words that fit are the words
   that fit. */
.project-northstar-table td[data-label="Due"] > small,
.project-northstar-table small.tone-muted {
  white-space: normal;
}

/* 48.23  The preview toolbar on the colours page is two dropdowns and a button
   in three fixed columns; on a narrow screen the button's column was 66px, so
   "Update preview" came out over six lines, one word tall. Let the row wrap
   and let each control keep a workable width. */
.gallery-color-manager__preview-toolbar,
.gallery-template-manager__preview-toolbar {
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}

/* 48.24  A page split into a wide half and a narrow half, where the narrow
   half insists on 290px. Once the menu has taken its 224px there is only 452px
   left on a small laptop or a tablet, so the wide half became 148px - narrower
   than the half that was meant to be narrow - and the "Add equipment" button
   inside it could not fit its own second word. Below 1000px the two halves go
   one above the other, as they already do on a phone. */
@media (max-width: 1000px) {
  .ecd-layout,
  .cal-layout,
  .rental-workspace-grid,
  .gallery-color-manager__layout,
  .gallery-template-manager__layout {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* 48.25  This page's own stylesheet loads after this one and sets the same
   three columns again, so the correction has to be written a shade more
   precisely to be heard. */
form.gallery-color-manager__preview-toolbar,
form.gallery-template-manager__preview-toolbar {
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}

/* 48.26  On a phone, every field inside a form is stretched to the full width
   of the screen so it is comfortable to tap. That rule was written for boxes
   you type in, and it caught tick boxes and radio buttons too - so on a phone
   a tick box was a 336px purple slab across the page, and the words next to it
   were pushed off the right-hand side entirely. Twenty pixels is a tick box at
   any screen size; the label beside it is what should have the room. */
body:not(.login-screen) :is(input[type="checkbox"], input[type="radio"]) {
  flex: 0 0 20px;
  max-width: 20px;
  min-width: 20px;
  width: 20px;
}

/* 48.27  A note, not a rule, because the fixes are in app.css where the faults
   were: search this file and app.css for "a basis is a height".

   Two search boxes and a row of buttons stood 320px, 360px and 560px tall on a
   phone, each holding one 44px line adrift in an empty panel. All three said
   `flex: 1 1 <n>px`, which means "start at n and share out what is left". In a
   row that n is a width. In a column it is a HEIGHT - and all three of these
   are turned into columns on a small screen.

   Anywhere a width is what is meant, say min-width, which means the same thing
   whichever way the box is facing. The same mistake was made once in this file
   too, on the team page, and is noted there. */

/* ==========================================================================
   49. The logo that was never there, 22 August 2026

   Three <link rel="icon"> tags and the mark at the top of the menu all pointed
   at assets/beetzee-logo.png. That file has never existed in this repository,
   so every page load asked the server for it twice and got nothing twice, and
   the top of the menu showed a grey picture-frame - the stand-in this stylesheet
   puts in place of any broken image, which had been quietly covering it up.

   Until a logo is uploaded on Settings, the name is written in words instead.
   ========================================================================== */

.brand-wordmark-text {
  color: var(--bz-text-primary, #f4f2f7);
  display: inline-block;
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.01em;
  line-height: 1.1;
  padding: var(--bz-space-2, 6px) 0;
}

.login-logo-mark.brand-wordmark-text {
  font-size: 30px;
}

/* 49.1  Five money tiles across the top of the dashboard, in five columns that
   never change count. On a laptop each is 170px, and section 34 above quite
   rightly forbids a peso figure to break mid-number - so instead of breaking,
   "PHP 753,210.00" was simply cut off at the tile's edge. Cutting a number is
   worse than wrapping one: the reader cannot tell it happened.

   The number still refuses to break. The tiles now fit themselves to the room,
   four across where five will not go. */
.mc-metrics {
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}

/* ==========================================================================
   50. Putting a day right, and the time nobody approved, 22 August 2026

   The owner could not time out. The screen said "Attendance could not be
   updated. Please try again." and nothing else, so nobody - not him, not the
   person he would have asked - could find out what was actually wrong. His
   words: "cant logout... let the admin edit this person's login and out...
   the aim is to edit and oversee clearly, cleanly and easily."

   Two things had to be visible on the page, not behind a link:

     1. The day itself, editable, with a reason written against the change.
     2. Time worked past the shift end that nobody approved. He was blunt
        about the rule: "if disapproved, it should still be recorded but put
        the error there." So it is recorded and it is paid at nothing, and the
        row says so rather than quietly dropping the hours or quietly paying
        them.

   The row that needs attention is marked with a stripe down its leading edge
   and nothing else. A filled row would be a painted box, which is the thing
   the owner asked to be rid of on the home screen a day earlier, and the
   stripe survives a colour-blind reader and a printed page where a pale fill
   does not.
   ========================================================================== */

#correct-a-day tr.is-unapproved > td:first-child {
  border-inline-start: 3px solid var(--bz-danger, #e5484d);
  padding-inline-start: calc(var(--bz-space-3, 10px) - 3px);
}

.bz-unapproved-note {
  color: var(--bz-danger, #e5484d);
  display: block;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.35;
  margin-top: 2px;
}

/* The note below a name is a sentence, and a sentence set four words wide is a
   column of confetti. The name column is given room to hold one, and the date
   beside it is never broken across lines - "Sat 22 Aug" stacked three high is
   the same mistake in the next column along. */
#correct-a-day td:first-child {
  min-width: 12rem;
}

/* The two figures are never broken across lines. "0h 00m" stacked two high
   pushes the Save button off the right-hand edge of the table, and a button
   you have to scroll sideways to find is not "easy to control", which is the
   whole of what was asked for. The day itself is not a column at all: both
   screens that draw this table show exactly one day, and the heading above
   already names it. */
#correct-a-day td:nth-child(4),
#correct-a-day td:nth-child(5),
#correct-a-day th:nth-child(4),
#correct-a-day th:nth-child(5),
#correct-a-day td:last-child {
  white-space: nowrap;
}

/* The two times and the reason sit in a table row, so they must not stretch it
   taller than the rows around them. tabular-nums keeps 09:05 and 17:30 the
   same width, which is what lets the eye run down the column. */
#correct-a-day input[type="time"] {
  font-variant-numeric: tabular-nums;
  min-width: 6rem;
  padding-block: var(--bz-space-2, 6px);
}

#correct-a-day input[name="reason"] {
  min-width: 9rem;
  padding-block: var(--bz-space-2, 6px);
  width: 100%;
}

/* Each row's form holds nothing but hidden fields and sits between the heading
   and the table. It must take up no room at all, whatever a later rule decides
   forms should look like. */
#correct-a-day > form {
  display: contents;
}

/* ==========================================================================
   51. cpgeeUpload: the link you hand round a room, 23 August 2026

   The subscriber's side of cpgeeUpload. The guest's side carries its own
   styling inside app/cpgeeupload_ui.php and deliberately loads nothing at all -
   it is opened by somebody who has never heard of beetzee, on a phone, on
   whatever signal a function room has.

   What the rows here have to do is make the address easy to take away. That is
   the whole reason somebody opens this page: they have made the link already,
   they came back to copy it. So the address is a field you press once to
   select, sized to show a whole link rather than the first third of one.
   ========================================================================== */

.bz-copy-field {
  background: var(--bz-bg-elevated, #14192a);
  border: 1px solid var(--bz-border, #262c40);
  border-radius: var(--bz-radius-sm, 8px);
  color: var(--bz-text-primary, #f4f2f7);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px;
  /* Small, and told to fill whatever the column gives it. A minimum wide
     enough to show a whole address made the table wider than the panel and
     pushed the last button off the edge - a button nobody can press. */
  min-width: 8rem;
  padding: var(--bz-space-2, 6px) var(--bz-space-3, 10px);
  width: 100%;
}

.bz-copy-field:focus {
  border-color: var(--bz-accent, #8f74ff);
  outline: none;
}

/* A closed link stays on the list on purpose - it is a thing that happened and
   somebody will ask about it. It reads quieter than a live one so the eye goes
   to the links that still work. */
tr.is-muted-row > td {
  opacity: 0.62;
}

/* The three things you can do to a link sit on one line and do not stack into
   a tower on a laptop. Laid out, not left to the whitespace between inline
   elements: the form around "Close it" carried a form's own padding and made
   the row wider than the panel it sits in, which put that button half off the
   right-hand edge. */
.bz-row-actions {
  align-items: center;
  display: flex;
  gap: var(--bz-space-2, 6px);
  justify-content: flex-end;
  white-space: nowrap;
}

/* The name of the event, and the address, each get room to be read on one
   line. Squeezed columns pushed "Close it" off the right-hand edge of the
   table on a laptop, which is a button you cannot press. */
#cpgeeupload td:first-child {
  min-width: 10.5rem;
}

/* The three things you can do to a link, on one line, and never wider than
   the panel they sit in. */
#cpgeeupload .bz-row-actions .secondary-button {
  padding-inline: var(--bz-space-3, 10px);
}

#cpgeeupload td:nth-child(2) {
  width: 100%;
}

.cpgeeupload-link-cards {
  display: grid;
  gap: var(--bz-space-4, 16px);
  margin-top: var(--bz-space-4, 16px);
}

.cpgeeupload-link-card {
  align-items: center;
  background: var(--bz-bg-elevated, #101522);
  border: 1px solid var(--bz-border, #2a3042);
  border-radius: var(--bz-radius-lg, 14px);
  display: grid;
  gap: var(--bz-space-5, 20px);
  grid-template-columns: minmax(0, 1fr) 156px;
  padding: var(--bz-space-5, 20px);
}

.cpgeeupload-link-card.is-closed {
  opacity: .68;
}

.cpgeeupload-link-card__content {
  display: grid;
  gap: var(--bz-space-4, 16px);
  min-width: 0;
}

.cpgeeupload-link-card__heading {
  align-items: start;
  display: flex;
  gap: var(--bz-space-3, 10px);
  justify-content: space-between;
}

.cpgeeupload-link-card__heading h3,
.cpgeeupload-link-card__heading p {
  margin: 0;
}

.cpgeeupload-link-card__heading p,
.cpgeeupload-link-card__address,
.cpgeeupload-link-card__closed {
  color: var(--bz-text-secondary, #aaa5b5);
  font-size: 13px;
}

.cpgeeupload-link-card__address {
  display: grid;
  font-weight: 700;
  gap: var(--bz-space-2, 6px);
}

.cpgeeupload-link-card__actions {
  flex-wrap: wrap;
  justify-content: flex-start;
}

.cpgeeupload-link-card__qr {
  align-items: center;
  background: #fff;
  border: 1px solid rgba(255, 255, 255, .14);
  border-radius: 12px;
  color: #17131f;
  cursor: pointer;
  display: grid;
  font: inherit;
  font-size: 12px;
  font-weight: 800;
  gap: 4px;
  justify-items: center;
  padding: 8px;
}

.cpgeeupload-link-card__qr img {
  display: block;
  height: auto;
  image-rendering: pixelated;
  max-width: 100%;
}

.cpgeeupload-link-card__qr:focus-visible {
  outline: 3px solid var(--bz-accent, #8f74ff);
  outline-offset: 3px;
}

.cpgeeupload-qr-dialog {
  max-width: min(560px, calc(100vw - 32px));
}

.cpgeeupload-qr-print-card {
  align-items: center;
  background: #fff;
  border-radius: 16px;
  color: #15111c;
  display: flex;
  flex-direction: column;
  padding: clamp(24px, 5vw, 44px);
  text-align: center;
}

.cpgeeupload-qr-print-card h2 {
  color: inherit;
  margin: 0;
}

.cpgeeupload-qr-print-card p {
  color: #5f5868;
  margin: 10px 0 24px;
  max-width: 34ch;
}

.cpgeeupload-qr-print-card img {
  display: block;
  height: auto;
  image-rendering: pixelated;
  max-width: min(100%, 420px);
}

.cpgeeupload-qr-print-card small {
  color: #5f5868;
  margin-top: 18px;
  overflow-wrap: anywhere;
}

.cpgeeupload-qr-dialog__actions {
  display: flex;
  gap: var(--bz-space-3, 10px);
  justify-content: flex-end;
  margin-top: var(--bz-space-4, 16px);
}

.cpgeeupload-qr-dialog__actions form {
  margin: 0;
  padding: 0;
}

@media (max-width: 700px) {
  .cpgeeupload-link-card {
    grid-template-columns: 1fr;
  }

  .cpgeeupload-link-card__qr {
    justify-self: start;
    width: 156px;
  }
}

@media print {
  body.cpgeeupload-qr-printing * {
    visibility: hidden !important;
  }

  body.cpgeeupload-qr-printing .cpgeeupload-qr-dialog.is-printing,
  body.cpgeeupload-qr-printing .cpgeeupload-qr-dialog.is-printing .cpgeeupload-qr-print-card,
  body.cpgeeupload-qr-printing .cpgeeupload-qr-dialog.is-printing .cpgeeupload-qr-print-card * {
    visibility: visible !important;
  }

  body.cpgeeupload-qr-printing .cpgeeupload-qr-dialog.is-printing {
    background: #fff;
    border: 0;
    box-shadow: none;
    display: block;
    inset: 0;
    margin: 0;
    max-height: none;
    max-width: none;
    padding: 0;
    position: absolute;
    width: 100%;
  }

  body.cpgeeupload-qr-printing .cpgeeupload-qr-print-card {
    border-radius: 0;
    min-height: 100vh;
    justify-content: center;
  }

  body.cpgeeupload-qr-printing .bz-dialog-dismiss,
  body.cpgeeupload-qr-printing .cpgeeupload-qr-dialog__actions {
    display: none !important;
  }
}

.bz-row-actions > * {
  /* Never squeezed narrower than their own words. "Close it" set on two lines
     is a button that looks broken. */
  flex: 0 0 auto;
}

.bz-row-actions > form {
  margin: 0;
  padding: 0;
}

/* One field under another, not three across.
   The house form grid puts fields in columns, which is right for a settings
   screen with twelve of them. Here there are four, one of them a web address
   and one of them a whole sentence to agree to - in three columns the address
   showed "https://drive.google.c" and the sentence became an eleven-line
   tower beside an empty half of the box. */
#cpgeeupload-new-dialog .form-grid,
.bz-dialog[id^="cpgeeupload-edit-"] .form-grid {
  grid-template-columns: 1fr;
}

/* A tick box with a sentence beside it, not a bare box with a word. This one
   is a promise about a folder beetzee cannot see, so it has to read like a
   sentence somebody is agreeing to. */
.bz-check-row {
  align-items: start;
  display: flex;
  gap: var(--bz-space-3, 10px);
  line-height: 1.45;
}

.bz-check-row > input[type="checkbox"] {
  flex: 0 0 auto;
  margin-top: 3px;
  /* A tick box a thumb can find. The browser default is about 13px. */
  height: 18px;
  width: 18px;
}

/* Internal payment recording should read like a receipt form, not like a
   dashboard tile grid. One payment method per row keeps every label readable
   in the project dialog and on the cashier page. */
.admin-payment-dialog {
  background: #ffffff;
  color: #111827;
  max-width: min(720px, calc(100vw - 32px));
}

.admin-payment-dialog .bz-dialog-head h2,
.admin-payment-dialog .bz-dialog-head p,
.admin-payment-dialog .eyebrow,
.admin-payment-dialog label,
.admin-payment-dialog legend {
  color: #111827;
}

.admin-payment-dialog .muted,
.admin-payment-dialog small {
  color: #64748b;
}

.admin-payment-dialog .bz-dialog-dismiss button {
  background: #f8fafc;
  border-color: #d8d9e6;
  color: #475569;
}

.admin-payment-dialog .bz-dialog-dismiss button:hover {
  background: #eef2ff;
  color: #111827;
}

.admin-payment-dialog .admin-payment-form {
  gap: 18px;
}

.admin-payment-method-grid,
.cashier-quick-payment-form .admin-payment-method-grid {
  display: grid;
  grid-template-columns: 1fr !important;
  gap: 10px;
}

.admin-payment-method-option {
  align-items: center;
  display: grid !important;
  gap: 14px;
  grid-template-columns: 48px minmax(0, 1fr) 20px;
  min-height: 76px;
  padding: 14px 16px;
  text-align: left;
  width: 100%;
}

.admin-payment-method-option input[type="radio"] {
  opacity: 0 !important;
  pointer-events: none !important;
  position: absolute !important;
}

.admin-payment-method-option .payment-method-icon {
  flex: 0 0 48px;
  height: 48px;
  width: 48px;
}

.admin-payment-method-copy {
  display: block;
  flex: 1 1 auto;
  min-width: 0;
  text-align: left;
}

.admin-payment-method-copy strong,
.admin-payment-method-copy small {
  display: block;
  max-width: 100%;
  overflow-wrap: break-word;
  text-align: left;
  white-space: normal;
  writing-mode: horizontal-tb !important;
  word-break: normal;
}

.admin-payment-method-copy strong {
  line-height: 1.2;
}

.admin-payment-method-copy small {
  line-height: 1.35;
}

.admin-payment-method-check {
  align-self: center;
  display: block;
  height: 18px;
  margin-left: 0;
  width: 18px;
}

.cashier-bill-picker {
  display: grid;
  gap: 8px;
}

.cashier-bill-picker > label {
  color: #f8fafc;
  font-weight: 850;
}

.cashier-bill-picker input[type="search"] {
  min-height: 52px;
  width: 100%;
  border: 1px solid #d8d9e6;
  border-radius: 8px;
  background: #ffffff;
  color: #111827;
  font-size: 1rem;
  font-weight: 800;
  padding: 0 14px;
}

.cashier-bill-picker input[type="search"]::placeholder {
  color: #64748b;
}

.cashier-bill-picker input[type="search"]:focus {
  border-color: #7c3aed;
  box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.22);
  outline: none;
}

.cashier-bill-results {
  display: grid;
  gap: 8px;
  max-height: 360px;
  overflow: auto;
}

.cashier-bill-result {
  align-items: center;
  border: 1px solid #d8d9e6;
  border-radius: 8px;
  background: #ffffff;
  color: #111827;
  cursor: pointer;
  display: grid;
  gap: 12px;
  grid-template-columns: minmax(0, 1fr) auto;
  min-height: 72px;
  padding: 14px 16px;
  text-align: left;
  width: 100%;
}

.cashier-bill-result:hover,
.cashier-bill-result:focus-visible,
.cashier-bill-result.is-selected {
  border-color: #7c3aed;
  box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.14);
  outline: none;
}

.cashier-bill-result span {
  display: grid;
  gap: 4px;
  min-width: 0;
}

.cashier-bill-result strong,
.cashier-bill-result b,
.cashier-bill-result small {
  display: block;
  line-height: 1.25;
  max-width: 100%;
  overflow-wrap: break-word;
  white-space: normal;
  writing-mode: horizontal-tb !important;
  word-break: normal;
}

.cashier-bill-result strong,
.cashier-bill-result b {
  color: #111827;
  font-weight: 850;
}

.cashier-bill-result small {
  color: #64748b;
  font-size: 0.8rem;
  font-weight: 750;
}

.cashier-bill-empty {
  border: 1px dashed #334155;
  border-radius: 8px;
  color: #a7b0c4;
  margin: 0;
  padding: 14px 16px;
}

@media (max-width: 720px) {
  .cashier-bill-result {
    grid-template-columns: 1fr;
  }
}

.admin-payment-dialog input,
.admin-payment-dialog select,
.admin-payment-dialog textarea {
  background: #ffffff !important;
  border-color: #cbd5e1 !important;
  color: #0f172a !important;
  color-scheme: light;
}

.admin-payment-dialog input::placeholder,
.admin-payment-dialog textarea::placeholder {
  color: #94a3b8 !important;
}

.admin-payment-dialog input:focus,
.admin-payment-dialog select:focus,
.admin-payment-dialog textarea:focus {
  border-color: #7c3aed !important;
  box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.22) !important;
  outline: none;
}

.project-anchor-target {
  display: block;
  height: 0;
  scroll-margin-top: 96px;
}

/* Value-first public creation: shape and preview the product before sign-in. */
.bz-public-creation-page {
  min-height: 100vh;
  background: radial-gradient(circle at 55% 0%, rgba(126, 64, 178, .28), transparent 38%), #090a10;
  background-attachment: fixed;
  background-position: center;
  background-size: cover;
  color: #f7f5fb;
}

.bz-public-creation-page--flipgallery {
  background-image: linear-gradient(90deg, rgba(7, 8, 14, .96), rgba(7, 8, 14, .78)), url("../client-product-flipgallery-v2.webp");
}
.bz-public-creation-page--lightbox_gallery {
  background-image: linear-gradient(90deg, rgba(7, 8, 14, .96), rgba(7, 8, 14, .78)), url("../client-product-gallery-v2.webp");
}
.bz-public-creation-page--drive_video {
  background-image: linear-gradient(90deg, rgba(7, 8, 14, .96), rgba(7, 8, 14, .78)), url("../client-product-vidplay-v2.webp");
}
.bz-public-creation-page--upload_link {
  background-image: linear-gradient(90deg, rgba(7, 8, 14, .96), rgba(7, 8, 14, .78)), url("../public-upload-link-feature-v1.webp");
}

.bz-public-creation-shell { width: min(1180px, calc(100% - 32px)); margin: 0 auto; }
.bz-public-creation-main { padding: 34px 0 54px; }
.bz-public-creation-main .cgd-standalone-page { max-width: 980px; margin: 0 auto; }

.bz-public-creation-return { transform: translateY(8px); }

.cgd-create-page--flipgallery {
  background-image: linear-gradient(rgba(11, 12, 22, .9), rgba(11, 12, 22, .96)), url("../client-product-flipgallery-v2.webp");
}
.cgd-create-page--lightbox_gallery {
  background-image: linear-gradient(rgba(11, 12, 22, .9), rgba(11, 12, 22, .96)), url("../client-product-gallery-v2.webp");
}
.cgd-create-page--drive_video {
  background-image: linear-gradient(rgba(11, 12, 22, .9), rgba(11, 12, 22, .96)), url("../client-product-vidplay-v2.webp");
}
.cgd-create-page--upload_link {
  background-image: linear-gradient(rgba(11, 12, 22, .9), rgba(11, 12, 22, .96)), url("../public-upload-link-feature-v1.webp");
}
.cgd-create-page[class*="cgd-create-page--"] { background-position: center; background-size: cover; }

/* The artwork belongs to the page canvas. Keep the creation workspace clear
   so it does not repeat the same image as a second rectangular background. */
.bz-public-creation-page .cgd-create-page[class*="cgd-create-page--"] {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
}

.cgd-creation-preview {
  position: relative;
  isolation: isolate;
  min-height: 310px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 10px;
  padding: clamp(24px, 5vw, 52px);
  border: 1px solid rgba(232, 227, 239, .55);
  border-radius: 18px;
  background-position: center;
  background-size: cover;
  box-shadow: 0 24px 70px rgba(0, 0, 0, .38);
}

.cgd-creation-preview::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg, rgba(4, 5, 11, .08), rgba(4, 5, 11, .95));
}

.cgd-creation-preview--flipgallery { background-image: url("../client-product-flipgallery-v2.webp"); }
.cgd-creation-preview--lightbox_gallery { background-image: url("../client-product-gallery-v2.webp"); }
.cgd-creation-preview--drive_video { background-image: url("../client-product-vidplay-v2.webp"); }
.cgd-creation-preview--upload_link { background-image: url("../public-upload-link-feature-v1.webp"); }

.cgd-creation-preview h3 {
  max-width: 760px;
  margin: 0;
  color: #fff;
  font-size: clamp(30px, 5vw, 56px);
  line-height: 1.02;
}

.cgd-creation-preview p { max-width: 680px; margin: 0; color: rgba(255, 255, 255, .82); font-size: 15px; }
.cgd-creation-preview[data-preview-model] {
  cursor: default;
  pointer-events: none;
  user-select: none;
}
.cgd-creation-preview__action {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  padding: 10px 14px;
  border: 1px solid rgba(255, 255, 255, .32);
  border-radius: 999px;
  background: rgba(12, 10, 20, .66);
  color: #fff;
  font-weight: 750;
}
.cgd-creation-preview__action small {
  color: rgba(255, 255, 255, .6);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.cgd-preview-model-note {
  margin: 10px 0 0;
  color: rgba(232, 226, 245, .7);
  font-size: 12px;
  text-align: center;
}

.cgd-preview-signin {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-top: 16px;
  padding: 18px;
  border: 1px solid rgba(232, 227, 239, .35);
  border-radius: 14px;
  background: rgba(20, 20, 28, .88);
}

.cgd-preview-signin strong, .cgd-preview-signin p { flex-basis: 100%; margin: 0; }
.bz-dialog--creation { width: min(1000px, calc(100vw - 28px)); max-width: 1000px; }
.bz-dialog--creation .cgd-standalone-page { margin: 0; border: 0; box-shadow: none; }

@media (max-width: 720px) {
  .bz-public-creation-shell { width: min(100% - 18px, 1180px); }
  .bz-public-creation-main { padding-top: 18px; }
  .cgd-creation-preview { min-height: 250px; padding: 24px; }
}

/* Product creation always has exactly four cpgeeSteps. Keep those four steps
   in one equal-width row even where the generic inline-wizard rule wraps
   side-panel processes for readability. */
body:not(.login-screen) .cgd-create-page .bz-wizard-steps {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  overflow: visible;
}

body:not(.login-screen) .cgd-create-page .bz-wizard-step {
  min-width: 0;
  white-space: normal;
  width: 100%;
}

.bz-expense-filters,
.bz-expense-forecast .form-grid,
.bz-scheduled-expenses .form-grid,
.bz-pnl-paper .form-grid {
  align-items: end;
}

.bz-accounting-details {
  margin-top: 16px;
  border: 1px solid rgba(148, 163, 184, .22);
  border-radius: 8px;
  background: rgba(15, 23, 42, .42);
}

.bz-accounting-details > summary {
  cursor: pointer;
  padding: 14px 16px;
  color: #f8fafc;
  font-weight: 800;
}

.bz-accounting-details .form-grid {
  padding: 0 16px 16px;
}

.bz-expense-tracker td small,
.bz-scheduled-expenses td small,
.bz-expense-forecast td small {
  display: block;
  margin-top: 4px;
  color: rgba(226, 232, 240, .66);
  line-height: 1.35;
}

.bz-pnl-paper {
  background: #fff;
  color: #111827;
}

.bz-pnl-paper .muted,
.bz-pnl-paper small {
  color: #64748b;
}

.bz-pnl-paper h3 {
  margin: 18px 0 8px;
  color: #111827;
  font-size: 16px;
}

.bz-pnl-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(260px, 340px);
  gap: 18px;
}

.bz-pnl-paper table {
  color: #111827;
}

.bz-pnl-paper td:last-child {
  width: 180px;
  text-align: right;
  font-weight: 800;
}

.bz-pnl-paper details > summary {
  cursor: pointer;
  font-weight: 800;
}

.bz-pnl-paper .panel-card {
  position: sticky;
  top: 16px;
  align-self: start;
  border: 1px solid #dbe3ef;
  background: #f8fafc;
  color: #111827;
}

.bz-pnl-paper .panel-card p {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  margin: 0;
  padding: 10px 0;
  border-bottom: 1px solid #e2e8f0;
}

.bz-pnl-paper .panel-card p:last-child {
  border-bottom: 0;
}

@media (max-width: 900px) {
  .bz-pnl-layout {
    grid-template-columns: 1fr;
  }

  .bz-pnl-paper .panel-card {
    position: static;
  }
}

@media print {
  .bz-pnl-paper {
    background: #fff !important;
    color: #111 !important;
    box-shadow: none !important;
  }

  .bz-pnl-paper form,
  .bz-pnl-paper .secondary-button {
    display: none !important;
  }
}
