﻿/* =====================================================================
   OpenConnection — Design Tokens
   Insurance wallet app · Brazilian Portuguese
   Colors and type derived from Figma "Fundamentos de Design".
   ===================================================================== */

/* Inter is the single brand font (4 weights in regular product use).
   Self-hosted variable fonts — covers 100→900 + italic in two files. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/Inter-VariableFont_opsz_wght.ttf") format("truetype-variations"),
       url("fonts/Inter-VariableFont_opsz_wght.ttf") format("truetype");
}
@font-face {
  font-family: "Inter";
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/Inter-Italic-VariableFont_opsz_wght.ttf") format("truetype-variations"),
       url("fonts/Inter-Italic-VariableFont_opsz_wght.ttf") format("truetype");
}

:root {
  /* ───────────────── BRAND ───────────────── */
  --seg-blue: #131F52;           /* Primary navy, headings, dark surfaces  */
  --seg-green: #BAD455;          /* Primary CTA lime, brand accent         */

  /* Seg Blue ramp (50 → 150) */
  --seg-blue-50:  #F3F4F6;
  --seg-blue-60:  #D0D2DC;
  --seg-blue-70:  #A1A5BA;
  --seg-blue-80:  #717997;
  --seg-blue-90:  #424C75;
  --seg-blue-100: #131F52;       /* base */
  --seg-blue-110: #0B1331;
  --seg-blue-120: #080C21;
  --seg-blue-130: #040610;
  --seg-blue-140: #010204;
  --seg-blue-150: #000000;

  /* Seg Green ramp (50 → 150) */
  --seg-green-50:  #FBFDF6;
  --seg-green-60:  #F1F6DD;
  --seg-green-70:  #E3EEBB;
  --seg-green-80:  #D6E599;
  --seg-green-90:  #C8DD77;
  --seg-green-100: #BAD455;      /* base */
  --seg-green-110: #707F33;
  --seg-green-120: #4A5522;
  --seg-green-130: #252A11;
  --seg-green-140: #090B04;

  /* Brand droplet & gradient */
  --brand-droplet-blue: #131F52;
  --brand-droplet-green: #BAD455;

  /* ───────────────── SEMANTIC ───────────────── */
  --info:    #0D5593;
  --info-light: #C2D4E4;
  --info-dark:  #0A406E;
  --info-bg:    #85A9C8;

  --success:    #549100;
  --success-light: #D4E3BF;
  --success-bg:    #F1F6DD;
  --success-dark:  #2A4800;

  --error:    #AF150D;
  --error-light: #EBC4C2;
  --error-dark:  #83100A;
  --error-bg:    #D68985;

  --alert:    #D98100;           /* warning / alert orange */
  --alert-light: #F5DFBF;
  --alert-bg:    #ECBF7F;
  --alert-dark:  #8B6914;

  /* ───────────────── NEUTRALS ───────────────── */
  --white: #FFFFFF;
  --black: #000000;
  --black-blue: #010204;         /* Black B */
  --black-green: #090B04;        /* Black G */

  --gray-05: #F2F2FF;            /* App background lavender */
  --gray-10: #E6E6FA;            /* Nav bar / soft surface */
  --gray-20: #CCCCE0;
  --gray-30: #B3B3C7;
  --gray-40: #9999AD;
  --gray-50: #7F7F94;
  --gray-60: #66667A;
  --gray-70: #4D4D61;
  --gray-80: #333347;
  --gray-90: #1A1A2E;

  /* ───────────────── SEMANTIC SURFACE / TEXT ───────────────── */
  --bg-app:        var(--gray-05);   /* #F2F2FF — main app background */
  --bg-surface:    var(--white);     /* cards, sheets */
  --bg-muted:      #F3F4F6;          /* input fields, dividers fill */
  --bg-nav:        var(--gray-10);   /* bottom tab bar */
  --bg-header:     var(--seg-green); /* lime hero band on profile */

  --fg-strong:     var(--seg-blue);  /* H1 / important figures (#131F52)*/
  --fg-default:    #424C75;          /* Body text default */
  --fg-secondary:  #717997;          /* Subdued labels */
  --fg-muted:      #A1A5BA;          /* Placeholder, meta, helpers */
  --fg-on-brand:   #333347;          /* Text on lime CTA */
  --fg-on-dark:    var(--white);

  --border-soft:   #E6E6FA;
  --border-strong: #CCCCE0;

  /* Action / link */
  --link:          #0D5593;
  --action-bg:     var(--seg-green);
  --action-bg-soft:#F1F6DD;
  --action-fg:     #333347;

  /* ───────────────── SHADOWS ───────────────── */
  /* The Figma source defines a single shadow primitive applied to cards. */
  --shadow-card:
      0 4px 4px -1px rgba(12,12,13,0.05),
      0 4px 4px -1px rgba(12,12,13,0.10);
  --shadow-pop:
      0 8px 18px -4px rgba(19,31,82,0.18),
      0 2px 6px -2px rgba(12,12,13,0.10);
  --shadow-protection:
      0 0 0 4px var(--white),
      0 6px 18px -4px rgba(19,31,82,0.25);

  /* Hero protection gradient (header img → navy at bottom) */
  --gradient-hero-shadow:
      linear-gradient(to bottom, rgba(9,15,39,0) 0%, #131F52 100%);
  /* Splash gradient image lives at assets/images/splash-gradient.png */

  /* ───────────────── RADIUS ───────────────── */
  --radius-xs:  8px;
  --radius-sm:  12px;   /* input field */
  --radius-md:  18px;   /* default card */
  --radius-lg:  20px;   /* pill, brand swatch */
  --radius-xl:  35px;   /* nav bar / sheet top */
  --radius-2xl: 40px;   /* large rounded section */
  --radius-pill: 9999px;

  /* ───────────────── SPACING ───────────────── */
  /* #905 Frente A Onda2 B1c (UI.Shell): 3px recorre como padding vertical de
     badge/pill (AcessoNegado + achado no mesmo padrão em Branding/Admin/Grc, fora
     do escopo desta onda) — abaixo de --s-1(4px), sem degrau existente. */
  --s-0: 3px;
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 10px;
  --s-4: 12px;
  --s-5: 16px;
  --s-6: 20px;
  --s-7: 24px;
  --s-8: 32px;
  --s-9: 40px;
  --s-10: 56px;
  /* #905 Frente A escopo 10: 48px recorre 8x idêntico nos 4 apps (Insights/Grc/
     Gamefied/LandingPages) — padding do hero de login e do empty-state. Sem isso
     cada app repetiria "48px" cru; nasce aqui entre --s-9(40) e --s-10(56). */
  --s-11: 48px;
  /* #905 Frente A Onda2 B1b (UI.Modals+UI.Consent): 14px recorre 13x cru como
     gap/padding/margin/inset em 6 componentes (ModalFinalidade, ModalRequerenteInfo,
     ReenvioCodigoModal, TermoConsentimentoDinamico, CorretorSearchBox,
     AssinaturaDigitalCapture) — sem degrau equivalente entre --s-4(12) e --s-5(16). */
  --s-12: 14px;
  /* #905 Frente A Onda2 B1b: 2px recorre 3x como micro-offset de margin (título logo
     abaixo de rótulo) em ModalFinalidade/ModalRequerenteInfo/ReenvioCodigoModal —
     abaixo de --s-1(4px), sem degrau existente. */
  --s-13: 2px;
  /* #905 Frente A Onda2 B1b: 6px recorre 4x como margin-bottom de <h3> de seção em
     TermosUsoModal (mesmo papel em qualquer heading de bloco legal) — acima de --s-1(4px)
     e abaixo de --s-2(8px), sem degrau existente. */
  --s-14: 6px;

  /* #905 Frente A Onda2 B1a (UI.Branding): 2/5/6/7/14/18px recorrem em composições compactas
     de ícone+texto (StatusBar, SegLogo, NotificationBar, BrandingKeyEditor, ImagePickerModal,
     BrandingPreviewContent) — gap/padding/margin sem degrau equivalente. NOTA: outra onda
     paralela (B1b) também precisou de 2/6/14px e pode ter criado tokens próprios (--s-12/13/14)
     em momento diferente desta mesma seção compartilhada concorrentemente por 5 agentes — se
     ambos existirem após o merge, é duplicata a consolidar na integração, não bug funcional. */
  --space-2: 2px;
  --space-5: 5px;
  --space-6: 6px;
  --space-7: 7px;
  --space-14: 14px;
  --space-18: 18px; /* padding horizontal de botão (4x BrandingPreviewContent) + dimensão de ícone (ImagePickerModal) */

  /* ───────────────── TYPOGRAPHY ───────────────── */
  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;

  --fw-light: 300;
  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semibold: 600;
  --fw-bold: 700;
  --fw-extrabold: 800;

  /* Display / Heading scale (Inter Bold) */
  --fs-display:  56px;     /* Splash / hero page title */
  --fs-h1: 48px;
  --fs-h2: 40px;
  --fs-h3: 32px;
  --fs-h4: 24px;           /* Section title in app  */
  --fs-h5: 20px;
  --fs-h6: 16px;
  /* #905 Frente A Onda2 B2d (Admin/Dpo/Finalidades.razor): titulo <h2> dos 2 modais
     (Nova Categoria/Nova Finalidade) — 17px, um degrau acima de --fs-h6(16px), sem
     equivalente existente. */
  --fs-modal-title: 17px;

  /* Body */
  --fs-body-1: 20px;       /* Lead / hero subtitle */
  --fs-body-2: 18px;
  --fs-body-3: 16px;       /* Default body */
  --fs-body-4: 14px;       /* Small / caption */
  --fs-caption: 12px;      /* Nav labels, hints */

  /* ───────────────── COMPONENT ALIASES (whitelabel cascade) ───────────────── */
  --brand-primary:         var(--seg-blue);
  --brand-accent:          var(--seg-green);
  --brand-text-sidebar:    var(--fg-on-dark);
  --brand-bg-app:          var(--bg-app);
  --brand-bg-sidebar:      var(--seg-blue);
  --bg-surface-soft:       var(--bg-muted);
  --border-light:          var(--border-soft);

  /* Fundo atrás da logo (WLT.A.01 / #617-#631 fix) — regra explícita do CTO:
     dark=#253264, light=#FFFFFF. Serve de default universal mesmo em apps
     ainda não wireados ao BrandingProvider/ColorVarsBranded (que, quando
     presente, sobrescreve estas 3 vars com o valor efetivo do tenant). */
  --brand-bg-logo-light:   #FFFFFF;
  --brand-bg-logo-dark:    #253264;
  --brand-bg-logo:         var(--brand-bg-logo-light);
  /* #905 Frente A Onda2 B1a (UI.Branding/ColorVarsBranded.razor): o fallback da PRÓPRIA
     propriedade --brand-bg-logo-dark não pode ser var(--brand-bg-logo-dark) — autorreferência
     é CSS inválido em tempo de computed-value (é exatamente o bug que o comentário original do
     componente documenta). Nome distinto, mesmo valor, evita o ciclo. */
  --brand-logo-fallback-dark: #253264;

  /* Paleta de preview genérica (BrandingPreviewContent.razor) — mostrada só quando o tenant
     ainda não configurou [whitelabel].[VisualConfig]. Deliberadamente distinta dos tokens
     semânticos reais (--error/--success/etc.): forçar os tokens reais mudaria a cor exibida
     no preview a cada retema, que é uma decisão de design, não uma equivalência de valor. */
  --preview-color-primary:    #2563EB;
  --preview-color-secondary:  #7c3aed;
  --preview-surface-page:     #f9fafb;
  --preview-outline-default:   #e5e7eb;
  --preview-fg-strong:     #111827;
  --preview-fg-muted:   #6b7280;
  --preview-semantic-success: #16a34a;
  --preview-semantic-error:   #dc2626;
  --preview-semantic-alert:   #d97706;
  --preview-semantic-info:    #0284c7;

  /* ───────────────── EXTENDED COMPONENT TOKENS ───────────────── */
  /* Aliases used by multiple app CSS files — single source of truth */
  --seg-primary:     var(--seg-blue);
  --fg-on-primary:   var(--white);
  --shadow-soft:     0 4px 12px rgba(0,0,0,0.08);
  --error-fg:        var(--error);
  --error-bg:        var(--error-light);
  --bg-subtle:       #EEF0F6;
  --r-2:             6px;

  /* ───────────────── TYPOGRAPHY EXTRAS ───────────────── */
  --fs-ui:           13px;
  --lh-compact:      1.3;
  /* #905 Frente A escopo 6 (UI.Branding/Modals/Consent): 11px recorre ~15x como
     legenda/meta-texto (badges, hints, sub-labels) sem degrau equivalente entre
     --fs-caption(12px) e nada abaixo — extinto o hardcode, nasce aqui em vez de
     repetir "11px" cru em cada componente. */
  --fs-micro:        11px;
  /* #905 Frente A Onda2 B1a (UI.Branding/BrandingPreviewContent.razor): 10px (legenda do
     código hex sob a amostra de cor) e 15px (corpo do texto de exemplo de tipografia) sem
     degrau equivalente entre --fs-nano(9px)/--fs-micro(11px) e --fs-body-4(14px)/--fs-body-3(16px). */
  --fs-10: 10px;
  --fs-15: 15px;

  /* ───────────────── RADIUS EXTRAS ───────────────── */
  /* #905 Frente A escopo 6: 14px recorre (cards/pills/dropdowns em Modals+Consent)
     no vão entre --radius-sm(12px) e --radius-md(18px). Mesmo motivo do --fs-micro
     acima: padrão real repetido, não invenção ad-hoc. */
  --radius-card:     14px;
  /* #905 Frente A Onda2 B1c (UI.Documents): 4px recorre como raio pequeno de campo
     (RichTextEditor content area) — abaixo de --radius-xs(8px), sem degrau existente.
     Mesmo padrão real-repetido-não-inventado do --radius-card acima (admin.css e
     theme.css também têm 4px cru, fora do escopo desta onda). */
  --radius-2xs:      4px;
  /* #905 Frente A Onda2 B1a (UI.Branding/ImagePickerModal.razor): 16px é o raio do modal
     principal — vão entre --radius-sm(12px) e --radius-md(18px). Nomeado pelo uso (não
     pela família 2xs/xs/sm/md, que quebraria a ordem: 5px "3xs" seria maior que 4px "2xs"). */
  --radius-modal: 16px;
  /* #905 Frente A Onda2 B2d (Admin/Consents/ConsentList.razor): raio "6px 6px 0 0" das
     abas de status (topo arredondado, base reta) — sem degrau equivalente entre
     --radius-xs(8px) e nenhum valor menor existente. */
  --radius-tab: 6px;
  /* #905 Frente A Onda2 B2d (Admin/Conta/Seguranca.razor): tela de enrollment TOTP —
     letter-spacing do rotulo micro-uppercase ("CHAVE SECRETA") e do codigo/segredo
     monoespaçado (legibilidade de digitos), sem equivalente nos tokens de letter-spacing
     existentes (que usam em, nao px). */
  --ls-code-label: .5px;
  --ls-code-value: 4px;
  /* #905 Frente A Onda2 B1a (UI.Branding/BrandingKeyEditor.razor): 5px recorre 4x como raio
     dos controles do stepper NUMERIC e do input COLOR — mesmo motivo do --radius-modal acima. */
  --radius-input-control: 5px;
  /* #905 Frente A Onda2 B1b (UI.Consent/BrokerCard.razor + AssinaturaDigitalCapture.razor):
     10px é o raio do chip/pill de status (badge "delegação contratual" / círculo do ícone de
     documento assinado) — vão entre --radius-2xs(4px) e --radius-input-control(5px)? não,
     entre 5px e --radius-xs(8px)/--radius-sm(12px); sem degrau existente nesse ponto. */
  --radius-chip: 10px;

  /* ───────────────── BORDER WIDTH ───────────────── */
  /* #905 Frente A Onda2 B1c (UI.Documents): "1px" de borda estava cru dentro de um
     style inline (RichTextEditor), disparando OCPL021 (NNpx solto). Token único de
     borda fina — reusável por qualquer componente que hoje escreve "1px solid ...". */
  --border-width-thin: 1px;
  /* #905 Frente A Onda2 B1a (UI.Branding/BrandingPreviewContent.razor): 1.5px recorre 2x
     (borda do botão "Outline" e do input de exemplo) — companheiro do --border-width-thin. */
  --border-width-md: 1.5px;
  /* #905 Frente A Onda2 B1a (UI.Branding/ImagePickerModal.razor): 2px é a borda do
     thumbnail selecionado no grid de imagens. */
  --border-width-thick: 2px;
  /* #905 Frente A Onda2 B1b (UI.Consent/AssinaturaDigitalCapture.razor spinner +
     BrokerCard.razor border-left de destaque): 4px — nome distinto de --border-width-thick
     (2px, já usado por B1a/UI.Branding) para não colidir valor diferente sob o mesmo nome.
     NOMEADO "dim-*" (não "border-width-*" nem "ring-*") de propósito: um token usado como
     valor SOZINHO (sem "prop:" na mesma string, ex. dentro de box-shadow computado em C#)
     com prefixo bg-/text-/border-/ring-/shadow-/fill-/stroke-/p-/m-/w-/h-/etc. dispara falso
     positivo no OCPL021A (heurística Tailwind por substring) — achado 22/jul em
     AssinaturaDigitalCapture.CircleShadow, reportado ao Desktop; renomeado aqui para não
     reproduzir o mesmo bug com um token novo. */
  --dim-thick-edge: 4px;

  /* ───────────────── COMPONENT SIZING ───────────────── */
  /* #905 Frente A Onda2 B1c (UI.Documents): min-height do editor rich-text (contentEditable)
     estava cru em style inline. Valor específico do componente, não da escala de
     spacing (--s-*) — nasce como token nomeado em vez de repetir "120px" cru. */
  --textarea-min-height: 120px;
  /* #905 Frente A Onda2 B2d (Admin/Certificates/CertificateManager.razor): altura FIXA
     (nao min-height) do textarea de colar PEM — Tailwind h-40(10rem/160px), degrau
     proprio por ser "height" e nao "min-height" como a familia acima. */
  --textarea-height-md: 160px;
  /* #905 Frente A Onda2 B2d (Admin/Notificacoes/Teste.razor): min-height do textarea de
     corpo da notificacao de teste — degrau curto, abaixo de --textarea-min-height(120px). */
  --textarea-min-height-sm: 72px;
  /* #905 Frente A Onda2 B2d (Admin/Certificates/CertificateManager.razor): Tailwind
     w-48(12rem/192px) do campo numerico de filtro por TenantId — sem degrau equivalente
     em --input-w-*/--form-field-min-w-*. */
  --input-w-192: 192px;
  /* #905 Frente A Onda2 B2d (Admin/Features.razor): largura da coluna do toggle switch
     (Tailwind w-32/8rem) — sem degrau equivalente. */
  --col-w-toggle: 128px;
  /* #905 Frente A Onda2 B1c (UI.Shell): 440px recorre como max-width de card/dialog
     centralizado (AcessoNegado.razor + mesmo valor cru em RouteAccessGuardExtensions.cs,
     AcceptInvite.razor, RegisterOperator.razor, ConsentDetail.razor, grc.css — fora do
     escopo desta onda, mas confirma padrão real, não invenção). */
  --dialog-max-width: 440px;
  /* #905 Frente A Onda2 B1c (UI.Shell): 480px recorre como segundo degrau de max-width
     de dialog/painel (SpocErrorBoundary + mesmo valor cru em SubscriptionList.razor,
     WorkflowInstancePage.razor — fora do escopo desta onda). */
  --dialog-max-width-lg: 480px;
  /* #905 Frente A Onda2 B1d (UI.Managers): 600px recorre como terceiro degrau de
     max-width de painel/card (ManagerContractsPanel.razor + mesmo valor cru em
     ImagePickerModal.razor/UI.Branding, ProjectCaps.razor/Admin, Teste.razor/Admin,
     DynamicCrud.razor/Admin — fora do escopo desta onda, mas confirma padrão real,
     não invenção). Mesma escala do --dialog-max-width(440)/--dialog-max-width-lg(480). */
  --dialog-max-width-xl: 600px;
  /* #905 Frente A Onda2 B2d (Admin): 500px/560px recorrem como degraus intermediarios
     de max-width de dialog entre --dialog-max-width-lg(480) e --dialog-max-width-xl(600)
     — Dpo/Finalidades.razor (500) e GameData/CampaignList.razor, Platform/RulesConfig.razor,
     Platform/PaymentConfig.razor (560). Nomeados pelo valor (nao ha rotulo sm/md/lg livre
     nesse intervalo sem colidir com os degraus ja existentes). */
  --dialog-max-width-500: 500px;
  --dialog-max-width-560: 560px;
  /* #905 Frente A Onda2 B2d (Admin/Notificacoes/Preferencias.razor): card de preferencias —
     degrau proprio, entre --dialog-max-width-520 e --dialog-max-width-560. */
  --dialog-max-width-540: 540px;
  /* #905 Frente A Onda2 B2f (Spoc): 520px e 640px sao mais 2 degraus da mesma familia
     de max-width de card/dialog centralizado — wizard de consentimento (Passo4Confirmacao,
     card um pouco mais largo que os --dialog-max-width-lg(480) dos demais passos) e o card
     de detalhe (ConsentDetail.razor, MinhaArea). Mesma convencao "nomeado pelo valor" ja
     adotada em --dialog-max-width-500/560 (B2d) para este intervalo sem rotulo sm/md/lg livre. */
  --dialog-max-width-520: 520px;
  --dialog-max-width-640: 640px;
  /* #905 Frente A Onda2 B1c (UI.Shell): 60px recorre como diâmetro do círculo de ícone
     de estado (cadeado 403 em AcessoNegado.razor, mesmo valor cru em
     RouteAccessGuardExtensions.cs .icon — fora do escopo desta onda). */
  --icon-circle-lg: 60px;
  /* #905 Frente A Onda2 B1c (UI.Shell): altura do <LogoBranded> na sidebar do
     MainShell — contexto próprio (sidebar compacta), distinto dos ~18/22/32/36px
     usados em login/header de outros apps (fora do escopo desta onda). */
  --logo-height-sidebar: 24px;
  /* #905 Frente A Onda2 B2g (InsuranceMarketplace/Grc): 32px recorre identico em TODOS os
     LoginLayout.razor do ecossistema (Admin/Gamefied/Grc/Insights/InsuranceMarketplace/
     LandingPages/Portal/SPOC) como altura da logo no hero de login — sem degrau equivalente.
     22px recorre em headers compactos (InsuranceMarketplace/MarketplaceLayout,
     Grc/MainLayout, Showcase/BrandingPage). Nomeados pelo uso, mesma familia de
     --logo-height-sidebar acima. */
  --logo-height-login: 32px;
  --logo-height-header: 22px;
  /* #905 Frente A Onda2 B2f (Spoc/MainLayout.razor): 18px e a altura da logo no header
     interno do app (acima do <main>, fora do fluxo login/sidebar) — valor proprio, distinto
     de --logo-height-header(22, usado em MarketplaceLayout/Grc/BrandingPage). */
  --logo-height-app-header: 18px;
  /* #905 Frente A Onda2 B1c (UI.Shell): espessura do conector entre bullets do
     ProgressBar — mesmo valor já usado (cru) em flow-styles.css .sn-progress .bar,
     que não se aplica ao DOM real do componente (bar é irmão de .step, não filho),
     por isso o inline style; o valor em si é o mesmo, agora nomeado. */
  --progress-bar-height: 2px;
  /* #905 Frente A Onda2 B1a (UI.Branding/BrandingKeyEditor.razor): 28px é o lado do
     input[type=color] e do thumbnail de preview de imagem (mesmo tamanho, mesmo
     contexto "amostra pequena quadrada" — reaproveitado, não duplicado). */
  --dim-color-swatch: 28px;
  /* #905 Frente A Onda2 B1a (UI.Branding/BrandingKeyEditor.razor): 26px recorre 3x como
     lado dos botões +/- e altura do rótulo de unidade do stepper NUMERIC. */
  --dim-stepper-btn: 26px;
  /* #905 Frente A Onda2 B1a (UI.Branding/BrandingKeyEditor.razor): largura dos campos de
     texto do editor de chave — hex (96px) e valor numérico do stepper (72px). */
  --input-w-hex: 96px;
  --input-w-numeric: 72px;
  /* #905 Frente A Onda2 B1a (UI.Branding/BrandingPreviewContent.razor): largura do input
     de exemplo na seção de tipografia do preview. */
  --input-w-lg: 280px;
  /* #905 Frente A Onda2 B1a (UI.Branding/BrandingKeyEditor.razor): max-width do preview de
     imagem no campo IMAGE_URL. */
  --img-thumb-max-w: 120px;
  /* #905 Frente A Onda2 B1a (UI.Branding/ImagePickerModal.razor): altura do thumbnail no
     grid de imagens do picker. */
  --img-thumb-h: 60px;
  /* #905 Frente A Onda2 B1a (UI.Branding/BrandingPreviewContent.razor): max-width da logo
     no cabeçalho do preview. */
  --logo-preview-max-w: 140px;
  /* #905 Frente A Onda2 B1a (UI.Branding/BrandingPreviewContent.razor): minmax() da grid
     de swatches na "Paleta de Cores". */
  --grid-col-min: 160px;
  /* #905 Frente A Onda2 B2d (Admin/Dpo/Finalidades.razor): minmax() do grid de cards de
     categoria — degrau maior da mesma familia, cards mais largos que swatch de cor. NOME
     "dpo-cat-grid-min" (nao "-grid-col-min-lg"): outra onda concorrente ja criou
     --grid-col-min-lg com valor DIFERENTE (280px, GamefiedDataCollection/Grc, ver abaixo)
     — mesmo risco de colisao ja documentado para --actwf-grid-min mais adiante neste arquivo. */
  --dpo-cat-grid-min: 300px;
  /* #905 Frente A Onda2 B2g (GamefiedDataCollection/Grc): 280px recorre identico como
     minmax() de grid de cards (Conta/Index.razor .sn-grid + grc.css .grc-card-grid) —
     mesma familia do --grid-col-min(160px) acima, degrau maior para card em vez de swatch. */
  --grid-col-min-lg: 280px;
  /* #905 Frente A Onda2 B1a (UI.Branding/ImagePickerModal.razor): largura do dialog de
     confirmação de exclusão — degrau próprio, abaixo de --dialog-max-width(440px). */
  --dialog-w-sm: 420px;
  /* #905 Frente A Onda2 B1c (UI.Shell): 44px recorre como diâmetro do círculo de ícone
     médio (card do WelcomeLanding + mesmo valor cru em flow-styles.css .sn-*,
     BrokerCard.razor/UI.Consent — fora do escopo desta onda, confirma padrão real). */
  --icon-circle-md: 44px;
  /* #905 Frente A Onda2 B1b (UI.Consent/CorretorSearchBox.razor): 28px é o diâmetro do avatar
     de iniciais no item de resultado da busca de corretor — degrau menor da mesma família de
     --icon-circle-md(44)/--icon-circle-lg(60). */
  --icon-circle-sm: 28px;
  /* #905 Frente A Onda2 B1b (UI.Modals+UI.Consent): 36px é o lado do badge quadrado de ícone
     (ModalFinalidade.razor lista de finalidades + AssinaturaDigitalCapture.razor bloco "termo
     assinado") — mesmo papel visual "selo de ícone pequeno" nos 2 nugets do escopo. */
  --icon-badge-sm: 36px;
  /* #905 Frente A Onda2 B1b (UI.Consent/AssinaturaDigitalCapture.razor): tela de loading/
     confirmação da assinatura digital (BLOCO D) — 5 medidas próprias do layout "hero
     centralizado" sem equivalente na escala genérica, todas usadas 1x cada. */
  /* #905 Frente A Onda2 B2d (Admin/Layout/CompanySelector.razor): dropdown "trocar de
     empresa" — glifo caret (10px, um degrau abaixo de --fs-nano(9px)... na verdade acima,
     entre --fs-nano(9px) e --fs-micro(11px), sem degrau existente ai), painel flutuante
     (raio 10px entre --radius-xs(8px)/--radius-sm(12px), sombra propria mais suave que
     --shadow-pop, e largura min/max sem equivalente na escala generica de dialog). */
  --fs-caret: 10px;
  --dropdown-panel-radius: 10px;
  --dropdown-panel-shadow: 0 8px 30px rgba(0, 0, 0, .15);
  --dropdown-panel-min-w: 240px;
  --dropdown-panel-max-w: 320px;
  --capture-circle-size: 130px;       /* diâmetro do círculo de status (width/height/padding-bottom da stage) */
  --capture-stage-pad-top: 90px;      /* padding-top da stage centralizada */
  --capture-stage-pad-x: 30px;        /* padding horizontal da stage centralizada */
  --capture-title-margin-top: 28px;   /* margin-top do <h2> abaixo do círculo */
  --capture-badge-margin-top: 22px;   /* margin-top do badge "termo assinado" abaixo do texto */
  --capture-text-max-width: 290px;    /* max-width do parágrafo de apoio */
  /* #905 Frente A Onda2 B1c (UI.Shell): diâmetro do avatar circular no card de
     "bem-vindo de volta" do WelcomeLanding — degrau maior da mesma família de
     --icon-circle-md(44)/--icon-circle-lg(60). */
  --avatar-size-lg: 64px;
  /* #905 Frente A Onda2 B2d (Admin/Routes.razor): padding vertical da pagina 404 —
     mesmo papel "empty-state centralizado" de outras telas, sem token equivalente. */
  --empty-state-pad-y: 64px;
  /* #905 Frente A Onda2 B1c (UI.Shell): 36px é o topo do clamp() do título hero do
     WelcomeLanding (font-size:clamp(24px,6vw,36px)); o piso 24px já existe como
     --fs-h4, faltava nomear o teto. */
  --fs-landing-title-max: 36px;

  /* #905 Frente A Onda2 B2f (Spoc): max-height da caixa de scroll do termo de consentimento
     gerado dinamicamente (Passo4Confirmacao.razor) — valor proprio do componente, nao da
     escala de spacing. */
  --term-scroll-max-height: 400px;
  /* #905 Frente A Onda2 B2f (Spoc/MinhaArea/Index.razor): max-width da celula de tabela que
     trunca o FapiConsentId (monospace + ellipsis) — mesmo padrao "id truncado em tabela" que
     recorre (cru) em varios apps fora do escopo desta onda (Admin/Grc/Portal). */
  --table-cell-truncate-w: 200px;
  /* #905 Frente A Onda2 B2f (Showcase): 844px e a altura do mockup de celular (.sc-phone),
     mesmo valor ja fixo (cru) em flow-styles.css .sn-app — nomeado agora para os 6 usos em
     inline style que envolvem .sc-phone (ShellsPage/ModalsPage/ConsentPage) com conteudo que
     nao usa .sn-app por dentro. 500px e o degrau curto (painel de busca de corretor, nao
     precisa da altura cheia do device frame) e 390px e a largura (mesmo valor de .sc-phone/
     .sn-app), reusada 1x num layout de coluna que imita largura de celular (CardsPage.razor). */
  --phone-frame-height: 844px;
  --phone-frame-min-height: 500px;
  --phone-frame-width: 390px;
  /* #905 Frente A Onda2 B2f (Showcase/BrandingPage.razor): min-width dos 2 sc-demo-card do
     grid de Branding — dimensao estrutural (dev tool), sem degrau equivalente na escala --s-N. */
  --demo-panel-min-w: 340px;

  /* #905 Frente A Onda2 B2b (Admin/Settings+SystemAdmin+Routes): larguras de coluna
     de tabela chumbadas em VisualConfigDefault.razor (thead "Estado"/"Ação" — não
     reaproveitei .sn-col-actions porque o min-width dela é 200px, valor diferente do
     100px cru original; teria mudado o layout). */
  --col-w-status: 90px;
  --col-w-action-sm: 100px;
  /* #905 Frente A Onda2 B2b: largura máxima de texto truncado (text-overflow:ellipsis)
     em célula de tabela — dois degraus medidos: VisualConfigDefault.razor (coluna
     "Default", 180px) e DynamicCrud.razor (coluna genérica de valor, 220px). */
  --truncate-w-sm: 180px;
  --truncate-w-md: 220px;
  /* #905 Frente A Onda2 B2d (Admin/Observabilidade/SqlErrorsViewer.razor): max-width da
     coluna "Mensagem" truncada — degrau maior, mensagem de erro SQL e mais longa que
     valor de config. */
  --truncate-w-lg: 340px;
  /* #905 Frente A Onda2 B2d (Admin/Monitoring/ApiCallLogViewer.razor): max-width da coluna
     "URL" truncada — degrau entre --truncate-w-md(220) e --truncate-w-xl(300). */
  --truncate-w-280: 280px;
  /* #905 Frente A Onda2 B2d (Admin/Platform/RulesConfig.razor): max-width da coluna
     "Expressão" truncada — degrau entre --truncate-w-md(220) e --truncate-w-lg(340). */
  --truncate-w-xl: 300px;
  /* #905 Frente A Onda2 B2b: família --input-w-* (já existia hex/numeric/lg) — graus
     que faltavam, medidos em Settings/SystemSettings.razor (TTL, 112px) e
     VisualConfigDefault.razor (filtro de designs 220px / filtro de chaves 300px). */
  --input-w-sm: 112px;
  --input-w-md: 220px;
  --input-w-xl: 300px;
  /* #905 Frente A Onda2 B2b (SystemAdmin/DynamicCrud.razor): min-width de campo de
     formulário em linha (flex) — 3 graus recorrentes também fora deste escopo
     (ActivityList/DocumentLibrary/WorkflowInstanceList, não tocados nesta onda). */
  /* #905 Frente A Onda2 B2d (Admin/Consents/ConsentList.razor + Monitoring/
     ApiCallLogViewer.razor): 150px recorre em campo de filtro em linha (flex) — degrau
     abaixo de --form-field-min-w-sm(160), sem equivalente existente. */
  --form-field-min-w-xs: 150px;
  --form-field-min-w-sm: 160px;
  --form-field-min-w-md: 180px;
  --form-field-min-w-lg: 200px;
  /* #905 Frente A Onda2 B2b (Routes/RouteList.razor): min-width do campo de busca —
     mesmo valor cru em ApiKeyManager.razor/ContractList.razor/ClientList.razor (fora
     do escopo desta onda, confirma padrão real, não invenção). */
  --filter-search-min-w: 250px;
  /* #905 Frente A Onda2 B2b (Settings/VisualConfigDefault.razor): painel de mini-preview
     flutuante (#214) — posição/tamanho próprios, sem equivalente na escala genérica. */
  --preview-panel-w: 320px;
  --preview-panel-top: 64px;
  --preview-logo-thumb-max-w: 100px;
  --preview-header-row-h: 26px; /* altura da linha logo+badges no mini-preview */
  /* #905 Frente A Onda2 B2b (Settings/WhatsAppConfig.razor): toggle switch estilo iOS —
     trilho e posições do polegar em translateX(). Extraído para computed property em
     @code (técnica 1 do falso-positivo "ternário em style" — ver comentário no .razor). */
  --toggle-track-w: 64px;
  /* #905 Frente A Onda2 B2d (Admin/Features.razor): trilho do toggle switch de feature —
     degrau menor, design mais compacto que --toggle-track-w(64px). */
  --toggle-track-w-sm: 44px;
  --toggle-thumb-off: 4px;
  --toggle-thumb-on: 36px;
  /* #905 Frente A Onda2 B2b: padding:28px recorre idêntico nos 5 modais de confirmação/
     formulário (VisualConfigDefault.razor x4 + TermTemplates.razor x1) — sempre junto de
     border-radius:16px (== --radius-modal, já existente). */
  --modal-pad: 28px;
  /* #905 Frente A Onda2 B2b (Settings/TermTemplates.razor): max-width do modal de
     edição de template (form maior que os modais de confirmação padrão). */
  --term-template-modal-w: 780px;
  /* #905 Frente A Onda2 B2b (Settings/TermTemplates.razor): min-height do editor WYSIWYG
     de corpo do termo — mesma família semântica do --textarea-min-height(120px), degrau
     maior por ser o corpo inteiro de um termo legal, não um campo de texto curto. */
  --textarea-min-height-lg: 260px;
  /* #905 Frente A Onda2 B2b (Settings/SystemSettings.razor): padding vertical de 1px do
     chip <code> inline (endpoint OPIN) — abaixo de qualquer degrau --s-*/--space-* existente. */
  --code-chip-pad-y: 1px;
  /* #905 Frente A Onda2 B2b (SystemAdmin/VirtualEntities.razor): 2 modais (criar/editar)
     com max-width próprios, entre --dialog-max-width-lg(480) e --dialog-max-width-xl(600)
     da escala genérica — nomeados pelo componente (mesmo motivo do --radius-modal: a
     escala xs/sm/md/lg/xl já está ocupada e não reflete a ordem 480→520→560→600). */
  --virtual-entity-modal-w: 520px;
  --virtual-entity-modal-w-lg: 560px;
  /* #905 Frente A Onda2 B2b (Settings/VisualConfigDefault.razor): largura dos 4 modais
     de confirmação (novo/clonar design 400px; ativar/desativar 380px cada; excluir
     360px) — sempre junto de --radius-modal(16px)/--modal-pad(28px) acima. */
  --confirm-modal-w-sm: 360px;
  --confirm-modal-w: 380px;
  --confirm-modal-w-lg: 400px;

  /* ───────────────── OVERLAY / SCRIM (modais) ───────────────── */
  /* #905 Frente A escopo 6: fundo escurecido atrás de modal/bottom-sheet — padrão
     que qualquer nugets/UI.Modals* futuro vai precisar; estava chumbado 2x dentro
     de ImagePickerModal (picker + confirm-delete empilhado, por isso 2 forças). */
  --overlay-backdrop:        rgba(0, 0, 0, .55);
  --overlay-backdrop-strong: rgba(0, 0, 0, .6);

  /* ───────────────── SHADOW EXTRAS ───────────────── */
  /* #905 Frente A escopo 6: sombra de modal flutuante — mesmo valor repetido 2x
     em ImagePickerModal (picker + confirm-delete). */
  --shadow-modal:    0 20px 60px rgba(0, 0, 0, .3);
  /* #905 Frente A Onda2 B2b (Settings/WhatsAppConfig.razor): sombra do polegar do toggle
     switch. */
  --shadow-toggle-thumb: 0 1px 3px rgba(0, 0, 0, .3);
  /* #905 Frente A Onda2 B2b (Settings/VisualConfigDefault.razor): sombra do painel de
     mini-preview flutuante (#214) — mais suave que --shadow-modal (usado por modais
     bloqueantes), consistente com o papel de painel não-modal ancorado no canto. */
  --shadow-preview-panel: 0 12px 40px rgba(0, 0, 0, .18);

  /* ───────────────── PROGRESS BAR COLORS ───────────────── */
  --prog-red:        #E5534B;
  --prog-orange:     #F0A23B;
  --prog-yellow:     #F4C842;
  --prog-lime:       var(--seg-green);
  --prog-green:      #4FB477;

  /* ───────────────── SEMANTIC DANGER / ACCENT ───────────────── */
  --seg-accent:      var(--seg-green);
  --seg-danger:      #C2410C;
  /* #905 Frente A Onda2 B2d (Admin/Certificates/CertificateManager.razor): abas
     via/upload/generate trocavam classe Tailwind inteira por ternario (falso-positivo
     classe 1 — cada ramo é uma classe utilitária de cor completa, não CSS declarativo).
     Cura: 1 classe semantica com modificador ".active" (ver admin.css .sn-tab-btn) em vez
     do ternario trocar utilitarias; hex identico ao Tailwind blue-600/gray-500 original
     (preserva resultado visual), nome proprio porque o papel (estado de aba) e distinto
     de --preview-color-primary/--preview-fg-muted (mesmo hex, proposito de preview). */
  --tab-active-color:   #2563EB;
  --tab-inactive-color: #6b7280;
  /* #905 Frente A Onda2 B2d (Admin/Layout/CompanySelector.razor): ".sn-company-opt.active"
     usava var(--fg-accent) e var(--bg-accent-soft, rgba(var(--accent-rgb),.08)) — nenhum
     dos 3 tokens (--fg-accent/--bg-accent-soft/--accent-rgb) jamais existiu em UI.Tokens,
     entao a regra ja renderizava sem cor de destaque (var() invalido cai em "unset").
     Nomeados aqui a partir do --seg-accent ja usado no resto do tema (mesmo papel
     semantico "cor de destaque"), corrigindo o latente em vez de repetir o var() morto. */
  --fg-accent:       var(--seg-accent);
  --bg-accent-soft:  color-mix(in srgb, var(--seg-accent) 8%, transparent);

  /* ───────────────── TOOLTIP / STATUSBAR ───────────────── */
  --seg-tooltip-fg:  var(--white);

  /* ───────────────── NOTIFICATION WIDGET ───────────────── */
  --spoc-bg:              var(--white);
  --spoc-bg-card:         var(--white);
  --spoc-bg-hover:        var(--bg-muted);
  --spoc-bg-unread:       #EFF6FF;
  --spoc-bg-unread-hover: #DBEAFE;
  --spoc-border:          var(--border-soft);
  --spoc-primary:         var(--info);
  --spoc-text:            var(--gray-90);
  --spoc-text-muted:      var(--fg-muted);

  /* ───────────────── CODE BLOCK DARK THEME ───────────────── */
  --code-bg-dark:          #0d1117;
  --code-bg-pre:           #111827;
  --code-bg-quote:         #1e2d4f;
  --code-bg-table:         #1a2744;
  --code-text:             #e2e8f0;
  --code-text-bright:      #f1f5f9;
  --code-text-dim:         #cbd5e1;
  --code-text-muted:       #94a3b8;
  --code-text-faint:       #9ca3af;
  --code-text-gray:        #d1d5db;
  --code-hl-blue:          #93c5fd;
  --code-hl-blue-soft:     #bfdbfe;
  --code-quote-text:       #c7d2fe;
  --code-quote-border:     #3730a3;

  /* ───────────────── TAG AMBER ───────────────── */
  --tag-amber-bg:          #FEF3C7;
  --tag-amber-fg:          #92400E;
  --tag-amber-border:      #F59E0B;
  /* #905 Frente A Onda2 B2d (Admin/Certificates/CertificateManager.razor): aviso inline
     "chave privada..." usava Tailwind text-amber-600 puro — degrau mais claro que
     --tag-amber-fg(amber-800/#92400E), hex proprio para preservar o resultado visual. */
  --text-amber-600:        #D97706;

  /* ───────────────── BADGE STATUS (WORKSTATE) ───────────────── */
  --badge-inprogress-bg:   #E7E0FB;
  --badge-inprogress-fg:   #5B36B5;
  --badge-modeling-bg:     #F0E4FB;
  --badge-modeling-fg:     #7B2FB5;

  /* ───────────────── VIOLET / CRITICAL ───────────────── */
  --critical:              #7c3aed;
  --violet-bg:             #F3E8FF;
  --violet-fg:             #6B21A8;
  --violet-soft-bg:        #f0ebfa;
  --violet-soft-fg:        #6b3fa0;
  --violet-soft-border:    #c9b3e8;

  /* ───────────────── WORKFLOW DIAGRAM (SVG editor) ───────────────── */
  /* #905 Frente A Onda2 B1d (UI.Workflow): WorkflowEditor.razor monta o SVG do
     diagrama de workflow via StringBuilder (não markup Razor), com ~19 ocorrências
     de #hex cravado formando uma paleta própria por StateType — sem token semântico
     equivalente até aqui. Nasce a paleta completa: cor por estado (fill+stroke) e
     cor de grade/traço do canvas (raias, setas, texto), reaproveitando --critical
     já existente para NOTIFY (roxo) em vez de duplicar. */
  --workflow-state-start:               #0D9488;  /* START/END — pílula teal */
  --workflow-state-start-stroke:        #0F766E;
  --workflow-state-intermediate:        #2563EB;  /* INTERMEDIATE — retângulo azul */
  --workflow-state-intermediate-stroke: #1D4ED8;
  --workflow-state-decision:            #D97706;  /* DECISION — losango âmbar */
  --workflow-state-decision-stroke:     #B45309;
  --workflow-state-notify:              var(--critical); /* NOTIFY — roxo (reusa --critical, já é #7c3aed) */
  --workflow-state-signature:           #EF4444;  /* REQUIRE_SIGNATURE — vermelho (ícone da paleta esquerda) */
  --workflow-state-action-stroke:       #6D28D9;  /* contorno roxo compartilhado por NOTIFY/REQUIRE_SIGNATURE no canvas */

  --workflow-canvas-bg:                 #F8FAFC;  /* fundo do SVG */
  --workflow-lane-even-bg:              #F1F5F9;  /* raia par */
  --workflow-lane-odd-bg:               #FFFFFF;  /* raia ímpar */
  --workflow-lane-header-even-bg:       #E2E8F0;  /* header da raia par */
  --workflow-lane-header-odd-bg:        #F1F5F9;  /* header da raia ímpar */
  --workflow-lane-border:               #CBD5E1;  /* borda das raias */
  --workflow-lane-label:                #475569;  /* texto do rótulo da raia */
  --workflow-lane-separator:            #94A3B8;  /* linha vertical header↔canvas */
  --workflow-edge-stroke:               #64748B;  /* seta de transição (sólida) */
  --workflow-edge-dashed-stroke:        #94A3B8;  /* seta de transição (tracejada) */
  --workflow-edge-label:                #64748B;  /* texto do rótulo da transição */

  /* ───────────────── BRAND GRADIENT ───────────────── */
  --brand-droplet-green-end: #75C99A;

  /* ───────────────── RGB TRIPLETS (para rgba(var(--x-rgb), alpha)) ───────────────── */
  /* #905 Frente A escopo 8 (Spoc): consent.css tinha ~15 rgba(255,255,255,N) /
     rgba(186,212,85,N) / rgba(19,31,82,N) chumbados — cada um com um alpha diferente
     por estado (border/hover/active/texto). Criar 1 token por combinação cor+alpha
     seria dezenas de tokens para um padrao que e sempre "marca + opacidade variavel
     por estado". Expor o triplete RGB deixa o alpha livre no ponto de uso
     (rgba(var(--seg-blue-rgb), .12)) sem perder a cor exata do tema (== --seg-blue /
     --seg-green / --white, byte a byte) e sem inventar token por combinacao. Mesmo
     padrao serve Admin/Gamefied/Showcase, que tem os mesmos valores chumbados. */
  --seg-blue-rgb:  19, 31, 82;     /* == --seg-blue  (#131F52) */
  --seg-green-rgb: 186, 212, 85;   /* == --seg-green (#BAD455) */
  --white-rgb:     255, 255, 255;  /* == --white */
  --black-rgb:     0, 0, 0;        /* == --black — completa o trio p/ rgba(var(--black-rgb),N) */
  /* #905 Frente A Onda2 B1a (UI.Branding/BrandingPreviewContent.razor): o próprio texto
     "rgba(var(--black-rgb),.08)" escrito no consumidor ainda dispara OCPL021 (o analyzer
     casa a substring "rgba(" literalmente, sem diferenciar var()-args de literal — possível
     falso positivo do analyzer #1, reportado). Cura sem contornar: computar em UI.Tokens (que
     é isento) e expor só var(--token) no consumidor — mesmo valor, resultado visual idêntico.
     NOME: a primeira tentativa (--swatch-border-hairline) disparou um SEGUNDO falso positivo,
     021A, por conter a forma "border-hairline" (2 segmentos, formato "prefixo-palavra" igual a
     uma classe Tailwind border-*) — mesma classe de falso positivo já documentada para
     "border-soft"/"bg-unread" em ImagePickerModal.razor. Renomeado para fugir da FORMA do nome
     (não do valor/função), sem suprimir nada. */
  --hairline-black-08: rgba(var(--black-rgb), .08);

  /* ───────────────── TYPOGRAPHY EXTRAS 2 (#905 Frente A escopo 10) ───────────────── */
  /* Insights/Grc/GamefiedDataCollection/LandingPages (4/4, mesmo scaffold "sn-*")
     repetiam estes 2 valores crus como font-size — sem degrau equivalente na escala
     existente (fs-nano fica abaixo de fs-micro=11px; fs-page-title/fs-hero preenchem
     o vão 20↔24 e 24↔32 respectivamente, usados de forma consistente e repetida nos
     4 .css + em telas como Economia/Routes). 13px já tem --fs-ui (escopo 8/Spoc) —
     reaproveitado, não duplicado aqui. */
  --fs-nano:       9px;   /* .sn-sidebar-brand-sub — eyebrow abaixo de fs-micro */
  --fs-page-title: 22px;  /* .sn-page-title — recorre nos 4 .css + Economia/Routes */
  --fs-hero:       28px;  /* .sn-auth-hero-title / .sn-stat-value — heading de destaque */

  /* ───────────────── SHADOW EXTRAS 2 (#905 Frente A escopo 10) ───────────────── */
  /* .sn-auth-card idêntico nos 4 .css (mesmo scaffold de login). var(--shadow-xl, <fallback>)
     já era referenciado nos 4 .css (drawer mobile da sidebar) antecipando este token —
     nunca existia de fato; nasce aqui. Ambos compostos com --seg-blue-rgb/--black-rgb
     em vez de repetir o rgb() cru (mesmo padrão do escopo 8). */
  --shadow-auth-card: 0 8px 32px rgba(var(--seg-blue-rgb), .10);
  --shadow-xl:        0 16px 40px rgba(var(--black-rgb), .35);

  /* ───────────────── FORM FIELD WIDTHS (#905 Frente A Onda2 B2c — Admin
     Activities/Workflow/Operators) ───────────────── */
  /* Família "actwf-input-w-*": min-width/width de campos de formulário tabular
     (edição inline em tabela, filtros de lista) usados só em ActivityList.razor
     (filtros + colunas de ação) e WorkStateAdmin.razor (edição inline de linha) —
     1 família reusada em vez de repetir NNpx cru. NOME com prefixo "actwf-"
     (nem "input-w-*" nem "field-w-*"): AMBOS já foram criados por ondas
     concorrentes com valores DIFERENTES dos daqui (--input-w-sm 112px/--input-w-md
     220px; --field-w-xs 80px/--field-w-sm 90px/--field-w-md 160px) — mesma raiz de
     nome com valor diferente quebraria silenciosamente um dos lados (:root não
     suporta overload; a declaração mais tardia no arquivo vence). Prefixo
     dedicado ao domínio evita a 3ª colisão consecutiva na mesma sessão.
     --input-w-md(220px, já existente) é reusado abaixo para o campo Buscar
     (mesmo valor, sem precisar de token novo). */
  --actwf-input-w-xs:   70px;   /* Ordem/SortOrder (WorkStateAdmin) */
  --actwf-input-w-sm:   120px;  /* Nome (WorkStateAdmin edição inline) */
  --actwf-input-w-md:   200px;  /* Tipo/Responsável/Módulo/Descrição/coluna Ações (ActivityList) */
  --actwf-input-w-date: 140px;  /* campos de data "Solicitado de/até" (ActivityList) */
  --table-min-w:  900px;  /* largura mínima da tabela de Atividades p/ não colapsar colunas */
  /* #905 Frente A Onda2 B2d (Admin/Monitoring/ApiCallLogViewer.razor + Observabilidade/
     SqlErrorsViewer.razor): tabela com 1 coluna a mais que a de Atividades — degrau maior. */
  --table-min-w-lg: 980px;
  /* Vão maior da família --grid-col-min(160px, já existente): grid de campos do
     formulário "Novo Estado" (WorkStateAdmin) e do cabeçalho da instância de
     workflow (WorkflowInstancePage) usam 180px, não 160px — valor real distinto,
     não invenção. NOME "actwf-grid-min" (nem "-grid-col-min-lg" nem "field-grid-min"):
     outra onda concorrente já criou --grid-col-min-lg com valor DIFERENTE (280px) —
     mesmo risco de colisão descrito acima na família actwf-input-w-*. */
  --actwf-grid-min: 180px;

  /* Degrau abaixo de --dialog-max-width(440px): modal de confirmação de exclusão de
     fase (ModulePhasesEditor) e painel "sem seleção" de transição (WorkflowInstancePage)
     usam 400px cru, mesmo padrão em ambos. */
  --dialog-max-width-sm: 400px;
  /* Degrau acima de --dialog-max-width-lg(480px)/--dialog-max-width-xl(600px): modal de
     prompts vinculados (ActivityPromptModal) precisa de mais largura p/ textarea de prompt. */
  --dialog-max-width-2xl: 860px;

  /* Altura do <LogoBranded> no CONTEÚDO da página (não no <aside> do LoginLayout — esse já
     usa 32px cru, fora do escopo desta onda) em telas standalone de onboarding (AcceptInvite,
     RegisterOperator) — 36px é o valor real do markup original, degrau distinto do
     --logo-height-sidebar(24px)/layout hero(32px). NOME "standalone" (não "-login", já usado
     por outra onda para o logo do LoginLayout com valor diferente/32px) evita a mesma
     colisão de nome-com-valor-diferente descrita acima na família field-w-*. */
  --logo-height-standalone: 36px;

  /* font-size em rem preservados como rem (não convertidos p/ token px): o analyzer
     OCPL021 só varre #hex/rgb()/NNpx em style inline — valores em rem não disparavam
     erro, mas ficavam sem token mesmo assim (badge de contagem de aba + textos
     secundários/botões pequenos em ActivityList/WorkStateAdmin repetiam .7rem/.8rem
     cru). Nomeados pelo valor (não por px-equivalente) porque a unidade de origem é rem. */
  --fs-rem-70: .7rem;
  --fs-rem-80: .8rem;
}

