/* ============================================================================
   dash-shark — CORE
   Familia 1 de 3. O esqueleto e os controles do dashboard da Shark Pro Trade.
   ----------------------------------------------------------------------------
   COBRE:
     shell        .ds-app, .ds-sidebar, .ds-topbar
     superficie   .ds-card, .ds-kpi
     controle     .ds-btn, .ds-badge, .ds-tabs, .ds-segmented
     formulario   .ds-field, .ds-input, .ds-select, .ds-textarea,
                  .ds-switch, .ds-checkbox, .ds-radio
     dados        .ds-table, .ds-avatar, .ds-scroll

   NAO COBRE (outras familias): grafico, sparkline, gauge, heatmap, modal,
   drawer, toast, tooltip, skeleton, empty state. Tambem nao ha reset,
   normalize, grid utilitario nem classe de espacamento aqui.

   DEPENDE DE: dash-shark.tokens.css — carregue ele ANTES deste arquivo.
   Nenhum token --ds-* e' declarado aqui; este arquivo so consome.

   REGRAS QUE O ARQUIVO SEGUE (nao mexa sem ler DESIGN-NOTES.md §2):
     - cor sempre via var(--ds-*); nada de hex solto
     - azul     = tecnologia / informativo / dado neutro / navegacao
     - verde    = conversao e LUCRO apenas
     - vermelho = perda e ERRO apenas
     - rosa     = energia / destaque / novidade / ATENCAO. Nunca informa valor:
                  nao substitui verde em lucro nem vermelho em perda.
     - NAO existe amarelo/dourado/ambar neste sistema. O papel que amarelo
       cumpre em outros design systems e' do ROSA aqui.
     - um neon por card, nunca dois competindo
     - toda duracao vem de var(--ds-dur-*), que zera sozinha em
       prefers-reduced-motion. Nunca hardcode milissegundo.
     - variavel de encanamento usa prefixo --_ds- (underline). Token --ds-*
       so' e' consumido, nunca declarado aqui.
   ========================================================================= */


/* ============================================================================
   1. SHELL — .ds-app
   Grade de duas faixas: rail de navegacao fixo a esquerda, topbar de vidro
   grudada no topo, conteudo rolando por baixo. O preto puro e' a tela; card
   em grafite so aparece a partir da secao 4.
   ========================================================================= */

.ds-app {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr);
  grid-template-areas:
    "sidebar topbar"
    "sidebar main";
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--ds-canvas);
  color: var(--ds-text-1);
  font-family: var(--ds-body);
  font-size: var(--ds-fs-base);
  line-height: var(--ds-lh-base);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.ds-app > .ds-sidebar { grid-area: sidebar; }
.ds-app > .ds-topbar  { grid-area: topbar; }

/* A area de conteudo. Ela e' quem rola, nao o body — assim a topbar de vidro
   fica colada sem depender de position:fixed. */
.ds-app-main {
  grid-area: main;
  min-width: 0;
  padding: var(--ds-space-7) var(--ds-space-8) var(--ds-space-10);
}

@media (max-width: 1279px) {
  .ds-app-main { padding: var(--ds-space-6) var(--ds-space-6) var(--ds-space-9); }
}

@media (max-width: 767px) {
  .ds-app-main { padding: var(--ds-space-5) var(--ds-space-4) var(--ds-space-8); }
}


/* ============================================================================
   2. SIDEBAR — .ds-sidebar
   Rail de navegacao. Fundo em grafite, uma fileira de trama sangrando no pe
   pra dar materia sem pedir mais uma cor.
   ========================================================================= */

.ds-sidebar {
  position: sticky;
  top: 0;
  align-self: start;
  z-index: var(--ds-z-sticky);
  display: flex;
  flex-direction: column;
  width: 264px;
  height: 100vh;
  height: 100dvh;
  padding: 0 var(--ds-space-3) var(--ds-space-5);
  /* O rail nao e' um retangulo chapado: recebe luz no alto (onde mora a marca)
     e afunda pro preto no pe, onde a trama entra. Duas camadas, nenhuma cor
     nova. */
  background-color: var(--ds-surface);
  background-image:
    linear-gradient(180deg,
      color-mix(in srgb, var(--ds-white) 4%, transparent) 0,
      transparent 200px),
    linear-gradient(180deg,
      var(--ds-surface-2) 0,
      var(--ds-surface) 38%,
      var(--ds-black) 100%);
  border-right: 1px solid var(--ds-line);
  /* dur-2, nao dur-3: abaixo de 1024px o rail vira gaveta e o scrim que o
     acompanha (overlays) sai em dur-2. Com dur-3 aqui, o scrim some antes e a
     pagina reaparece com o rail ainda deslizando. As duas tem que casar. */
  transition: width var(--ds-dur-2) var(--ds-ease),
              transform var(--ds-dur-2) var(--ds-ease);
}

/* Trilho de luz na quina direita: a borda capta luz no meio da altura e apaga
   nas pontas, como metal. E' o que separa o rail do preto puro do canvas sem
   precisar engordar o border pra 2px. */
.ds-sidebar::before {
  content: "";
  position: absolute;
  inset: 0 -1px 0 auto;
  width: 1px;
  pointer-events: none;
  background: linear-gradient(180deg,
    transparent 0,
    color-mix(in srgb, var(--ds-white) 18%, transparent) 16%,
    color-mix(in srgb, var(--ds-blue) 30%, transparent) 48%,
    transparent 86%);
}

/* Trama no pe do rail: dither Bayer traduzido em radial-gradient, com mascara
   pra ele nascer do nada. E' a mesma malha que a familia de graficos usa. */
.ds-sidebar::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 160px;
  pointer-events: none;
  background-image: radial-gradient(var(--ds-mesh-dot) 0.5px, transparent 0.5px);
  background-size: var(--ds-mesh-size) var(--ds-mesh-size);
  opacity: 0.35;
  -webkit-mask-image: linear-gradient(to top, var(--ds-black), transparent);
          mask-image: linear-gradient(to top, var(--ds-black), transparent);
}

/* --- marca ---------------------------------------------------------------
   Altura casada com a da topbar (64px) pra a linha horizontal atravessar a
   tela inteira sem degrau. */
.ds-sidebar-brand {
  display: flex;
  align-items: center;
  gap: var(--ds-space-3);
  height: 64px;
  flex: 0 0 auto;
  padding: 0 var(--ds-space-2);
  margin-bottom: var(--ds-space-4);
  color: var(--ds-text-1);
  font-family: var(--ds-display);
  font-size: var(--ds-fs-md);
  font-weight: 600;
  letter-spacing: var(--ds-track-tight);
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
}

.ds-sidebar-brand img,
.ds-sidebar-brand svg {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
}

/* --- corpo rolavel do rail ----------------------------------------------- */
.ds-sidebar-body {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: var(--ds-space-5);
}

.ds-sidebar-foot {
  flex: 0 0 auto;
  position: relative;
  z-index: var(--ds-z-base);
  padding-top: var(--ds-space-4);
  margin-top: var(--ds-space-4);
  border-top: 1px solid var(--ds-line-faint);
}

/* --- grupo ---------------------------------------------------------------- */
.ds-sidebar-group {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.ds-sidebar-group-title {
  padding: 0 var(--ds-space-3) var(--ds-space-2);
  color: var(--ds-text-3);
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-micro);
  font-weight: 500;
  letter-spacing: var(--ds-track-label);
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
}

/* --- item ----------------------------------------------------------------- */
.ds-sidebar-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--ds-space-3);
  min-height: 38px;
  padding: var(--ds-space-2) var(--ds-space-3);
  border: 1px solid transparent;
  border-radius: var(--ds-r-md);
  background: transparent;
  color: var(--ds-text-2);
  font-family: inherit;
  font-size: var(--ds-fs-sm);
  font-weight: 500;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--ds-dur-2) var(--ds-ease),
              color var(--ds-dur-2) var(--ds-ease),
              border-color var(--ds-dur-2) var(--ds-ease);
}

.ds-sidebar-item-icon {
  flex: 0 0 20px;
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  opacity: 0.9;
  transition: color var(--ds-dur-2) var(--ds-ease),
              opacity var(--ds-dur-2) var(--ds-ease),
              filter var(--ds-dur-2) var(--ds-ease);
}

.ds-sidebar-item-icon svg,
.ds-sidebar-item-icon img {
  width: 18px;
  height: 18px;
}

.ds-sidebar-item-label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Slot da direita: contador, badge, atalho de teclado. */
.ds-sidebar-item-trail {
  flex: 0 0 auto;
  color: var(--ds-text-3);
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-micro);
  letter-spacing: var(--ds-track-label);
}

.ds-sidebar-item:hover {
  background: var(--ds-surface-2);
  color: var(--ds-text-1);
}

.ds-sidebar-item:hover .ds-sidebar-item-icon { opacity: 1; }

.ds-sidebar-item:focus-visible {
  outline: none;
  color: var(--ds-text-1);
  box-shadow: var(--ds-ring-blue);
}

/* Ativo: azul, porque navegacao e' dado neutro/informativo — nunca verde.
   A tinta nao e' chapada: ela e' forte na barra de acento e evapora pra
   direita, entao o olho e' puxado pra o inicio da linha (onde esta o icone)
   e nao pro retangulo inteiro. */
.ds-sidebar-item.is-active {
  color: var(--ds-text-1);
  background-color: color-mix(in srgb, var(--ds-blue) 9%, transparent);
  background-image: linear-gradient(90deg,
    color-mix(in srgb, var(--ds-blue) 22%, transparent) 0,
    color-mix(in srgb, var(--ds-blue) 5%, transparent) 58%,
    transparent 100%);
  border-color: color-mix(in srgb, var(--ds-blue) 26%, transparent);
  box-shadow: inset 0 1px 0 0 color-mix(in srgb, var(--ds-white) 9%, transparent),
              0 10px 24px -20px var(--ds-glow-blue);
}

/* Foco vence a caixa do ativo: sem isto, o item ativo focado ficaria sem anel
   (mesma especificidade, e .is-active vem depois na cascata). */
.ds-sidebar-item.is-active:focus-visible {
  box-shadow: var(--ds-ring-blue),
              0 0 0 4px color-mix(in srgb, var(--ds-blue) 16%, transparent);
}

/* O icone do item ativo acende: cor cheia + halo curto. */
.ds-sidebar-item.is-active .ds-sidebar-item-icon {
  opacity: 1;
  color: var(--ds-blue);
  filter: drop-shadow(0 0 7px var(--ds-glow-blue));
}

/* Barra de acento vertical na borda esquerda do item ativo. Fica no trecho
   reto da borda (16%..84%) pra nao brigar com o squircle, e o degrade faz ela
   nascer branca no topo — a mesma luz que vem de cima no card. */
.ds-sidebar-item.is-active::before {
  content: "";
  position: absolute;
  left: -1px;
  top: 16%;
  bottom: 16%;
  width: 3px;
  border-radius: var(--ds-r-pill);
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--ds-white) 55%, var(--ds-blue)) 0,
    var(--ds-blue) 42%,
    color-mix(in srgb, var(--ds-blue) 55%, transparent) 100%);
  box-shadow: 0 0 16px 1px var(--ds-glow-blue);
}

.ds-sidebar-item[aria-disabled="true"],
.ds-sidebar-item:disabled {
  color: var(--ds-text-4);
  pointer-events: none;
}

/* --- variante colapsada --------------------------------------------------- */
.ds-sidebar--collapsed { width: 76px; }

.ds-sidebar--collapsed .ds-sidebar-item {
  justify-content: center;
  padding-inline: 0;
}

.ds-sidebar--collapsed .ds-sidebar-item-label,
.ds-sidebar--collapsed .ds-sidebar-item-trail,
.ds-sidebar--collapsed .ds-sidebar-brand span {
  display: none;
}

/* O titulo do grupo vira um traco: some o texto, sobra a separacao. */
.ds-sidebar--collapsed .ds-sidebar-group-title {
  height: 1px;
  padding: 0;
  margin: var(--ds-space-2) auto var(--ds-space-3);
  width: 24px;
  color: transparent;
  background: var(--ds-line-strong);
}

.ds-sidebar--collapsed .ds-sidebar-brand {
  justify-content: center;
  padding-inline: 0;
}


/* ============================================================================
   3. TOPBAR — .ds-topbar
   Faixa de vidro. Nao e' um card: nao tem raio, nao tem glow. Ela so segura
   o contexto e a busca.
   ========================================================================= */

