/* Utilitarios de cor semantica para o painel.
 *
 * O Basecoat entrega SO classes de componente (.btn, .card, .badge...). Ele nao
 * entrega utilitarios de cor. E as classes equivalentes do Tailwind v3 deste
 * repo sao invalidas aqui: o tailwind.config mapeia, por exemplo,
 * muted-foreground para hsl(var(--muted-foreground)), enquanto o Basecoat
 * define essa variavel em oklch — o resultado vira hsl(oklch(...)), que o
 * navegador descarta em silencio.
 *
 * Entao as poucas cores semanticas que o painel precisa sao definidas aqui,
 * lendo direto as variaveis --color-* do Basecoat.
 *
 * Carregar SEMPRE depois do basecoat.min.css.
 */

.text-foreground { color: var(--color-foreground); }
.text-muted-foreground { color: var(--color-muted-foreground); }
.text-primary { color: var(--color-primary); }
.text-primary-foreground { color: var(--color-primary-foreground); }
.text-secondary-foreground { color: var(--color-secondary-foreground); }
.text-accent-foreground { color: var(--color-accent-foreground); }
.text-destructive { color: var(--color-destructive); }
.text-card-foreground { color: var(--color-card-foreground); }

.bg-background { background-color: var(--color-background); }
.bg-foreground { background-color: var(--color-foreground); }
.bg-muted { background-color: var(--color-muted); }
.bg-card { background-color: var(--color-card); }
.bg-primary { background-color: var(--color-primary); }
.bg-secondary { background-color: var(--color-secondary); }
.bg-accent { background-color: var(--color-accent); }
.bg-destructive { background-color: var(--color-destructive); }
.bg-popover { background-color: var(--color-popover); }

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

.ring-ring { --tw-ring-color: var(--color-ring); }


/* ==========================================================================
 * UI COLOR KIT — base
 *
 * O tema padrao do Basecoat e cinza puro (croma 0). Aqui os neutros ganham um
 * traco minimo da marca: hue 192, o mesmo do verde-pinho do logo (#002c2b =
 * oklch(26.5% 0.045 192.4)). O croma fica entre 0.003 e 0.015 — a olho continua
 * neutro, mas para de brigar com a marca. Verde saturado NAO entra na interface:
 * ele aparece so no primary (acao) e no foco.
 *
 * Demarcacao: o canvas deixa de ser branco puro e o card continua branco, entao
 * todo card "levanta" do fundo sem precisar de sombra pesada. Antes os dois eram
 * oklch(100%) e nada separava um do outro.
 * ========================================================================== */