/* =====================================================================
   Reset-lite + base elements
   ===================================================================== */
html, body {
  background: var(--bg-app);
  color: var(--fg-default);
  font-family: var(--font-sans);
  font-size: var(--fs-body-3);
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6 { color: var(--fg-strong); font-weight: var(--fw-bold); line-height: 1.1; margin: 0; }
h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); }
h4 { font-size: var(--fs-h4); }
h5 { font-size: var(--fs-h5); }
h6 { font-size: var(--fs-h6); }

p  { font-size: var(--fs-body-3); color: var(--fg-default); margin: 0; }
small { font-size: var(--fs-body-4); color: var(--fg-secondary); }

a  { color: var(--link); text-decoration: none; }
a:hover { opacity: 0.85; }

button { font-family: inherit; }

/* =====================================================================
   Reusable semantic helpers (optional, used across previews)
   ===================================================================== */
.sn-display { font-size: var(--fs-display); font-weight: var(--fw-bold); color: var(--fg-strong); letter-spacing: -0.01em; }
.sn-lead    { font-size: var(--fs-body-1); color: var(--fg-secondary); font-weight: var(--fw-regular); }
.sn-eyebrow { font-size: var(--fs-caption); font-weight: var(--fw-semibold); letter-spacing: 0.04em; text-transform: uppercase; color: var(--fg-secondary); }