.ds-topbar {
  position: sticky;
  top: 0;
  z-index: var(--ds-z-sticky);
  display: flex;
  align-items: center;
  gap: var(--ds-space-4);
  min-height: 64px;
  padding: var(--ds-space-2) var(--ds-space-8);
  /* Mais vidro: alem do blur, uma luz rasante no topo e a trama da marca em
     alfa baixissimo. A trama e' o que impede a faixa de parecer um retangulo
     translucido generico de framework. */
  background-color: var(--ds-glass);
  background-image:
    linear-gradient(180deg,
      color-mix(in srgb, var(--ds-white) 6%, transparent) 0,
      transparent 62%),
    radial-gradient(
      color-mix(in srgb, var(--ds-mesh-dot) 40%, transparent) 0.5px,
      transparent 0.5px);
  background-size: auto, var(--ds-mesh-size) var(--ds-mesh-size);
  border-bottom: 1px solid var(--ds-line);
  box-shadow: inset 0 -1px 0 0 color-mix(in srgb, var(--ds-white) 5%, transparent),
              0 20px 44px -38px var(--ds-black);
  -webkit-backdrop-filter: blur(var(--ds-blur-lg)) saturate(180%);
          backdrop-filter: blur(var(--ds-blur-lg)) saturate(180%);
}

/* Sombra de separacao logo abaixo da faixa: o conteudo que rola por baixo
   entra na penumbra antes de sumir sob o vidro. pointer-events none pra ela
   nunca roubar clique da primeira linha do conteudo. */
.ds-topbar::after {
  content: "";
  position: absolute;
  inset: 100% 0 auto 0;
  height: 28px;
  pointer-events: none;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--ds-black) 68%, transparent) 0,
    transparent 100%);
}

.ds-topbar-title {
  flex: 0 1 auto;
  min-width: 0;
  margin: 0;
  color: var(--ds-text-1);
  font-family: var(--ds-display);
  font-size: var(--ds-fs-lg);
  font-weight: 600;
  letter-spacing: var(--ds-track-tight);
  line-height: var(--ds-lh-snug);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Kicker opcional acima/ao lado do titulo. */
.ds-topbar-kicker {
  color: var(--ds-text-3);
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-micro);
  letter-spacing: var(--ds-track-wide);
  text-transform: uppercase;
}

/* --- busca: pill de vidro ------------------------------------------------- */
.ds-topbar-search {
  flex: 0 1 420px;
  display: flex;
  align-items: center;
  gap: var(--ds-space-3);
  height: 38px;
  padding: 0 var(--ds-space-4);
  /* Sem borda, igual ao card: poco escuro + luz de quina. O campo e a PILL —
     o <input> dentro dele e' so' texto. NAO ponha .ds-input aqui: ele traria
     raio, fundo e anel de foco proprios, e o anel apareceria DENTRO da pill,
     menor que ela. Foi exatamente esse bug que gerou este comentario. */
  border: 0;
  border-radius: var(--ds-r-pill);
  background: var(--ds-sunken);
  box-shadow: inset 0 1px 0 0 color-mix(in srgb, var(--ds-white) 7%, transparent);
  color: var(--ds-text-3);
  -webkit-backdrop-filter: blur(var(--ds-blur-sm));
          backdrop-filter: blur(var(--ds-blur-sm));
  transition: box-shadow var(--ds-dur-2) var(--ds-ease),
              background-color var(--ds-dur-2) var(--ds-ease);
}

/* O anel de foco vive na PILL, nao no input — assim ele acompanha o raio e a
   largura reais do controle. */
.ds-topbar-search:focus-within {
  background: var(--ds-black);
  box-shadow:
    inset 0 1px 0 0 color-mix(in srgb, var(--ds-white) 9%, transparent),
    0 0 0 2px color-mix(in srgb, var(--ds-blue) 34%, transparent),
    0 0 22px -6px var(--ds-glow-blue);
}

.ds-topbar-search:focus-within .ds-topbar-search-lupa { color: var(--ds-blue); }

.ds-topbar-search-lupa {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 15px;
  height: 15px;
  color: var(--ds-text-3);
  transition: color var(--ds-dur-2) var(--ds-ease);
}

.ds-topbar-search svg {
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
}

.ds-topbar-search input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  background: none;
  color: var(--ds-text-1);
  font-family: inherit;
  font-size: var(--ds-fs-sm);
  outline: none;
}

.ds-topbar-search input::placeholder { color: var(--ds-text-3); }

.ds-topbar-search:focus-within {
  border-color: color-mix(in srgb, var(--ds-blue) 55%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--ds-blue) 45%, transparent),
              0 0 0 4px color-mix(in srgb, var(--ds-blue) 13%, transparent),
              0 0 24px -8px var(--ds-glow-blue);
  color: var(--ds-text-2);
}

/* Atalho de teclado no fim da pill. */
.ds-topbar-search kbd {
  flex: 0 0 auto;
  padding: 2px 6px;
  border: 1px solid var(--ds-line);
  border-radius: var(--ds-r-xs);
  color: var(--ds-text-3);
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-micro);
  letter-spacing: var(--ds-track-label);
}

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

@media (max-width: 1023px) {
  .ds-topbar { padding-inline: var(--ds-space-5); }
  .ds-topbar-search { flex-basis: 240px; }
}

@media (max-width: 767px) {
  .ds-topbar { padding-inline: var(--ds-space-4); gap: var(--ds-space-3); }
  .ds-topbar-search { flex: 1 1 auto; }
  .ds-topbar-search kbd { display: none; }
}


/* ============================================================================
   4. CARD — .ds-card
   A superficie base. O under-glow de spread NEGATIVO e' a assinatura da casa:
   a luz vaza por baixo do card, nao circunda ele.
   ========================================================================= */

.ds-card {
  /* ENCANAMENTO DA PROFUNDIDADE (leia antes de mexer)
     Modificador troca ESTAS variaveis, nunca o box-shadow inteiro. E' o que
     faz o fio de luz da borda de cima sobreviver a hover, foco, estado ativo
     e variante de neon — antes, cada variante reescrevia a pilha e apagava a
     camada de baixo sem querer.
       --_ds-card-top     cor da luz que cai do topo (a camada radial)
       --_ds-card-edge    quanto a borda de cima capta dessa luz
       --_ds-card-shadow  sombra ambiente (e2 no repouso, e3 levantado)
       --_ds-card-lift    o neon: under-glow de spread negativo, ou anel */
  --_ds-card-top: color-mix(in srgb, var(--ds-white) 6%, transparent);
  --_ds-card-edge: color-mix(in srgb, var(--ds-white) 9%, transparent);
  --_ds-card-shadow: var(--ds-e2);
  --_ds-card-lift: 0 0 0 0 transparent;

  position: relative;
  display: block;
  /* Tres camadas: luz radial vindo de cima da borda, corpo em degrade que
     escurece pro pe, e a cor de superficie como chao. Fundo chapado nao
     existe mais aqui. */
  background-color: var(--ds-surface);
  background-image:
    radial-gradient(118% 74% at 50% -14%, var(--_ds-card-top), transparent 62%),
    linear-gradient(180deg,
      var(--ds-surface-raised) 0,
      var(--ds-surface) 46%,
      var(--ds-sunken) 100%);
  /* SEM BORDA, e isso e' decisao de linguagem, nao esquecimento.
     Nenhuma das referencias do produto usa fio de 1px em card. Elas separam a
     peca do fundo por CONTRASTE DE SUPERFICIE + SOMBRA, e e' isso que produz o
     "solto": o card parece uma placa flutuando, nao um retangulo desenhado.
     Borda de 1px em fundo preto sempre le como moldura — e moldura e' o
     oposto de janela.
     Quem precisar de contorno (tabela dentro de card, area de drop, seletor)
     usa .ds-card--framed. */
  border: 0;
  border-radius: var(--ds-r-lg);
  padding: var(--ds-space-6);
  color: inherit;
  box-shadow:
    /* fio de luz no topo: nao e' moldura, e' a quina captando luz. Fica. */
    inset 0 1px 0 0 var(--_ds-card-edge),
    inset 0 -1px 0 0 color-mix(in srgb, var(--ds-black) 55%, transparent),
    var(--_ds-card-shadow),
    var(--_ds-card-lift);
  transition: box-shadow var(--ds-dur-2) var(--ds-ease),
              transform var(--ds-dur-2) var(--ds-ease),
              background-color var(--ds-dur-2) var(--ds-ease);
}

/* Sem borda, a separacao passa a depender da sombra — entao ela precisa ser
   maior do que era quando havia fio. e3 no lugar de e2. */
.ds-card { --_ds-card-shadow: var(--ds-e3); }

/* Escape hatch pra quando o contorno for FUNCIONAL e nao decorativo. */
.ds-card--framed {
  box-shadow:
    inset 0 0 0 1px var(--ds-line),
    var(--_ds-card-shadow),
    var(--_ds-card-lift);
}

/* Squircle maior quando o card e' o heroi da tela. */
.ds-card--xl { border-radius: var(--ds-r-xl); padding: var(--ds-space-7); }

/* --lit = o card recebe luz de cima de verdade: a cupula radial fica mais
   quente E o fio de 1px na borda superior vira quase branco no meio, com um
   halo curto. Nao e' so' a linha de antes. */
.ds-card--lit {
  --_ds-card-top: color-mix(in srgb, var(--ds-white) 13%, transparent);
  --_ds-card-edge: color-mix(in srgb, var(--ds-white) 16%, transparent);
}

.ds-card--lit::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  border-radius: inherit;
  background: linear-gradient(90deg,
    transparent 0,
    color-mix(in srgb, var(--ds-white) 10%, transparent) 16%,
    color-mix(in srgb, var(--ds-white) 66%, transparent) 50%,
    color-mix(in srgb, var(--ds-white) 10%, transparent) 84%,
    transparent 100%);
  box-shadow: 0 0 14px 0 color-mix(in srgb, var(--ds-white) 16%, transparent);
}

/* Um neon por card. Escolha UM destes tres — nunca dois juntos. */
.ds-card--glow-blue {
  --_ds-card-top: color-mix(in srgb, var(--ds-blue) 15%, transparent);
  --_ds-card-edge: color-mix(in srgb, var(--ds-blue) 34%, transparent);
  --_ds-card-lift: var(--ds-underglow-blue);
  border-color: color-mix(in srgb, var(--ds-blue) 18%, var(--ds-line));
}

/* NOTA: verde e' conversao/lucro. So use --glow-green em card de receita,
   assinatura fechada ou P&L positivo. Nunca como "card de sucesso". */
.ds-card--glow-green {
  --_ds-card-top: color-mix(in srgb, var(--ds-green) 13%, transparent);
  --_ds-card-edge: color-mix(in srgb, var(--ds-green) 30%, transparent);
  --_ds-card-lift: var(--ds-underglow-green);
  border-color: color-mix(in srgb, var(--ds-green) 16%, var(--ds-line));
}

/* --- rosa: o card de ENERGIA ---------------------------------------------
   Rosa e' novidade, destaque, chamada de campanha e estado de atencao. Ele
   NAO informa valor: card de lucro continua verde, card de perda continua
   vermelho. Se o numero dentro do card e' dinheiro, este nao e' o card. */
.ds-card--pink {
  --_ds-card-top: color-mix(in srgb, var(--ds-atencao) 20%, transparent);
  --_ds-card-edge: color-mix(in srgb, var(--ds-atencao) 46%, transparent);
  --_ds-card-lift: 0 50px 140px -70px var(--ds-glow-atencao);
  border-color: color-mix(in srgb, var(--ds-atencao) 26%, var(--ds-line));
}

/* Fio de luz rosa no topo. Declarado DEPOIS do --lit de proposito: se as duas
   classes cairem no mesmo card, o rosa vence e nao ficam dois fios brigando. */
.ds-card--pink::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  border-radius: inherit;
  background: linear-gradient(90deg,
    transparent 0,
    color-mix(in srgb, var(--ds-atencao) 30%, transparent) 18%,
    var(--ds-atencao) 50%,
    color-mix(in srgb, var(--ds-atencao) 30%, transparent) 82%,
    transparent 100%);
  box-shadow: 0 0 18px 0 var(--ds-glow-atencao);
}

/* --- raios: o card de destaque -------------------------------------------
   Faixas de BORDA DURA irradiando de um ponto acima da quina esquerda —
   parada dura no conic-gradient, espessura variavel, nada de blur. O que come
   os raios com a distancia e' um veu radial da propria cor de superficie, e
   nao uma mascara: assim o miolo do card continua legivel e o dado nunca
   disputa com a textura. A trama entra por baixo, so' viva perto da origem.

   Custa 5 camadas de background. Use em UM card por tela, o heroi. */