:root {
  /*
   * Raio base. O Basecoat deriva toda a escala daqui:
   *   --radius-sm = raio - 4px | --radius-md = raio - 2px
   *   --radius-lg = raio       | --radius-xl = raio + 4px
   * e o tailwind.config aponta rounded-sm/md/lg/xl para as mesmas contas.
   * Mudar este valor unico reaperta o painel inteiro.
   */
  --radius: 5px;

  /* Tipografia do painel. O Basecoat aponta --font-sans para "Geist Sans", que
     nao e carregada em lugar nenhum — o painel caia no system-ui do sistema.
     "Plus Jakarta Sans Fallback" fica na frente das genericas para o caso de
     alguem definir a metrica de fallback; se nao existir, o navegador so pula
     para a proxima. */
  --font-sans: "Plus Jakarta Sans", "Plus Jakarta Sans Fallback", ui-sans-serif,
    system-ui, -apple-system, "Segoe UI", sans-serif, "Apple Color Emoji",
    "Segoe UI Emoji";

  --background: oklch(98.4% 0.003 192);
  --foreground: oklch(18% 0.012 192);

  --card: oklch(100% 0 0);
  --card-foreground: oklch(18% 0.012 192);
  --popover: oklch(100% 0 0);
  --popover-foreground: oklch(18% 0.012 192);

  /* Acao principal = verde-pinho da marca. Em botao lê quase preto-esverdeado:
     presenca de marca sem poluir. Texto branco sobre ele da 14.4:1. */
  --primary: oklch(26.5% 0.045 192.4);
  --primary-foreground: oklch(98.5% 0.005 192);

  --secondary: oklch(96.5% 0.006 192);
  --secondary-foreground: oklch(26.5% 0.045 192.4);
  --muted: oklch(96.5% 0.006 192);
  --muted-foreground: oklch(50% 0.015 192);   /* 5.95:1 no card */
  --accent: oklch(95.5% 0.012 192);
  --accent-foreground: oklch(26.5% 0.045 192.4);

  /* Linhas: a borda antiga (92.2%) sumia no branco. Input mais forte que border
     porque ali a linha e a unica pista de que o campo e editavel. */
  --border: oklch(88.5% 0.008 192);
  --input: oklch(80% 0.014 192);

  /* Foco no teal da marca (#007875) — 5.33:1 sobre branco. */
  --ring: oklch(51.7% 0.089 191.7);

  /* ------------------------------------------------------------------------
   * ESPINHA — a sidebar e a unica superficie escura do painel.
   *
   * Motivo: o conteudo precisa ser neutro (card branco sobre canvas quase
   * branco), entao sobrava zero lugar para a marca aparecer. Com sidebar
   * branca o painel era branco sobre branco sobre quase-branco e a borda
   * fazia todo o trabalho de separacao.
   *
   * O verde-pinho e' o $overlap de dash/_variables.scss (#002c2b), o mesmo
   * theme_color do PWA. O logo knockout que ele pede ja existe no repo desde
   * o painel Tabler: /img/logo-horizontal-lime.png.
   *
   * O Basecoat le SO estas variaveis para desenhar a sidebar inteira
   * (.sidebar nav usa --color-sidebar/--color-sidebar-foreground; hover e
   * [aria-current=page] usam --color-sidebar-accent). Por isso a virada e'
   * feita aqui e nao no markup do menu.
   * ---------------------------------------------------------------------- */
  --sidebar: oklch(26.5% 0.045 192.4);
  --sidebar-foreground: oklch(86% 0.022 185);
  /* Destaque = verde-limao da marca ($light_green #E3FFCC), knockout sobre o
     pinho. E' o unico ponto de cor viva da casca. */
  --sidebar-primary: oklch(96.8% 0.07 128);
  --sidebar-primary-foreground: oklch(26.5% 0.045 192.4);
  --sidebar-accent: oklch(32% 0.042 192.4);
  --sidebar-accent-foreground: oklch(98.5% 0.005 192);
  --sidebar-border: oklch(36% 0.032 192.4);
  --sidebar-ring: oklch(72% 0.075 191.7);

  /* Series de grafico — categoricas, ordem fixa, nunca ciclada.
     Validadas em scripts/validate_palette.js (faixa de luminosidade, piso de
     croma, separacao para daltonismo e contraste com a superficie). */
  /* Os dois primeiros slots atendem o caso comum do painel — dinheiro e volume —
     e sao os tons mais claros que ainda dao 3:1 sobre o canvas. Mais claro que
     isto a linha fina comeca a sumir no fundo.
     A ordem dos demais mantem distancia entre vizinhos: azul e violeta juntos
     reprovavam a separacao (dE 3,4 em protanopia), por isso o ambar entra entre
     os dois. */
  --chart-1: #3EB268;  /* verde  — R$ / faturamento */
  --chart-2: #4BA1ED;  /* azul   — quantidade */
  --chart-3: #B45309;
  --chart-4: #7C3AED;
  --chart-5: #BE185D;
  --chart-6: #4D7C0F;
}

html.dark {
  --background: oklch(15.5% 0.008 192);
  --foreground: oklch(97% 0.004 192);
  --card: oklch(20.5% 0.01 192);
  --card-foreground: oklch(97% 0.004 192);
  --popover: oklch(20.5% 0.01 192);
  --popover-foreground: oklch(97% 0.004 192);

  --primary: oklch(72% 0.075 191.7);
  --primary-foreground: oklch(18% 0.02 192);

  --secondary: oklch(26% 0.012 192);
  --secondary-foreground: oklch(97% 0.004 192);
  --muted: oklch(26% 0.012 192);
  --muted-foreground: oklch(71% 0.015 192);
  --accent: oklch(29% 0.016 192);
  --accent-foreground: oklch(97% 0.004 192);

  --border: oklch(30% 0.014 192);
  --input: oklch(36% 0.016 192);
  --ring: oklch(65% 0.09 191.7);

  /* No escuro a espinha continua sendo a superficie mais escura da tela — ela
     ancora o layout do mesmo jeito, so que por baixo do canvas em vez de por
     cima. O destaque segue no verde-limao. */
  --sidebar: oklch(18% 0.018 192.4);
  --sidebar-foreground: oklch(86% 0.022 185);
  --sidebar-primary: oklch(96.8% 0.07 128);
  --sidebar-primary-foreground: oklch(18% 0.02 192);
  --sidebar-accent: oklch(25% 0.024 192.4);
  --sidebar-accent-foreground: oklch(97% 0.004 192);
  --sidebar-border: oklch(30% 0.022 192.4);
  --sidebar-ring: oklch(72% 0.075 191.7);

  --chart-1: #36AC62;
  --chart-2: #4098E3;
  --chart-3: #CA6728;
  --chart-4: #9257FF;
  --chart-5: #E04178;
  --chart-6: #669733;
}