.sn-tag {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: var(--radius-pill);
  background: var(--action-bg-soft); color: var(--success); font-size: 12px; font-weight: var(--fw-semibold);
}

/* Primary lime CTA */
.sn-btn-primary {
  height: 40px; padding: 0 24px;
  border-radius: var(--radius-lg);
  background: var(--seg-green); color: var(--action-fg);
  font-size: var(--fs-body-3); font-weight: var(--fw-regular);
  border: 0; cursor: pointer;
  box-shadow: var(--shadow-card);
  transition: transform 120ms ease, filter 120ms ease;
}
.sn-btn-primary:hover { filter: brightness(0.96); }
.sn-btn-primary:active { transform: scale(0.98); }

/* Soft pale-lime secondary */
.sn-btn-secondary {
  height: 30px; padding: 0 20px;
  border-radius: var(--radius-lg);
  background: var(--action-bg-soft); color: var(--gray-80);
  font-size: var(--fs-body-4); font-weight: var(--fw-regular);
  border: 0; cursor: pointer;
}

/* Ghost / neutral pill */
.sn-btn-ghost {
  height: 30px; padding: 0 20px;
  border-radius: var(--radius-lg);
  background: var(--gray-10); color: var(--seg-blue-80);
  font-size: var(--fs-body-4); border: 0; cursor: pointer;
}

