/* ═══════════════════════════════════════════════════════════════════════════
   Tuff: os tokens da identidade visual do ambiente.

   Este arquivo é a fonte única da paleta, da tipografia, da geometria e da fonte
   do VSSH. O shell o carrega como `tuff/tuff-tokens.css`, antes de toda folha
   dele; um vssh-app o recebe pelo prefixo reservado do SDK web, como
   `_sdk/tuff/tuff-tokens.css`, e os dois leem os mesmos bytes. Um app roda num
   `<iframe>` e não herda folha nenhuma do shell, então é por este arquivo que a
   janela dele fica com a cara das outras janelas.

   ─── De onde vem cada parte ─────────────────────────────────────────────────

   Os valores nasceram no shell (`css/design-tokens.css`, hoje este arquivo). A
   forma vem da biblioteca de componentes do toolkit de apps
   (`vssh-app-toolkit/lib/web/tuff/`): o `@font-face` junto dos tokens, com URL
   relativa, e a camada `@layer vssh`. Os dois lados se fundiram aqui, e a regra
   da fusão é uma: o que o shell lê continua existindo com o mesmo valor.

   ─── Estrutura ──────────────────────────────────────────────────────────────
     1. Tokens brutos     (--tuff-*)   a base
     2. Tokens semânticos (--ds-*)     o que os componentes leem

   Componente escreve `--ds-*`. Os `--tuff-*` existem para a base poder mudar sem
   uma caça a cor em vinte arquivos; os componentes do shell fazem centenas de
   usos de `--ds-*` e nenhum de `--tuff-*`, e um app segue a mesma regra.

   Este arquivo declara só tokens e a fonte. O reset mora em `tuff-base.css` e os
   componentes em `tuff.css`, porque há quem queira a cor do ambiente sem a
   aparência dele: um app com identidade visual própria que só quer acompanhar a
   cor de destaque carrega este arquivo sozinho.
   ═══════════════════════════════════════════════════════════════════════════ */


/* ── A fonte, servida por quem serve este arquivo ────────────────────────────

   `Instrument Sans` é a fonte do ambiente e não atravessa o iframe: são dois
   documentos, e o `@font-face` de um não vale no outro. Um app que só nomeasse a
   família cairia em `system-ui` e ficaria estrangeiro ao lado das outras janelas.
   A tipografia denuncia uma janela antes de qualquer cor.

   Os arquivos moram em `fonts/`, ao lado deste CSS, e ninguém pede fonte à rede
   de quem senta na frente: uma requisição a um terceiro no caminho crítico do
   boot é uma tela que muda de fonte conforme o bloqueador de anúncios.

   É a versão variável: um arquivo cobre os pesos 400 a 700, sem um `.woff2` por
   peso. São 41 KB somando os dois subconjuntos, e o `unicode-range` faz o
   `latin-ext` (11 KB) só ser baixado quando a página usa um caractere dele.
   Português cabe no `latin`.

   A URL é relativa (`fonts/…`) de propósito, e precisa continuar assim: ela
   resolve contra a URL deste CSS, que no shell é `tuff/` e num app instalado é o
   prefixo do proxy mais `_sdk/tuff/`. Uma URL absoluta funcionaria num dos dois
   lugares e daria 404 no outro, e o sintoma seria só a fonte errada, sem erro na
   tela. O portal carimba o `url()` na hora de servir; em disco ele fica simples.

   Licença: SIL OFL 1.1, em `fonts/OFL.txt`, distribuída junto como ela exige. */