/* --------------------------------------------------------------------------
 * Tons semanticos: success / warning / info
 *
 * O tema padrao do Basecoat so tem primary, secondary, destructive e muted.
 * O painel precisa de "deu certo", "atencao" e "informativo" em varios lugares
 * (status da loja, status da IA, tiles do dashboard, alertas, badges).
 *
 * Definidos aqui em oklch, no mesmo formato do Basecoat, com variante dark —
 * em vez de rgba fixo espalhado por arquivo, que nao acompanha o dark mode.
 * -------------------------------------------------------------------------- */

/*
 * Cada tom tem QUATRO papeis, e trocar um pelo outro e' o erro comum:
 *   --color-X              preenchimento solido (botao, barra, ponto)
 *   --color-X-foreground   texto SOBRE o solido
 *   --color-X-muted        fundo opaco do badge/tile
 *   --color-X-on-muted     texto SOBRE o fundo opaco  <- este faltava
 *
 * Antes o badge usava --color-X como texto sobre o tint. Medido: success 2.94:1,
 * warning 1.88:1, info 3.15:1, destructive 4.06:1 — todos abaixo de 4.5:1.
 * O -on-muted e a mesma cor rebaixada ate passar sobre o tint E sobre o branco.
 */
:root {
  --color-success: oklch(62.7% 0.17 149.2);
  --color-success-foreground: oklch(98% 0.02 149.2);
  --color-success-muted: oklch(95.8% 0.055 149.2);
  --color-success-on-muted: oklch(52.6% 0.15 149.2);      /* 4.52:1 no tint */

  --color-warning: oklch(76.9% 0.163 70.1);
  --color-warning-foreground: oklch(27% 0.06 70.1);
  --color-warning-muted: oklch(96% 0.075 70.1);
  --color-warning-on-muted: oklch(53.3% 0.13 70.1);       /* 4.51:1 no tint */

  --color-info: oklch(62.3% 0.155 253.1);
  --color-info-foreground: oklch(98% 0.02 253.1);
  --color-info-muted: oklch(95.8% 0.05 253.1);
  --color-info-on-muted: oklch(53.7% 0.14 253.1);         /* 4.50:1 no tint */

  --color-destructive-muted: oklch(96% 0.045 27.325);
  --color-destructive-on-muted: oklch(55.1% 0.19 27.325); /* 4.50:1 no tint */

  --color-primary-muted: oklch(96.2% 0.03 192.4);
  --color-primary-on-muted: oklch(26.5% 0.045 192.4);
}

html.dark {
  --color-success: oklch(72.3% 0.16 149.2);
  --color-success-foreground: oklch(20% 0.03 149.2);
  --color-success-muted: oklch(27% 0.05 149.2);

  --color-warning: oklch(82% 0.15 70.1);
  --color-warning-foreground: oklch(20% 0.04 70.1);
  --color-warning-muted: oklch(28% 0.05 70.1);

  --color-info: oklch(70.4% 0.15 253.1);
  --color-info-foreground: oklch(20% 0.03 253.1);
  --color-info-muted: oklch(27% 0.05 253.1);
  --color-destructive-muted: oklch(27% 0.05 27.325);

  /* No escuro o tint e' escuro, entao o texto sobe de luminosidade em vez de descer. */
  --color-success-on-muted: oklch(84% 0.14 149.2);
  --color-warning-on-muted: oklch(87% 0.13 70.1);
  --color-info-on-muted: oklch(84% 0.12 253.1);
  --color-destructive-on-muted: oklch(80% 0.13 27.325);
  --color-primary-muted: oklch(27% 0.04 192.4);
  --color-primary-on-muted: oklch(84% 0.08 191.7);
}

/* Texto/icone sobre superficie clara usa a versao rebaixada: a cor de
   preenchimento nao tem contraste suficiente como texto. */