/* =====================================================================
   DARK MODE — Override apenas semantic surfaces.
   Brand colors (--seg-blue, --seg-green) permanecem inalteradas.
   Aplicação: <html data-theme="dark"> via ThemeService.
   ===================================================================== */
:root[data-theme="dark"] {
  --bg-app:        var(--seg-blue-130);
  --bg-surface:    var(--seg-blue-120);
  --bg-muted:      var(--seg-blue-110);
  --bg-nav:        var(--seg-blue-130);
  --bg-header:     var(--seg-blue-120);

  --fg-strong:     var(--white);
  --fg-default:    #D0D2DC;
  --fg-secondary:  #A1A5BA;
  --fg-muted:      #717997;
  --fg-on-brand:   var(--seg-blue-120);
  --fg-on-dark:    var(--white);

  --border-soft:   var(--seg-blue-110);
  --border-strong: var(--seg-blue-90);

  --link:          #5DCAA5;

  --brand-bg-logo: var(--brand-bg-logo-dark);
}

/* Respeitar preferência do SO se cookie não definido */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not([data-theme="dark"]) {
    --bg-app:        var(--seg-blue-130);
    --bg-surface:    var(--seg-blue-120);
    --bg-muted:      var(--seg-blue-110);
    --bg-nav:        var(--seg-blue-130);
    --bg-header:     var(--seg-blue-120);
    --fg-strong:     var(--white);
    --fg-default:    #D0D2DC;
    --fg-secondary:  #A1A5BA;
    --fg-muted:      #717997;
    --fg-on-brand:   var(--seg-blue-120);
    --fg-on-dark:    var(--white);
    --border-soft:   var(--seg-blue-110);
    --border-strong: var(--seg-blue-90);
    --link:          #5DCAA5;
    --brand-bg-logo: var(--brand-bg-logo-dark);
  }
}