.ds-card--rays {
  --_ds-ray: var(--ds-atencao);
  --_ds-card-top: color-mix(in srgb, var(--ds-white) 5%, transparent);
  background-image:
    radial-gradient(118% 74% at 50% -14%, var(--_ds-card-top), transparent 62%),
    radial-gradient(112% 128% at 16% -14%,
      transparent 0,
      color-mix(in srgb, var(--ds-surface) 42%, transparent) 34%,
      color-mix(in srgb, var(--ds-surface) 92%, transparent) 70%),
    repeating-conic-gradient(from -86deg at 16% -14%,
      color-mix(in srgb, var(--_ds-ray) 38%, transparent) 0deg 1.2deg,
      transparent 1.2deg 3.6deg,
      color-mix(in srgb, var(--_ds-ray) 16%, transparent) 3.6deg 4.3deg,
      transparent 4.3deg 8.2deg,
      color-mix(in srgb, var(--_ds-ray) 26%, transparent) 8.2deg 9.4deg,
      transparent 9.4deg 16deg),
    radial-gradient(var(--ds-mesh-dot) 0.5px, transparent 0.5px),
    linear-gradient(180deg,
      var(--ds-surface-raised) 0,
      var(--ds-surface) 46%,
      var(--ds-sunken) 100%);
  background-size:
    auto,
    auto,
    auto,
    var(--ds-mesh-size) var(--ds-mesh-size),
    auto;
}

/* Os raios herdam o neon do card quando ele ja tem um. Um neon por card
   continua valendo — o raio nao e' uma segunda cor, e' a MESMA. */
.ds-card--rays.ds-card--glow-blue  { --_ds-ray: var(--ds-blue); }
.ds-card--rays.ds-card--glow-green { --_ds-ray: var(--ds-green); }

/* Sem padding: pra tabela, grafico ou mapa encostarem na borda. Head e foot
   reconquistam o respiro sozinhos. */
.ds-card--flush { padding: 0; }

.ds-card--flush > .ds-card-head {
  padding: var(--ds-space-6) var(--ds-space-6) 0;
  margin-bottom: var(--ds-space-4);
}

.ds-card--flush > .ds-card-body { padding: 0; }

.ds-card--flush > .ds-card-foot {
  padding: var(--ds-space-4) var(--ds-space-6) var(--ds-space-5);
  margin-top: 0;
}

/* --- anatomia ------------------------------------------------------------- */
.ds-card-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--ds-space-4);
  margin-bottom: var(--ds-space-5);
}

.ds-card-title {
  margin: 0;
  color: var(--ds-text-1);
  font-family: var(--ds-display);
  font-size: var(--ds-fs-lg);
  font-weight: 600;
  letter-spacing: var(--ds-track-tight);
  line-height: var(--ds-lh-snug);
}

/* Micro-label mono acima do titulo — o kicker da marca. */
.ds-card-kicker {
  display: block;
  margin-bottom: var(--ds-space-2);
  color: var(--ds-text-3);
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-micro);
  font-weight: 500;
  letter-spacing: var(--ds-track-label);
  text-transform: uppercase;
}

.ds-card-sub {
  margin: var(--ds-space-1) 0 0;
  color: var(--ds-text-2);
  font-size: var(--ds-fs-sm);
  line-height: var(--ds-lh-snug);
}

.ds-card-body { min-width: 0; }

.ds-card-foot {
  display: flex;
  align-items: center;
  gap: var(--ds-space-3);
  margin-top: var(--ds-space-5);
  padding-top: var(--ds-space-4);
  border-top: 1px solid var(--ds-line-faint);
  color: var(--ds-text-3);
  font-size: var(--ds-fs-xs);
}

/* Acoes do head, encostadas na direita. */
.ds-card-tools {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--ds-space-2);
}

/* --- estados -------------------------------------------------------------- */
/* Levantar so quando o card e' clicavel de verdade. Card estatico nao mexe.
   O hover mexe na SOMBRA e na luz da borda, nunca em --_ds-card-top: senao um
   card rosa ou verde perderia a cor da cupula so' por passar o mouse. */
:is(a, button, [tabindex], [role="button"]).ds-card:hover {
  --_ds-card-shadow: var(--ds-e3);
  --_ds-card-edge: color-mix(in srgb, var(--ds-white) 22%, transparent);
  border-color: var(--ds-line-strong);
  transform: translateY(-2px);
}

:is(a, button, [tabindex], [role="button"]).ds-card:focus-visible {
  outline: none;
  --_ds-card-shadow: var(--ds-e3);
  --_ds-card-lift: var(--ds-ring-blue),
                   0 0 0 5px color-mix(in srgb, var(--ds-blue) 13%, transparent);
  border-color: color-mix(in srgb, var(--ds-blue) 40%, transparent);
}

.ds-card.is-active {
  --_ds-card-shadow: var(--ds-e3);
  --_ds-card-lift: var(--ds-ring-blue), var(--ds-underglow-blue);
  --_ds-card-edge: color-mix(in srgb, var(--ds-blue) 38%, transparent);
  border-color: color-mix(in srgb, var(--ds-blue) 34%, transparent);
}

@media (max-width: 767px) {
  .ds-card { padding: var(--ds-space-5); border-radius: var(--ds-r-md); }
  .ds-card--xl { padding: var(--ds-space-6); border-radius: var(--ds-r-lg); }
  .ds-card--flush > .ds-card-head { padding: var(--ds-space-5) var(--ds-space-5) 0; }
  .ds-card--flush > .ds-card-foot { padding: var(--ds-space-4) var(--ds-space-5); }
}


/* ============================================================================
   5. KPI — .ds-kpi
   Numero-heroi. Valor gigante + micro-label mono uppercase. Vive dentro do
   .ds-card-body, mas funciona solto tambem.
   ========================================================================= */

.ds-kpi {
  display: flex;
  flex-direction: column;
  gap: var(--ds-space-2);
  min-width: 0;
}

/* O rotulo e' o fantasma: mono, minusculo, esparso e dessaturado. Ele existe
   pra desaparecer ao lado do numero — a distancia entre 9,5px espacado em
   text-3 e um heroi de 58px em branco cheio E' a hierarquia. Nao aumente. */
.ds-kpi-label {
  color: var(--ds-text-3);
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-micro);
  font-weight: 500;
  letter-spacing: var(--ds-track-label);
  text-transform: uppercase;
  line-height: var(--ds-lh-snug);
}

.ds-kpi-value {
  /* --_ds-kpi-ink e' a tinta do numero. Quem precisa de um KPI de lucro ou de
     perda troca SO' esta variavel (ver .is-up / .is-down abaixo) — nao troque
     `color`, ele e' consumido pelo degrade. */
  --_ds-kpi-ink: var(--ds-white);
  display: block;
  color: var(--_ds-kpi-ink);
  font-family: var(--ds-display);
  font-size: var(--ds-fs-hero);
  font-weight: 700;
  letter-spacing: var(--ds-track-hero);
  line-height: var(--ds-lh-tight);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

/* A luz cai de cima no numero como cai no card: topo do glifo em tinta cheia,
   pe em 62%. E' o que separa o valor do rotulo sem precisar de mais uma cor.
   Fora do @supports o numero fica solido — nunca invisivel. */
@supports (-webkit-background-clip: text) or (background-clip: text) {
  .ds-kpi-value {
    background-image: linear-gradient(180deg,
      var(--_ds-kpi-ink) 0,
      var(--_ds-kpi-ink) 34%,
      color-mix(in srgb, var(--_ds-kpi-ink) 62%, transparent) 100%);
    -webkit-background-clip: text;
            background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
  }
}

/* ARMADILHA: -webkit-text-fill-color e' HERDADO. Sem este reset, qualquer
   filho do valor (a unidade, um badge inline) sumiria junto com o recorte do
   degrade. Vale tanto pra unidade dentro do valor quanto fora dele. */
.ds-kpi-value .ds-kpi-unit,
.ds-kpi-value > .ds-badge {
  background-image: none;
  -webkit-text-fill-color: currentColor;
}

/* Lucro e perda no numero-heroi, mesma regra do delta e da tabela. */
.ds-kpi-value.is-up   { --_ds-kpi-ink: var(--ds-green); }
.ds-kpi-value.is-down { --_ds-kpi-ink: var(--ds-red); }

/* Sufixo/prefixo (R$, %, un.). Cai de xl pra lg de proposito: contra um numero
   de 38-58px, o salto tem que ser brutal — se a unidade quase alcanca o valor,
   os dois viram uma coisa so' e o KPI para de gritar. */
.ds-kpi-unit {
  margin-left: 0.14em;
  color: var(--ds-text-3);
  font-size: var(--ds-fs-lg);
  font-weight: 500;
  letter-spacing: var(--ds-track-tight);
}

/* --- delta ---------------------------------------------------------------
   Aqui o verde e o vermelho estao dentro da regra: is-up e' lucro, is-down
   e' perda. Nao use estas classes pra "ok/atencao" generico. */
.ds-kpi-delta {
  display: inline-flex;
  align-items: center;
  gap: var(--ds-space-2);
  align-self: flex-start;
  padding: 4px var(--ds-space-3) 4px var(--ds-space-2);
  border: 1px solid var(--ds-line);
  border-radius: var(--ds-r-pill);
  background-color: var(--ds-surface-2);
  color: var(--ds-text-2);
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-xs);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--ds-track-tight);
  line-height: 1.4;
  box-shadow: inset 0 1px 0 0 color-mix(in srgb, var(--ds-white) 7%, transparent);
}

/* O delta e' a segunda leitura do KPI: ele nao pode ser um chip apagado. Tinta
   de fundo em degrade, borda mais firme e um under-glow curto na cor do sinal
   — a mesma luz de baixo que o card usa, em escala de pilula. */
.ds-kpi-delta.is-up {
  color: var(--ds-green);
  background-color: color-mix(in srgb, var(--ds-green) 12%, transparent);
  background-image: linear-gradient(180deg,
    color-mix(in srgb, var(--ds-green) 14%, transparent) 0,
    transparent 100%);
  border-color: color-mix(in srgb, var(--ds-green) 34%, transparent);
  box-shadow: inset 0 1px 0 0 color-mix(in srgb, var(--ds-green) 30%, transparent),
              0 8px 20px -13px var(--ds-glow-green);
}

.ds-kpi-delta.is-down {
  color: var(--ds-red);
  background-color: color-mix(in srgb, var(--ds-red) 12%, transparent);
  background-image: linear-gradient(180deg,
    color-mix(in srgb, var(--ds-red) 14%, transparent) 0,
    transparent 100%);
  border-color: color-mix(in srgb, var(--ds-red) 34%, transparent);
  box-shadow: inset 0 1px 0 0 color-mix(in srgb, var(--ds-red) 30%, transparent),
              0 8px 20px -13px var(--ds-glow-red);
}

/* ATENCAO / novidade: rosa. Nao e' lucro nem perda — e' "olha isto". O ponto
   pulsa? Nao: ele so' brilha. Animacao infinita num KPI e' exatamente o
   efeito gratuito que o sistema evita. */
.ds-kpi-delta.is-alert {
  color: var(--ds-atencao);
  background-color: color-mix(in srgb, var(--ds-atencao) 12%, transparent);
  background-image: linear-gradient(180deg,
    color-mix(in srgb, var(--ds-atencao) 16%, transparent) 0,
    transparent 100%);
  border-color: color-mix(in srgb, var(--ds-atencao) 36%, transparent);
  box-shadow: inset 0 1px 0 0 color-mix(in srgb, var(--ds-atencao) 32%, transparent),
              0 8px 22px -13px var(--ds-glow-atencao);
}

/* Seta desenhada em CSS: nada de icone obrigatorio pra ler o sinal. */
.ds-kpi-delta.is-up::before,
.ds-kpi-delta.is-down::before {
  content: "";
  width: 0;
  height: 0;
  border-left: 4.5px solid transparent;
  border-right: 4.5px solid transparent;
}

.ds-kpi-delta.is-up::before {
  border-bottom: 6px solid var(--ds-green);
  filter: drop-shadow(0 0 5px var(--ds-glow-green));
}

.ds-kpi-delta.is-down::before {
  border-top: 6px solid var(--ds-red);
  filter: drop-shadow(0 0 5px var(--ds-glow-red));
}

/* O sinal do alerta e' um ponto, nao uma seta: nao ha direcao pra apontar. */
.ds-kpi-delta.is-alert::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: var(--ds-r-pill);
  background: var(--ds-atencao);
  box-shadow: 0 0 9px 1px var(--ds-glow-atencao);
}

/* --- slot de sparkline ---------------------------------------------------
   O desenho e' da familia de graficos. O que o core entrega e' o poco com a
   trama ja preenchida, pra o card nunca ficar com um buraco vazio. */
.ds-kpi-spark {
  position: relative;
  min-height: 46px;
  margin-top: var(--ds-space-3);
  border-radius: var(--ds-r-sm);
  background-image: radial-gradient(var(--ds-mesh-dot) 0.5px, transparent 0.5px);
  background-size: var(--ds-mesh-size) var(--ds-mesh-size);
  -webkit-mask-image: linear-gradient(to top, var(--ds-black), transparent);
          mask-image: linear-gradient(to top, var(--ds-black), transparent);
}

.ds-kpi-spark > svg,
.ds-kpi-spark > canvas {
  display: block;
  width: 100%;
  height: 100%;
}