.text-success { color: var(--color-success-on-muted); }
.text-warning { color: var(--color-warning-on-muted); }
.text-info    { color: var(--color-info-on-muted); }

.bg-success { background-color: var(--color-success); color: var(--color-success-foreground); }
.bg-warning { background-color: var(--color-warning); color: var(--color-warning-foreground); }
.bg-info    { background-color: var(--color-info);    color: var(--color-info-foreground); }

/* Tints — fundo suave com texto na cor forte, pra tiles e destaques. */
.bg-success-muted { background-color: var(--color-success-muted); color: var(--color-success-on-muted); }
.bg-warning-muted { background-color: var(--color-warning-muted); color: var(--color-warning-on-muted); }
.bg-info-muted    { background-color: var(--color-info-muted);    color: var(--color-info-on-muted); }
.bg-destructive-muted { background-color: var(--color-destructive-muted); color: var(--color-destructive-on-muted); }

.border-success { border-color: var(--color-success); }
.border-warning { border-color: var(--color-warning); }
.border-info    { border-color: var(--color-info); }

/* Estende os componentes do Basecoat com os mesmos tons. */
/* Mesmo tratamento do destructive do Basecoat: fundo com 10% da cor e texto
   na cor cheia. O preenchimento solido ficava gritante demais na topbar. */
.badge[data-variant='success'] {
  background-color: var(--color-success-muted);
  color: var(--color-success-on-muted);
  border-color: transparent;
}
.badge[data-variant='warning'] {
  background-color: var(--color-warning-muted);
  color: var(--color-warning-on-muted);
  border-color: transparent;
}
.badge[data-variant='info'] {
  background-color: var(--color-info-muted);
  color: var(--color-info-on-muted);
  border-color: transparent;
}

.alert[data-variant='success'] { border-color: var(--color-success); color: var(--color-success); }
.alert[data-variant='warning'] { border-color: var(--color-warning); color: var(--color-warning); }
.alert[data-variant='info']    { border-color: var(--color-info);    color: var(--color-info); }

/* Variantes de botao nos tons semanticos.
 * Precisam existir como .btn[data-variant=...] (especificidade 0,2,0) porque
 * uma classe utilitaria solta (0,1,0) perde para .btn:not([data-variant]). */
.btn[data-variant='success'] {
  background-color: var(--color-success);
  color: var(--color-success-foreground);
  border-color: transparent;
}
.btn[data-variant='success']:hover { background-color: color-mix(in oklab, var(--color-success) 88%, black); }
.btn[data-variant='success']:focus-visible { outline-color: var(--color-success); }

.btn[data-variant='warning'] {
  background-color: var(--color-warning);
  color: var(--color-warning-foreground);
  border-color: transparent;
}
.btn[data-variant='warning']:hover { background-color: color-mix(in oklab, var(--color-warning) 88%, black); }
.btn[data-variant='warning']:focus-visible { outline-color: var(--color-warning); }

.btn[data-variant='info'] {
  background-color: var(--color-info);
  color: var(--color-info-foreground);
  border-color: transparent;
}
.btn[data-variant='info']:hover { background-color: color-mix(in oklab, var(--color-info) 88%, black); }
.btn[data-variant='info']:focus-visible { outline-color: var(--color-info); }

/* --------------------------------------------------------------------------
 * Botao de fechar do dialog
 *
 * O Basecoat ja posiciona no canto qualquer <button> que seja filho DIRETO do
 * container do dialog (.dialog>*>button). Mas o nosso X esta dentro do
 * <header>, que e flex-column — por isso caia numa linha abaixo do titulo.
 * Aplica as mesmas regras do Basecoat ao botao dentro do header, em vez de
 * mexer nos 21 arquivos que usam esse padrao.
 * -------------------------------------------------------------------------- */
.dialog > * > header > button[aria-label='Fechar'] {
  position: absolute;
  inset-inline-end: calc(var(--spacing) * 4);
  top: calc(var(--spacing) * 4);
  opacity: 0.7;
}

.dialog > * > header > button[aria-label='Fechar']:hover {
  opacity: 1;
}

/* Espaco pro X nao encostar num titulo longo. */
.dialog > * > header:has(> button[aria-label='Fechar']) > h2,
.dialog > * > header:has(> button[aria-label='Fechar']) > p {
  padding-right: calc(var(--spacing) * 8);
}