/* =====================================================================
   BREAKPOINTS — Omnichannel mobile-first.
   ===================================================================== */
:root {
  --bp-mobile:  0px;
  --bp-tablet:  768px;
  --bp-desktop: 1024px;
  --bp-wide:    1440px;
}

.sn-hide-mobile { display: none; }
@media (min-width: 768px) { .sn-hide-mobile { display: initial; } }

.sn-hide-desktop { display: initial; }
@media (min-width: 768px) { .sn-hide-desktop { display: none; } }

@media (max-width: 767px) {
  .sn-touch { min-height: 44px; min-width: 44px; }
}

/* Card */
.sn-card {
  background: var(--bg-surface);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
}

/* ============ Tenant white-label overrides ============ */
/* Quando <TenantBrandingStyle /> renderiza :root[data-tenant-branding] com --brand-*,
   este bloco propaga para os tokens semânticos do design system. */
:root[data-tenant-branding] {
  --seg-blue:      var(--brand-primary,        var(--seg-blue));
  --seg-green:     var(--brand-accent,         var(--seg-green));
  --bg-app:        var(--brand-bg-app,         var(--bg-app));
  --bg-sidebar:    var(--brand-bg-sidebar,     var(--seg-blue));
  --fg-strong:     var(--brand-text-primary,   var(--fg-strong));
  --fg-on-sidebar: var(--brand-text-sidebar,   var(--white));
}