/* Versao compacta pra fileira de 4+ indicadores. */
.ds-kpi--sm .ds-kpi-value { font-size: var(--ds-fs-2xl); }
.ds-kpi--sm .ds-kpi-unit  { font-size: var(--ds-fs-md); }
.ds-kpi--sm .ds-kpi-spark { min-height: 32px; }

/* Label embaixo do numero em vez de em cima. */
.ds-kpi--label-below { flex-direction: column-reverse; }


/* ============================================================================
   6. BOTAO — .ds-btn
   Base = acao secundaria (grafite). Primaria e' AZUL: azul e' a cor de
   sistema. Nao existe botao verde de proposito — verde e' conversao/lucro e
   viraria ruido em toda tela. Ver NOTA no fim do arquivo.
   ========================================================================= */

.ds-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--ds-space-2);
  height: 38px;
  padding: 0 var(--ds-space-4);
  border: 1px solid var(--ds-line-strong);
  border-radius: var(--ds-r-pill);
  background: var(--ds-surface-2);
  color: var(--ds-text-1);
  font-family: var(--ds-body);
  font-size: var(--ds-fs-sm);
  font-weight: 600;
  letter-spacing: var(--ds-track-tight);
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  user-select: none;
  transition: background-color var(--ds-dur-2) var(--ds-ease),
              border-color var(--ds-dur-2) var(--ds-ease),
              color var(--ds-dur-2) var(--ds-ease),
              box-shadow var(--ds-dur-2) var(--ds-ease),
              transform var(--ds-dur-1) var(--ds-ease);
}

.ds-btn svg { width: 16px; height: 16px; flex: 0 0 auto; }

.ds-btn:hover:not(:disabled):not([aria-disabled="true"]) {
  background: var(--ds-surface-raised);
  border-color: var(--ds-line-strong);
}

.ds-btn:active:not(:disabled):not([aria-disabled="true"]) {
  transform: translateY(1px);
}

.ds-btn:focus-visible {
  outline: none;
  box-shadow: var(--ds-ring-blue),
              0 0 0 4px color-mix(in srgb, var(--ds-blue) 16%, transparent);
}

/* --- primaria e rosa: os dois unicos neons da area de acao ----------------
   Compartilham o corpo (degrade + luz interna no topo + under-glow) e trocam
   so' duas variaveis. AZUL continua sendo a acao primaria padrao — "salvar",
   "aplicar", "confirmar". ROSA e' a acao de ENERGIA: "novo", "ativar
   campanha", a chamada principal de um destaque. Rosa nao e' um segundo
   primario: se a tela tem dois rosas, um deles esta errado. */
.ds-btn--primary,
.ds-btn--pink {
  --_ds-btn-cor: var(--ds-blue);
  --_ds-btn-glow: var(--ds-glow-blue);
  background-color: var(--_ds-btn-cor);
  /* Duas camadas: luz batendo no alto da pilula, sombra no pe. E' o que da
     volume sem inventar uma segunda cor. */
  background-image:
    linear-gradient(180deg,
      color-mix(in srgb, var(--ds-white) 30%, transparent) 0,
      color-mix(in srgb, var(--ds-white) 7%, transparent) 44%,
      transparent 64%),
    linear-gradient(180deg,
      transparent 52%,
      color-mix(in srgb, var(--ds-black) 26%, transparent) 100%);
  border-color: color-mix(in srgb, var(--ds-white) 22%, var(--_ds-btn-cor));
  color: var(--ds-white);
  box-shadow:
    inset 0 1px 0 0 color-mix(in srgb, var(--ds-white) 52%, transparent),
    inset 0 -1px 0 0 color-mix(in srgb, var(--ds-black) 28%, transparent),
    0 10px 30px -14px var(--_ds-btn-glow),
    0 0 0 0 transparent;
}

.ds-btn--pink {
  --_ds-btn-cor: var(--ds-atencao);
  --_ds-btn-glow: var(--ds-glow-atencao);
  /* A TINTA precisa vir DEPOIS da regra compartilhada com --primary, que declara
     branco. Menta e' clara: com branco da' 1,42:1 e o rotulo do botao desaparece.
     Era rosa profundo (7,59:1 com branco) ate' 12/08 — trocar a cor obrigou a
     inverter a tinta, e este e' o unico lugar onde a heranca de --primary
     escondia isso. */
  color: var(--ds-atencao-tinta);
}

/* O glow responde ao hover: a sombra de baixo cresce E nasce um halo curto
   colado na pilula. A pilha continua com 4 sombras nas duas pontas, entao a
   transicao interpola de verdade em vez de dar um salto. */
.ds-btn--primary:hover:not(:disabled):not([aria-disabled="true"]),
.ds-btn--pink:hover:not(:disabled):not([aria-disabled="true"]) {
  background-color: color-mix(in srgb, var(--_ds-btn-cor) 86%, var(--ds-white));
  /* Repetido de proposito: o :hover generico de .ds-btn usa o atalho
     `background`, que zera background-image com especificidade maior que a da
     variante. Sem esta linha o degrade some justo no hover. */
  background-image:
    linear-gradient(180deg,
      color-mix(in srgb, var(--ds-white) 34%, transparent) 0,
      color-mix(in srgb, var(--ds-white) 9%, transparent) 44%,
      transparent 64%),
    linear-gradient(180deg,
      transparent 52%,
      color-mix(in srgb, var(--ds-black) 24%, transparent) 100%);
  border-color: color-mix(in srgb, var(--ds-white) 36%, var(--_ds-btn-cor));
  box-shadow:
    inset 0 1px 0 0 color-mix(in srgb, var(--ds-white) 72%, transparent),
    inset 0 -1px 0 0 color-mix(in srgb, var(--ds-black) 28%, transparent),
    0 16px 44px -14px var(--_ds-btn-glow),
    0 0 24px -8px var(--_ds-btn-glow);
}

/* Apertado: a luz de cima vira sombra de cima. O botao afunda de verdade. */
.ds-btn--primary:active:not(:disabled):not([aria-disabled="true"]),
.ds-btn--pink:active:not(:disabled):not([aria-disabled="true"]) {
  box-shadow:
    inset 0 2px 5px 0 color-mix(in srgb, var(--ds-black) 38%, transparent),
    inset 0 -1px 0 0 color-mix(in srgb, var(--ds-black) 28%, transparent),
    0 6px 18px -14px var(--_ds-btn-glow),
    0 0 0 0 transparent;
}

/* Foco do rosa em rosa: um anel azul num botao rosa leria como dois neons. */
.ds-btn--pink:focus-visible {
  box-shadow: 0 0 0 1px var(--ds-atencao),
              0 0 0 4px color-mix(in srgb, var(--ds-atencao) 20%, transparent);
}

/* --- ghost: acao terciaria, sem caixa ------------------------------------- */
.ds-btn--ghost {
  background: transparent;
  border-color: transparent;
  color: var(--ds-text-2);
}

.ds-btn--ghost:hover:not(:disabled):not([aria-disabled="true"]) {
  background: var(--ds-surface-2);
  border-color: transparent;
  color: var(--ds-text-1);
}

/* --- outline: mesma hierarquia do ghost, mas com contorno ----------------- */
.ds-btn--outline {
  background: transparent;
  border-color: var(--ds-line-strong);
  color: var(--ds-text-1);
}

.ds-btn--outline:hover:not(:disabled):not([aria-disabled="true"]) {
  background: var(--ds-surface-2);
  border-color: color-mix(in srgb, var(--ds-blue) 40%, var(--ds-line-strong));
}

/* --- danger ---------------------------------------------------------------
   Vermelho = erro/perda. Fica tintado no repouso e so vira solido no hover,
   pra a tela nao ter um bloco vermelho gritando o tempo todo. */
.ds-btn--danger {
  background: color-mix(in srgb, var(--ds-red) 12%, transparent);
  border-color: color-mix(in srgb, var(--ds-red) 34%, transparent);
  color: var(--ds-red);
}

.ds-btn--danger:hover:not(:disabled):not([aria-disabled="true"]) {
  background: var(--ds-red);
  border-color: var(--ds-red);
  color: var(--ds-white);
  box-shadow: 0 10px 30px -14px var(--ds-glow-red);
}

.ds-btn--danger:focus-visible {
  box-shadow: 0 0 0 1px var(--ds-red),
              0 0 0 4px color-mix(in srgb, var(--ds-red) 18%, transparent);
}

/* --- so icone: quadrado com squircle -------------------------------------- */
.ds-btn--icon {
  width: 38px;
  padding: 0;
  border-radius: var(--ds-r-md);
}

/* --- tamanhos ------------------------------------------------------------- */
.ds-btn--sm {
  height: 30px;
  padding: 0 var(--ds-space-3);
  font-size: var(--ds-fs-xs);
}

.ds-btn--sm.ds-btn--icon { width: 30px; padding: 0; border-radius: var(--ds-r-sm); }
.ds-btn--sm svg { width: 14px; height: 14px; }

.ds-btn--lg {
  height: 46px;
  padding: 0 var(--ds-space-6);
  font-size: var(--ds-fs-md);
}

.ds-btn--lg.ds-btn--icon { width: 46px; padding: 0; border-radius: var(--ds-r-lg); }
.ds-btn--lg svg { width: 18px; height: 18px; }

/* Ocupa a linha inteira — util no rodape de card em mobile. */
.ds-btn--block { display: flex; width: 100%; }

/* --- desligado: vem depois de todas as variantes de proposito ------------- */
.ds-btn:disabled,
.ds-btn[aria-disabled="true"] {
  background: var(--ds-surface-2);
  border-color: var(--ds-line);
  color: var(--ds-text-4);
  box-shadow: none;
  transform: none;
  cursor: not-allowed;
}


/* ============================================================================
   7. BADGE — .ds-badge
   Etiqueta mono uppercase. Cor tem significado: azul informa, verde e'
   conversao/lucro, vermelho e' erro/perda, neutral e' o resto.
   ========================================================================= */

.ds-badge {
  /* --_ds-badge-cor e' a TINTA da variante, e so' isso. As versoes --refinado
     e --solid leem esta variavel pra montar borda, fundo, halo do ponto e
     under-glow: quem inventar uma cor nova troca uma linha, nao seis. */
  --_ds-badge-cor: var(--ds-white);

  display: inline-flex;
  align-items: center;
  gap: var(--ds-space-2);
  /* Respiro maior que o da v1 (era 3px / 12px). O rotulo e' mono de 9,5px com
     0,16em de tracking: com padding curto a ultima letra encostava na curva da
     pilula e o selo parecia apertado. 5px/12px e' o minimo pra a pilula
     respirar sem virar botao. Quem precisa de selo miudo em tabela densa usa
     .ds-badge--sm, que devolve o padding antigo. */
  padding: 5px var(--ds-space-3);
  border: 1px solid var(--ds-line);
  border-radius: var(--ds-r-pill);
  background: var(--ds-surface-2);
  color: var(--ds-text-2);
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-micro);
  font-weight: 500;
  letter-spacing: var(--ds-track-label);
  text-transform: uppercase;
  line-height: 1.5;
  white-space: nowrap;
}

/* Ponto opcional. Herda a cor da variante. */
.ds-badge-dot {
  width: 5px;
  height: 5px;
  flex: 0 0 auto;
  border-radius: var(--ds-r-pill);
  background: currentColor;
  box-shadow: 0 0 8px 1px currentColor;
}

.ds-badge--blue {
  --_ds-badge-cor: var(--ds-blue);
  color: var(--ds-blue);
  background: color-mix(in srgb, var(--ds-blue) 12%, transparent);
  border-color: color-mix(in srgb, var(--ds-blue) 28%, transparent);
}

.ds-badge--green {
  --_ds-badge-cor: var(--ds-green);
  color: var(--ds-green);
  background: color-mix(in srgb, var(--ds-green) 11%, transparent);
  border-color: color-mix(in srgb, var(--ds-green) 26%, transparent);
}

.ds-badge--red {
  --_ds-badge-cor: var(--ds-red);
  color: var(--ds-red);
  background: color-mix(in srgb, var(--ds-red) 11%, transparent);
  border-color: color-mix(in srgb, var(--ds-red) 28%, transparent);
}

/* Rosa = energia / novidade / ATENCAO. Tintado com TEXTO rosa, como o azul e o
   verde acima — nesse formato o rosa nao carrega texto sobre fundo cheio, entao
   o --ds-pink puro pode ser usado. Se for preencher a pilula, veja --solid. */
.ds-badge--pink {
  --_ds-badge-cor: var(--ds-atencao);
  color: var(--ds-atencao);
  background: color-mix(in srgb, var(--ds-atencao) 12%, transparent);
  border-color: color-mix(in srgb, var(--ds-atencao) 30%, transparent);
}

.ds-badge--neutral {
  --_ds-badge-cor: var(--ds-white);
  color: var(--ds-text-3);
  background: var(--ds-sunken);
  border-color: var(--ds-line-faint);
}

/* Sem preenchimento: pra quando o badge cai dentro de uma celula ja tintada. */
.ds-badge--outline {
  background: transparent;
  border-color: var(--ds-line-strong);
  color: var(--ds-text-2);
}

