/* Editor::CanvasComponent — SVG do sequence diagram (DS suíço).
   Cor "de dado" (paleta do participante) entra via custom property (--fill/--hue);
   cor "fixa" do componente fica no CSS. Em SVG, CSS vence atributo de apresentação. */
.c-editor-canvas{
  overflow: auto; padding: 34px 40px; user-select: none; -webkit-user-select: none;
  /* EXCEÇÃO deliberada ao DS: o design system é sharp (--radius: 0), mas o DESENHO do fluxo é
     arredondado. Vale só aqui dentro — o chrome ao redor (barra, ficha, botões) segue de canto
     vivo. Token local para não abrir precedente global.
     A fronteira é semântica, não geográfica: o que é TRAÇO do fluxo (setas, laços, badges, quadros
     de fragmento) arredonda; o que é CAIXA de chrome dentro do SVG — header do participante e o
     slot "+ participante" — fica sharp, como os botões da barra. */
  --r-node: 4px;    /* quadro do fragmento */
  --r-bar: 3px;     /* barras finas: ativação, etiqueta do fragmento */
  --r-loop: 7px;    /* raio do laço da self-message (usado também no render.js) */
}
/* O canvas é o ÚNICO scrollport (rola nos dois eixos): é isso que deixa o sticky dos headers ser
   nativo. O `content` é a caixa do desenho — largura do SVG, centrada quando sobra tela. Centrar
   aqui, e não no SVG, mantém a faixa sticky alinhada com as colunas de graça: os dois moram na
   mesma caixa. */
.c-editor-canvas__content{ width: max-content; margin: 0 auto; }
.c-editor-canvas__svg{ display: block; }

/* ── modo navegar ────────────────────────────────────────────────────────────
   O canvas deixa de ser um trecho de página que rola e vira uma JANELA: `overflow: hidden` (a
   altura continua vindo do flex da ilha — nenhum controller mede nada). É o que dá navegação sem
   limite — barra de rolagem tem batente, `transform` não. O desenho anda livre, inclusive para
   fora da vista.
   Apagar o pointer-events de dentro do SVG faz o "clique não seleciona nada" ser literal: some todo
   hover e todo cursor de afordância, e o pointerdown cai direto no <svg>, onde o listener mora. */
.c-editor-canvas--nav{ overflow: hidden; cursor: grab; }
.c-editor-canvas--nav .c-editor-canvas__svg{ margin: 0; }  /* centrar brigaria com a câmera */
.c-editor-canvas--nav .c-editor-canvas__svg *{ pointer-events: none; }
.c-editor-canvas--panning{ cursor: grabbing; }

.c-editor-canvas__lifeline-group{ cursor: crosshair; }
.c-editor-canvas__lifeline-hit{ fill: transparent; }
.c-editor-canvas__lifeline{ stroke: var(--line-2); stroke-width: 1; pointer-events: none; stroke-linecap: round; }

/* ── faixa dos headers (sticky NATIVO) ───────────────────────────────────────
   Rolou além dos headers e a lifeline vira uma linha anônima. Então a faixa gruda no topo do canvas
   — por `position: sticky`, não por JS: o scroll do navegador é composto fora da thread principal,
   e qualquer transform escrito num listener de scroll chega um quadro atrasado (os headers
   "nadavam" atrás do desenho). Aqui não há JS no caminho.
   A caixa tem altura ZERO: ela sobrepõe o desenho em vez de empurrá-lo. E a faixa INTEIRA (fundo,
   headers, régua) é TRANSLÚCIDA — vidro, não parede: o fluxo segue legível por trás. A opacidade
   vai na caixa, não em cada peça, senão o desenho apareceria "dentro" do header em vez de atrás
   do conjunto. */
.c-editor-canvas__sentinel{ height: 1px; }
.c-editor-canvas__heads{
  /* `top` NEGATIVO no tamanho do padding do canvas: o sticky pinaria a faixa na borda interna do
     padding, e a fresta de 34px acima dela deixaria o desenho passar por cima da faixa. Puxando-a
     até a borda do canvas, a faixa cobre até o fim — e o header cai a 34px do topo, o mesmo respiro
     que ele tem em repouso. */
  position: sticky; top: -34px; z-index: 5; height: 0; opacity: .85;
}
.c-editor-canvas__heads-svg{ display: block; }
.c-editor-canvas__band-bg{ fill: var(--surface); pointer-events: none; }
/* a régua só acende quando a faixa está de fato pinada (classe posta pelo IntersectionObserver) —
   no topo ela seria uma linha a mais num lugar onde não há nada para separar */
.c-editor-canvas__band-rule{ stroke: var(--line-2); stroke-width: 1; opacity: 0; pointer-events: none; }
.c-editor-canvas__heads--stuck .c-editor-canvas__band-rule{ opacity: 1; }