/* ═════════════════ #905 Frente A Onda2 B2a (OpenConnection.Admin —
   Pages/Clients + Pages/Contracts + Pages/Documents) ═════════════════ */
:root {
  /* Larguras de input/select/coluna repetidas cru nas telas administrativas de
     tenant/contrato/documento — reaproveita a escala --s-*/--space-*/--fs-* onde o
     valor já tinha degrau (3px=--s-0, 2px=--s-13, 5px=--space-5, 6px=--space-6,
     8px=--s-2, 10px=--s-3/--fs-10, 18px=--space-18, 22px=--fs-page-title, 48px=--s-11,
     120px=--img-thumb-max-w, 600px=--dialog-max-width-xl) e nasce aqui só o que não
     tinha equivalente ainda. */
  --field-w-xs:        80px;   /* input numérico curto (ex.: máx. seguradoras/consent) */
  --field-w-sm:        90px;   /* coluna estreita de tabela (ex.: código de contrato) */
  --field-w-md:        160px;  /* input/select largura média (ex.: UserId do participante) */
  --field-w-lg:        180px;  /* select largura maior (ex.: componente estrutural do bloco) */
  --field-w-xl:        200px;  /* filtro/select largura grande (busca de documentos) */
  --field-w-2xl:       220px;  /* select de versão do documento */
  --field-min-w-card:  250px;  /* min-width de card/filtro em layout flex-wrap */
  --panel-max-w-sm:    500px;  /* max-width/max-height de painel médio (créditos, preview) */
  --panel-max-w-md:    520px;  /* max-width de modal/tabela (chave de API, saldo de créditos) */
  --panel-max-w-lg:    680px;  /* max-width do card de formulário (ClientForm) */
  --panel-max-w-xl:    700px;  /* max-width do modal de biblioteca de cláusulas */

  /* DocumentEditor.razor (RenderBlock via RenderTreeBuilder manual) tinha 3 rgba() cruas
     formando uma paleta própria de destaque de bloco (bloco-sugestão / bloco-promovido —
     fraco e forte). Nomes evitam propositalmente os prefixos "bg-"/"border-"/"text-" que
     colidem com a heurística Tailwind do OCPL021A (achado 22/jul, mesma classe de falso
     positivo de --border-soft/--spoc-bg-unread já documentada). */
  --doc-suggestion-highlight:        rgba(59, 130, 246, .06);
  --doc-promoted-highlight-soft:     rgba(16, 185, 129, .08);
  --doc-promoted-highlight-strong:   rgba(16, 185, 129, .18);
}
