
@media (min-width: 768px) and (max-width: 1279px) {
  .dashboard-desktop-only {
    display: none;
  }

  .dashboard-tablet-only {
    display: block;
  }

  .workspace-page-dashboard {
    gap: 1rem;
  }

  .workspace-page-dashboard .workspace-topbar,
  .workspace-page-dashboard .workspace-panel,
  .workspace-page-dashboard .dashboard-panel,
  .workspace-page-dashboard .workspace-metric-card,
  .workspace-page-dashboard .dashboard-metric-card {
    padding: 1rem;
  }

  .workspace-page-dashboard .workspace-metric-strip-compact {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
  }

  .workspace-page-dashboard-clients .dashboard-metrics-row {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.875rem;
  }

  .workspace-page-dashboard-clients .dashboard-summary-grid,
  .workspace-page-dashboard-clients .dashboard-two-col {
    grid-template-columns: repeat(1, minmax(0, 1fr));
  }

  .dashboard-tablet-tabs .workspace-tab-strip {
    flex-wrap: nowrap;
    overflow-x: auto;
    padding-bottom: 0;
    gap: 0.625rem;
  }

  .dashboard-tablet-tabs .workspace-tab-button {
    flex: 0 0 auto;
    justify-content: center;
    min-height: 2.75rem;
    padding-left: 0.875rem;
    padding-right: 0.875rem;
    text-align: center;
  }

  .dashboard-tablet-tabs .workspace-tab-panel {
    padding-top: 1rem;
  }

  .dashboard-tablet-stack .workspace-panel,
  .dashboard-tablet-stack .dashboard-panel {
    min-width: 0;
  }

  .dashboard-tablet-stack .workspace-fact-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    margin-top: 1rem;
    gap: 0.75rem;
  }

  .dashboard-tablet-stack .dashboard-position-list,
  .dashboard-tablet-stack .workspace-list {
    margin-top: 1rem;
  }

  .workspace-page-dashboard-clients .dashboard-hero {
    gap: 0.75rem;
    padding-top: 1rem;
    padding-bottom: 1rem;
  }

  .workspace-page-dashboard-clients .dashboard-hero-value {
    font-size: clamp(2.2rem, 6vw, 3rem);
  }

  .workspace-page-dashboard-clients .dashboard-composition-card-body {
    grid-template-columns: 14rem minmax(0, 1fr);
  }

  .workspace-page-dashboard-clients .dashboard-composition-chart-area {
    padding: 1.25rem 1rem;
    border-right-width: 1px;
    border-bottom-width: 0;
  }

  .workspace-page-dashboard-clients .dashboard-composition-chart-area .dashboard-donut-chart {
    height: 12.5rem;
    width: 12.5rem;
  }

  .workspace-page-dashboard-clients .dashboard-composition-row {
    flex-direction: row;
    align-items: center;
    gap: 0.75rem;
  }

  .workspace-page-dashboard-clients .dashboard-composition-data {
    gap: 0.875rem;
  }

  .workspace-page-dashboard-clients .dashboard-composition-col {
    min-width: 4.5rem;
  }

  .workspace-page-dashboard-partners .workspace-funnel-summary {
    width: 100%;
    min-width: 0;
  }

  .workspace-page-dashboard-partners .workspace-funnel-strip {
    gap: 0.875rem;
  }

  .workspace-page-dashboard-partners .workspace-funnel-step-card {
    padding: 1rem;
    gap: 0.875rem;
  }

  .workspace-page-dashboard-partners .workspace-funnel-value {
    font-size: clamp(1.85rem, 4vw, 2.35rem);
  }

  .workspace-page-dashboard-partners .chart-bar-container {
    height: 180px;
    gap: 0.75rem;
    padding-top: 0.75rem;
    padding-bottom: 0.75rem;
  }

  .workspace-page-dashboard-partners .chart-bar-track {
    max-width: 40px;
  }

  .workspace-page-dashboard-admin .workspace-fact-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .workspace-page-dashboard-admin .dashboard-bar-list {
    margin-top: 1rem;
  }
}