/* --------------------------------------------------------------------------
 * SVG dentro de .text-center
 *
 * O preflight do Basecoat define img/svg/video como display:block. Antes, com
 * o reboot do Bootstrap, svg era inline e text-center dava conta de
 * centralizar. Agora um bloco ignora text-align, e todo icone de dropzone /
 * estado vazio ficava encostado a esquerda.
 * -------------------------------------------------------------------------- */
.text-center > svg,
.text-center > label > svg {
  margin-inline: auto;
}

/* --------------------------------------------------------------------------
 * Estado vazio de widget
 *
 * O texto explicativo ocupa o lugar de um numero grande. Sem isso ele herda o
 * text-3xl/font-bold do valor e fica gritando na tela.
 * -------------------------------------------------------------------------- */
.is-empty {
  font-size: var(--text-sm);
  font-weight: 400;
  line-height: 1.35;
  color: var(--color-muted-foreground);
}

/* --------------------------------------------------------------------------
 * Modal: o conteudo rola dentro, nunca escapa da caixa.
 *
 * O Basecoat limita a altura da caixa (.dialog > * { max-height: calc(100% - 2rem) })
 * mas deixa overflow visible e nao define rolagem em lugar nenhum. Resultado
 * medido num modal de pedido com a caixa em 260px: o conteudo seguia 357px
 * para fora, passando por cima do fundo arredondado e do backdrop.
 *
 * A caixa ja e' flex column, entao basta: esconder o transbordo nela e deixar
 * o <section> (o corpo) rolar. Cabecalho e rodape ficam fixos, que e' o
 * comportamento esperado de um modal — o botao de confirmar nao pode sumir
 * junto com o scroll.
 *
 * min-height:0 e' o que permite um filho flex encolher abaixo do proprio
 * conteudo; sem ele o <section> continuaria empurrando a caixa.
 * -------------------------------------------------------------------------- */
.dialog > *,
.alert-dialog > * {
  overflow: hidden;
}

.dialog > * > section,
.alert-dialog > * > section {
  min-height: 0;
  overflow-y: auto;
  /* Nao encadeia a rolagem para a pagina atras do modal. */
  overscroll-behavior: contain;
}



/* --------------------------------------------------------------------------
 * Casca do SweetAlert (ver public/js/panel-swal-toplayer.js)
 *
 * O container do Swal passa a viver dentro de um <dialog> proprio, aberto com
 * showModal — e o ultimo modal aberto e sempre o de cima. Aqui a casca perde
 * todo o estilo padrao de <dialog> (borda, padding, fundo, largura limitada)
 * para virar apenas uma camada transparente do tamanho da tela.
 * -------------------------------------------------------------------------- */
dialog[data-swal-host] {
  position: fixed;
  inset: 0;
  width: 100vw;
  max-width: 100vw;
  height: 100vh;
  max-height: 100vh;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  overflow: visible;
}

/* O escurecido quem faz e o proprio Swal; o backdrop da casca some. */
dialog[data-swal-host]::backdrop {
  background: transparent;
}

/* z-index alto ainda ajuda nos modais comuns, que empilham normalmente. */
.swal2-container {
  z-index: 2147483647;
}

/*
 * Menu de select promovido ao top layer (panel-popover-toplayer.js).
 *
 * O Basecoat aplica `transition: all` no popover. Ao reposiciona-lo em
 * coordenadas de viewport, top e left entram em transicao e ficam presos no
 * valor antigo — medido: inline top 200px com o computado ainda em 1211px, o
 * menu desenhado fora da tela. Aqui a posicao precisa valer na hora.
 */
[data-popover][data-no-top-layer],
.ts-dropdown[data-no-top-layer] {
  transition: opacity 0.1s linear !important;
  /*
   * O Basecoat dimensiona o menu com `width: max-content` e `min-width: 100%`.
   * Os dois passam a se resolver contra a viewport quando o menu vira fixed —
   * 100% viram a largura da tela inteira. A largura util e a do campo, escrita
   * inline pelo panel-popover-toplayer.js.
   */
  min-width: 0 !important;
  max-width: calc(100vw - 16px) !important;
}