.ds-badge--outline.ds-badge--blue  { color: var(--ds-blue);  border-color: color-mix(in srgb, var(--ds-blue) 34%, transparent); }
.ds-badge--outline.ds-badge--green { color: var(--ds-green); border-color: color-mix(in srgb, var(--ds-green) 32%, transparent); }
.ds-badge--outline.ds-badge--red   { color: var(--ds-red);   border-color: color-mix(in srgb, var(--ds-red) 34%, transparent); }
.ds-badge--outline.ds-badge--pink  { color: var(--ds-atencao);  border-color: color-mix(in srgb, var(--ds-atencao) 36%, transparent); }

/* Compacto: o padding da v1. Existe pra tabela densa, onde 4px a mais por selo
   viram 4px a mais em CADA linha e a tela perde duas operacoes de altura. */
.ds-badge--sm { padding: 2px var(--ds-space-2); gap: var(--ds-space-1); }

/* --- refinado: o selo com materia ----------------------------------------
   A versao sofisticada. O truque nao e' mais cor, e' mais CAMADA: fundo com
   tinta assentada sobre a superficie (nao um veu solto), um degrade vertical de
   amplitude baixissima (7% no alto, 18% de preto no pe) pra a pilula ter face
   e nao adesivo, um fio de 1px captando luz no topo e outro de sombra no pe —
   a mesma leitura do card, em escala de etiqueta — e um under-glow curto na
   cor da variante.

   NAO combine com --outline: outline zera o fundo (e, em .ds-badge--outline.
   ds-badge--blue, vence por especificidade) e o selo perde tudo que esta
   secao adiciona. Os dois sao alternativas, nao camadas. */
.ds-badge--refinado {
  /* mais respiro ainda: o selo refinado e' o que aparece sozinho num head de
     card, onde ele tem espaco pra ocupar */
  padding: 5px var(--ds-space-4);
  background-color: color-mix(in srgb, var(--_ds-badge-cor) 8%, var(--ds-surface-2));
  background-image: linear-gradient(180deg,
    color-mix(in srgb, var(--ds-white) 7%, transparent) 0,
    transparent 44%,
    color-mix(in srgb, var(--ds-black) 20%, transparent) 100%);
  border-color: color-mix(in srgb, var(--_ds-badge-cor) 26%, var(--ds-line));
  box-shadow:
    inset 0 1px 0 0 color-mix(in srgb, var(--ds-white) 13%, transparent),
    inset 0 -1px 0 0 color-mix(in srgb, var(--ds-black) 40%, transparent),
    0 6px 16px -12px color-mix(in srgb, var(--_ds-badge-cor) 65%, transparent);
}

/* O micro-ponto de status ganha um anel de tinta em volta do nucleo: le como
   LED atras de vidro em vez de bolinha chapada. */
.ds-badge--refinado .ds-badge-dot {
  width: 6px;
  height: 6px;
  box-shadow:
    0 0 0 2.5px color-mix(in srgb, var(--_ds-badge-cor) 15%, transparent),
    0 0 8px 1px currentColor;
}

/* --- solido: pilula preenchida -------------------------------------------
   Para o selo que precisa gritar (um "NOVO" no topo, um estado terminal). O
   fundo NUNCA e' o tom puro da marca: puro reprova em contraste com branco
   (azul 4,02:1, vermelho 4,06:1, rosa 4,01:1). Cada variante abaixo usa o tom
   ESCURECIDO — mesmo matiz, so' menos luz — e os numeros conferidos ficam
   anotados na linha. O rosa ja' tem esse tom pronto em token: --ds-pink-deep.

   Verde inverte a logica: ele e' claro demais pra texto branco, entao leva
   tinta escura (--ds-text-on-accent), que e' pra que esse token existe. */
.ds-badge--solid {
  --_ds-badge-fundo: var(--ds-surface-raised);
  --_ds-badge-tinta: var(--ds-white);
  color: var(--_ds-badge-tinta);
  background-color: var(--_ds-badge-fundo);
  background-image: linear-gradient(180deg,
    color-mix(in srgb, var(--ds-white) 15%, transparent) 0,
    transparent 50%,
    color-mix(in srgb, var(--ds-black) 16%, transparent) 100%);
  border-color: color-mix(in srgb, var(--ds-white) 20%, var(--_ds-badge-fundo));
  box-shadow:
    inset 0 1px 0 0 color-mix(in srgb, var(--ds-white) 26%, transparent),
    0 6px 16px -12px color-mix(in srgb, var(--_ds-badge-cor) 70%, transparent);
}

.ds-badge--solid.ds-badge--blue  { --_ds-badge-fundo: color-mix(in srgb, var(--ds-blue) 62%, var(--ds-black)); }  /* 8,3:1 com branco */
.ds-badge--solid.ds-badge--red   { --_ds-badge-fundo: color-mix(in srgb, var(--ds-red) 58%, var(--ds-black)); }   /* 9,4:1 com branco */
.ds-badge--solid.ds-badge--pink  { --_ds-badge-fundo: var(--ds-atencao);
                                   --_ds-badge-tinta: var(--ds-atencao-tinta); }  /* 12,65:1 com tinta escura */
.ds-badge--solid.ds-badge--green {                                                                                 /* 13,6:1 com tinta escura */
  --_ds-badge-fundo: var(--ds-green);
  --_ds-badge-tinta: var(--ds-text-on-accent);
}

/* No solido o ponto nao pode ser currentColor: ficaria um ponto branco no meio
   de um fundo cheio. Ele vira um furo escuro com um halo claro em volta. */
.ds-badge--solid .ds-badge-dot {
  background: color-mix(in srgb, var(--ds-black) 55%, transparent);
  box-shadow: 0 0 0 1.5px color-mix(in srgb, var(--_ds-badge-tinta) 45%, transparent);
}


/* ============================================================================
   8. FORMULARIO
   Campo em poco (--ds-sunken): input afunda, card sobe. O foco e' sempre
   azul — foco e' estado informativo, nunca conversao.
   ========================================================================= */

/* --- field: rotulo + controle + ajuda/erro -------------------------------- */
.ds-field {
  display: flex;
  flex-direction: column;
  gap: var(--ds-space-2);
  min-width: 0;
}

.ds-field-label {
  color: var(--ds-text-2);
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-micro);
  font-weight: 500;
  letter-spacing: var(--ds-track-label);
  text-transform: uppercase;
}

/* Marcador de obrigatorio. Vermelho aqui e' erro em potencial, nao enfeite. */
.ds-field-label[data-required]::after {
  content: "*";
  margin-left: 3px;
  color: var(--ds-red);
}

.ds-field-hint {
  color: var(--ds-text-3);
  font-size: var(--ds-fs-xs);
  line-height: var(--ds-lh-snug);
}

.ds-field-error {
  color: var(--ds-red);
  font-size: var(--ds-fs-xs);
  line-height: var(--ds-lh-snug);
}

/* --- controles de texto --------------------------------------------------- */
.ds-input,
.ds-select,
.ds-textarea {
  /* ENCANAMENTO DO POCO (o gesto de janela trazido pra dentro do controle)
     O campo nao e' um retangulo chapado com borda: e' um vao com CEU. Duas
     variaveis montam isso, e estado (hover, foco, invalido, desligado) troca
     SO' elas — nunca reescreve a pilha de camadas.
       --_ds-poco-teto  a sombra que a borda de cima projeta pra dentro
       --_ds-poco-luz   a luz que NASCE la' no fundo do poco, abaixo da borda
                        inferior, e sobe. E' a mesma mecanica do .ds-scene-sky:
                        centro definido fora do quadro visivel, queda longa. Um
                        veu uniforme por cima leria como "filtro"; isto le como
                        lugar. */
  --_ds-poco-teto: color-mix(in srgb, var(--ds-black) 62%, transparent);
  --_ds-poco-luz:  color-mix(in srgb, var(--ds-blue) 7%, transparent);

  width: 100%;
  min-width: 0;
  padding: 0 var(--ds-space-4);
  border: 1px solid var(--ds-line);
  border-radius: var(--ds-r-md);
  background-color: var(--ds-sunken);
  background-image:
    linear-gradient(180deg, var(--_ds-poco-teto) 0, transparent 40%),
    radial-gradient(126% 88% at 50% 134%, var(--_ds-poco-luz), transparent 76%);
  color: var(--ds-text-1);
  font-family: var(--ds-body);
  font-size: var(--ds-fs-sm);
  line-height: 1.4;
  /* O poco e' poco: sombra interna no alto, como se a borda de cima projetasse
     pra dentro. Card sobe, campo afunda — a leitura da profundidade e' essa.
     Cinco camadas SEMPRE, mesmo em repouso (as ultimas quatro em transparente):
     e' o que faz o foco interpolar em vez de dar salto. A camada 2 e' o
     brilho de dentro, e ela e' inset de proposito — o glow do foco acende
     DENTRO do vao antes de vazar pra fora. */
  box-shadow: inset 0 1px 3px 0 color-mix(in srgb, var(--ds-black) 60%, transparent),
              inset 0 0 0 0 transparent,
              0 0 0 0 transparent,
              0 0 0 0 transparent,
              0 0 0 0 transparent;
  transition: border-color var(--ds-dur-2) var(--ds-ease),
              box-shadow var(--ds-dur-2) var(--ds-ease),
              background-color var(--ds-dur-2) var(--ds-ease);
}

.ds-input,
.ds-select { height: 40px; }

.ds-textarea {
  min-height: 108px;
  padding: var(--ds-space-3) var(--ds-space-4);
  line-height: var(--ds-lh-base);
  resize: vertical;
}

.ds-input::placeholder,
.ds-textarea::placeholder { color: var(--ds-text-3); }

/* O hover ja' acende o fundo do poco de leve: antes de clicar, o campo mostra
   que tem profundidade. Amplitude pequena (7% -> 12%) — hover e' convite. */
.ds-input:hover:not(:disabled),
.ds-select:hover:not(:disabled),
.ds-textarea:hover:not(:disabled) {
  --_ds-poco-luz: color-mix(in srgb, var(--ds-blue) 12%, transparent);
  border-color: var(--ds-line-strong);
}

/* :focus e nao :focus-visible — campo de texto tem que acender no clique.
   Anel de foco em QUATRO tempos: o brilho interno subindo do fundo do vao,
   fio de 1px colado na borda, halo de 5px e um glow solto que sangra pra fora.
   A sombra interna do poco continua ali, mais funda — o campo focado nao vira
   uma caixa plana com borda azul, ele vira um vao ILUMINADO. */
.ds-input:focus,
.ds-select:focus,
.ds-textarea:focus {
  outline: none;
  --_ds-poco-luz: color-mix(in srgb, var(--ds-blue) 26%, transparent);
  background-color: var(--ds-black);
  border-color: color-mix(in srgb, var(--ds-blue) 62%, transparent);
  box-shadow: inset 0 1px 4px 0 color-mix(in srgb, var(--ds-black) 75%, transparent),
              inset 0 -14px 22px -16px color-mix(in srgb, var(--ds-blue) 62%, transparent),
              0 0 0 1px color-mix(in srgb, var(--ds-blue) 55%, transparent),
              0 0 0 5px color-mix(in srgb, var(--ds-blue) 15%, transparent),
              0 0 26px -6px var(--ds-glow-blue);
}

.ds-input:disabled,
.ds-select:disabled,
.ds-textarea:disabled {
  /* Apaga o poco pelas VARIAVEIS, nao com background-image:none — zerar a
     imagem aqui levaria junto a seta do .ds-select, que mora nesse mesmo
     background, e o campo desligado ficaria sem indicar que e' uma lista. */
  --_ds-poco-teto: transparent;
  --_ds-poco-luz: transparent;
  color: var(--ds-text-4);
  background-color: var(--ds-surface);
  border-color: var(--ds-line-faint);
  /* Desligado nao afunda: sem o poco, o campo deixa de parecer clicavel. */
  box-shadow: none;
  cursor: not-allowed;
}

.ds-input[readonly] { color: var(--ds-text-2); }

/* Valor numerico digitado tambem e' dado: mono e tabular. */
.ds-input--num {
  font-family: var(--ds-mono);
  font-variant-numeric: tabular-nums;
  text-align: right;
  letter-spacing: var(--ds-track-tight);
}

/* Estado invalido no wrapper: uma classe, tres controles corrigidos. */
.ds-field.is-invalid .ds-input,
.ds-field.is-invalid .ds-select,
.ds-field.is-invalid .ds-textarea,
.ds-input[aria-invalid="true"],
.ds-select[aria-invalid="true"],
.ds-textarea[aria-invalid="true"] {
  --_ds-poco-luz: color-mix(in srgb, var(--ds-red) 10%, transparent);
  border-color: color-mix(in srgb, var(--ds-red) 50%, transparent);
}