@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(fonts/instrument-sans-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
                 U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
                 U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(fonts/instrument-sans-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
                 U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
                 U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}


/* ── A camada ────────────────────────────────────────────────────────────────
   Os tokens entram em `@layer vssh`, como o resto da biblioteca. Regra em camada
   perde para regra fora de camada, seja qual for a ordem no arquivo, e é isso
   que dá a hierarquia certa sem `!important`:

       padrão da biblioteca  <  escolha do app  <  escolha do ambiente
       (@layer vssh)            (CSS sem camada)   (inline no `<html>`)

   No shell a camada não muda nada: nenhuma folha dele declara um `--ds-*` no
   `<html>`, e a cor que a pessoa escolhe chega inline, que vence camada e folha.

   O `@font-face` acima fica fora: ele não é regra de estilo e não participa da
   cascata. */

/* ── 1. Tokens brutos ────────────────────────────────────────────────────── */

@layer vssh {

:root {
  /* Superfícies. Os degraus da pedra em cinza puro, sem matiz: a cor do ambiente é a de destaque
     que a pessoa escolhe, e a paleta é medida contra as sete opções de Configurações. */
  --tuff-bg:           #1b1b1b;
  --tuff-bg2:          #222222;
  --tuff-bg3:          #2b2b2b;
  --tuff-bg-input:     #353535;
  --tuff-bg-hover:     rgba(255,255,255,0.06);

  /* Bordas. O contorno de campo é mais claro que o fio porque o campo se acha por ele: o degrau
     de fundo entre o campo e a peça fica em 1,30:1, e o contorno passa de 3:1 (3,21 sobre
     `--tuff-bg2`), o mínimo de um componente de interface. */
  --tuff-border:       #454545;
  --tuff-border-input: #707070;
  --tuff-border-dark:  #1a1a1a;
  --tuff-border-focus: var(--tuff-accent);

  /* Texto. O apagado passa no AA (4,5:1) sobre as três superfícies e sobre o campo: 6,59:1 em
     `--tuff-bg`, 6,08:1 em `--tuff-bg2`, 5,41:1 em `--tuff-bg3` e 4,69:1 em `--tuff-bg-input`. */
  --tuff-text:         #d8d8d8;
  --tuff-text-dim:     #a0a0a0;
  --tuff-text-bright:  #ededed;
  --tuff-text-inv:     #ffffff;

  /* Acentos. Os cinco tokens de destaque são os únicos que mudam em runtime: a
     pessoa escolhe a cor em Configurações, e o shell reescreve `--ds-accent`,
     `--ds-accent-h`, `--ds-accent-bg`, `--ds-sel` e `--ds-on-accent` inline no
     `<html>`. O resto da paleta é estático, e é isso que mantém a ponte com os
     apps pequena. O tom sob o ponteiro é o destaque com 15% de preto, porque o
     texto sobre o azul padrão é branco e o hover não pode tirar contraste dele. */
  --tuff-accent:       #0e639c;
  --tuff-accent-h:     #0c5485;
  --tuff-accent-bg:    rgba(14,99,156,0.15);
  /* A seleção é o destaque a 22% sobre a superfície, o mesmo que `_applyAccentColor` escreve
     quando a pessoa escolhe uma cor, para quem não escolheu ver a seleção de quem escolheu o azul. */
  --tuff-sel:          rgba(14,99,156,0.22);
  --tuff-sel-text:     #ffffff;

  /* Estado. Três cores semânticas, longe do destaque e de luminosidade parecida, todas acima de
     4,5:1 sobre a página: o ok a 6,34, o aviso a 7,62 e o erro a 5,15 (4,76 sobre `--tuff-bg2`).
     Com o âmbar ou o vermelho como destaque, o aviso e o erro se separam dele pelo ícone e pelo
     texto que trazem, e nunca só pela cor. O ok é também o cursor do terminal. */
  --tuff-green:        #4caf7d;
  --tuff-red:          #f05a50;
  --tuff-red-bg:       rgba(240,90,80,0.12);
  /* O fundo do botão que destrói: 5,65:1 com o texto branco (o `DESIGN.md`, "Estado e
     categoria"). O `--tuff-red` é cor de texto e de ícone, e branco sobre ele não passa de 4,5. */
  --tuff-red-solid:    #b93a32;
  --tuff-red-solid-h:  #9f322b;
  /* O âmbar de aviso, para a pílula e a dica de aviso, a barra de quase cheio e a linha de aviso
     do log concordarem. */
  --tuff-amber:        #d6a531;

  /* Categoria. Uma paleta para dado e para código, sem par semântico: um visualizador de dados
     ou um editor precisa de cores de categoria que sejam daqui, e seis cores inventadas por app é
     como o ambiente deixa de parecer um ambiente. Elas servem a gráfico e a código, e nunca à
     moldura. */
  --tuff-green2:       #6a9955;   /* código: strings */
  --tuff-yellow:       #dcdcaa;
  --tuff-orange:       #ce9178;
  --tuff-blue:         #569cd6;
  --tuff-cyan:         #4ec9b0;
  --tuff-purple:       #c678dd;

  /* Tipografia. A pilha do sistema atrás da `Instrument Sans` é o que aparece
     nos ~100 ms até o arquivo chegar (`font-display: swap`). */
  --tuff-font:         'Instrument Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --tuff-font-mono:    'JetBrains Mono', 'Cascadia Code', Consolas, 'Courier New', monospace;
  --tuff-size-2xs:     10px;
  --tuff-size-xs:      11px;
  --tuff-size-sm:      12px;
  --tuff-size-md:      13px;
  --tuff-size-lg:      14px;
  --tuff-size-xl:      16px;
  --tuff-size-2xl:     20px;
  --tuff-weight-n:     400;
  --tuff-weight-m:     500;
  --tuff-weight-b:     600;

  /* Geometria */
  --tuff-radius-xs:    2px;
  --tuff-radius-sm:    3px;
  --tuff-radius-md:    4px;
  --tuff-radius-lg:    6px;
  --tuff-radius-xl:    8px;

  /* Espaçamento */
  --tuff-gap-xs:       2px;
  --tuff-gap-sm:       4px;
  --tuff-gap-md:       8px;
  --tuff-gap-lg:       12px;
  --tuff-gap-xl:       20px;
  --tuff-gap-2xl:      32px;

  /* Sombras. Sem glassmorfismo: `--tuff-blur: none` é decisão de produto. */
  --tuff-shadow-sm:    0 1px 3px rgba(0,0,0,0.3);
  --tuff-shadow-md:    0 2px 8px rgba(0,0,0,0.4);
  --tuff-shadow-lg:    0 4px 16px rgba(0,0,0,0.5);
  --tuff-blur:         none;

  /* Scrollbar */
  --tuff-sb-w:         6px;
  --tuff-sb-track:     #1b1b1b;
  --tuff-sb-thumb:     #4a4a4a;
  --tuff-sb-thumb-h:   #606060;

  /* Animação */
  --tuff-ease:         ease;
  --tuff-ease-out:     ease-out;
  --tuff-dur:          0.15s;
  --tuff-dur-fast:     0.08s;
}

/* Com o movimento reduzido no sistema, as transições caem: toda transição do Tuff lê as durações
   destes dois tokens. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --tuff-dur:        0s;
    --tuff-dur-fast:   0s;
  }
}


/* ── 2. Tokens semânticos (--ds-*) ───────────────────────────────────────────
   Componentes leem daqui, e só daqui.

   Eles moram no `:root`: o shell tem quase mil usos de `--ds-*`, a maioria sem
   fallback, e um `<html>` que dependesse do atributo de tema ficaria ilegível
   durante os scripts síncronos do boot. */

:root {
  --ds-bg:             var(--tuff-bg);
  --ds-bg2:            var(--tuff-bg2);
  --ds-bg3:            var(--tuff-bg3);
  --ds-bg-input:       var(--tuff-bg-input);
  --ds-bg-hover:       var(--tuff-bg-hover);
  --ds-border:         var(--tuff-border);
  --ds-border-input:   var(--tuff-border-input);
  /* O anel de foco é o destaque clareado do texto (`--ds-accent-texto`, abaixo): o destaque cru
     fica entre 1,92 e 3,35:1 sobre as superfícies, e um indicador de estado pede 3:1. O clareado
     passa de 4,8:1 com as sete cores sobre a página, a peça, o terceiro degrau e o campo. */
  --ds-border-focus:   var(--ds-accent-texto);
  --ds-text:           var(--tuff-text);
  --ds-text-dim:       var(--tuff-text-dim);
  --ds-text-mid:       var(--tuff-text-bright);
  --ds-text-inv:       var(--tuff-text-inv);

  /* ── Os cinco que mudam em runtime, e um contrato lido de fora ─────────────
     `SettingsWindow._applyAccentColor` reescreve estes cinco inline no `<html>`
     quando a pessoa escolhe uma cor. Um vssh-app acompanha a cor lendo estas
     custom properties do `<html>` do pai, pela ponte do SDK web, então os cinco
     nomes são um contrato: renomear um deles não quebra nada no shell e deixa a
     janela de todo app instalado fora do tom, sem erro em lugar nenhum. */
  --ds-accent:         var(--tuff-accent);
  --ds-accent-h:       var(--tuff-accent-h);
  --ds-accent-bg:      var(--tuff-accent-bg);
  --ds-sel:            var(--tuff-sel);
  --ds-sel-text:       var(--tuff-sel-text);

  /* Texto sobre a cor de destaque. Branco sobre o azul padrão dá 6,40:1. Quando
     a pessoa escolhe uma cor, o shell reescreve este token: branco quando ele
     passa de 4,5:1 sobre a cor, e `#1b1b1b` quando não passa. */
  --ds-on-accent:      var(--tuff-text-inv);

  /* A cor de destaque como TEXTO ou ícone sobre as superfícies (o item ativo, o marcado, o link).
     O `#0e639c` dá cerca de 2,4:1 sobre o grafite, abaixo dos 4,5:1 de texto e dos 3:1 de ícone;
     misturado com branco ele passa de 4,9:1 nas três superfícies e na tinta de destaque. Ele parte
     de `--ds-accent`, então segue a cor que a pessoa escolher. Sobre `--ds-sel` o texto é
     `--ds-sel-text`: ali o destaque clareado não chega a 4,5:1. */
  --ds-accent-texto:   color-mix(in srgb, var(--ds-accent) 55%, #ffffff);

  /* A pasta é o único ícone de arquivo na cor de destaque, clareada: a frente com 62% do destaque
     e o fundo com 85%, misturados com branco, passam de 3,7:1 sobre a página com qualquer uma das
     sete cores. A gravura das pastas da pessoa fica um tom abaixo da frente. `TuffArquivo` lê os
     três, e eles seguem a cor quando ela muda. */
  --ds-pasta-frente:   color-mix(in oklab, var(--ds-accent) 62%, #ffffff);
  --ds-pasta-fundo:    color-mix(in oklab, var(--ds-accent) 85%, #ffffff);
  --ds-pasta-gravura:  color-mix(in oklab, var(--ds-accent) 70%, #000000);

  --ds-green:          var(--tuff-green);
  --ds-warn:           var(--tuff-amber);
  --ds-danger:         var(--tuff-red);
  --ds-danger-bg:      var(--tuff-red-bg);
  --ds-danger-solid:   var(--tuff-red-solid);
  --ds-danger-solid-h: var(--tuff-red-solid-h);
  --ds-font:           var(--tuff-font);
  --ds-font-mono:      var(--tuff-font-mono);
  --ds-radius-sm:      var(--tuff-radius-sm);
  --ds-radius-md:      var(--tuff-radius-md);
  --ds-radius-lg:      var(--tuff-radius-lg);
  --ds-radius-xl:      var(--tuff-radius-xl);
  --ds-shadow-sm:      var(--tuff-shadow-sm);
  --ds-shadow-md:      var(--tuff-shadow-md);
  --ds-shadow-lg:      var(--tuff-shadow-lg);
  --ds-blur:           var(--tuff-blur);
  --ds-ease:           var(--tuff-ease);
  --ds-ease-out:       var(--tuff-ease-out);
  --ds-dur:            var(--tuff-dur);
  --ds-dur-fast:       var(--tuff-dur-fast);

  /* A escala de espaçamento, promovida a semântica. Os componentes do Tuff a
     leem (`padding: var(--ds-gap-md)`) e acertam a densidade do ambiente sem
     saber que ela é 8px. As folhas do shell ainda escrevem os pixels à mão, e
     cada uma passa a ler daqui quando for tocada. */
  --ds-gap-xs:         var(--tuff-gap-xs);
  --ds-gap-sm:         var(--tuff-gap-sm);
  --ds-gap-md:         var(--tuff-gap-md);
  --ds-gap-lg:         var(--tuff-gap-lg);
  --ds-gap-xl:         var(--tuff-gap-xl);
  --ds-gap-2xl:        var(--tuff-gap-2xl);

  /* A altura de um controle e a largura do botão de ícone: 26 px sob o ponteiro fino, a densidade
     de uma ferramenta, e 44 px sob o dedo, o alvo de toque mínimo. Quem decide é o ponteiro, e não
     a largura: uma janela estreita no desktop continua apontada por um mouse, e um tablet largo
     continua tocado por um dedo. */
  --ds-alvo:           26px;

  /* ── A superfície do próprio ambiente ──────────────────────────────────────
     Um token que só o shell lê: um app não desenha a área de trabalho. Ele mora
     aqui porque a fonte é uma, e chega a um app sem custo e sem uso.

     O fundo padrão da área de trabalho, o que se vê sem escolha: os estratos.
     Três consumidores concordam sobre ele, o `body` do desktop, a prévia de
     Configurações e a camada de baixo de uma imagem. Os estratos se tingem com
     a cor de destaque, e um SVG num `data:` não lê variável CSS: quem escreve o
     valor de verdade é o shell (`SettingsWindow._initWallpaper`, com o desenho
     de `Fundos.css`), a cada troca de cor. O valor daqui é o que aparece antes
     do primeiro script, no cinza dos estratos. */
  --ds-fundo-padrao:
    linear-gradient(180deg, #181818 0%, #1c1c1c 35%, #202020 70%, #191919 100%);
}

@media (pointer: coarse) {
  :root { --ds-alvo: 44px; }
}

/* No celular, o dedo numa tela estreita, a letra pequena sobe um ponto: o corpo vai a 14 px e as
   notas a 12, lidos a um braço de distância. O tablet, largo, fica na escala da ferramenta, e os
   títulos não mudam. */
@media (pointer: coarse) and (width < 600px) {
  :root {
    --tuff-size-xs: 12px;
    --tuff-size-sm: 13px;
    --tuff-size-md: 14px;
  }
}

}  /* @layer vssh */
