    :root {
      --bg:       #f1f5f9;
      --surface:  #ffffff;
      --border:   #e2e8f0;
      --primary:  #2563eb;
      --primary-h:#1d4ed8;
      --primary-soft: rgba(37,99,235,.10);
      --text:     #1e293b;
      --muted:    #64748b;
      --danger:   #dc2626;
      --warning:  #d97706;
      --success:  #16a34a;
      --radius:   12px;
      --radius-sm: 8px;
      --shadow:   0 1px 2px rgba(15,23,42,.05), 0 2px 8px rgba(15,23,42,.05);
      --chart-bar: #2563eb;   /* validado: contraste ≥3:1 sobre #ffffff */
      --mark:     #fef08a;
    }
    html[data-theme="dark"] {
      color-scheme: dark;
      --bg:       #0f172a;
      --surface:  #1e293b;
      --border:   #334155;
      --primary:  #3b82f6;
      --primary-h:#60a5fa;
      --primary-soft: rgba(59,130,246,.16);
      --text:     #e2e8f0;
      --muted:    #94a3b8;
      --danger:   #f87171;
      --warning:  #fbbf24;
      --success:  #4ade80;
      --shadow:   0 1px 2px rgba(0,0,0,.25), 0 2px 8px rgba(0,0,0,.25);
      --chart-bar: #3b82f6;   /* validado: banda de luminosidade ok sobre #1e293b */
      --mark:     #713f12;
    }

    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

    body {
      font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
      background: var(--bg);
      color: var(--text);
      min-height: 100vh;
      font-size: 15px;
      transition: background .2s, color .2s;
    }

    /* ── Header (neutro) ── */
    header {
      background: var(--surface);
      color: var(--text);
      padding: .7rem 1.25rem;
      display: flex;
      align-items: center;
      gap: .6rem;
      border-bottom: 1px solid var(--border);
      position: sticky;
      top: 0;
      z-index: 10;
    }
    header h1 { font-size: 1.05rem; font-weight: 700; letter-spacing: -.01em; }
    header .icon { font-size: 1.3rem; }
    .hdr-btn {
      background: transparent;
      color: var(--muted);
      border: 1px solid var(--border);
      border-radius: var(--radius-sm);
      padding: .35rem .7rem;
      font-size: .82rem;
      font-weight: 600;
      cursor: pointer;
      font-family: inherit;
      transition: border-color .15s, color .15s;
    }
    .hdr-btn:hover { border-color: var(--primary); color: var(--primary); }
    #btn-theme { margin-left: auto; }
    #btn-logout { display: none; }

    /* ── Layout: sidebar + conteúdo ── */
    /* Largura da área útil. Era 1080px (com o conteúdo travado em 860px), o que
       deixava ~800px vazios à direita num monitor Full HD — a "área livre" que o
       usuário apontou em 2026-08-06. Vale para TODAS as telas de cartão de uma vez.
       ⚠️ Reverter é trocar estes dois valores de volta (1080px / 860px). */
    .app { display: flex; max-width: 1480px; margin: 0 auto; align-items: flex-start; }
    .sidebar {
      width: 210px;
      flex-shrink: 0;
      padding: 1.25rem .75rem;
      position: sticky;
      top: 56px;
      max-height: calc(100vh - 56px);
      overflow-y: auto;
    }
    .nav-item {
      display: flex;
      align-items: center;
      gap: .6rem;
      width: 100%;
      padding: .55rem .8rem;
      border: none;
      background: transparent;
      border-radius: 10px;
      color: var(--muted);
      font-family: inherit;
      font-size: .9rem;
      font-weight: 500;
      cursor: pointer;
      margin-bottom: 2px;
      transition: background .15s, color .15s;
      text-align: left;
    }
    .nav-item.active { background: var(--primary-soft); color: var(--primary); font-weight: 600; }
    .nav-item:hover:not(.active) { background: var(--bg); color: var(--text); }
    .nav-item[hidden] { display: none; }   /* par obrigatório de quem tem display */
    .nav-item .ico { font-size: 1.05rem; width: 1.4rem; text-align: center; }
    .nav-count {
      margin-left: auto;
      font-size: .7rem;
      font-weight: 700;
      background: var(--border);
      color: var(--muted);
      border-radius: 999px;
      padding: .08rem .45rem;
      min-width: 1.4rem;
      text-align: center;
    }
    .nav-count.alert { background: var(--danger); color: #fff; }
    .nav-count:empty { display: none; }
    .content { flex: 1; min-width: 0; padding: 1.5rem 1.25rem 3rem; max-width: none; }

    /* ── Barra inferior (mobile) ── */
    .bottomnav {
      display: none;
      position: fixed;
      bottom: 0; left: 0; right: 0;
      background: var(--surface);
      border-top: 1px solid var(--border);
      z-index: 50;
      justify-content: space-around;
      padding: .3rem .25rem calc(.3rem + env(safe-area-inset-bottom));
    }
    .bottomnav .nav-item {
      flex-direction: column;
      gap: 1px;
      font-size: .6rem;
      padding: .25rem .35rem;
      width: auto;
      margin: 0;
      position: relative;
    }
    .bottomnav .nav-item .ico { font-size: 1.3rem; width: auto; }
    .bottomnav .nav-count {
      position: absolute;
      top: 0; right: 2px;
      margin: 0;
      font-size: .58rem;
      padding: .02rem .3rem;
      min-width: 1.05rem;
    }
    @media (max-width: 768px) {
      .sidebar { display: none; }
      .bottomnav { display: flex; }
      body { padding-bottom: 68px; }
      .content { padding: 1rem .75rem 2rem; }
      /* A prévia da última atualização (.task-update-block) tem `flex:1;
         min-width:0` — no espaço apertado do celular, ao lado dos botões de
         + Atualizar/Copiar/Anexos/Histórico, o navegador prefere encolher
         esse bloco quase a zero (min-width:0 autoriza) em vez de quebrar
         linha, e o texto quebra letra a letra. `flex-basis: 100%` faz o
         bloco reivindicar a linha inteira pra si — os botões descem para a
         linha de baixo, layout normal de app mobile.
         ⚠️ Seletor com DOIS níveis (`.task-update-row .task-update-block`),
         de propósito: `.task-update-block` sozinho tem a MESMA especificidade
         da regra `flex:1` de baixo (linha ~644, fora da media query) — como
         as duas empatam, venceria quem vem depois no arquivo, que é a de
         baixo, e este fix não faria nada. Com dois níveis a especificidade é
         maior e a ordem no arquivo deixa de importar. */
      .task-update-row .task-update-block { flex-basis: 100%; }

      /* Espaço à direita mal aproveitado no celular (2026-08-10, print dele):
         `.task-card` é uma linha flex — `.task-body` (título/badges/status/
         datas/comentário) de um lado, `.task-actions` (Concluir, Nova tarefa,
         +1/+2 dias, Editar, excluir) do outro, os dois esticados pela ALTURA
         inteira do cartão. Como a coluna de ações é bem mais larga que o
         próprio texto de cada botão (a largura da coluna é a do botão mais
         largo, "🔗 Nova tarefa"), `.task-body` fica preso a essa largura
         estreita do título até o fim — mesmo nas linhas de baixo, onde já não
         sobra nenhum botão ao lado. No celular, `.task-card` vira coluna: os
         botões descem pro fim do cartão (viram outra fileira, igual à de
         + Atualizar/Copiar/Anexos/Histórico), e o conteúdo passa a usar a
         largura inteira em toda a altura.
         ⚠️ Ficaram no FIM do cartão (depois do comentário), não logo abaixo
         do título — mover pra lá exigiria mudar a ORDEM no HTML (o `action`
         já nasce depois do `task-body` no template), e isso mudaria o
         desktop também, que não tem esse problema. */
      .task-card { flex-direction: column; }
      /* Dois níveis de propósito, mesma razão da regra acima: `.task-actions`
         sozinho empataria com a definição de baixo (linha ~998, fora da
         media query) e perderia por ordem no arquivo. */
      .task-card .task-actions {
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
        justify-content: flex-start;
      }

      /* "Histórico" sobrava sozinho numa 2ª linha, com folga visível depois de
         + Atualizar/Recado/Copiar/📎 na 1ª (2026-08-10, print dele: "parece
         que cabe"). Pela conta do CSS declarado (fonte .72rem, padding .45rem
         nas laterais, gap .5rem entre os 5 botões) a soma fica bem perto da
         largura útil do cartão num celular comum — falta pouco, não sobra
         muito. Aperta gap e padding só no celular; sem dado de tela real pra
         confirmar o número exato (o sandbox não tem navegador), então é uma
         aposta bem fundamentada, não uma certeza — conferir se os 5 já cabem
         numa linha só, ou se ainda falta um pouco. */
      /* Dois níveis de novo, mesma razão de sempre: `.task-update-row` sozinho
         empataria com a definição de baixo (linha ~668, fora da media query,
         `gap: .5rem`) e perderia por ordem no arquivo. */
      .task-body .task-update-row { gap: .3rem; }
      .task-update-row .btn-add-update,
      .task-update-row .btn-show-history,
      .task-update-row .btn-show-attach,
      .task-update-row .btn-copy-task,
      .task-update-row .btn-send-recado {
        padding: .15rem .3rem;
      }
    }

    /* ── Card ── */
    .card {
      background: var(--surface);
      border: 1px solid var(--border);
      border-radius: var(--radius);
      padding: 1.25rem;
      box-shadow: var(--shadow);
    }

    /* ── Sub-tabs ── */
    .sub-tabs {
      display: flex;
      border-bottom: 2px solid var(--border);
      margin-bottom: 1.25rem;
    }
    .sub-tab {
      padding: .5rem 1.1rem;
      border: none;
      background: transparent;
      cursor: pointer;
      font-size: .875rem;
      font-weight: 600;
      color: var(--muted);
      border-bottom: 2px solid transparent;
      margin-bottom: -2px;
      transition: color .15s, border-color .15s;
      font-family: inherit;
    }
    .sub-tab.active { color: var(--primary); border-bottom-color: var(--primary); }
    .sub-tab:hover:not(.active) { color: var(--text); }

    /* ── Formulário ── */
    .form-group { margin-bottom: .9rem; }
    label {
      display: block;
      font-size: .8rem;
      font-weight: 600;
      text-transform: uppercase;
      letter-spacing: .04em;
      color: var(--muted);
      margin-bottom: .35rem;
    }
    textarea, input[type="text"], input[type="date"],
    input[type="time"], select {
      width: 100%;
      padding: .6rem .75rem;
      border: 1px solid var(--border);
      border-radius: var(--radius);
      font-size: .95rem;
      font-family: inherit;
      color: var(--text);
      background: var(--surface);
      transition: border-color .15s, box-shadow .15s;
      appearance: auto;
    }
    textarea:focus, input:focus, select:focus {
      outline: none;
      border-color: var(--primary);
      box-shadow: 0 0 0 3px rgba(37,99,235,.12);
    }
    textarea { min-height: 96px; resize: vertical; line-height: 1.5; }

    /* ── Editor de texto formatado (fase 3) ──────────────────────────────────────
       Os 6 campos que aceitam negrito/itálico/sublinhado deixaram de ser <textarea>
       e viraram `contenteditable`. Duas consequências de propósito:
        • o crescimento na vertical passou a ser NATIVO (a div cresce com o conteúdo),
          então o antigo ajustarAltura() em JS não existe mais — o TETO virou `max-height`
          com rolagem por dentro, mantendo os valores validados em 2026-07-29
          (220px nos títulos, 360px nos comentários);
        • Enter quebra linha aqui também (decisão de 2026-07-29), e as quebras vão para
          o banco — quem lê o campo é `lerCampo`, que devolve texto puro enquanto não
          houver marcação de verdade. */
    .editor-campo {
      width: 100%;
      padding: .6rem .75rem;
      border: 1px solid var(--border);
      border-radius: var(--radius);
      font-size: .95rem;
      font-family: inherit;
      color: var(--text);
      background: var(--surface);
      transition: border-color .15s, box-shadow .15s;
      line-height: 1.45;
      white-space: pre-wrap;        /* mostra as quebras digitadas */
      overflow-wrap: anywhere;      /* palavra gigante não estoura o cartão */
      max-height: 220px;            /* teto dos títulos */
      overflow-y: auto;
      cursor: text;
    }
    .editor-campo[data-max-altura="360"] { max-height: 360px; }
    .editor-campo:focus {
      outline: none;
      border-color: var(--primary);
      box-shadow: 0 0 0 3px rgba(37,99,235,.12);
    }
    /* `:empty` não serve: o contenteditable deixa um <br> sobrando quando se apaga
       tudo, e o campo deixaria de parecer vazio. Quem marca é o JS (`marcarVazio`). */
    .editor-campo.vazio::before {
      content: attr(data-placeholder);
      color: var(--muted);
      pointer-events: none;
    }
    /* o comentário inicial abria com 2 linhas (era rows="2") — mantido */
    .editor-campo.duas-linhas { min-height: 3.4rem; }

    /* Barrinha N / I / S: UMA só, reposicionada acima do campo em foco */
    #editor-barra {
      position: absolute;
      z-index: 1200;
      display: flex;
      gap: .15rem;
      padding: .2rem;
      background: var(--surface);
      border: 1px solid var(--border);
      border-radius: var(--radius);
      box-shadow: 0 4px 12px rgba(0,0,0,.12);
    }
    /* o par obrigatório: `display:flex` venceria o atributo hidden do navegador */
    #editor-barra[hidden] { display: none; }
    #editor-barra button {
      min-width: 2rem;
      padding: .25rem .45rem;
      border: none;
      border-radius: 6px;
      background: transparent;
      color: var(--text);
      font-size: .9rem;
      font-family: inherit;
      cursor: pointer;
      line-height: 1.2;
    }
    #editor-barra button:hover { background: var(--bg); }
    #editor-barra button.ativo { background: var(--primary); color: #fff; }

    /* Grid picker de tabela (2026-09-02), estilo Word — mesmo z-index/sombra
       do #editor-barra, posicionado por JS perto do botão que abriu. */
    .notas-tabela-popover {
      position: absolute; z-index: 1210;
      background: var(--surface); border: 1px solid var(--border);
      border-radius: var(--radius); box-shadow: 0 4px 12px rgba(0,0,0,.12);
      padding: .6rem;
    }
    /* o par obrigatório de sempre: `display` do grid venceria o atributo hidden */
    .notas-tabela-popover[hidden] { display: none; }
    .notas-tabela-grid {
      display: grid; grid-template-columns: repeat(8, 18px); grid-auto-rows: 18px;
      gap: 2px;
    }
    .notas-tabela-celula {
      width: 18px; height: 18px; border: 1px solid var(--border);
      border-radius: 2px; background: var(--bg);
    }
    .notas-tabela-celula.ativa { background: var(--primary); border-color: var(--primary); }
    .notas-tabela-label {
      margin-top: .4rem; font-size: .78rem; color: var(--muted); text-align: center;
    }
    /* Tabela inserida no CONTEÚDO de uma nota — borda visível pra separar as
       células enquanto edita/lê. max-width evita estourar a largura do
       painel com muitas colunas. */
    .editor-campo table {
      border-collapse: collapse; margin: .4rem 0; max-width: 100%;
    }
    .editor-campo table td {
      border: 1px solid var(--border); padding: .3rem .5rem; min-width: 2rem;
    }

    /* Paleta fixa de cor de fundo de célula (2026-09-02) — mesmo figurino do
       popover de tabela (posição/sombra), só o conteúdo muda: 5 botões
       redondos com a cor sólida já aplicada de fundo. */
    .notas-cor-celula-popover {
      position: absolute; z-index: 1210;
      background: var(--surface); border: 1px solid var(--border);
      border-radius: var(--radius); box-shadow: 0 4px 12px rgba(0,0,0,.12);
      padding: .5rem; display: flex; gap: .4rem;
    }
    .notas-cor-celula-popover[hidden] { display: none; }
    .notas-cor-celula-opcao {
      width: 26px; height: 26px; border-radius: 50%;
      border: 2px solid var(--surface); box-shadow: 0 0 0 1px var(--border);
      cursor: pointer; padding: 0;
    }
    .notas-cor-celula-opcao:hover { box-shadow: 0 0 0 2px var(--primary); }

    /* Popover de apagar linha/coluna/tabela (2026-09-02) — mesmo figurino
       dos outros popovers, opções em COLUNA com texto (ação destrutiva,
       vale ser explícito em vez de só ícone). */
    .notas-apagar-popover {
      position: absolute; z-index: 1210;
      background: var(--surface); border: 1px solid var(--border);
      border-radius: var(--radius); box-shadow: 0 4px 12px rgba(0,0,0,.12);
      padding: .4rem; display: flex; flex-direction: column; gap: .2rem;
    }
    .notas-apagar-popover[hidden] { display: none; }
    .notas-apagar-opcao {
      display: block; width: 100%; text-align: left; white-space: nowrap;
      padding: .4rem .6rem; border: none; border-radius: 6px;
      background: transparent; color: var(--text); font-size: .85rem;
      font-family: inherit; cursor: pointer;
    }
    .notas-apagar-opcao:hover { background: var(--bg); }
    .hint {
      font-size: .78rem;
      color: var(--muted);
      margin-top: .3rem;
    }
    .form-row { display: flex; gap: .75rem; }
    .form-row > .form-group { flex: 1; }

    /* ── Botões ── */
    .btn {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      gap: .45rem;
      padding: .6rem 1.2rem;
      border: none;
      border-radius: var(--radius);
      cursor: pointer;
      font-size: .9rem;
      font-weight: 600;
      font-family: inherit;
      transition: background .15s, opacity .15s, transform .08s;
    }
    .btn:active { transform: scale(.97); }
    .btn-primary { background: var(--primary); color: #fff; }
    .btn-primary:hover { background: var(--primary-h); }
    .btn-primary:disabled { opacity: .55; cursor: default; transform: none; }
    .btn-sm {
      font-size: .78rem;
      padding: .3rem .7rem;
      border-radius: 6px;
    }
    .btn-complete { background: var(--success); color: #fff; }
    .btn-complete:hover { opacity: .88; }
    /* Exclusão: discreta por padrão (ação destrutiva não deve competir com
       Concluir/Editar), assumindo a cor de perigo só no hover */
    .btn-delete {
      background: var(--bg);
      color: var(--muted);
      border: 1px solid var(--border);
      padding: .3rem .5rem;
    }
    .btn-delete:hover { background: var(--danger); color: #fff; border-color: var(--danger); }
    .btn-ghost {
      background: var(--bg);
      color: var(--muted);
      border: 1px solid var(--border);
    }
    .btn-ghost:hover { border-color: var(--primary); color: var(--primary); }
    #search-export[hidden] { display: none; }   /* par obrigatório de quem tem display */

    /* ── Seções ── */
    section { display: none; }
    section.active { display: block; }

    /* ── Filtros ── */
    .filter-bar {
      display: flex;
      align-items: center;
      gap: .5rem;
      margin-bottom: 1rem;
      flex-wrap: wrap;
    }
    .filter-btn {
      padding: .35rem .85rem;
      border: 1px solid var(--border);
      background: var(--surface);
      border-radius: 999px;
      cursor: pointer;
      font-size: .82rem;
      font-weight: 500;
      color: var(--muted);
      transition: all .15s;
      font-family: inherit;
    }
    .filter-btn.active {
      background: var(--primary);
      color: #fff;
      border-color: var(--primary);
    }
    .filter-btn:hover:not(.active) { border-color: var(--primary); color: var(--primary); }
    .filter-sep { width: 1px; height: 1.2rem; background: var(--border); margin: 0 .25rem; }
    /* Ocultar empresa (2026-09-15) — "ativo" aqui significa "empresa
       ESCONDIDA agora", o oposto visual do resto dos filtros (que destacam
       em azul o que ESTÁ mostrando) — por isso a cor muda pra riscado/opaco
       em vez do azul de .filter-btn.active padrão. */
    .filter-btn.empresa-excluir.active {
      background: var(--bg); color: var(--muted); border-color: var(--border);
      text-decoration: line-through; opacity: .65;
    }

    /* Dropdown de filtro (Categoria/Pessoa/Empresa): botão compacto que abre um
       painel com caixas de marcar — substitui a fileira de chips, que crescia
       demais conforme o cadastro aumenta */
    .sf-dd { position: relative; display: inline-block; }
    .sf-dd-btn { display: inline-flex; align-items: center; gap: .35rem; }
    .sf-dd-panel {
      position: absolute; z-index: 40; top: calc(100% + 4px); left: 0;
      min-width: 210px; max-height: 300px; overflow-y: auto;
      background: var(--surface); border: 1px solid var(--border);
      border-radius: 10px; padding: .35rem;
      box-shadow: 0 8px 24px rgba(0,0,0,.18);
    }
    .sf-dd-opt {
      display: flex; align-items: center; gap: .5rem;
      padding: .38rem .5rem; border-radius: 6px; cursor: pointer;
      font-size: .85rem; color: var(--text);
      /* o <label> global é CAIXA ALTA; aqui é texto normal de opção */
      text-transform: none; letter-spacing: normal; font-weight: 400; margin: 0;
    }
    .sf-dd-opt:hover { background: var(--bg); }
    .sf-dd-opt input { width: auto; margin: 0; cursor: pointer; }
    .sf-dd-todas { border-bottom: 1px solid var(--border); border-radius: 0; margin-bottom: .2rem; padding-bottom: .45rem; }
    .sf-dd-vazio { padding: .4rem .5rem; font-size: .8rem; color: var(--muted); font-style: italic; }
    /* 1ª linha do dropdown: busca dentro da lista. Fica grudada no topo para
       não sumir ao rolar as opções (o painel rola em 300px). */
    .sf-dd-busca {
      position: sticky; top: -.35rem; z-index: 1;
      width: 100%; box-sizing: border-box;
      margin-bottom: .25rem; padding: .38rem .5rem;
      border: 1px solid var(--border); border-radius: 6px;
      background: var(--bg); color: var(--text); font-size: .85rem;
    }
    .sf-dd-busca:focus { outline: none; border-color: var(--primary); }
    .sf-dd-opt[hidden] { display: none; }   /* [hidden] perde para o display:flex */
    .task-count { margin-left: auto; font-size: .82rem; color: var(--muted); }

    /* Editor de membros de grupo (empresa/pessoa, 2026-08-24): membro atual
       vira chip removível; adicionar é buscar entre os disponíveis (não mais
       uma parede de checkbox com o cadastro inteiro). */
    .grp-membros-chips { display: flex; flex-wrap: wrap; gap: .1rem .3rem; margin-bottom: .5rem; }
    .grp-membro-chip {
      display: inline-flex; align-items: center; gap: .3rem;
      background: var(--bg); border: 1px solid var(--border); border-radius: 999px;
      padding: .25rem .5rem .25rem .7rem; font-size: .82rem; color: var(--text);
    }
    .grp-membro-remover {
      background: none; border: none; cursor: pointer; color: var(--muted);
      font-size: .8rem; line-height: 1; padding: .1rem; border-radius: 50%;
    }
    .grp-membro-remover:hover { color: var(--danger); background: var(--surface); }
    .grp-membro-add { margin-bottom: .6rem; max-width: 340px; }
    .grp-membro-opt-novo { color: var(--primary); font-weight: 600; }

    /* ── Cartão de tarefa (denso) ── */
    .task-card {
      background: var(--surface);
      border: 1px solid var(--border);
      border-left: 3px solid var(--border);
      border-radius: var(--radius);
      padding: .65rem .85rem;
      margin-bottom: .45rem;
      display: flex;
      align-items: flex-start;
      gap: .7rem;
      box-shadow: var(--shadow);
      transition: box-shadow .15s, transform .12s;
      animation: fadeSlide .18s ease both;
    }
    @keyframes fadeSlide {
      from { opacity: 0; transform: translateY(4px); }
      to   { opacity: 1; transform: none; }
    }
    @media (prefers-reduced-motion: reduce) {
      .task-card { animation: none; }
    }
    .task-card:hover { box-shadow: 0 3px 12px rgba(15,23,42,.10); }
    .task-card.alta   { border-left-color: var(--danger); }
    .task-card.normal { border-left-color: var(--warning); }
    .task-card.baixa  { border-left-color: var(--success); }
    .task-card.done   { opacity: .55; }

    .task-body { flex: 1; min-width: 0; }
    /* pre-wrap: o título pode ter quebras de linha (2026-07-29). Sem isso o HTML as
       transformaria em espaço e o cartão mostraria um título diferente do gravado.
       Cuidado ao mexer no template do .task-title: com pre-wrap, qualquer indentação
       DENTRO da div viraria espaço visível — hoje o conteúdo é montado em uma linha só. */
    /* Peso normal desde 2026-07-29 (fase 4): o título era 600 e, com o editor, negrito
       nele não se distinguia do resto. A pedido do usuário o padrão virou texto normal,
       e o negrito é só o que ele marcar. */
    .task-title {
      font-weight: 400;
      font-size: .92rem;
      margin-bottom: .3rem;
      line-height: 1.35;
      white-space: pre-wrap;
    }
    /* Com o título em peso normal, o trecho marcado usa o negrito de sempre (700).
       Vale nos 2 renderizadores de cartão, que usam a mesma classe. */
    .task-title b { font-weight: 700; }
    /* Número da tarefa no fim do título — discreto, para citar o ID no bot (/anexar, /excluir) */
    .task-id {
      font-weight: 500;
      font-size: .78rem;
      color: var(--muted);
      margin-left: .35rem;
      white-space: nowrap;
    }
    .task-meta { display: flex; flex-wrap: wrap; gap: .3rem .45rem; align-items: center; }

    /* ── Chip de categoria (ponto colorido + nome) ── */
    .cat-chip {
      display: inline-flex;
      align-items: center;
      gap: .32rem;
      font-size: .72rem;
      font-weight: 600;
      color: var(--muted);
    }

    /* ── Skeleton loading ── */
    .skeleton {
      border-radius: var(--radius);
      background: linear-gradient(90deg, var(--border) 25%, var(--bg) 50%, var(--border) 75%);
      background-size: 200% 100%;
      animation: shimmer 1.2s linear infinite;
      height: 62px;
      margin-bottom: .45rem;
    }
    @keyframes shimmer { to { background-position: -200% 0; } }

    /* ── Gráfico de barras (concluídas por semana) ── */
    .chart-bars {
      display: flex;
      align-items: flex-end;
      gap: 2px;                       /* vão de 2px entre barras */
      height: 120px;
      border-bottom: 1px solid var(--border);   /* linha de base recessiva */
      margin-top: .75rem;
    }
    .chart-col {
      flex: 1;
      height: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: flex-end;
      position: relative;
    }
    .chart-bar {
      width: 60%;
      max-width: 26px;
      background: var(--chart-bar);
      border-radius: 4px 4px 0 0;     /* topo arredondado, base ancorada */
      min-height: 2px;
      transition: opacity .15s;
    }
    .chart-bar.zero { background: var(--border); }
    .chart-col:hover .chart-bar { opacity: .75; }
    .chart-val {
      font-size: .68rem;
      font-weight: 600;
      color: var(--muted);            /* rótulo em token de texto, não na cor da série */
      margin-bottom: 2px;
    }
    .chart-labels { display: flex; gap: 2px; margin-top: .3rem; }
    .chart-labels span {
      flex: 1;
      text-align: center;
      font-size: .62rem;
      color: var(--muted);
    }
    .chart-tip {
      display: none;
      position: absolute;
      bottom: calc(100% + 6px);
      left: 50%;
      transform: translateX(-50%);
      background: var(--text);
      color: var(--bg);
      font-size: .72rem;
      font-weight: 500;
      padding: .3rem .55rem;
      border-radius: 6px;
      white-space: nowrap;
      z-index: 5;
      pointer-events: none;
    }
    .chart-col:hover .chart-tip { display: block; }

    /* ── Modo escuro: cores fixas que não usam variáveis ── */
    html[data-theme="dark"] .badge { background: #334155; color: #cbd5e1; }
    html[data-theme="dark"] .badge-trabalho { background: rgba(59,130,246,.20); color: #93c5fd; }
    html[data-theme="dark"] .badge-pessoal  { background: rgba(139,92,246,.22); color: #c4b5fd; }
    html[data-theme="dark"] .badge-geral    { background: #334155; color: #cbd5e1; }
    html[data-theme="dark"] .badge-alta     { background: rgba(239,68,68,.22);  color: #fca5a5; }
    html[data-theme="dark"] .badge-baixa    { background: rgba(34,197,94,.20);  color: #86efac; }
    html[data-theme="dark"] .badge-prazo-ok       { background: rgba(34,197,94,.20); color: #86efac; }
    html[data-theme="dark"] .badge-prazo-atrasado { background: rgba(239,68,68,.22); color: #fca5a5; }
    html[data-theme="dark"] .badge-prazo-sem      { background: #334155; color: #cbd5e1; }
    /* Texto preto também no tema escuro (pedido dele, 2026-08-27, revisão
       rápida — a versão anterior mantinha a cor clara aqui de propósito,
       pra contraste; ele preferiu preto igual ao claro mesmo assim).
       Fundo bem mais opaco que antes (.20/.22 → .80, subiu de .55 depois
       de ele pedir mais contraste) — com pouca opacidade, preto ficava
       ilegível sobre o fundo escuro. */
    html[data-theme="dark"] .note-task-ref-concluida   { background: rgba(34,197,94,.80);  color: #000; }
    html[data-theme="dark"] .note-task-ref-executada   { background: rgba(234,179,8,.80);  color: #000; }
    html[data-theme="dark"] .note-task-ref-atrasada    { background: rgba(239,68,68,.80);  color: #000; }
    html[data-theme="dark"] .note-task-ref-andamento   { background: rgba(59,130,246,.80); color: #000; }
    html[data-theme="dark"] .note-task-ref-naoiniciada { background: rgba(249,115,22,.80); color: #000; }
    html[data-theme="dark"] .note-task-ref-indefinida  { background: #94a3b8; color: #000; }
    html[data-theme="dark"] .linha-com-tarefa          { color: #000; }
    html[data-theme="dark"] .cal-chip           { background: rgba(59,130,246,.22); color: #93c5fd; }
    html[data-theme="dark"] .cal-chip.atrasada  { background: rgba(239,68,68,.22);  color: #fca5a5; }
    html[data-theme="dark"] .cal-chip.concluida { background: rgba(34,197,94,.18);  color: #86efac; }
    html[data-theme="dark"] .login-error { background: rgba(239,68,68,.18); }
    html[data-theme="dark"] .login-aviso { background: rgba(251,191,36,.12); }
    html[data-theme="dark"] #toast { background: #f1f5f9; color: #0f172a; }
    html[data-theme="dark"] #toast.error { background: var(--danger); color: #0f172a; }
    html[data-theme="dark"] #toast.ok    { background: var(--success); color: #0f172a; }
    mark.hl { background: var(--mark); border-radius: 2px; padding: 0 1px; color: inherit; }

    /* ── Badges ── */
    .badge {
      display: inline-block;
      padding: .15rem .5rem;
      border-radius: 999px;
      font-size: .73rem;
      font-weight: 600;
      background: #f1f5f9;   /* padrão para categorias customizadas */
      color: #475569;
    }
    .badge-trabalho { background: #dbeafe; color: #1d4ed8; }
    .badge-pessoal  { background: #ede9fe; color: #7c3aed; }
    .badge-geral    { background: #f1f5f9; color: #475569; }
    .badge-alta     { background: #fee2e2; color: #dc2626; }
    .badge-baixa    { background: #dcfce7; color: #15803d; }

    .task-date, .task-reminder {
      font-size: .78rem;
      color: var(--muted);
      display: flex;
      align-items: center;
      gap: .2rem;
    }
    .task-done-mark {
      font-size: .78rem;
      color: var(--success);
      font-weight: 600;
    }

    /* ── Referência de tarefa dentro de uma nota — cor por prioridade entre
       ANDAMENTO e PRAZO (revisado 2026-08-27, esquema final pedido dele):
         1. concluída            → verde  (sempre, não importa o prazo)
         2. atrasada (e não é concluída) → vermelho (vence executada/andamento/não-iniciada)
         3. executada (e não está atrasada) → amarelo
         4. em andamento + no prazo → azul (só quando NÃO está atrasada)
         5. não iniciada (e não está atrasada) → laranja
         6. sobra (ex.: em andamento sem prazo nenhum, dado legado) → cinza indefinida
       Ver notasEstilizarRefs (prioridade calculada em JS) — a cor nunca é
       gravada, sempre recalculada na exibição. ── */
    .note-task-ref {
      cursor: pointer;
      border-radius: 3px;
      padding: 0 .15rem;
      text-decoration: underline dotted;
      text-underline-offset: 2px;
    }
    /* Texto preto (pedido dele, 2026-08-27) — só o FUNDO indica o status,
       tanto no trecho vinculado quanto no resto da linha (.linha-com-tarefa,
       o <b> que negritarLinhaDoSpan cria). Só no tema CLARO: no escuro o
       preto ficaria ilegível em cima do fundo escuro, então lá mantém a cor
       clara de cada status (bloco html[data-theme="dark"] mais acima).
       ⚠️ Regra por CLASSE, não agrupada num só seletor (`.a, .b, .c {...}`)
       de propósito — o jsdom calcula errado a especificidade de um seletor
       agrupado contra `html[data-theme="dark"] .x` (trata como empate e usa
       ordem de origem em vez de especificidade de verdade); sem agrupar,
       fica igual ao padrão que o resto do arquivo já usa em todo badge,
       testável e correto nos dois. Ver docs/armadilhas.md. */
    .note-task-ref-concluida   { background: #dcfce7; color: #000; }
    .note-task-ref-executada   { background: #fef9c3; color: #000; }
    .note-task-ref-atrasada    { background: #fee2e2; color: #000; }
    .note-task-ref-andamento   { background: #dbeafe; color: #000; }
    .note-task-ref-naoiniciada { background: #ffedd5; color: #000; }
    .note-task-ref-indefinida  { background: #f1f5f9; color: #000; }
    .linha-com-tarefa          { color: #000; }

    /* ── Badges de prazo ── */
    .badge-prazo-ok       { background: #dcfce7; color: #15803d; }
    .badge-prazo-atrasado { background: #fee2e2; color: #dc2626; }
    .badge-prazo-sem      { background: #f1f5f9; color: #475569; }

    /* ── Linha de atualização ── */
    .task-update-row {
      display: flex;
      align-items: center;
      gap: .5rem;
      margin-top: .45rem;
      flex-wrap: wrap;
    }
    .task-update-text {
      font-size: .8rem;
      color: var(--muted);
      font-style: italic;
      flex: 1;
      min-width: 0;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .task-update-block { flex: 1; min-width: 0; }
    /* A prévia 💬 do cartão mostra a última atualização INTEIRA, quebrando na
       largura do cartão (2026-08-04, a pedido). Anula o trio de uma linha só
       (nowrap + overflow hidden + ellipsis) que continua valendo para o
       `.task-update-text` solto, usado no cartão sem atualização.
       ⚠️ `white-space` fica em `normal`, NÃO `pre-wrap`: o texto já chega com
       `<br>` no lugar das quebras (textoParaHtml), então `pre-wrap` duplicaria
       a quebra em qualquer registro que também tivesse `\n`.
       `overflow-wrap: anywhere` impede que uma URL ou palavra sem espaços
       estoure a largura do cartão. */
    .task-update-block .task-update-text {
      display: block;
      flex: none;
      white-space: normal;
      overflow: visible;
      text-overflow: clip;
      overflow-wrap: anywhere;
    }
    .task-update-date {
      font-size: .65rem;
      color: var(--muted);
      opacity: .75;
      margin-bottom: .1rem;
    }
    .btn-add-update, .btn-show-history, .btn-show-attach, .btn-copy-task, .btn-send-recado {
      background: none;
      border: 1px solid var(--border);
      border-radius: 6px;
      cursor: pointer;
      font-size: .72rem;
      color: var(--muted);
      padding: .15rem .45rem;
      white-space: nowrap;
      font-family: inherit;
      transition: border-color .15s, color .15s;
    }
    .btn-add-update:hover, .btn-show-history:hover, .btn-show-attach:hover,
    .btn-copy-task:hover, .btn-send-recado:hover {
      border-color: var(--primary);
      color: var(--primary);
    }
    /* Confirmação de cópia: o próprio botão avisa, sem depender só do toast */
    .btn-copy-task.copiado {
      border-color: var(--success);
      color: var(--success);
    }

    /* ── Bloco de anexos ── */
    .attach-block {
      display: none;
      margin-top: .5rem;
      padding: .6rem;
      background: var(--bg);
      border-radius: var(--radius);
      border: 1px solid var(--border);
    }
    .attach-block.open { display: block; }
    .attach-item {
      display: flex;
      align-items: center;
      gap: .5rem;
      padding: .35rem 0;
      border-bottom: 1px solid var(--border);
      font-size: .8rem;
    }
    .attach-item:last-of-type { border-bottom: none; }
    .attach-thumb {
      width: 44px; height: 44px;
      object-fit: cover;
      border-radius: 6px;
      border: 1px solid var(--border);
      flex-shrink: 0;
      display: block;
    }
    /* Miniatura um pouco maior só dentro do 💬 histórico (2026-08-27, pedido
       dele) — o painel 📎 de anexos comum continua com o tamanho de sempre. */
    .hist-anexo-corpo .attach-thumb { width: 72px; height: 72px; }
    .attach-icon {
      width: 44px; height: 44px;
      display: flex; align-items: center; justify-content: center;
      font-size: 1.4rem;
      background: var(--surface);
      border: 1px solid var(--border);
      border-radius: 6px;
      flex-shrink: 0;
      text-decoration: none;
    }
    .attach-name { flex: 1; min-width: 0; }
    .attach-name a {
      color: var(--text);
      text-decoration: none;
      display: block;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .attach-name a:hover { color: var(--primary); }
    .attach-meta-line { font-size: .68rem; color: var(--muted); }
    .btn-att-del {
      background: none; border: none;
      cursor: pointer; font-size: .95rem;
      opacity: .6; flex-shrink: 0;
    }
    .btn-att-del:hover { opacity: 1; }

    /* Histórico: ações por atualização (editar/excluir) */
    .hist-item { padding: .5rem 0; border-bottom: 1px solid var(--border); }
    .hist-top  { display: flex; align-items: flex-start; gap: .5rem; }
    .hist-top .hist-meta { flex: 1; min-width: 0; font-size: .75rem; color: var(--muted); margin-bottom: .2rem; }
    .hist-acoes { display: flex; gap: .1rem; flex-shrink: 0; }
    .btn-hist {
      background: none; border: none; cursor: pointer;
      font-size: .85rem; opacity: .55; padding: .1rem .25rem; border-radius: 6px;
    }
    .btn-hist:hover { opacity: 1; background: var(--bg); }
    /* pre-wrap: o comentário pode ter quebras de linha (digitadas aqui com Enter ou
       vindas do bot). Sem isso o HTML as transformaria em espaço e a tela mostraria
       um parágrafo corrido, diferente do que está gravado. */
    .hist-text { font-size: .9rem; white-space: pre-wrap; }
    /* Anexo dentro da timeline do histórico (2026-08-10) — mesma miniatura/ícone
       do painel 📎, só lado a lado com o nome em vez de empilhado */
    .hist-anexo-corpo { display: flex; align-items: center; gap: .5rem; white-space: normal; }
    .hist-anexo-corpo a:not(.attach-icon) { color: var(--primary); text-decoration: none; }
    .hist-anexo-corpo a:not(.attach-icon):hover { text-decoration: underline; }
    /* #N dentro do texto do histórico (ex.: "Criada automaticamente ao concluir
       #254") — abre o histórico DAQUELA tarefa (2026-08-10) */
    .task-ref {
      color: var(--primary); cursor: pointer; text-decoration: underline dotted;
      text-underline-offset: 2px;
    }
    .task-ref:hover { text-decoration-style: solid; }
    /* Cabeçalho de contexto do modal: de QUAL tarefa é este histórico —
       necessário desde que o modal passou a abrir para tarefas referenciadas,
       não só a que o usuário tinha na tela */
    #history-task-summary {
      font-size: .85rem; color: var(--muted); margin-bottom: .75rem;
      padding-bottom: .5rem; border-bottom: 1px solid var(--border);
    }
    #history-task-summary strong { color: var(--text); font-weight: 600; }
    /* A caixa de editar uma atualização já gravada virou editor (fase 3): fonte menor
       que a dos outros campos, para caber no item do histórico */
    .hist-edit .editor-campo {
      box-sizing: border-box;
      font-size: .9rem; padding: .4rem .5rem; border-radius: 8px;
    }
    .hist-edit-acoes { display: flex; gap: .4rem; margin-top: .35rem; }
    .attach-upload {
      display: flex;
      gap: .5rem;
      margin-top: .55rem;
      align-items: center;
      flex-wrap: wrap;
    }
    .attach-upload .att-file { font-size: .78rem; color: var(--muted); min-width: 0; flex: 1; }

    /* ── Lista de anexos escolhidos no formulário de nova tarefa ── */
    .f-anexos-list { display: flex; flex-direction: column; gap: .35rem; margin-top: .5rem; }
    .f-anexo-item {
      display: flex; align-items: center; gap: .5rem;
      padding: .4rem .6rem;
      background: var(--bg);
      border: 1px solid var(--border);
      border-radius: 6px;
      font-size: .78rem;
    }
    .f-anexo-item .f-anexo-nome { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .f-anexo-item .f-anexo-tam { color: var(--muted); flex-shrink: 0; }
    .f-anexo-item .btn-f-anexo-rm {
      background: none; border: none; cursor: pointer;
      font-size: .9rem; opacity: .6; flex-shrink: 0; color: var(--danger);
    }
    .f-anexo-item .btn-f-anexo-rm:hover { opacity: 1; }

    /* ── Form inline de atualização ── */
    .update-inline-form {
      display: none;
      margin-top: .5rem;
      padding: .7rem;
      background: var(--bg);
      border-radius: var(--radius);
      border: 1px solid var(--border);
    }
    .update-inline-form.open { display: block; }

    /* Sugestão de prazo (2026-08-06). O formulário espelha o de atualização —
       ⚠️ com o par [hidden]/.open, senão o `display:block` do CSS venceria
       (regra de ouro nº 5). */
    .sug-inline-form {
      display: none;
      margin-top: .5rem;
      padding: .7rem;
      background: var(--bg);
      border-radius: var(--radius);
      border: 1px dashed var(--border);
    }
    .sug-inline-form.open { display: block; }
    .sug-alvo {
      font-size: .8rem; color: var(--muted); margin-bottom: .5rem; line-height: 1.35;
    }
    .sug-faixa {
      display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
      justify-content: space-between;
      margin-top: .5rem; padding: .5rem .7rem;
      font-size: .85rem;
      background: color-mix(in srgb, var(--primary) 10%, transparent);
      border-left: 3px solid var(--primary);
      border-radius: var(--radius);
    }
    .sug-faixa[hidden] { display: none; }
    .sug-faixa.sug-aguardando {
      background: var(--bg); border-left-color: var(--muted); color: var(--muted);
    }
    /* Aba 🕒 Atualizações (2026-08-06) */
    .atv-cab { display: flex; flex-wrap: wrap; align-items: center;
               justify-content: space-between; gap: .5rem; }
    .atv-filtros { display: flex; gap: .4rem; }
    .atv-dia {
      font-size: .78rem; text-transform: uppercase; letter-spacing: .04em;
      color: var(--muted); margin: .9rem 0 .35rem;
    }
    .atv-item {
      display: flex; align-items: baseline; gap: .5rem;
      padding: .45rem .6rem; margin-bottom: .25rem;
      background: var(--card); border: 1px solid var(--border);
      border-radius: var(--radius); cursor: pointer; font-size: .87rem;
    }
    .atv-item:hover { border-color: var(--primary); }
    .atv-hora { color: var(--muted); font-size: .78rem; min-width: 2.7rem; }
    .atv-txt { flex: 1; min-width: 0; }
    .atv-tarefa { color: var(--muted); }
    .atv-detalhe {
      display: block; color: var(--muted); font-size: .8rem;
      white-space: pre-wrap; overflow-wrap: anywhere;
    }
    .sug-acoes { display: flex; gap: .4rem; }
    .sug-acoes[hidden] { display: none; }
    /* A terceira opção troca de lugar com os botões, na MESMA linha — a faixa
       não muda de altura. ⚠️ O par [hidden] é obrigatório: sem ele o
       `display:flex` venceria o atributo (regra de ouro nº 5). */
    .sug-outra-campos { display: flex; gap: .3rem; align-items: center; }
    .sug-outra-campos[hidden] { display: none; }
    .sug-outra-campos input {
      padding: .25rem .4rem; font-size: .8rem;
      border: 1px solid var(--border); border-radius: 4px;
      background: var(--card); color: var(--text);
    }
    .sug-nova-date { max-width: 8.6rem; }
    .sug-nova-time { max-width: 5.6rem; }
    /* O campo do texto já foi input, depois textarea e agora é editor — o seletor
       precisa cobrir os três, senão a margem some do formulário inline */
    .update-inline-form input[type="text"],
    .update-inline-form textarea,
    .update-inline-form .editor-campo { margin-bottom: .45rem; }
    .update-inline-form .form-row { margin-bottom: .45rem; }
    .update-inline-actions { display: flex; gap: .4rem; }

    /* ── Form inline do 📝 Recado ──
       Mesma caixa do formulário de atualização, com a borda em destaque para
       deixar claro que o que se escreve aqui SAI (vai para o Telegram da pessoa)
       em vez de ficar gravado como as atualizações. */
    .recado-inline-form {
      display: none;
      margin-top: .5rem;
      padding: .7rem;
      background: var(--bg);
      border-radius: var(--radius);
      border: 1px solid var(--primary);
    }
    .recado-inline-form.open { display: block; }
    .recado-inline-form .editor-campo { margin-bottom: .45rem; }
    .recado-alvo {
      font-size: .75rem;
      color: var(--muted);
      margin-bottom: .4rem;
    }

    /* ── Select de andamento ── */
    .andamento-select {
      font-size: .78rem;
      padding: .2rem .45rem;
      border-radius: 6px;
      border: 1px solid var(--border);
      background: var(--surface);
      color: var(--text);
      cursor: pointer;
      font-family: inherit;
      transition: border-color .15s;
    }
    .andamento-select:focus {
      outline: none;
      border-color: var(--primary);
    }
    .andamento-select:disabled { opacity: .55; cursor: default; }

    /* ── Estado vazio / carregando ── */
    .empty { text-align: center; padding: 3rem 1rem; color: var(--muted); }
    .empty .em { font-size: 2.5rem; margin-bottom: .6rem; }
    .empty p { font-size: .9rem; }
    .loading { text-align: center; padding: 2.5rem; color: var(--muted); font-size: .9rem; }
    .spinner {
      display: inline-block;
      width: 20px; height: 20px;
      border: 2px solid var(--border);
      border-top-color: var(--primary);
      border-radius: 50%;
      animation: spin .7s linear infinite;
      vertical-align: middle;
      margin-right: .5rem;
    }
    @keyframes spin { to { transform: rotate(360deg); } }

    /* ── Toast ── */
    #toast {
      position: fixed;
      bottom: 1.25rem;
      right: 1.25rem;
      background: var(--text);
      color: #fff;
      padding: .7rem 1.1rem;
      border-radius: var(--radius);
      font-size: .875rem;
      line-height: 1.4;
      box-shadow: 0 4px 16px rgba(0,0,0,.22);
      transform: translateY(80px);
      opacity: 0;
      transition: transform .22s ease, opacity .22s ease;
      z-index: 999;
      max-width: 300px;
      pointer-events: none;
    }
    #toast.show  { transform: translateY(0); opacity: 1; }
    #toast.error { background: var(--danger); }
    #toast.ok    { background: var(--success); }

    /* ── Botão editar (e cancelar do form inline, mesmo visual) ── */
    .btn-edit, .btn-upd-cancel {
      background: var(--surface);
      color: var(--muted);
      border: 1px solid var(--border);
    }
    .btn-edit:hover, .btn-upd-cancel:hover { border-color: var(--primary); color: var(--primary); }

    /* ── Ações da tarefa ── */
    .task-actions { display: flex; flex-direction: column; gap: .4rem; align-items: flex-end; }

    /* Adiar +1/+2 dias: par de botões discretos na mesma linha, sem competir
       com Concluir/Editar (mesma lógica visual do botão de excluir) */
    .postpone-row { display: flex; gap: .3rem; }
    .btn-postpone {
      background: var(--bg);
      color: var(--muted);
      border: 1px solid var(--border);
      padding: .3rem .5rem;
      white-space: nowrap;
    }
    .btn-postpone:hover { border-color: var(--primary); color: var(--primary); }
    .btn-postpone:disabled { opacity: .5; cursor: default; }

    /* ── Modal ── */
    .modal-overlay {
      display: none;
      position: fixed;
      inset: 0;
      background: rgba(0,0,0,.45);
      z-index: 100;
      align-items: center;
      justify-content: center;
      padding: 1rem;
    }
    .modal-overlay.open { display: flex; }
    .modal {
      background: var(--surface);
      border-radius: var(--radius);
      box-shadow: 0 8px 32px rgba(0,0,0,.22);
      width: 100%;
      max-width: 480px;
      max-height: 90vh;
      overflow-y: auto;
      padding: 1.5rem;
    }
    /* O modal de EDIÇÃO é largo: com 480px os 7 blocos de campos passavam
       de 90vh e a tela rolava. */
    .modal-edicao { max-width: 720px; }
    /* 💬 Histórico alargado (2026-08-27, pedido dele) — praticamente o dobro
       do padrão de 480px. Reverte a decisão original ("lista de leitura não
       precisa de coluna larga") — na prática ele queria mais espaço mesmo. */
    .modal-historico { max-width: 960px; }
    /* Data + hora do mesmo campo lado a lado, dentro de um único form-group,
       para prazo e lembrete caberem na MESMA linha. */
    .campo-duplo { display: flex; gap: .5rem; }
    .campo-duplo[hidden] { display: none; }   /* par obrigatório de quem tem display */
    .campo-duplo > input { flex: 1; min-width: 0; }
    .modal-header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-bottom: 1.1rem;
    }
    .modal-header h2 { font-size: 1rem; font-weight: 700; }
    .btn-close {
      background: none;
      border: none;
      cursor: pointer;
      font-size: 1.3rem;
      color: var(--muted);
      line-height: 1;
      padding: .2rem .4rem;
      border-radius: 4px;
    }
    .btn-close:hover { background: var(--bg); color: var(--text); }

    /* ── Seção "delegadas para mim" (bloco 4, multiusuário) ── */
    .deleg-sec { margin-bottom: 1.25rem; }
    .deleg-sec[hidden] { display: none; }
    .deleg-cab {
      display: flex; align-items: center; gap: .5rem;
      font-size: .82rem; font-weight: 700; color: var(--muted);
      text-transform: uppercase; letter-spacing: .04em;
      margin-bottom: .6rem;
    }
    .deleg-toggle { display: flex; gap: .5rem; margin-bottom: .6rem; }
    .deleg-item {
      display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap;
      padding: .6rem .8rem; margin-bottom: .4rem;
      background: var(--surface); border-radius: var(--radius);
      border-left: 3px solid var(--warning);
    }
    .deleg-de { font-size: .74rem; color: var(--muted); }
    .deleg-tit { font-weight: 600; }
    .deleg-prazo { font-size: .78rem; color: var(--muted); margin-left: auto; }
    /* Usuários (Ajustes) — o item é <label>? não: <div>, para não herdar a
       CAIXA ALTA global de label (armadilha conhecida do projeto). */
    .usr-item {
      display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
      padding: .55rem 0; border-bottom: 1px solid var(--border);
    }
    .usr-nome { font-weight: 600; }
    .usr-id { font-size: .76rem; color: var(--muted); font-family: monospace; }
    .usr-tag {
      font-size: .68rem; padding: .12rem .45rem; border-radius: 999px;
      background: rgba(217,119,6,.15); color: var(--warning); font-weight: 600;
    }
    .usr-off { opacity: .55; }
    .usr-arroba {
      width: 9rem; font-size: .8rem; padding: .2rem .45rem;
      border: 1px solid var(--border); border-radius: var(--radius);
      background: var(--bg); color: var(--text);
    }
    .usr-acoes { margin-left: auto; }

    /* ── Modal de login ── */
    #login-overlay { z-index: 200; background: rgba(15,23,42,.7); }
    .login-card {
      background: var(--surface);
      border-radius: var(--radius);
      box-shadow: 0 8px 40px rgba(0,0,0,.3);
      width: 100%;
      max-width: 380px;
      padding: 2rem 1.75rem;
    }
    .login-logo {
      text-align: center;
      font-size: 2.2rem;
      margin-bottom: .5rem;
    }
    .login-title {
      text-align: center;
      font-size: 1.1rem;
      font-weight: 700;
      margin-bottom: .25rem;
    }
    .login-sub {
      text-align: center;
      font-size: .83rem;
      color: var(--muted);
      margin-bottom: 1.5rem;
    }
    .login-error {
      display: none;
      margin-top: .75rem;
      padding: .6rem .8rem;
      background: #fee2e2;
      border-radius: var(--radius);
      color: var(--danger);
      font-size: .83rem;
    }
    /* Aviso de uso responsável — visível nos dois passos do login */
    .login-aviso {
      margin-top: 1.25rem;
      padding: .65rem .8rem;
      background: rgba(217,119,6,.10);
      border-left: 3px solid var(--warning);
      border-radius: var(--radius);
      color: var(--muted);
      font-size: .78rem;
      line-height: 1.45;
    }
    .login-aviso b { color: var(--warning); font-weight: 600; }
    .otp-input {
      font-size: 1.8rem !important;
      letter-spacing: .4em;
      text-align: center;
      font-weight: 700;
    }

    /* ── Filtros da pesquisa ── */
    .search-filters { display: flex; flex-direction: column; gap: .45rem; margin-bottom: 1rem; }
    .filter-group   { display: flex; align-items: center; gap: .3rem; flex-wrap: wrap; }
    /* Categoria + Pessoa + Empresa numa linha só, ocupando a largura que
       sobrava à direita. `flex-wrap` devolve um por linha no celular. */
    .filter-row     { display: flex; align-items: center; flex-wrap: wrap; gap: .45rem 1.8rem; }
    .filter-label   {
      font-size: .72rem; font-weight: 700; color: var(--muted);
      text-transform: uppercase; letter-spacing: .05em;
      min-width: 76px; flex-shrink: 0;
    }

    /* ── Calendário ── */
    .cal-nav {
      display: flex; align-items: center; gap: .6rem; margin-bottom: .8rem;
    }
    .cal-nav .btn-ghost { padding: .3rem .7rem; font-size: .95rem; }
    #cal-title { font-weight: 700; font-size: .95rem; min-width: 150px; text-align: center; }
    .cal-grid {
      display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px;
    }
    .cal-dow {
      font-size: .68rem; font-weight: 700; color: var(--muted);
      text-align: center; padding: .3rem 0; text-transform: uppercase;
    }
    .cal-day {
      min-height: 74px; border: 1px solid var(--border); border-radius: 6px;
      padding: .25rem; background: var(--surface); cursor: pointer;
      font-size: .75rem; overflow: hidden; text-align: left;
      transition: border-color .15s;
    }
    .cal-day:hover { border-color: var(--primary); }
    .cal-day.outro { opacity: .35; background: var(--bg); }
    .cal-day.hoje  { border: 2px solid var(--primary); }
    .cal-day.selecionado { box-shadow: 0 0 0 2px var(--primary); }
    .cal-num { font-weight: 600; font-size: .74rem; margin-bottom: 2px; }
    .cal-chip {
      display: block; font-size: .64rem; line-height: 1.3; padding: 1px 4px;
      border-radius: 3px; margin-bottom: 2px; white-space: nowrap;
      overflow: hidden; text-overflow: ellipsis;
      background: #dbeafe; color: #1d4ed8;
    }
    .cal-chip.atrasada  { background: #fee2e2; color: #dc2626; }
    .cal-chip.concluida { background: #dcfce7; color: #15803d; text-decoration: line-through; }
    .cal-mais { font-size: .64rem; color: var(--muted); }
    .cal-dots { display: none; font-size: .7rem; color: var(--primary); font-weight: 700; }
    @media (max-width: 500px) { .cal-dots { display: block; } }
    .cal-chip[draggable="true"] { cursor: grab; }
    .cal-chip[draggable="true"]:active { cursor: grabbing; }
    .cal-day.dragover { outline: 2px dashed var(--primary); outline-offset: -3px; }

    /* ── Linha do tempo ── */
    .tl-group-title {
      font-size: .8rem; font-weight: 700; margin: 1.1rem 0 .5rem;
      color: var(--muted); text-transform: uppercase; letter-spacing: .04em;
    }
    .tl-group-title:first-child { margin-top: 0; }
    .tl-group-title.atrasadas { color: var(--danger); }

    /* ── Estatísticas ── */
    .stats-line {
      display: flex; justify-content: space-between; align-items: center;
      padding: .4rem 0; border-bottom: 1px solid var(--border); font-size: .9rem;
    }
    .stats-line:last-child { border-bottom: none; }
    .stats-line b { font-size: 1rem; }
    .stats-title { font-size: .8rem; font-weight: 700; color: var(--muted);
      text-transform: uppercase; letter-spacing: .04em; margin-bottom: .5rem; }

    /* ── Ajustes ── */
    .settings-item {
      display: flex; align-items: center; gap: .5rem;
      padding: .45rem 0; border-bottom: 1px solid var(--border); font-size: .9rem;
    }
    .settings-item .nome { flex: 1; }
    .btn-remove {
      background: none; border: 1px solid var(--border); border-radius: 6px;
      cursor: pointer; font-size: .72rem; color: var(--muted);
      padding: .15rem .5rem; font-family: inherit;
    }
    .btn-remove:hover { border-color: var(--danger); color: var(--danger); }
    /* Painel de configuração da pessoa (recuado, para ficar claro que
       pertence à linha acima e não é mais um item da lista) */
    .person-perms {
      margin: 0 0 .5rem 1.7rem;
      padding: .6rem .8rem;
      background: var(--bg);
      border: 1px solid var(--border);
      border-radius: 8px;
    }
    .perms-grupo {
      font-size: .72rem; text-transform: uppercase; letter-spacing: .04em;
      color: var(--muted); margin: .5rem 0 .3rem;
    }
    .perms-grupo:first-child { margin-top: 0; }
    /* O <label> global é CAIXA ALTA (usado nos formulários); dentro do painel
       da pessoa isso pesa e atrapalha a leitura das explicações */
    .perms-item, .perms-campo > label {
      text-transform: none; letter-spacing: normal; margin-bottom: 0;
    }
    .perms-item {
      display: flex; align-items: flex-start; gap: .5rem;
      padding: .3rem 0; font-size: .85rem; cursor: pointer; font-weight: 400;
    }
    .perms-item input { margin-top: .2rem; flex-shrink: 0; cursor: pointer; }
    .perms-item small { display: block; color: var(--muted); font-size: .75rem; }

    /* Identificação (nome e @) dentro do painel: rótulo, campo e Salvar na
       mesma linha, quebrando para baixo em telas estreitas */
    .perms-campo {
      display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
      padding: .25rem 0; font-size: .85rem;
    }
    .perms-campo > label { flex: 0 0 6.2rem; color: var(--muted); font-size: .8rem; }
    .perms-campo input[type="text"] {
      flex: 1; min-width: 9rem; font-family: inherit; font-size: .85rem;
      padding: .3rem .5rem; border: 1px solid var(--border); border-radius: 6px;
      background: var(--surface); color: var(--text);
    }
    .perms-campo .btn-salvar {
      background: none; border: 1px solid var(--border); border-radius: 6px;
      cursor: pointer; font-size: .72rem; color: var(--muted);
      padding: .15rem .5rem; font-family: inherit;
    }
    .perms-campo .btn-salvar:hover { border-color: var(--primary); color: var(--primary); }
    .perms-campo .btn-salvar:disabled { opacity: .5; cursor: default; }

    /* Horário de trabalho por pessoa: um bloco por dia da semana, cada um
       com sua lista de turnos (2026-08-07) */
    .exp-semana { margin: .2rem 0 .4rem; }
    .exp-dia { padding: .35rem 0; border-top: 1px solid var(--border); }
    .exp-dia:first-child { border-top: none; }
    .exp-dia-cab { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
    .exp-dia-nome { font-size: .82rem; font-weight: 600; }
    .exp-turno-add {
      background: none; border: 1px solid var(--border); border-radius: 6px;
      cursor: pointer; font-size: .72rem; color: var(--muted);
      padding: .15rem .5rem; font-family: inherit;
    }
    .exp-turno-add:hover { border-color: var(--primary); color: var(--primary); }
    .exp-turnos { margin-top: .3rem; }
    .exp-turno { display: flex; align-items: center; gap: .4rem; padding: .15rem 0; }
    .exp-turno select {
      font-family: inherit; font-size: .82rem; padding: .25rem .4rem;
      border: 1px solid var(--border); border-radius: 6px;
      background: var(--surface); color: var(--text);
    }
    .exp-turno .btn-remove { margin-left: auto; }
    .exp-folga { color: var(--muted); font-style: italic; }

    .perms-status {
      display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
      padding: .35rem 0; font-size: .8rem; color: var(--muted);
    }
    /* Rodapé destrutivo: separado do resto para não ser clicado sem querer */
    .perms-perigo { margin-top: .7rem; padding-top: .6rem; border-top: 1px solid var(--border); }
    .perms-perigo .hint { margin: 0 0 .4rem; }

    /* ── Ajustes: menu de telas ── */
    /* 3 por linha no desktop: cadastros (pessoas/empresas/categorias) em cima,
       notificações (silêncio/briefing) embaixo */
    .aj-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
      gap: .8rem;
    }
    /* Sem isto o `display: grid` acima vence o atributo hidden e o menu
       continua na tela por baixo da configuração aberta */
    .aj-grid[hidden] { display: none; }
    .aj-card {
      display: flex; flex-direction: column; align-items: center; justify-content: center;
      gap: .5rem; padding: 1.4rem 1rem; cursor: pointer; font-family: inherit;
      background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
      color: var(--text); text-align: center; transition: border-color .15s, transform .15s;
    }
    .aj-card:hover { border-color: var(--primary); transform: translateY(-2px); }
    .aj-card:active { transform: none; }
    .aj-ico { font-size: 1.8rem; line-height: 1; }
    .aj-nome { font-size: .92rem; font-weight: 600; }
    .aj-topo {
      display: flex; align-items: center; gap: .7rem; margin-bottom: .9rem;
    }
    .aj-titulo { font-size: 1rem; font-weight: 700; }

    .settings-add { display: flex; gap: .5rem; margin-top: .8rem; }
    .settings-add input { flex: 1; }
    .settings-add .emoji-input { flex: 0 0 64px; text-align: center; }

    /* Cadastro rápido no formulário de nova tarefa (categoria/pessoa/empresa) */
    .cad-rapido { display: flex; flex-direction: column; gap: .5rem;
      margin-top: .5rem; padding: .65rem;
      border: 1px dashed var(--border); border-radius: var(--radius-sm);
      background: var(--bg); }
    .cad-rapido[hidden] { display: none; }  /* [hidden] perde para display:flex */
    .cad-rapido-campos { display: flex; gap: .5rem; }
    .cad-rapido-campos input { flex: 1; min-width: 0; }
    .cad-rapido-campos .emoji-input { flex: 0 0 64px; text-align: center; }
    .cad-rapido-acoes { display: flex; gap: .5rem; justify-content: flex-end; }
    .campo-com-botao { display: flex; gap: .5rem; }
    .campo-com-botao input { flex: 1; min-width: 0; }

    /* ── 🗒️ Notas de reunião (2026-08-25) ──
       Cards/subcards em árvore livre, estilo OneNote. O corpo do card
       reaproveita .editor-campo (mesmo editor rich-text N/I/S da tarefa,
       ver #editor-barra) — nada de CSS/JS de edição novo aqui. */
    .notas-toolbar {
      display: flex; align-items: center; justify-content: space-between;
      gap: .6rem; margin-bottom: .8rem; flex-wrap: wrap;
    }
    .notas-toolbar h2 { font-size: 1.05rem; }
    .notas-grid {
      display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
      gap: .7rem;
    }
    .note-card {
      position: relative;
      background: var(--surface); border: 1px solid var(--border);
      border-radius: var(--radius); padding: .8rem .9rem;
      cursor: pointer; box-shadow: var(--shadow);
      transition: box-shadow .15s;
    }
    .note-card:hover { box-shadow: 0 3px 12px rgba(15,23,42,.10); }
    /* Card com painel aberto (2026-08-25, navegação em árvore multi-painel):
       destaque para saber qual dos cards do grid já está expandido abaixo. */
    .note-card.aberto { border-color: var(--primary); box-shadow: 0 0 0 2px var(--primary-soft); }
    .note-card-titulo { font-weight: 600; padding-right: 1.4rem; overflow-wrap: anywhere; }
    .note-card-sub { font-size: .78rem; color: var(--muted); margin-top: .35rem; }
    .note-card-del {
      position: absolute; top: .5rem; right: .5rem;
      background: none; border: none; cursor: pointer; color: var(--muted);
      font-size: .85rem; line-height: 1; padding: .15rem; border-radius: 4px;
    }
    .note-card-del:hover { color: var(--danger); background: var(--bg); }

    /* Compartilhamento de quadro (2026-09-14) — "⋮" no canto do quadro
       PRÓPRIO (abre o painel de acesso); badge no quadro que ALGUÉM
       compartilhou com você (papel + nome do dono), sem "⋮" nenhum. */
    .note-card-compart {
      position: absolute; top: .5rem; right: .5rem;
      background: none; border: none; cursor: pointer; color: var(--muted);
      font-size: 1.05rem; line-height: 1; padding: .15rem .4rem; border-radius: 4px;
    }
    .note-card-compart:hover { color: var(--primary); background: var(--bg); }
    .note-card-badge-papel {
      display: inline-block; font-size: .72rem; font-weight: 600; margin-top: .35rem;
      padding: .1rem .5rem; border-radius: 999px; background: var(--primary-soft); color: var(--primary);
    }
    .notas-subtitulo {
      font-size: .85rem; font-weight: 600; color: var(--muted); text-transform: uppercase;
      letter-spacing: .03em; margin: 1.1rem 0 .5rem;
    }
    .notas-subtitulo:first-of-type { margin-top: 0; }

    /* Quadro aberto em papel Ver/Editar que não é o dono: aviso curto ao
       lado do título, mesma família visual do badge "🆕 por X" da tarefa. */
    .notas-aviso-papel {
      font-size: .78rem; font-weight: 600; color: var(--muted);
      background: var(--bg); border-radius: 999px; padding: .15rem .6rem;
    }

    /* Campo sem permissão de escrita (papel = leitor): sem cursor de texto,
       sem realce de foco — só leitura, mesmo conteúdo. */
    .editor-campo[contenteditable="false"] {
      cursor: default; background: var(--bg);
    }

    /* Painel "⋮ Compartilhar quadro" (2026-09-14) */
    .notas-compart-linha {
      display: flex; align-items: center; gap: .5rem; padding: .4rem 0;
      border-bottom: 1px solid var(--border);
    }
    .notas-compart-linha .nome { flex: 1; overflow-wrap: anywhere; }
    .notas-compart-add {
      display: flex; align-items: center; gap: .5rem; margin-top: .8rem;
      padding-top: .8rem; border-top: 1px solid var(--border); flex-wrap: wrap;
    }
    /* Achado dele, 2026-09-14: `flex: 1` nos dois <select> deixava até o de
       permissão (só 2 opções curtas) esticar pra ocupar o espaço sobrando —
       o de pessoa, com nomes mais longos, ficava enorme e desproporcional.
       Cada um com seu próprio teto agora. */
    #notas-compart-select-pessoa { flex: 1 1 180px; max-width: 260px; }
    #notas-compart-select-permissao { flex: 0 0 auto; max-width: 130px; }
    #btn-notas-compart-adicionar { flex: 0 0 auto; }

    .notas-cabecalho-quadro {
      display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; margin-bottom: .9rem;
    }
    .notas-cabecalho-quadro h2 { font-size: 1.05rem; flex: 1; overflow-wrap: anywhere; }

    /* Painéis abertos do MESMO pai, lado a lado (até 3) — rola na horizontal
       em vez de quebrar layout quando a soma das larguras não cabe. */
    /* Modelo por nível (5ª revisão, 2026-08-25 — achado no uso real: ele
       criou os cards de topo direto na raiz, sem um "card guarda-chuva",
       e esperava o multi-painel já no nível 1): níveis 1 e 2 são
       MULTI-painel, até NOTAS_MAX_ABERTOS lado a lado cada (2, ver JS),
       FIFO fecha o mais antigo. O nível 3 (o mais fundo — sem
       "+ Subcard") continua editor único, mas só DENTRO do painel de
       nível 2 específico onde foi aberto. */
    .notas-painel {
      background: var(--surface); border: 1px solid var(--border);
      border-radius: var(--radius); padding: .8rem; box-shadow: var(--shadow);
    }
    /* Largura DINÂMICA com o número de painéis abertos (pedido dele,
       2026-09-01) — substitui o teto fixo de 720px (25/08), que deixava
       espaço vazio sobrando com um painel só aberto num monitor largo.
       Escopado a `.notas-paineis > .notas-painel` (o container flex dos
       níveis 1/2, multi) — o painel do nível 3 (sempre sozinho, fora
       de `.notas-paineis`, ver renderNotasNivel3) fica de fora de
       propósito e já ocupa a largura inteira do pai por ser bloco comum.
       Com NOTAS_MAX_ABERTOS = 2: um só (:only-child) ocupa tudo; dois
       dividem a metade cada — o `-.4rem` desconta a metade do `gap`
       de `.notas-paineis`, senão os dois juntos estourariam 100% e
       forçariam rolagem horizontal à toa. */
    .notas-paineis > .notas-painel {
      flex: 1 1 0; min-width: 280px; max-width: calc(50% - .4rem);
    }
    .notas-paineis > .notas-painel:only-child { max-width: 100%; }
    /* Imagem colada dentro do conteúdo de um card (2026-09-01) — nunca
       maior que o campo, cantos discretos, respiro entre linhas de texto. */
    .nota-imagem { max-width: 100%; border-radius: 6px; display: block; margin: .3rem 0; }
    .notas-painel-topo { display: flex; justify-content: flex-end; gap: .4rem; margin-bottom: .5rem; }
    .notas-painel-titulo {
      font-size: 1.05rem; font-weight: 600; margin-bottom: .6rem; max-height: none;
    }
    .editor-campo.nota-conteudo { min-height: 140px; max-height: 360px; }
    /* Conteúdo do card VIVO (Fase 5, colaboração ao vivo) — o ProseMirror
       monta dentro deste container, que substitui o .editor-campo.nota-conteudo
       acima quando o card está com a sincronia ligada. Mesmo visual do campo
       antigo, pra não estranhar a troca. */
    .nota-conteudo-viva { min-height: 140px; max-height: 360px; overflow-y: auto; padding: .5rem .6rem; }
    .nota-conteudo-viva .ProseMirror { outline: none; }
    .nota-conteudo-viva img { max-width: 100%; border-radius: 6px; display: block; margin: .3rem 0; }
    /* Redimensionar imagem por arraste (2026-09-14) — o wrap recebe o
       width:% (nunca a <img> direto, ver comentário em notas-real.entry.js);
       as 4 alças só aparecem com a imagem selecionada. */
    .nota-img-wrap { position: relative; display: inline-block; max-width: 100%; vertical-align: bottom; }
    .nota-img-handle { position: absolute; width: .6rem; height: .6rem; background: var(--primary, #3b82f6);
      border: 2px solid var(--bg, #fff); border-radius: 50%; display: none; z-index: 2; }
    .nota-img-wrap.nota-img-selecionada .nota-img-handle { display: block; }
    .nota-img-handle-nw { top: -.3rem; left: -.3rem; cursor: nwse-resize; }
    .nota-img-handle-ne { top: -.3rem; right: -.3rem; cursor: nesw-resize; }
    .nota-img-handle-sw { bottom: -.3rem; left: -.3rem; cursor: nesw-resize; }
    .nota-img-handle-se { bottom: -.3rem; right: -.3rem; cursor: nwse-resize; }
    .nota-conteudo-viva table { border-collapse: collapse; margin: .4rem 0; }
    .nota-conteudo-viva td, .nota-conteudo-viva th { border: 1px solid var(--border); padding: .3rem .45rem; min-width: 2.2rem; }
    .notas-viva-status { font-size: .75rem; color: var(--muted, #888); margin-left: .4rem; }
    .notas-viva-status.erro { color: #c0392b; }
    .notas-viva-barra {
      display: flex; align-items: center; gap: .3rem; flex-wrap: wrap;
      margin-bottom: .4rem; padding-bottom: .4rem; border-bottom: 1px dashed var(--border);
    }
    .notas-viva-barra button {
      font-size: .95rem; padding: .2rem .5rem; cursor: pointer;
      border: 1px solid var(--border); border-radius: 4px; background: var(--surface);
    }
    .notas-viva-barra input[type=color] { width: 1.8rem; height: 1.8rem; padding: 0; cursor: pointer; }
    .notas-viva-paleta { display: flex; gap: .2rem; }
    .notas-viva-paleta button { width: 1.3rem; height: 1.3rem; padding: 0; border-radius: 3px; border: 1px solid #0003; }
    .notas-viva-separador { width: 1px; align-self: stretch; background: var(--border); margin: 0 .15rem; }
    /* Grupo de EDITAR tabela (linha/coluna/cor de célula) — só visível com
       o cursor dentro de uma tabela (JS: onEmTabela em app.js). inline-flex
       com o MESMO gap da barra, pra não perder o espaçamento entre os
       botões quando aparece (`[hidden]` já cuida de escondido). */
    .notas-viva-grupo-tabela { display: inline-flex; align-items: center; gap: .3rem; }
    /* Modal mínimo pra virar trecho em tarefa no editor vivo — só os 2
       campos obrigatórios (título/prazo). O modal rico de sempre (categoria/
       pessoa/empresa/lembrete) continua servindo o card ANTIGO; unificar os
       dois fica pra um refino futuro (ver docs/notas.md, Fase 5). */
    #modal-vinculo-vivo {
      position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 200;
      display: flex; align-items: center; justify-content: center;
    }
    #modal-vinculo-vivo[hidden] { display: none; }
    #modal-vinculo-vivo .modal-caixa {
      background: var(--surface); border-radius: var(--radius); padding: 1.2rem; width: 320px;
    }
    #modal-vinculo-vivo .modal-caixa h2 { font-size: 1rem; margin: 0 0 .75rem; }
    #modal-vinculo-vivo .modal-caixa .acoes { display: flex; gap: .5rem; justify-content: flex-end; margin-top: 1rem; }
    .notas-subnivel { margin-top: .8rem; padding-top: .7rem; border-top: 1px dashed var(--border); }
    .notas-toolbar-mini {
      display: flex; align-items: center; justify-content: space-between;
      gap: .5rem; margin-bottom: .5rem;
    }
    .notas-toolbar-mini .hint { margin: 0; }
    .notas-grid:empty { display: none; }
    /* Painéis do nível 2, lado a lado dentro do painel de nível 1 (até 3). */
    .notas-paineis {
      display: flex; gap: .8rem; align-items: flex-start;
      overflow-x: auto; padding-bottom: .3rem; margin-top: .6rem;
    }
    .notas-paineis:empty { display: none; margin-top: 0; }

    /* Busca de quadro (lista) e busca de texto nos cards de um quadro aberto
       (2026-08-29) — cliente puro, os dados já estão carregados inteiros
       (NOTAS_QUADROS / NOTAS_BOARD.cards), sem endpoint novo. */
    .notas-busca-input { flex: 1 1 220px; max-width: 320px; }
    .notas-busca-resultados { display: flex; flex-direction: column; gap: .5rem; margin-bottom: .9rem; }
    .notas-busca-resultado-item {
      background: var(--surface); border: 1px solid var(--border);
      border-radius: var(--radius); padding: .6rem .8rem; cursor: pointer;
      transition: box-shadow .15s;
    }
    .notas-busca-resultado-item:hover { box-shadow: 0 3px 12px rgba(15,23,42,.10); }
    .notas-busca-caminho { font-size: .75rem; color: var(--muted); margin-bottom: .15rem; overflow-wrap: anywhere; }
    .notas-busca-titulo { font-weight: 600; overflow-wrap: anywhere; }
    .notas-busca-trecho { font-size: .85rem; color: var(--muted); margin-top: .25rem; overflow-wrap: anywhere; }
    /* Flash temporário no painel encontrado pela busca (removido por JS
       depois de ~1,6s — sem transição na saída de propósito, é só um aviso
       rápido de "é aqui", não precisa de animação elaborada). */
    .notas-destaque-busca { box-shadow: 0 0 0 3px var(--primary) !important; }

    /* ── Responsivo ── */
    @media (max-width: 500px) {
      .form-row { flex-direction: column; }
      .filter-sep, .task-count { display: none; }
      .cal-day { min-height: 54px; }
      .cal-chip { display: none; }
      .cal-dots { font-size: .6rem; }
    }
  