.ds-field.is-invalid .ds-input:focus,
.ds-field.is-invalid .ds-select:focus,
.ds-field.is-invalid .ds-textarea:focus,
.ds-input[aria-invalid="true"]:focus,
.ds-select[aria-invalid="true"]:focus,
.ds-textarea[aria-invalid="true"]:focus {
  /* A luz do fundo do poco troca de cor junto: um campo invalido com anel
     vermelho e ceu azul dentro leria como dois estados ao mesmo tempo. */
  --_ds-poco-luz: color-mix(in srgb, var(--ds-red) 22%, transparent);
  border-color: color-mix(in srgb, var(--ds-red) 62%, transparent);
  box-shadow: inset 0 1px 4px 0 color-mix(in srgb, var(--ds-black) 75%, transparent),
              inset 0 -14px 22px -16px color-mix(in srgb, var(--ds-red) 55%, transparent),
              0 0 0 1px var(--ds-red),
              0 0 0 5px color-mix(in srgb, var(--ds-red) 15%, transparent),
              0 0 26px -6px var(--ds-glow-red);
}

/* --- select: o controle que virou janela ---------------------------------
   Este e' o controle mais chato do formulario: <select> e' elemento
   substituido, nao aceita ::before nem ::after e nao aceita filho estilizavel.
   Tudo que da' pra fazer nele tem que caber em CAMADA DE BACKGROUND — o que,
   por sorte, e' exatamente a linguagem da cena: recorte (a borda), camadas em
   profundidades diferentes, e a luz nascendo de dentro.

   SEIS camadas, da frente pro fundo:
     1+2  a seta, em duas metades de gradiente (a receita classica)
     3    a divisoria de 1px que separa o campo do compartimento da seta —
          e' ela que faz o controle parecer INSTRUMENTO e nao caixa de texto
     4    o halo atras da seta: uma fonte de luz pontual DENTRO do controle,
          nao um veu por cima. E' o gesto do .ds-scene-sky em miniatura
     5    o ceu do poco (herdado do bloco compartilhado, via --_ds-poco-luz)
     6    a sombra do teto do poco

   Estado nao reescreve a pilha: hover e foco trocam so' --_ds-sel-seta e
   --_ds-sel-halo. Custom property dentro de background-image reavalia sozinha
   quando a variavel muda — e' o mesmo padrao do encanamento do card. */
.ds-select {
  --_ds-sel-seta: color-mix(in srgb, var(--ds-white) 66%, transparent);
  --_ds-sel-halo: color-mix(in srgb, var(--ds-white) 5%, transparent);
  --_ds-sel-linha: color-mix(in srgb, var(--ds-white) 12%, transparent);

  appearance: none;
  -webkit-appearance: none;
  /* 56px: cabe a divisoria (40px da direita) e o compartimento da seta sem o
     texto da opcao longa passar por baixo dela */
  padding-right: var(--ds-space-9);
  background-image:
    linear-gradient(45deg, transparent 50%, var(--_ds-sel-seta) 50%),
    linear-gradient(135deg, var(--_ds-sel-seta) 50%, transparent 50%),
    linear-gradient(180deg, transparent 0, var(--_ds-sel-linha) 50%, transparent 100%),
    radial-gradient(24px 24px at calc(100% - 20px) 50%, var(--_ds-sel-halo), transparent 100%),
    radial-gradient(126% 88% at 50% 134%, var(--_ds-poco-luz), transparent 76%),
    linear-gradient(180deg, var(--_ds-poco-teto) 0, transparent 40%);
  background-position:
    calc(100% - 27px) calc(50% - 3px),
    calc(100% - 20px) calc(50% - 3px),
    calc(100% - 40px) 50%,
    0 0,
    0 0,
    0 0;
  background-size:
    7px 7px,
    7px 7px,
    1px 54%,
    auto,
    auto,
    auto;
  background-repeat: no-repeat;
  cursor: pointer;
}

.ds-select:hover:not(:disabled) {
  --_ds-sel-seta: color-mix(in srgb, var(--ds-white) 88%, transparent);
  --_ds-sel-halo: color-mix(in srgb, var(--ds-white) 9%, transparent);
}

/* No foco a seta assume a cor do sistema e o halo atras dela vira a fonte de
   luz do controle: o compartimento da direita acende antes do resto. */
.ds-select:focus {
  --_ds-sel-seta: var(--ds-blue);
  --_ds-sel-halo: color-mix(in srgb, var(--ds-blue) 22%, transparent);
  --_ds-sel-linha: color-mix(in srgb, var(--ds-blue) 34%, transparent);
}

.ds-select:disabled {
  --_ds-sel-seta: var(--ds-text-4);
  --_ds-sel-halo: transparent;
  --_ds-sel-linha: var(--ds-line-faint);
}

/* Invalido: a seta e a divisoria acompanham o vermelho, senao sobra um detalhe
   azul num campo em erro. */
.ds-field.is-invalid .ds-select:focus,
.ds-select[aria-invalid="true"]:focus {
  --_ds-sel-seta: var(--ds-red);
  --_ds-sel-halo: color-mix(in srgb, var(--ds-red) 20%, transparent);
  --_ds-sel-linha: color-mix(in srgb, var(--ds-red) 34%, transparent);
}

/* O menu nativo nao herda o tema; forcar aqui evita a lista branca do SO. */
.ds-select option {
  background: var(--ds-surface-raised);
  color: var(--ds-text-1);
}

/* --- switch ---------------------------------------------------------------
   Trilho desligado leva trama, nao cinza chapado: o "off" tambem e' dado. */
.ds-switch {
  display: inline-flex;
  align-items: center;
  gap: var(--ds-space-3);
  position: relative;
  color: var(--ds-text-2);
  font-size: var(--ds-fs-sm);
  cursor: pointer;
  user-select: none;
}

.ds-switch > input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.ds-switch-track {
  position: relative;
  flex: 0 0 auto;
  width: 44px;
  height: 24px;
  border: 1px solid var(--ds-line-strong);
  border-radius: var(--ds-r-pill);
  background-color: var(--ds-sunken);
  background-image: radial-gradient(var(--ds-mesh-dot) 0.5px, transparent 0.5px);
  background-size: var(--ds-mesh-size) var(--ds-mesh-size);
  transition: background-color var(--ds-dur-2) var(--ds-ease),
              border-color var(--ds-dur-2) var(--ds-ease),
              box-shadow var(--ds-dur-2) var(--ds-ease);
}

.ds-switch-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 18px;
  height: 18px;
  border-radius: var(--ds-r-pill);
  background: var(--ds-text-3);
  transition: transform var(--ds-dur-2) var(--ds-ease),
              background-color var(--ds-dur-2) var(--ds-ease),
              box-shadow var(--ds-dur-2) var(--ds-ease);
}

.ds-switch > input:checked ~ .ds-switch-track {
  background-color: color-mix(in srgb, var(--ds-blue) 22%, transparent);
  background-image: none;
  border-color: color-mix(in srgb, var(--ds-blue) 45%, transparent);
}

.ds-switch > input:checked ~ .ds-switch-track .ds-switch-thumb {
  transform: translateX(20px);
  background: var(--ds-blue);
  box-shadow: 0 0 12px 1px var(--ds-glow-blue);
}

.ds-switch > input:focus-visible ~ .ds-switch-track {
  box-shadow: var(--ds-ring-blue),
              0 0 0 4px color-mix(in srgb, var(--ds-blue) 16%, transparent);
}

.ds-switch > input:disabled ~ .ds-switch-track { opacity: 0.4; }
.ds-switch:has(> input:disabled) { color: var(--ds-text-4); cursor: not-allowed; }

/* --- checkbox e radio ----------------------------------------------------- */
.ds-checkbox,
.ds-radio {
  display: inline-flex;
  align-items: center;
  gap: var(--ds-space-3);
  color: var(--ds-text-2);
  font-size: var(--ds-fs-sm);
  line-height: var(--ds-lh-snug);
  cursor: pointer;
  user-select: none;
}

.ds-checkbox > input,
.ds-radio > input {
  appearance: none;
  -webkit-appearance: none;
  flex: 0 0 auto;
  position: relative;
  width: 18px;
  height: 18px;
  margin: 0;
  border: 1px solid var(--ds-line-strong);
  background-color: var(--ds-sunken);
  cursor: inherit;
  transition: background-color var(--ds-dur-1) var(--ds-ease),
              border-color var(--ds-dur-1) var(--ds-ease),
              box-shadow var(--ds-dur-1) var(--ds-ease);
}

.ds-checkbox > input { border-radius: var(--ds-r-xs); }
.ds-radio > input    { border-radius: var(--ds-r-pill); }

.ds-checkbox > input:hover:not(:disabled),
.ds-radio > input:hover:not(:disabled) {
  border-color: color-mix(in srgb, var(--ds-blue) 45%, var(--ds-line-strong));
}

.ds-checkbox > input:checked,
.ds-radio > input:checked {
  background-color: var(--ds-blue);
  border-color: var(--ds-blue);
  box-shadow: 0 0 14px -2px var(--ds-glow-blue);
}

/* Marca de confirmado: duas bordas rotacionadas, sem SVG externo. */
.ds-checkbox > input:checked::after {
  content: "";
  position: absolute;
  left: 5px;
  top: 2px;
  width: 5px;
  height: 9px;
  border: solid var(--ds-black);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

.ds-checkbox > input:indeterminate {
  background-color: var(--ds-blue);
  border-color: var(--ds-blue);
}

.ds-checkbox > input:indeterminate::after {
  content: "";
  position: absolute;
  left: 3px;
  top: 7px;
  width: 10px;
  height: 2px;
  background: var(--ds-black);
}

.ds-radio > input:checked::after {
  content: "";
  position: absolute;
  inset: 4px;
  border-radius: var(--ds-r-pill);
  background: var(--ds-black);
}

.ds-checkbox > input:focus-visible,
.ds-radio > input:focus-visible {
  outline: none;
  box-shadow: var(--ds-ring-blue),
              0 0 0 4px color-mix(in srgb, var(--ds-blue) 16%, transparent);
}

.ds-checkbox > input:disabled,
.ds-radio > input:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.ds-checkbox:has(> input:disabled),
.ds-radio:has(> input:disabled) {
  color: var(--ds-text-4);
  cursor: not-allowed;
}


/* ============================================================================
   9. TABS e SEGMENTED
   Tabs = troca de secao (sublinhado neon). Segmented = troca de recorte do
   MESMO dado (pill de vidro). Nao troque um pelo outro.
   ========================================================================= */

/* SUTILEZA DO DEGRADE (o pedido do dono, e o que ele significa em numero)
   Um degrade "se incorpora ao fundo" quando tem AMPLITUDE BAIXA e RAMPA LONGA,
   e quando a cor dele deriva da superficie que esta' embaixo em vez de ser uma
   cor colada por cima. Os degrades desta secao ficam todos entre 3% e 10% e
   morrem em 60-80% do percurso. Acima de ~15% em rampa curta o olho para de
   ler "luz" e comeca a ler "degrade aplicado" — que era o problema. */
.ds-tabs {
  display: flex;
  align-items: center;
  gap: var(--ds-space-1);
  /* 3% de branco morrendo em 78% da altura: a faixa recebe a mesma luz de cima
     que o card recebe, e nao ganha uma cor propria. */
  background-image: linear-gradient(180deg,
    color-mix(in srgb, var(--ds-white) 3%, transparent) 0,
    transparent 78%);
  border-bottom: 1px solid var(--ds-line);
  overflow-x: auto;
  scrollbar-width: none;
}

.ds-tabs::-webkit-scrollbar { display: none; }

.ds-tabs-item {
  position: relative;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: var(--ds-space-2);
  height: 40px;
  padding: 0 var(--ds-space-4);
  border: 0;
  background: none;
  color: var(--ds-text-3);
  font-family: inherit;
  font-size: var(--ds-fs-sm);
  font-weight: 600;
  letter-spacing: var(--ds-track-tight);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--ds-dur-2) var(--ds-ease);
}

.ds-tabs-item::after {
  content: "";
  position: absolute;
  left: var(--ds-space-3);
  right: var(--ds-space-3);
  bottom: -1px;
  height: 2px;
  border-radius: var(--ds-r-pill);
  background: transparent;
  transition: background-color var(--ds-dur-2) var(--ds-ease),
              box-shadow var(--ds-dur-2) var(--ds-ease);
}

.ds-tabs-item:hover { color: var(--ds-text-2); }

.ds-tabs-item:focus-visible {
  outline: none;
  color: var(--ds-text-1);
  border-radius: var(--ds-r-sm);
  box-shadow: var(--ds-ring-blue);
}

/* A aba ativa nao ganha um "fundo de aba": ela ganha a luz que SOBE do proprio
   indicador. Nasce em transparente no topo e chega a 10% de azul so' na ultima
   linha de pixel — rampa de 100% da altura pra uma amplitude de 10%. E' o
   mesmo gesto do horizonte da cena, na altura de um controle. */