/* Botao de confirmacao de acao destrutiva (window.confirmarAcao). */
.swal2-confirm-perigo {
  background-color: var(--color-destructive) !important;
  color: var(--color-destructive-foreground, #fff) !important;
}

/* ==========================================================================
 * TITULO DE CARD
 *
 * Padrao do painel: <h3> sem margem e em bold. O Basecoat entrega o titulo do
 * card em font-medium; aqui ele vira bold e a margem some, para que todo card
 * tenha o mesmo peso de titulo, com ou sem classe inline.
 * ========================================================================== */
.card > header :is(h1, h2, h3, h4, h5, h6, [data-title], .card-title) {
  margin: 0;
  font-weight: 700;
}

/*
 * Com o titulo sem margem, a descricao logo abaixo precisa do respiro — o
 * <p> tambem vem zerado pelo preflight. Vale so fora do <header> (que ja tem
 * gap proprio) e cede para qualquer utilitario mt-* escrito no proprio <p>.
 */
:where(.card) :not(header) > :is(h1, h2, h3, h4, h5, h6) + :is(p, .card-text) {
  margin-top: calc(var(--spacing, 0.25rem) * 2);
}

/* ==========================================================================
 * ESPACAMENTO ENTRE CAMPOS DE FORMULARIO
 *
 * O .field do Basecoat nao tem margem: campos empilhados encostam um no outro
 * quando o pai nao define gap. A regra vale so entre irmaos (nunca no primeiro
 * campo) e fica fora de pais com layout proprio (.grid/.flex, que ja tem gap).
 * Especificidade zero via :where() — qualquer utilitario de margem no proprio
 * campo continua vencendo.
 * ========================================================================== */
:where(:not(.grid, .flex, .fieldset) > .field + .field),
:where(:not(.grid, .flex) > .form-group + .form-group) {
  margin-top: calc(var(--spacing, 0.25rem) * 4);
}

/* Legado Bootstrap: .form-group ainda aparece em modais nao migrados. */
:where(.form-group) {
  margin-bottom: calc(var(--spacing, 0.25rem) * 4);
}


/* ==========================================================================
 * TRILHO
 *
 * A assinatura visual do painel: uma barra fina na borda de ataque de tudo
 * que tem estado — cartao de pedido, linha de tabela com pendencia, alerta,
 * tile de indicador.
 *
 * A regra que faz o trilho funcionar nao esta neste arquivo, esta na cabeca de
 * quem escreve a tela:
 *
 *   COR SO EXISTE NO TRILHO E NO GRAFICO. Todo o resto e' tinta sobre papel.
 *
 * Ou seja: indicador nao e' verde, badge de "nao conectado" nao e' vermelho,
 * marca de canal (iFood, Instagram) nao ganha cor. Quando tudo e' colorido a
 * cor para de avisar — foi assim que o painel passou a piscar dois alarmes
 * falsos na topbar a cada load sem ninguem reclamar.
 *
 * O trilho codifica URGENCIA NO TEMPO, nunca categoria e nunca marca. E a
 * AUSENCIA dele e' o estado normal: um quadro sem trilho nenhum quer dizer que
 * esta tudo certo. E' o mesmo principio ja escrito na faixa de atencao do
 * dashboard — "o silencio vira informacao" — agora com forma grafica.
 *
 * Os tons reaproveitam os semanticos que ja existem acima; nao entra paleta
 * nova no sistema so por causa deste componente.
 *
 * Uso:
 *   <div class="card trilho" data-tom="critico"> ... </div>
 *   <tr class="trilho" data-tom="atencao"> ... </tr>
 * ========================================================================== */

.trilho {
  position: relative;
  /* overflow:hidden faz o trilho respeitar o border-radius do elemento. */
  overflow: hidden;
}

.trilho[data-tom]::before {
  content: '';
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  width: 4px;
  background: var(--trilho-cor);
  /* Fica por baixo de qualquer conteudo posicionado do card. */
  z-index: 0;
}

/*
 * O trilho NAO empurra o conteudo.
 *
 * A primeira versao adicionava padding-inline-start no elemento com data-tom.
 * Isso so' serve para bloco sem padding proprio — e quase nenhum caso real e'
 * assim: card, alert e linha de tabela ja tem o seu, entao o recuo dobrava e o
 * cartao com trilho ficava desalinhado dos vizinhos sem trilho, dentro da mesma
 * coluna. Como a barra tem 4px e o padding existente e' de 12 a 16px, ela cabe
 * dentro do respiro que ja existe. Quem precisar de folga extra adiciona no
 * proprio elemento.
 */

/* <tr> nao aceita padding-inline-start util nem overflow:hidden; ali o trilho
   vira uma borda na primeira celula. */
tr.trilho[data-tom] {
  overflow: visible;
  padding-inline-start: 0;
}
tr.trilho[data-tom]::before {
  content: none;
}
tr.trilho[data-tom] > :first-child {
  box-shadow: inset 4px 0 0 0 var(--trilho-cor);
}

.trilho[data-tom='critico'] { --trilho-cor: var(--color-destructive); }
.trilho[data-tom='atencao'] { --trilho-cor: var(--color-warning); }
.trilho[data-tom='calmo']   { --trilho-cor: var(--color-success); }
.trilho[data-tom='espera']  { --trilho-cor: var(--color-info); }


/* ==========================================================================
 * WIDGET — carregando e falha
 *
 * O painel renderiza os numeros zerados no servidor e troca por AJAX depois
 * (Sys.renderizarWidget em public/js/functions.js). Sem estes dois estados, as
 * tres situacoes abaixo tinham EXATAMENTE a mesma aparencia na tela que o dono
 * usa para decidir:
 *
 *   1. ainda carregando          -> "R$ 0,00"
 *   2. dia realmente sem venda   -> "R$ 0,00"
 *   3. API do widget caiu        -> "R$ 0,00"
 *
 * O caso 3 era o pior: o `if (!res.error)` nao tinha `else`, entao a falha nao
 * fazia nada e a tela seguia afirmando que nao houve venda.
 * ========================================================================== */

/* Carregando: o valor vira uma barra cinza com a mesma largura que teria. Nao
   some, para o layout nao pular quando o numero chegar. */
.widget-carregando [data-name] {
  color: transparent !important;
  border-radius: var(--radius-sm);
  background-image: linear-gradient(
    90deg,
    var(--color-muted) 25%,
    color-mix(in oklab, var(--color-muted) 55%, var(--color-border)) 37%,
    var(--color-muted) 63%
  );
  background-size: 400% 100%;
  animation: widget-esqueleto 1.4s ease infinite;
  /* Elemento inline (span, a) precisa ganhar caixa para pintar o fundo. */
  display: inline-block;
  min-width: 3ch;
}

.widget-carregando [data-name] * {
  visibility: hidden;
}

@keyframes widget-esqueleto {
  0%   { background-position: 100% 50%; }
  100% { background-position: 0 50%; }
}

@media (prefers-reduced-motion: reduce) {
  .widget-carregando [data-name] { animation: none; }
}

/* Falha: o aviso entra dentro da propria caixa, junto do numero que ele
   desmente. Um SweetAlert global nao serviria — ele some, o numero errado fica. */
.widget-erro {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: calc(var(--spacing) * 3);
  margin-bottom: calc(var(--spacing) * 4);
  padding: calc(var(--spacing) * 3) calc(var(--spacing) * 4);
  border: 1px dashed color-mix(in oklab, var(--color-destructive) 40%, var(--color-border));
  border-radius: var(--radius-lg);
  background: var(--color-destructive-muted);
  color: var(--color-destructive-on-muted);
  font-size: var(--text-sm);
}

.widget-erro-texto {
  flex: 1 1 22ch;
  min-width: 0;
}

/* Com a caixa em falha, os numeros que sobraram na tela nao podem continuar se
   apresentando como verdade. */
.widget-falhou [data-name] {
  opacity: 0.35;
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}


/* ==========================================================================
 * SUBNAV — navegacao secundaria vertical
 *
 * Usada por Configuracoes (e destinada a Fiscal e Relatorios). Substitui o
 * componente .tabs do Basecoat nos casos em que cada "aba" e' na verdade uma
 * ROTA: com role=tab o JS do Basecoat troca o painel visivel na hora e so'
 * depois o navegador recarrega, piscando o conteudo errado no meio do caminho.
 * Aqui sao links comuns, com aria-current="page" no ativo.
 * ========================================================================== */

.subnav {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.subnav .g {
  padding: calc(var(--spacing) * 3.5) calc(var(--spacing) * 2.5) calc(var(--spacing) * 1);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--color-muted-foreground);
}

.subnav .g:first-child {
  padding-top: calc(var(--spacing) * 0.5);
}

.subnav a {
  display: flex;
  align-items: center;
  gap: calc(var(--spacing) * 2);
  padding: calc(var(--spacing) * 1.75) calc(var(--spacing) * 2.5);
  border-radius: var(--radius-md);
  text-decoration: none;
  font-size: 0.84375rem;
  font-weight: 500;
  line-height: 1.3;
  color: var(--color-muted-foreground);
}

.subnav a:hover {
  background: var(--color-accent);
  color: var(--color-accent-foreground);
}

.subnav a[aria-current='page'],
.subnav a.on {
  background: var(--color-primary);
  color: var(--color-primary-foreground);
  font-weight: 600;
}

.subnav a:focus-visible {
  outline: 2px solid var(--color-ring);
  outline-offset: -2px;
}

/* Ponto de pendencia: a aba tem algo por resolver. */
.subnav a .av {
  margin-inline-start: auto;
  width: 7px;
  height: 7px;
  flex: none;
  border-radius: 50%;
  background: var(--color-warning);
}

.subnav a[aria-current='page'] .av {
  background: var(--color-primary-foreground);
}

/* ==========================================================================
 * FILTROS EM CHIP
 *
 * Fila horizontal de recortes de uma mesma lista, com a contagem de cada um:
 * "Falta configurar 4 · Configurados 34 · Todos 38". Sao LINKS com query
 * string — o recorte fica na URL, da' para compartilhar e o voltar do
 * navegador funciona.
 *
 * Nao confundir com .subnav, que e' a coluna vertical das telas de
 * configuracao. As duas ja' existiam no mockup com papeis diferentes.
 * ========================================================================== */

.filtros {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--spacing) * 1.5);
}