.c-editor-canvas__phead{ fill: var(--fill, #fff); stroke: var(--hue, var(--ink)); stroke-width: 1.5; cursor: grab; }
.c-editor-canvas__phead--selected{ stroke: var(--accent); stroke-width: 2; }
.c-editor-canvas__pindex{
  font: 500 9px/1 var(--font-mono); letter-spacing: .1em;
  fill: var(--ink-3); text-anchor: middle;
}
.c-editor-canvas__plabel{
  font: 600 12.5px/1 var(--font-ui); letter-spacing: -.01em;
  fill: var(--hue, var(--ink)); text-anchor: middle; dominant-baseline: middle;
}

.c-editor-canvas__msg-hit{ stroke: transparent; stroke-width: 14; fill: none; cursor: pointer; }
.c-editor-canvas__msg{
  stroke: var(--ink); stroke-width: 1.3; fill: none; marker-end: url(#arrow); pointer-events: none;
  stroke-linecap: round; stroke-linejoin: round;   /* o laço da self-message vira curva */
}
.c-editor-canvas__msg--return{ stroke-dasharray: 4 4; }
.c-editor-canvas__msg--async{ marker-end: url(#arrow-open); }
.c-editor-canvas__msg--selected{ stroke: var(--accent); stroke-width: 1.8; marker-end: url(#arrow-accent); }
/* seta da mensagem selecionada — fill via token (marker herda --accent do :root) */
.c-editor-canvas__arrowhead-accent{ fill: var(--accent); stroke: var(--accent); }

/* O render põe o rótulo no PONTO MÉDIO da seta assumindo `middle` — mas a classe não declarava
   anchor nenhum, e o default do SVG é `start`: o texto nascia no meio da seta e crescia TODO para a
   direita, até o viewBox comê-lo. O `__plabel` (acima) sempre declarou o seu; este foi esquecido.
   A self-message é a exceção: ela pende ancorada à esquerda, do fim do laço para a direita.
   Vai por CLASSE, não por atributo: em SVG o CSS vence o atributo de apresentação (v. topo). */
.c-editor-canvas__mlabel{
  font: 400 12.5px/1 var(--font-ui); fill: var(--ink); letter-spacing: -.01em;
  text-anchor: middle;
}
.c-editor-canvas__mlabel--self{ text-anchor: start; }
.c-editor-canvas__mlabel--muted{ fill: var(--ink-2); }

.c-editor-canvas__mlabel--selected{ fill: var(--accent); font-weight: 700; }

/* Régua: mede, não desenha. `visibility: hidden` e NÃO `display: none` — nó sem caixa não tem
   comprimento de texto, e a régua mediria zero. Mora dentro do SVG do desenho para medir na mesma
   fonte e no mesmo sistema de coordenadas: `getComputedTextLength` devolve unidades de USUÁRIO,
   imune ao zoom (que vive na moldura, não no viewBox). */
.c-editor-canvas__mlabel--measure{ visibility: hidden; pointer-events: none; }

/* badge = alça de arrasto + código estável do step. Círculo: `rx` não se aplica a <circle>. */
.c-editor-canvas__badge{ fill: var(--ink); cursor: grab; }
.c-editor-canvas__badge--selected{ fill: var(--accent); }
.c-editor-canvas__bnum{
  font: 600 9.5px/1 var(--font-mono); fill: #fff;
  text-anchor: middle; dominant-baseline: central; pointer-events: none;
}

.c-editor-canvas__activation{ fill: #efefee; stroke: var(--line-2); stroke-width: 1; pointer-events: none; rx: var(--r-bar); }

/* seleção / drag / edição */
.c-editor-canvas__handle{ fill: #fff; stroke: var(--accent); stroke-width: 1.5; rx: 1.5px; }
.c-editor-canvas__ghost{ stroke: var(--accent); stroke-width: 1.6; stroke-dasharray: 5 4; pointer-events: none; stroke-linecap: round; }
.c-editor-canvas__target-line{ stroke: var(--accent); stroke-width: 3; opacity: .45; pointer-events: none; stroke-linecap: round; }
.c-editor-canvas__input{
  position: fixed; transform: translate(-50%, -50%); z-index: 50;
  border: 1px solid var(--accent); background: var(--surface);
  padding: 2px 6px; font: 400 12.5px var(--font-ui); text-align: center;
  user-select: text; -webkit-user-select: text;
}

/* slot "+ participante" (mouse-only) */
.c-editor-canvas__add{ cursor: pointer; }
.c-editor-canvas__add-box{ fill: transparent; stroke: var(--line-2); stroke-width: 1.5; stroke-dasharray: 4 4; }
.c-editor-canvas__add:hover .c-editor-canvas__add-box{ stroke: var(--ink-3); }
.c-editor-canvas__add-plus{ font: 400 20px/1 var(--font-ui); fill: var(--ink-3); text-anchor: middle; dominant-baseline: central; pointer-events: none; }

/* ── fragmento combinado (alt / opt / loop) ──────────────────────────────────
   O quadro é cenário, não conteúdo: fica atrás das mensagens e não captura clique — quem captura
   é a etiqueta do canto, que é a alça do fragmento. Assim arrastar um step DENTRO do quadro
   continua sendo arrastar o step. */
.c-editor-canvas__frame{
  fill: none; stroke: var(--line-2); stroke-width: 1.5; pointer-events: none; rx: var(--r-node);
}
.c-editor-canvas__frame--selected{ stroke: var(--accent); stroke-width: 2; }

/* etiqueta do operador: mesma linguagem dos rótulos mono do DS, virada em alça */
.c-editor-canvas__ftag{ fill: var(--surface-sunken); stroke: var(--line-2); stroke-width: 1.5; cursor: grab; rx: var(--r-bar); }
.c-editor-canvas__ftag--selected{ fill: var(--accent); stroke: var(--accent); }
.c-editor-canvas__foperator{
  font: 600 10px/1 var(--font-mono); letter-spacing: .1em; text-transform: uppercase;
  fill: var(--ink-2); text-anchor: middle; dominant-baseline: central; pointer-events: none;
}
.c-editor-canvas__ftag--selected + .c-editor-canvas__foperator,
.c-editor-canvas__fragment:has(.c-editor-canvas__ftag--selected) .c-editor-canvas__foperator{ fill: #fff; }

/* guarda do ramo: clicar edita no lugar (mesmo gesto do rótulo da mensagem).
   O rect de acerto existe porque, em SVG, só os GLIFOS do <text> são clicáveis — sem ele o clique
   escorrega pelo vão entre as letras. */
.c-editor-canvas__guard{ cursor: text; }
.c-editor-canvas__guard-hit{ fill: transparent; rx: var(--r-bar); }
.c-editor-canvas__gtext{
  font: 400 11px/1 var(--font-mono); fill: var(--ink-2); dominant-baseline: central;
  pointer-events: none;
}
/* guarda ainda não escrita: é convite, não dado — por isso não finge ser texto preenchido */
.c-editor-canvas__gtext--empty{ fill: var(--ink-3); font-style: italic; }
.c-editor-canvas__guard:hover .c-editor-canvas__guard-hit{ fill: var(--surface-sunken); }
.c-editor-canvas__guard:hover .c-editor-canvas__gtext{ fill: var(--accent); }

/* tracejado que separa um ramo do anterior (o "senão" do alt) */
.c-editor-canvas__fsep{ stroke: var(--line-2); stroke-width: 1; stroke-dasharray: 5 4; pointer-events: none; stroke-linecap: round; }

/* indicador de solta: onde a linha arrastada vai aterrissar. Dentro de um ramo ele tem a largura
   do quadro — é assim que se lê "soltar aqui é entrar neste ramo". */
.c-editor-canvas__drop-line{ stroke: var(--accent); stroke-width: 2.5; opacity: .85; pointer-events: none; stroke-linecap: round; }

/* ── tinta temporária (modo apresentar) ──────────────────────────────────────
   Camada DENTRO do SVG (irmã do `layer`), então GRUDA no fluxo: zoom, scroll e pan a levam junto,
   sem matemática — a escala é a do próprio SVG. O re-render só limpa o `layer`, nunca a `inkLayer`.
   O modo é como o navegar: crosshair e pointer-events de dentro do SVG apagados, para o pointerdown
   cair no <svg> (onde o roteador o desvia para o traço) sem acender afordância de edição. */
.c-editor-canvas--ink{ cursor: crosshair; }
.c-editor-canvas--ink .c-editor-canvas__svg *{ pointer-events: none; }

/* traço à mão livre = GRUPO de segmentos, cada um com sua espessura (pela velocidade). O fade vai no
   grupo: o SVG achata o <g> antes de compor, então esmaece como uma peça só, sem costuras. Some
   sozinho no animationend (CSS no caminho, não JS).
   Acabamento de MARCA-TEXTO: coral quente (não o vermelho de danger), levemente translúcido e com um
   halo suave — lê como tinta sobre o desenho, não como risco sólido. A opacidade vai no GRUPO (não
   no segmento), senão as sobreposições dos segmentos escureceriam nas junções. */
.c-editor-canvas__ink-stroke{
  pointer-events: none; opacity: .8;
  filter: drop-shadow(0 0 3px color-mix(in srgb, var(--ink-marker) 55%, transparent));
}
.c-editor-canvas__ink-seg{
  stroke: var(--ink-marker); fill: none; stroke-linecap: round; pointer-events: none;
}
/* segura um instante e some — anotação de apresentação, não desenho para guardar */
.c-editor-canvas__ink-stroke--fading{
  animation: c-editor-ink-fade var(--ink-fade-ms, 1400ms) ease-in forwards;
}
/* começa na opacidade-base do traço (.8) para não dar um "pop" de brilho ao iniciar o fade */
@keyframes c-editor-ink-fade{ 0%, 35%{ opacity: .8; } 100%{ opacity: 0; } }