.ds-tabs-item.is-active {
  color: var(--ds-text-1);
  background-image: linear-gradient(180deg,
    transparent 0,
    color-mix(in srgb, var(--ds-blue) 4%, transparent) 64%,
    color-mix(in srgb, var(--ds-blue) 10%, transparent) 100%);
}

/* Indicador FIRME: barra cheia, quina definida, halo curto e colado nela. O
   glow de antes (14px de blur com spread POSITIVO de 1px) inflava a barra pra
   fora e borrava a quina — de longe lia como um degrade azul decorativo
   embaixo da aba, nao como um indicador. Spread negativo mantem o brilho
   dentro do contorno. */
.ds-tabs-item.is-active::after {
  background: var(--ds-blue);
  box-shadow: 0 0 10px -2px var(--ds-glow-blue);
}

.ds-tabs-item:disabled,
.ds-tabs-item[aria-disabled="true"] {
  color: var(--ds-text-4);
  pointer-events: none;
}

/* Contador ao lado do rotulo da aba. */
.ds-tabs-item-count {
  color: var(--ds-text-3);
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-micro);
  letter-spacing: var(--ds-track-label);
}

/* --- segmented: controle em pill de vidro --------------------------------- */
.ds-segmented {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--ds-line);
  border-radius: var(--ds-r-pill);
  /* O trilho e' um SULCO, nao uma pilula clara: sombra de 22% no alto que morre
     em 58%, entao o que o olho ve e' a superficie de tras afundando um pouco,
     e nao uma cor nova por cima. O preto e' o mesmo do canvas — o degrade
     deriva do fundo, e' o que faz ele se incorporar. */
  background-color: var(--ds-glass);
  background-image: linear-gradient(180deg,
    color-mix(in srgb, var(--ds-black) 22%, transparent) 0,
    transparent 58%);
  -webkit-backdrop-filter: blur(var(--ds-blur-md)) saturate(150%);
          backdrop-filter: blur(var(--ds-blur-md)) saturate(150%);
}

.ds-segmented-item {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--ds-space-2);
  height: 30px;
  padding: 0 var(--ds-space-4);
  border: 0;
  border-radius: var(--ds-r-pill);
  background: transparent;
  color: var(--ds-text-3);
  font-family: inherit;
  font-size: var(--ds-fs-xs);
  font-weight: 600;
  letter-spacing: var(--ds-track-tight);
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--ds-dur-2) var(--ds-ease),
              color var(--ds-dur-2) var(--ds-ease),
              box-shadow var(--ds-dur-2) var(--ds-ease);
}

.ds-segmented-item:hover { color: var(--ds-text-2); }

.ds-segmented-item:focus-visible {
  outline: none;
  color: var(--ds-text-1);
  box-shadow: var(--ds-ring-blue);
}

/* A tecla ativa e' FIRME: ela sobe do sulco. Corpo em surface-raised, 6% de luz
   no alto morrendo em 64%, fio claro na aresta de cima e fio escuro na de
   baixo. Nenhuma cor de acento aqui de proposito — segmented troca o RECORTE do
   mesmo dado, nao a secao; se ele acendesse em azul brigaria com a aba ativa,
   que e' quem tem direito ao neon. */
.ds-segmented-item.is-active {
  background-color: var(--ds-surface-raised);
  background-image: linear-gradient(180deg,
    color-mix(in srgb, var(--ds-white) 6%, transparent) 0,
    transparent 64%);
  color: var(--ds-text-1);
  box-shadow: var(--ds-e1),
              inset 0 1px 0 0 color-mix(in srgb, var(--ds-white) 13%, transparent),
              inset 0 -1px 0 0 color-mix(in srgb, var(--ds-black) 42%, transparent);
}

.ds-segmented-item:disabled,
.ds-segmented-item[aria-disabled="true"] {
  color: var(--ds-text-4);
  pointer-events: none;
}

/* Ocupa a largura toda e divide igual — o formato que sobrevive no mobile. */
.ds-segmented--full { display: flex; width: 100%; }
.ds-segmented--full .ds-segmented-item { flex: 1 1 0; }

/* Filtro de periodo em mono (7D, 30D, YTD). */
.ds-segmented--mono .ds-segmented-item {
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-micro);
  letter-spacing: var(--ds-track-label);
  text-transform: uppercase;
}


/* ============================================================================
   10. AVATAR — .ds-avatar
   Squircle, nao circulo: o raio da marca vale tambem aqui. Fallback com
   iniciais sobre trama, entao um avatar sem foto nunca fica como buraco.

   QUATRO ESTADOS, e eles sao diferentes de proposito:
     iniciais   ha' pessoa, nao ha' foto           (so' o texto no HTML)
     foto       ha' pessoa e ha' foto              (.ds-avatar-img)
     ghost      NAO ha' pessoa — e' o estado final (.ds-avatar--ghost)
     skeleton   ainda nao se sabe, esta' chegando  (.ds-avatar--skeleton)
   Trocar ghost por skeleton (ou vice-versa) mente pro usuario: um diz "nunca
   vai ter", o outro diz "espera um segundo".
   ========================================================================= */

.ds-avatar {
  position: relative;
  display: inline-grid;
  place-items: center;
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  overflow: hidden;
  border: 1px solid var(--ds-line);
  border-radius: var(--ds-r-md);
  background-color: var(--ds-surface-raised);
  background-image: radial-gradient(var(--ds-mesh-dot) 0.5px, transparent 0.5px);
  background-size: var(--ds-mesh-size) var(--ds-mesh-size);
  color: var(--ds-text-2);
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-xs);
  font-weight: 500;
  letter-spacing: var(--ds-track-label);
  text-transform: uppercase;
  text-indent: var(--ds-track-label); /* compensa o tracking na centralizacao */
  user-select: none;
}

/* Moldura: fio de luz na aresta de cima e penumbra no pe, POR CIMA da foto.
   Sem isto a imagem parece colada em cima do quadro; com isto ela parece estar
   DENTRO dele — e o avatar com foto passa a combinar com o de iniciais, que ja'
   ganhava essa leitura pela trama. Fica em ::after porque nenhum outro bloco
   deste arquivo usa pseudo-elemento em .ds-avatar (o ::before e' do ghost,
   logo abaixo, e os dois nunca convivem no mesmo elemento). */
.ds-avatar::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  border-radius: inherit;
  box-shadow:
    inset 0 1px 0 0 color-mix(in srgb, var(--ds-white) 14%, transparent),
    inset 0 -10px 16px -12px color-mix(in srgb, var(--ds-black) 90%, transparent);
}

/* --- avatar com foto ------------------------------------------------------
   ESTRUTURA (as iniciais continuam no HTML, como texto, mesmo tendo foto):

     <span class="ds-avatar">
       <img class="ds-avatar-img" src="…" alt="Daniel Okonam" data-initials="DO">
       DO
     </span>

   A foto e' ABSOLUTA e cobre as iniciais em vez de substituir elas. E' o que
   permite a queda graciosa: se a imagem nao carrega, o que sobra embaixo ja'
   e' o fallback correto, sem onerror, sem JS, sem classe extra. */
.ds-avatar img,
.ds-avatar-img {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  object-position: center;
  /* o recorte do squircle: o overflow:hidden do pai ja' corta, mas o Safari
     perde esse corte quando ha' transform na pilha (.ds-avatar-group:hover),
     e o raio proprio segura */
  border-radius: inherit;
}

/* IMAGEM QUEBRADA — a queda graciosa, sem JS.
   Enquanto a imagem carrega ok, o <img> e' elemento SUBSTITUIDO e o navegador
   ignora ::before/::after dele. No instante em que ela falha, ele deixa de ser
   substituido e os dois pseudos passam a existir. Entao estas duas regras so'
   pintam no estado de erro: o ::before tapa o icone de imagem quebrada com a
   mesma superficie do avatar e o ::after redesenha as iniciais a partir de
   data-initials.
   Safari nao gera pseudo-elemento em <img> nunca — la' o <img> quebrado vira
   uma caixa vazia e transparente, e aparecem as iniciais que estao no HTML
   embaixo. Os dois caminhos chegam no mesmo lugar; por isso as iniciais em
   texto NAO sao opcionais. */
.ds-avatar-img::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background-color: var(--ds-surface-raised);
  background-image: radial-gradient(var(--ds-mesh-dot) 0.5px, transparent 0.5px);
  background-size: var(--ds-mesh-size) var(--ds-mesh-size);
}

.ds-avatar-img::after {
  content: attr(data-initials);
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  border-radius: inherit;
  color: var(--ds-text-2);
  font-family: var(--ds-mono);
  font-size: inherit;
  font-weight: 500;
  letter-spacing: var(--ds-track-label);
  text-indent: var(--ds-track-label);
  text-transform: uppercase;
}

/* --- ghost: nao ha' pessoa ------------------------------------------------
   Placeholder de identidade desconhecida (convite pendente, autor removido,
   linha de auditoria sem dono). Silhueta desenhada em gradiente, em % pra
   escalar sozinha nos tres tamanhos. Nao e' skeleton: aqui nao esta carregando
   nada, este E' o estado final. */
.ds-avatar--ghost {
  color: transparent;   /* se houver iniciais no HTML, elas somem: nao ha' quem */
}

.ds-avatar--ghost::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background-image:
    radial-gradient(19% 19% at 50% 33%,
      color-mix(in srgb, var(--ds-white) 22%, transparent) 0 96%, transparent 100%),
    radial-gradient(33% 29% at 50% 101%,
      color-mix(in srgb, var(--ds-white) 22%, transparent) 0 96%, transparent 100%);
}

/* --- skeleton: esta carregando -------------------------------------------
   Estatico de proposito. A versao com brilho correndo e' .ds-skeleton (familia
   de overlays), e ela e' feita pra UM bloco grande. Avatar aparece em fileira
   de 5, 10, 40 — uma animacao infinita por avatar e' exatamente o orcamento
   que o sistema evita. O que marca "carregando" aqui e' o contraste rebaixado
   e a ausencia de qualquer marca de identidade. */
.ds-avatar--skeleton {
  color: transparent;
  background-color: var(--ds-surface-2);
  background-image:
    linear-gradient(105deg,
      transparent 30%,
      color-mix(in srgb, var(--ds-white) 6%, transparent) 50%,
      transparent 70%),
    radial-gradient(var(--ds-mesh-dot) 0.5px, transparent 0.5px);
  background-size: auto, var(--ds-mesh-size) var(--ds-mesh-size);
  border-color: var(--ds-line-faint);
}

/* No skeleton a moldura tambem apaga: um fio de luz forte num bloco de
   carregamento chama atencao pra um lugar que ainda nao tem dado. */
.ds-avatar--skeleton::after { box-shadow: none; }

.ds-avatar--sm {
  width: 26px;
  height: 26px;
  border-radius: var(--ds-r-sm);
  font-size: var(--ds-fs-micro);
}

.ds-avatar--lg {
  width: 52px;
  height: 52px;
  border-radius: var(--ds-r-lg);
  font-size: var(--ds-fs-base);
}

/* Circulo, quando o contexto exigir (foto de perfil dentro de menu). */
.ds-avatar--round { border-radius: var(--ds-r-pill); }

/* Anel azul pra marcar "voce" ou o item selecionado. */
.ds-avatar.is-active {
  border-color: color-mix(in srgb, var(--ds-blue) 45%, transparent);
  box-shadow: var(--ds-ring-blue);
}

/* --- pilha ---------------------------------------------------------------- */
.ds-avatar-group {
  display: inline-flex;
  align-items: center;
  padding-left: var(--ds-space-2);
}

.ds-avatar-group .ds-avatar {
  margin-left: calc(var(--ds-space-2) * -1);
  /* o "recorte" da pilha e' a propria cor da tela, nao uma borda clara */
  box-shadow: 0 0 0 2px var(--ds-canvas);
  transition: transform var(--ds-dur-2) var(--ds-ease);
}

.ds-avatar-group .ds-avatar:hover {
  transform: translateY(-3px);
  z-index: var(--ds-z-base);
}

/* Dentro de card, o recorte tem que ser da cor do card. */
.ds-card .ds-avatar-group .ds-avatar { box-shadow: 0 0 0 2px var(--ds-surface); }


/* ============================================================================
   11. TABELA — .ds-table
   Numero e' mono, tabular e alinhado a direita. Sempre. E' o que faz duas
   linhas de valor poderem ser comparadas de relance.
   ========================================================================= */

.ds-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--ds-fs-sm);
  color: var(--ds-text-2);
}