/* Wave 279.B — banner persistente exibido no painel cliente quando o cadastro
   esta vencido. Renderizado pelo ViewComponent RegistrationExpiredBanner via
   _LayoutApp.cshtml; some fora da area "clients" e quando cadastro esta em dia. */
.app-banner-registration-expired {
  background-color: var(--color-diff-old, #fef2f2);
  border-bottom: 1px solid var(--color-error-border, #fecaca);
  color: var(--color-status-text-danger);
}

.app-banner-registration-expired .app-banner-inner {
  margin-left: auto;
  margin-right: auto;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  max-width: 1600px;
  padding: 0.75rem 1rem;
  flex-wrap: wrap;
}

@media (min-width: 1024px) {
  .app-banner-registration-expired .app-banner-inner {
    padding-left: 2rem;
    padding-right: 2rem;
  }
}

.app-banner-registration-expired .app-banner-icon {
  font-size: 1.25rem;
  line-height: 1;
}

.app-banner-registration-expired .app-banner-text {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  flex: 1 1 auto;
  min-width: 0;
}

.app-banner-registration-expired .app-banner-text strong {
  font-weight: 600;
}

.app-banner-registration-expired .app-banner-cta {
  display: inline-flex;
  align-items: center;
  padding: 0.5rem 1rem;
  border-radius: 0.375rem;
  background-color: var(--color-danger-hover, #b91c1c);
  color: var(--color-surface, #ffffff);
  font-weight: 600;
  text-decoration: none;
  transition: background-color 0.15s ease-in-out;
}

.app-banner-registration-expired .app-banner-cta:hover {
  background-color: var(--color-error-dark, #991b1b);
}

.app-banner-registration-expired .app-banner-cta:focus-visible {
  outline: 2px solid var(--color-warning-light, #fbbf24);
  outline-offset: 2px;
}

/* Wave 279.C / Bug #1120 — banner amarelo "Atualização cadastral solicitada".
   Renderizado pelo ViewComponent RegistrationExpiredBanner quando o admin formaliza
   pedido de renovação cadastral (adjustments_requested). Espelha estrutura do banner
   vermelho expired, com paleta âmbar para diferenciar urgência. */
.app-banner-registration-renewal {
  background-color: var(--color-status-pill-bg-amber);
  border-bottom: 1px solid var(--color-warning-border, #fde68a);
  color: var(--color-status-pill-text-amber);
}

.app-banner-registration-renewal .app-banner-inner {
  margin-left: auto;
  margin-right: auto;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  max-width: 1600px;
  padding: 0.75rem 1rem;
  flex-wrap: wrap;
}

@media (min-width: 1024px) {
  .app-banner-registration-renewal .app-banner-inner {
    padding-left: 2rem;
    padding-right: 2rem;
  }
}

.app-banner-registration-renewal .app-banner-icon {
  font-size: 1.25rem;
  line-height: 1;
}

.app-banner-registration-renewal .app-banner-text {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  flex: 1 1 auto;
  min-width: 0;
}

.app-banner-registration-renewal .app-banner-text strong {
  font-weight: 600;
}

.app-banner-registration-renewal .app-banner-cta {
  display: inline-flex;
  align-items: center;
  padding: 0.5rem 1rem;
  border-radius: 0.375rem;
  background-color: var(--color-accent-amber-strong);
  color: var(--color-surface, #ffffff);
  font-weight: 600;
  text-decoration: none;
  transition: background-color 0.15s ease-in-out;
}

.app-banner-registration-renewal .app-banner-cta:hover {
  background-color: var(--color-warning-dark, #a16207);
}

.app-banner-registration-renewal .app-banner-cta:focus-visible {
  outline: 2px solid var(--color-danger-hover, #b91c1c);
  outline-offset: 2px;
}

/* Sprint 2026-05-09 — impersonate read-only canonical
   (feedback_menu_organization_and_impersonate). Banner sticky exibido em
   QUALQUER área enquanto a sessão impersonate estiver ativa. Tom âmbar para
   distinguir do banner vermelho (cadastro vencido) e do amarelo de renovação
   (CTA "Atualizar"). Inclui um <form> embutido para o POST de encerramento. */
.app-banner-impersonate {
  background-color: var(--color-status-pill-bg-amber);
  border-bottom: 1px solid var(--color-accent-amber-strong, #d97706);
  color: var(--color-status-pill-text-amber);
  /* Faixa FIXA no topo absoluto (diretiva 2026-06-12): acima do header (z-40) e do
     filtro de contexto (z-30). Empurra o site inteiro para baixo via :has() abaixo —
     nada passa por debaixo dela. z-index alto para cobrir qualquer elemento da página. */
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 60;
}

/* Compensacao: quando o banner de impersonate esta presente (1o filho de .app-layout),
   desloca header + filtro de contexto + frame pela altura REAL do banner. A variavel
   --impersonate-banner-height e setada por js/layout/impersonate-banner-offset.js
   (mede o banner e reage a resize/quebra de linha); o fallback 3.5rem cobre 1 linha. */
.app-layout:has(> .app-banner-impersonate) .app-header {
  top: var(--impersonate-banner-height, 3.5rem);
}

.app-layout:has(> .app-banner-impersonate) .context-filter {
  top: calc(var(--app-header-height) + var(--impersonate-banner-height, 3.5rem));
}

.app-layout:has(> .app-banner-impersonate) .app-frame {
  padding-top: calc(
    var(--app-header-height) + var(--impersonate-banner-height, 3.5rem) + 1rem
  );
}

.app-layout.has-context-filter:has(> .app-banner-impersonate) .app-frame {
  padding-top: calc(
    var(--app-header-height) + var(--context-filter-height, 2.75rem) +
      var(--impersonate-banner-height, 3.5rem) + 1rem
  );
}

.app-banner-impersonate .app-banner-inner {
  margin-left: auto;
  margin-right: auto;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  max-width: 1600px;
  padding: 0.75rem 1rem;
  flex-wrap: wrap;
}

@media (min-width: 1024px) {
  .app-banner-impersonate .app-banner-inner {
    padding-left: 2rem;
    padding-right: 2rem;
  }
}

.app-banner-impersonate .app-banner-icon {
  font-size: 1.25rem;
  line-height: 1;
}

.app-banner-impersonate .app-banner-text {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  flex: 1 1 auto;
  min-width: 0;
}

.app-banner-impersonate .app-banner-text strong {
  font-weight: 600;
}

.app-banner-impersonate-admin,
.app-banner-impersonate-target {
  font-weight: 600;
}

.app-banner-impersonate-form {
  margin: 0;
  display: inline-flex;
}

.app-banner-impersonate .app-banner-cta {
  display: inline-flex;
  align-items: center;
  padding: 0.5rem 1rem;
  border-radius: 0.375rem;
  background-color: var(--color-accent-amber-strong, #d97706);
  color: var(--color-surface, #ffffff);
  font-weight: 600;
  text-decoration: none;
  border: none;
  cursor: pointer;
  transition: background-color 0.15s ease-in-out;
}

.app-banner-impersonate .app-banner-cta:hover {
  background-color: var(--color-warning-dark, #a16207);
}

.app-banner-impersonate .app-banner-cta:focus-visible {
  outline: 2px solid var(--color-danger-hover, #b91c1c);
  outline-offset: 2px;
}

/* F5 — banner de aviso do admin: IN-FLOW (nao fixo) e persistente, no topo do conteudo.
   Avisa o admin sobre algo fora do permitido (ex.: valor fora do min/max da oferta) sem
   bloquear e sem sumir como um toast. Paleta amber, consistente com o impersonate. */
.app-banner-admin-notice {
  display: flex;
  align-items: flex-start;
  gap: 0.625rem;
  margin: 0 0 1rem 0;
  padding: 0.75rem 1rem;
  background-color: var(--color-status-pill-bg-amber);
  border: 1px solid var(--color-accent-amber-strong, #d97706);
  border-radius: 0.5rem;
  color: var(--color-status-pill-text-amber);
  font-size: 0.875rem;
  line-height: 1.4;
}

.app-banner-admin-notice-icon {
  flex-shrink: 0;
  font-size: 1.05rem;
  line-height: 1.2;
}

.app-banner-admin-notice-text {
  flex: 1 1 auto;
  min-width: 0;
}