.filtros .chip {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--spacing) * 1.5);
  padding: calc(var(--spacing) * 1.5) calc(var(--spacing) * 3);
  border: 1px solid var(--color-border);
  border-radius: 999px;
  background: var(--color-card);
  color: var(--color-muted-foreground);
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
}

.filtros .chip:hover {
  background: var(--color-accent);
  color: var(--color-accent-foreground);
}

.filtros .chip .num {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

.filtros .chip.on {
  border-color: var(--color-primary);
  background: var(--color-primary);
  color: var(--color-primary-foreground);
}


/* ==========================================================================
 * BARRA DE SALVAR
 *
 * Fica colada no fim do formulario e diz, sem ambiguidade, se ha algo por
 * salvar. Nenhuma aba de Configuracoes tinha estado de salvamento: o retorno
 * vinha por SweetAlert, que some — e com ele a informacao de que deu errado.
 * ========================================================================== */

.barra-salvar {
  position: sticky;
  bottom: 0;
  z-index: 10;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: calc(var(--spacing) * 3);
  margin-top: calc(var(--spacing) * 4);
  padding: calc(var(--spacing) * 3) calc(var(--spacing) * 4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-card);
  box-shadow: 0 -2px 12px rgb(0 0 0 / 0.05);
}


/* --------------------------------------------------------------------------
 * Faixa de area administrativa
 *
 * O /admin usa o mesmo shell do painel do cliente. Sem nenhuma marca, e' facil
 * esquecer que as acoes dali (trocar plano, estender vencimento, cancelar
 * assinatura) valem sobre a conta de um restaurante real. A faixa e' o unico
 * elemento que diferencia as duas areas.
 *
 * Verde-pinho com o limao da marca: chama atencao sem usar vermelho, que no
 * painel significa "algo deu errado" e nao "cuidado com o que voce faz".
 * -------------------------------------------------------------------------- */
.admin-faixa {
  display: flex;
  align-items: center;
  gap: calc(var(--spacing) * 2);
  padding: calc(var(--spacing) * 1.75) calc(var(--spacing) * 6);
  background: var(--color-primary);
  color: var(--sidebar-primary);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.03em;
}

.admin-faixa svg { flex: none; }

/* ==========================================================================
   Popover: oculto ate ser aberto
   ========================================================================== */

/*
 * O Basecoat define [data-popover] como VISIVEL por padrao e so o esconde com
 * [aria-hidden=true]. Como o atributo e escrito pelo JS na inicializacao, todo
 * popover cujo markup nao traz aria-hidden="true" fica pintado na tela ate o
 * script rodar — os menus de impressora, conta, status etc. piscavam a cada
 * troca de pagina.
 *
 * Aqui o padrao e invertido: escondido, a menos que esteja explicitamente
 * aberto. O Basecoat escreve aria-hidden="false" ao abrir, entao o menu aberto
 * continua aparecendo normalmente, com a mesma transicao.
 *
 * Vale tambem para markup novo: quem esquecer o aria-hidden="true" no blade
 * nao reintroduz o flash.
 */
[data-popover]:not([aria-hidden='false']) {
  visibility: hidden;
  opacity: 0;
}