.ds-table-head th,
.ds-table-head .ds-table-cell,
.ds-table thead th {
  position: sticky;
  top: 0;
  z-index: var(--ds-z-base);
  padding: var(--ds-space-3) var(--ds-space-4);
  background-color: var(--ds-glass-strong);
  background-image: linear-gradient(180deg,
    color-mix(in srgb, var(--ds-white) 5%, transparent) 0,
    transparent 72%);
  border-bottom: 1px solid var(--ds-line);
  box-shadow: 0 12px 24px -24px var(--ds-black);
  color: var(--ds-text-3);
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-micro);
  font-weight: 500;
  letter-spacing: var(--ds-track-label);
  text-transform: uppercase;
  text-align: left;
  white-space: nowrap;
  -webkit-backdrop-filter: blur(var(--ds-blur-sm));
          backdrop-filter: blur(var(--ds-blur-sm));
}

.ds-table-row { transition: background-color var(--ds-dur-1) var(--ds-ease); }

.ds-table-cell,
.ds-table tbody td {
  padding: var(--ds-space-4);
  border-bottom: 1px solid var(--ds-line-faint);
  vertical-align: middle;
  /* A transicao mora na CELULA, nao na linha: quem pinta o fundo no hover sao
     os <td>, e uma transicao no <tr> nunca chegou a rodar. */
  transition: background-color var(--ds-dur-1) var(--ds-ease),
              color var(--ds-dur-1) var(--ds-ease);
}

/* A linha acende: tinta azul de verdade (nao um cinza a mais), texto puxado
   pro branco e a trama da marca aparecendo por baixo do dado. */
.ds-table-row:hover .ds-table-cell,
.ds-table tbody tr:hover td {
  background-color: color-mix(in srgb, var(--ds-blue) 9%, var(--ds-surface-2));
  background-image: radial-gradient(
    color-mix(in srgb, var(--ds-mesh-dot) 55%, transparent) 0.5px,
    transparent 0.5px);
  background-size: var(--ds-mesh-size) var(--ds-mesh-size);
  color: var(--ds-text-1);
}

/* Fio de luz na entrada da linha sob o cursor. Mais fraco que o da linha
   selecionada de proposito: hover e' passagem, .is-active e' escolha. */
.ds-table-row:hover .ds-table-cell:first-child,
.ds-table tbody tr:hover td:first-child {
  box-shadow: inset 2px 0 0 0 color-mix(in srgb, var(--ds-blue) 45%, transparent);
}

.ds-table-row:last-child .ds-table-cell,
.ds-table tbody tr:last-child td { border-bottom: 0; }

/* Primeira coluna carrega o nome da coisa: ela puxa o branco. */
.ds-table-cell--key {
  color: var(--ds-text-1);
  font-weight: 600;
}

/* Celula numerica: mono, tabular, direita. */
.ds-table-cell--num {
  font-family: var(--ds-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--ds-track-tight);
  text-align: right;
  white-space: nowrap;
  color: var(--ds-text-1);
}

/* Lucro e perda dentro da tabela seguem a mesma regra do delta do KPI. */
.ds-table-cell.is-up   { color: var(--ds-green); }
.ds-table-cell.is-down { color: var(--ds-red); }

/* Coluna de acoes, encostada na direita e sem quebrar. */
.ds-table-cell--actions {
  width: 1%;
  white-space: nowrap;
  text-align: right;
}

.ds-table-row.is-active .ds-table-cell,
.ds-table tbody tr.is-active td {
  background-color: color-mix(in srgb, var(--ds-blue) 11%, transparent);
  background-image: none;
  color: var(--ds-text-1);
}

/* Fio azul na borda esquerda da linha selecionada — cheio, com halo. */
.ds-table-row.is-active .ds-table-cell:first-child,
.ds-table tbody tr.is-active td:first-child {
  box-shadow: inset 3px 0 0 0 var(--ds-blue),
              inset 12px 0 20px -14px var(--ds-glow-blue);
}

.ds-table-foot td,
.ds-table tfoot td {
  padding: var(--ds-space-3) var(--ds-space-4);
  border-top: 1px solid var(--ds-line);
  color: var(--ds-text-3);
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-xs);
}

/* --- densa: pra tela de operacao, onde cabem 30 linhas ------------------- */
.ds-table--dense { font-size: var(--ds-fs-xs); }

.ds-table--dense .ds-table-cell,
.ds-table--dense tbody td {
  padding: var(--ds-space-2) var(--ds-space-3);
}

.ds-table--dense .ds-table-head th,
.ds-table--dense thead th {
  padding: var(--ds-space-2) var(--ds-space-3);
}

/* Zebra em trama, nao em cinza: a linha par recebe malha quase invisivel. */
.ds-table--mesh tbody tr:nth-child(even) td {
  background-image: radial-gradient(var(--ds-mesh-dot) 0.5px, transparent 0.5px);
  background-size: var(--ds-mesh-size) var(--ds-mesh-size);
}

@media (max-width: 767px) {
  .ds-table { font-size: var(--ds-fs-xs); }
  .ds-table-cell,
  .ds-table tbody td { padding: var(--ds-space-3); }
}


/* ============================================================================
   12. SCROLL — .ds-scroll
   Barra fina e discreta. Aplique no wrapper de tabela, de lista lateral e no
   corpo de qualquer poco que role.
   ========================================================================= */

.ds-scroll {
  overflow: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--ds-line-strong) transparent;
  overscroll-behavior: contain;
}

.ds-scroll--x { overflow-x: auto; overflow-y: hidden; }
.ds-scroll--y { overflow-x: hidden; overflow-y: auto; }

.ds-scroll::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

.ds-scroll::-webkit-scrollbar-track {
  background: transparent;
}

.ds-scroll::-webkit-scrollbar-thumb {
  background-color: var(--ds-line-strong);
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: var(--ds-r-pill);
}

.ds-scroll::-webkit-scrollbar-thumb:hover {
  background-color: var(--ds-text-3);
}

.ds-scroll::-webkit-scrollbar-corner { background: transparent; }


/* ============================================================================
   13. RESPONSIVO DO SHELL
   Abaixo de 1024px o rail vira gaveta: sai da grade e desliza por cima.
   O scrim/overlay NAO e' deste arquivo — ele mora na familia de overlay.
   ========================================================================= */

@media (max-width: 1023px) {
  .ds-app {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "topbar"
      "main";
  }

  .ds-app > .ds-sidebar {
    position: fixed;
    top: 0;
    left: 0;
    z-index: var(--ds-z-drawer);
    width: 272px;
    transform: translateX(-100%);
    box-shadow: var(--ds-e4);
  }

  /* .is-open e' ligado por JS no botao de menu da topbar. */
  .ds-app > .ds-sidebar.is-open { transform: translateX(0); }

  /* Colapsado nao faz sentido em gaveta: ela abre inteira ou nao abre. */
  .ds-sidebar--collapsed { width: 272px; }
  .ds-sidebar--collapsed .ds-sidebar-item { justify-content: flex-start; padding-inline: var(--ds-space-3); }
  .ds-sidebar--collapsed .ds-sidebar-item-label,
  .ds-sidebar--collapsed .ds-sidebar-item-trail { display: block; }
}


/* ============================================================================
   NOTAS DE DECISAO (pra proxima pessoa que abrir este arquivo)

   1. NAO existe .ds-btn--success nem botao verde. Verde e' conversao/lucro:
      se todo "salvar" fosse verde, o verde deixaria de significar dinheiro.
      Acao primaria e' azul. Se um dia precisar de um botao de checkout de
      verdade, ele nasce na familia de marketing, nao aqui.

   2. color-mix() aparece bastante pra tinta de fundo e de borda. Nao e' cor
      literal: o argumento e' sempre um token --ds-*. Foi a forma de ter 8%,
      12% e 26% de azul/verde/vermelho sem inventar 12 tokens novos.

   3. Onde o desenho pediu um valor que nao existe em token — altura de
      controle (30/38/40/46px), largura do rail (264/76px), tamanho de avatar
      — o numero esta literal mesmo. Token de dimensao de componente nao
      existe no arquivo de tokens e nao cabia a este arquivo criar.

   4. :has() e' usado em .ds-switch / .ds-checkbox / .ds-radio so pra apagar
      o rotulo quando o input esta disabled. Navegador sem :has() perde o
      cinza do texto e mais nada — o controle continua correto.

   5. ROSA entrou como a cor de ENERGIA (.ds-card--pink, .ds-card--rays,
      .ds-btn--pink, .ds-kpi-delta.is-alert). Ele nao informa valor: numero de
      dinheiro continua verde/vermelho. O teste e' simples — se o rosa esta
      dizendo "quanto", esta errado; se esta dizendo "olha isto", esta certo.
      Rosa tambem e' o estado de ATENCAO, o papel que amarelo cumpre em outros
      sistemas. NAO existe amarelo/dourado/ambar aqui.

   6. A profundidade do card e da acao primaria e' montada em VARIAVEL interna
      (--_ds-card-top / -edge / -shadow / -lift, --_ds-btn-cor / -glow), nao
      em box-shadow reescrito por variante. Se voce for adicionar um modo
      novo de card, troque as variaveis; reescrever a pilha de sombra apaga o
      fio de luz da borda de cima e o card volta a parecer chapado.

   7. .ds-card--rays custa 5 camadas de background. E' o card heroi, UM por
      tela. Os raios sao conic com parada dura (borda nitida, nao blur) e quem
      os apaga com a distancia e' um veu radial da propria cor de superficie —
      por isso nao ha mask no elemento e o miolo do card continua legivel.

   8. .ds-kpi-value usa background-clip:text pra o degrade do numero, dentro de
      @supports. Consequencia: -webkit-text-fill-color e' herdado, entao todo
      filho do valor precisa de reset (ja feito pra .ds-kpi-unit e .ds-badge).
      Se voce puser outro elemento dentro do valor, inclua ele nesse reset ou
      ele sai invisivel.

   9. AVATAR COM FOTO: as iniciais continuam no HTML mesmo quando ha' <img>. A
      foto e' absoluta e COBRE elas; nao substitui. Isso e' o que faz a imagem
      quebrada cair no fallback certo sem uma linha de JS. Chrome e Firefox
      pintam ::before/::after do <img> quebrado (o navegador para de tratar ele
      como elemento substituido) e a gente redesenha a superficie + o
      data-initials ali; o Safari nao gera esses pseudos nunca, e la' o <img>
      quebrado vira caixa vazia deixando as iniciais de baixo aparecerem. Os
      dois caminhos so' funcionam porque o texto esta' no HTML. Se alguem
      "limpar" as iniciais achando que a foto basta, o fallback do Safari vira
      um quadrado vazio.

  10. O CONTRASTE DO SELO PREENCHIDO nao e' chute. Nenhum tom puro da marca
      passa em fundo cheio com texto branco (azul 4,02:1, vermelho 4,06:1,
      rosa 4,01:1 — reprovam ate' no AA). Por isso .ds-badge--solid escurece
      cada matiz por color-mix com preto (azul 62% -> 8,3:1, vermelho 58% ->
      9,4:1), usa o token --ds-pink-deep pronto no rosa (7,59:1) e inverte a
      tinta no verde, que e' claro demais (--ds-text-on-accent, 13,6:1). Se
      voce criar uma cor solida nova, meca antes: tinta clara sobre matiz puro
      da marca reprova por padrao.

  11. O CAMPO DE FORMULARIO GANHOU CEU. .ds-input/.ds-select/.ds-textarea
      montam um poco de verdade com duas variaveis (--_ds-poco-teto, a sombra
      do teto; --_ds-poco-luz, a luz que nasce no fundo do vao e sobe) e uma
      pilha FIXA de 5 sombras. Estado troca so' as variaveis. Duas armadilhas:
        - nao reescreva a pilha de box-shadow numa variante nova: com contagem
          diferente entre repouso e foco, a transicao para de interpolar e o
          anel aparece de estalo;
        - nao use background-image:none pra apagar o campo desligado. A seta do
          .ds-select mora nesse mesmo background (select e' elemento
          substituido: nao aceita ::before, ::after nem filho estilizavel), e
          zerar a imagem tira a seta junto. Apague pelas variaveis.

  12. .ds-select tem SEIS camadas de background e o motivo e' o conceito de
      janela: como o elemento nao aceita pseudo nem filho, recorte + camadas +
      luz de dentro tiveram que caber todos em background — seta (2), divisoria
      de 1px do compartimento (1), halo pontual atras da seta (1), ceu do poco
      (1) e sombra do teto (1). background-position e background-size sao listas
      posicionais: se voce inserir ou remover uma camada, as tres listas tem que
      ser mexidas juntas ou tudo desalinha silenciosamente.

  13. SUTILEZA DE DEGRADE (secao 9) tem numero: amplitude entre 3% e 10%, rampa
      morrendo entre 58% e 100% do percurso, e a cor derivando da superficie de
      baixo (branco pra luz, preto pra sulco) em vez de uma cor de acento
      colada por cima. Acima de ~15% em rampa curta, o olho para de ler "luz" e
      passa a ler "degrade aplicado". O acento continua permitido no INDICADOR
      (a barra da aba ativa), que e' firme e de quina dura — o que ficou proibido
      e' o degrade decorativo.
   ========================================================================= */
