/* ============================================================
   ESTUDIO — camada de editor sobre o mural.
   Carregada DEPOIS de mural.css, entao tambem serve para
   ajustar o que mudou no comportamento das animacoes.
   ============================================================ */

/* ==========================================================
   1. Palco, escala e rolagem
   ========================================================== */
/* O mural fica no MEIO de uma prancheta bem maior: sobra papel
   quadriculado para todos os lados, entao da para navegar para cima,
   baixo, esquerda e direita — e ao reduzir a escala nunca sobra
   faixa branca, porque a prancheta continua maior que a janela. */
#stage {
  /* posicionado: as pecas vivem aqui dentro, em coordenadas do palco */
  position: relative;
  display: flex; align-items: stretch; width: max-content;
  /* Margem enorme em volta do mural: espaco livre para vagar em
     qualquer direcao. A tecla 1 traz a vista de volta.

     EM PIXELS, E NAO EM `vh`/`vw`. Esta folga e a ORIGEM do sistema de
     coordenadas do palco — e onde a primeira pagina comeca —, e a
     caneta guarda cada traco em coordenadas do palco. Com `400vh
     400vw` a origem se mexia junto com a janela: bastava a barra de
     "compartilhando esta guia" aparecer, tirando 36px de altura, para
     a folga encolher 144px, as paginas subirem 144px e os tracos
     ficarem onde estavam — as setas paravam de apontar para o que
     apontavam. O mesmo acontecia em silencio ao abrir num monitor de
     tamanho diferente daquele em que o projeto foi desenhado.

     Em pixels a origem nao se mexe, e coordenada do palco quer dizer a
     mesma coisa em qualquer tela e a qualquer hora. Projetos salvos
     antes disto trazem a origem antiga gravada no arquivo, e o
     `restaurar` reposiciona os tracos por ela. */
  padding: 5120px;
}
#board { overflow-y: auto; height: var(--altura-janela, 100vh); }
.panel { height: var(--altura-janela, 100vh); }
#board::-webkit-scrollbar { width: 0; height: 0; }
#progress { display: none; }

body.modo-nav      #board { cursor: default; }
body.modo-hand     #board { cursor: grab; }
body.modo-hand     #board.arrastando { cursor: grabbing; }
body.colando       #board { cursor: copy; }

/* A previa do que vai ser colado, ao lado do ponteiro. Fica FORA do
   #board de proposito: assim a gravacao isolada nao a filma — ela e
   andaime de quem monta, e nao parte do mural.

   `pointer-events: none` porque ela anda debaixo do ponteiro o tempo
   todo: recebendo clique, seria ela a ser clicada, e nunca o mural. */
.previa-colar {
  position: fixed; left: 0; top: 0; z-index: 140;
  pointer-events: none; will-change: transform;
  opacity: .85;
  filter: drop-shadow(0 .2vh .4vh rgba(20,22,26,.25));
}
.previa-colar > * { display: block; }
.previa-colar .previa-quadro {
  width: 3.4vh; height: 3.4vh; border-radius: .5vh;
  border: .2vh solid var(--ink);
}
.previa-colar .previa-emoji { font-size: 3.4vh; line-height: 1; }

/* A MINIATURA DO POST-IT E A DO MENU, na cor escolhida.

   A previa dele era um quadrado para os quatro formatos: quem
   escolhia coracao e quem escolhia marca-paginas viam a mesma coisa,
   e o unico botao do menu que ja tinha o desenho certo nao era
   aproveitado.

   Maior que no menu, e sem o contorno: aqui ela anda sozinha sobre o
   mural, e o traco que ajuda a separar um botao do vizinho so suja o
   desenho quando nao ha vizinho nenhum. */
.previa-colar .mini { --mini: 3.4vh; margin: 0; box-shadow: none; }

/* ==========================================================
   ARTE MIUDA: O MESMO DESENHO NO BOTAO E NA PREVIA
   ==========================================================
   A previa do que vai ser colado e o icone do menu sao a MESMA
   classe, e nao dois desenhos parecidos. Duas artes para a mesma
   peca acabam diferentes — foi a licao da miniatura do
   temporizador —, e uma previa que nao bate com o resultado e pior
   do que previa nenhuma.

   Tudo aqui deriva de `--mini`, que e a unica medida: o menu pede
   uma, a previa pede outra, e o desenho e o mesmo nos dois. */
.arte-mini {
  --mini: 3vh;
  display: block; position: relative; flex: none;
}
.pin-galeria .arte-mini, .pop-grid .arte-mini { --mini: max(3vh, 24px); }
.previa-colar .arte-mini { --mini: 3.4vh; }

/* A caixinha de tarefa: cartao branco, a caixa na cor escolhida e a
   linha do texto. */
.arte-mini--check {
  width: calc(var(--mini) * 1.9); height: calc(var(--mini) * .72);
  border-radius: calc(var(--mini) * .18);
  background: #fff; border: .12vh solid #d7dee8;
  display: flex; align-items: center; gap: calc(var(--mini) * .14);
  padding: 0 calc(var(--mini) * .16);
}
.arte-mini--check::before {
  content: ''; flex: none;
  width: calc(var(--mini) * .34); height: calc(var(--mini) * .34);
  border-radius: calc(var(--mini) * .08);
  border: .16vh solid var(--cor-check, var(--cor-pin, #1fbf6b));
}
.arte-mini--check::after {
  content: ''; flex: 1; height: calc(var(--mini) * .12);
  border-radius: 999px; background: #c7cfdb;
}

/* A barra escura em cima e o que identifica a janela de longe, entao
   e ela que o desenho carrega. */
.arte-mini--janela {
  width: calc(var(--mini) * 1.5); height: calc(var(--mini) * 1.05);
  border-radius: calc(var(--mini) * .12);
  background: #fff; border: .12vh solid #b9c2ce;
  border-top: calc(var(--mini) * .3) solid #3f3f3f;
}

/* A polaroid e papel branco com a foto em cima e a margem grossa
   embaixo, que e onde vai a legenda. */
.arte-mini--polaroid {
  width: calc(var(--mini) * .96); height: calc(var(--mini) * 1.12);
  background: #fff; border: .12vh solid #d7dee8;
  padding: calc(var(--mini) * .1) calc(var(--mini) * .1) calc(var(--mini) * .3);
  box-shadow: 0 .1vh .3vh rgba(20,22,26,.16);
}
.arte-mini--polaroid::before {
  content: ''; display: block; width: 100%; height: 100%;
  background: #e6ebf2;
}


/* O calendario: a faixa do mes em cima e a grade dos dias embaixo. */
.arte-mini--calendario {
  width: calc(var(--mini) * 1.15); height: calc(var(--mini) * 1.05);
  border-radius: calc(var(--mini) * .12);
  background: #fff; border: .12vh solid #d7dee8;
  border-top: calc(var(--mini) * .26) solid var(--red, #e8232a);
  padding: calc(var(--mini) * .12);
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: calc(var(--mini) * .07); align-content: start;
}
.arte-mini--calendario i {
  display: block; aspect-ratio: 1; border-radius: calc(var(--mini) * .04);
  background: #dbe2ec;
}
.arte-mini--calendario i:nth-child(6) { background: var(--red, #e8232a); }

/* ---------- peças que só existem em tamanho real ----------
   O temporizador não tem miniatura: o que existe é o relógio de
   verdade, de 320 a 380px. Ele entra inteiro e é reduzido por
   transformação, medido depois de estar na tela — é o mesmo caminho
   das miniaturas de layout do menu dele. */
.previa-encaixe {
  position: relative; overflow: hidden;
  width: calc(var(--mini, 3.4vh) * 3.4); height: calc(var(--mini, 3.4vh) * 2.1);
  border-radius: .6vh; background: #fff;
  border: .12vh solid var(--borda);
}
.previa-encaixe > * {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%); transform-origin: center center;
}
/* O GIF importado já é uma imagem: a prévia é ele mesmo. */
.previa-colar .previa-gif {
  width: 4.4vh; height: 4.4vh; object-fit: contain;
  border-radius: .4vh;
}
body.mexendo       { user-select: none; }
body.soltando      #board { outline: .5vh dashed var(--blue); outline-offset: -1vh; }

/* ==========================================================
   2. Animacoes continuas dos vetores
   O texto e os infograficos ficam parados de proposito.
   ========================================================== */

/* entrada: so opacidade, para nunca brigar com a transformacao
   dos objetos que voce move, gira e escala */
/* Opacidade sozinha nao diz de onde a coisa veio: ela simplesmente
   materializa no lugar. Um deslocamento curto e uma escala de 2% dao
   direcao ao aparecimento sem custar tempo nenhum a mais. */
@keyframes pop {
  from { opacity: 0; transform: translateY(.8vh) scale(.98); }
  to   { opacity: 1; transform: none; }
}
@keyframes popRot { from { opacity: 0; } to { opacity: 1; } }
.js .pop { opacity: 0; transform: none; }

/* setas: o corpo fica firme, so a ponta pisca */
@keyframes pontaSeta { 0%, 100% { opacity: .45; } 50% { opacity: 1; } }
.doodle--arrow path + path {
  animation: pontaSeta 1.2s ease-in-out infinite;
}
.doodle--arrow path + path + path { animation-delay: .12s; }

/* brilho cintilando */
@keyframes cintilar {
  0%, 100% { opacity: .35; transform: scale(.82) rotate(0deg); }
  50%      { opacity: 1;   transform: scale(1.12) rotate(22deg); }
}
.doodle--spark path {
  transform-box: fill-box; transform-origin: center;
  animation: cintilar 2.6s ease-in-out infinite;
}

/* stickers com brilho passando por cima */
.sticker { overflow: hidden; }
.sticker > * { position: relative; z-index: 1; }
.sticker::after {
  content: ''; position: absolute; inset: -60%;
  background: linear-gradient(115deg, transparent 42%, rgba(255,255,255,.6) 50%, transparent 58%);
  animation: brilhoPassa 4.2s ease-in-out infinite;
  pointer-events: none; z-index: 2;
}
@keyframes brilhoPassa {
  0%        { transform: translateX(-110%); }
  55%, 100% { transform: translateX(110%); }
}

/* emojis do conteudo */
@keyframes emoBalanca { 0%,100% { transform: rotate(-9deg); } 50% { transform: rotate(9deg); } }
@keyframes emoPula    { 0%,100% { transform: translateY(0); }  50% { transform: translateY(-.5em); } }
@keyframes emoPulsa   { 0%,100% { transform: scale(1); }       50% { transform: scale(1.18); } }
.emo { display: inline-block; transform-origin: 50% 85%; will-change: transform; }
.emo--a { animation: emoBalanca 2.6s ease-in-out infinite; }
.emo--b { animation: emoPula 2.2s ease-in-out infinite; }
.emo--c { animation: emoPulsa 3s ease-in-out infinite; }

/* infograficos ficam estaticos */
.panel .bar__col { transition: none; height: var(--h, 50%); }

/* ==========================================================
   3. Interacoes de mouse no conteudo
   ========================================================== */
.card, .tl__dot, .check, .tbl tbody tr, .legend div { transition: transform var(--t-botao) var(--mov-padrao), box-shadow var(--t-botao) var(--mov-padrao), background var(--t-botao) var(--mov-padrao); }
body.modo-nav .card:hover     { transform: translateY(-.5vh); box-shadow: var(--shadow-lg); }
body.modo-nav .tl__dot:hover  { transform: scale(1.14); }
body.modo-nav .tbl tbody tr:hover { background: #fff6e8; }
body.modo-nav .legend div:hover   { transform: translateX(.6vh); }
/* O tracejado do passar do mouse saiu: ver a nota no clean.css. */
body.modo-pen .panel > *:hover, body.modo-hand .panel > *:hover,
body.modo-erase .panel > *:hover { outline: none !important; }

/* caixas de check: comecam vazias */
.check__box { cursor: pointer; padding: 0; }
.check__box svg { opacity: 0; transform: scale(.5); transition: all .2s var(--mov-estouro); color: var(--green-dp); }
.check__box.on { background: #e8fbf1; border-color: var(--green-dp); }
.check__box.on svg { opacity: 1; transform: scale(1); }
.check__box:hover { border-color: var(--green-dp); transform: scale(1.08); }

/* ==========================================================
   4. Barra de ferramentas
   ========================================================== */
/* centraliza usando left/right + margin: com "left:50%" a largura
   disponivel viraria so metade da tela e a barra quebraria em linhas */
#toolbar {
  left: 0; right: 0; transform: none; margin: 0 auto;
  width: max-content; max-width: 96vw;
  /* O vao nao se decide aqui: ele vem do `--vao-barra`, no clean.css. */
  flex-wrap: wrap; justify-content: center; padding: .9vh 1.1vh;
}
.tool { width: 4.2vh; height: 4.2vh; }
.tool svg { width: 2.2vh; height: 2.2vh; }
.swatch { width: 3.9vh; height: 3.9vh; }
.size button { width: 3.5vh; height: 3.5vh; font-size: max(2.1vh, 16.8px); }
.size__preview { width: 4.6vh; height: 3.9vh; }

.zoom {
  display: flex; align-items: center; gap: .7vh;
  background: #f3f6fa; border-radius: 10vh; padding: .5vh .8vh;
}
.zoom button {
  width: 3.5vh; height: 3.5vh; border-radius: 50%; background: #fff;
  box-shadow: var(--shadow-sm); font-weight: 800; font-size: max(2vh, 16.0px); line-height: 1;
  display: grid; place-items: center; transition: transform var(--t-botao) var(--mov-padrao);
}
.zoom button:hover { transform: scale(1.1); }
/* width: auto num <input> vale ~20 caracteres. Sem medida propria,
   a caixinha de zoom ficava do tamanho de um campo de texto. */
#zoom-num { width: 5vh; min-width: 0; padding: 0 .4vh; border-radius: 10vh; font-size: max(1.5vh, 12.0px); }
#zoom-range { width: 9vh; accent-color: var(--red); cursor: pointer; }

/* ==========================================================
   5. Popovers
   ========================================================== */
.pop-menu {
  position: fixed; z-index: 97;
  background: #fff; border: .28vh solid var(--ink); border-radius: 1.8vh;
  box-shadow: 0 2vh 5vh rgba(20,22,26,.26), .6vh .6vh 0 rgba(20,22,26,.9);
  padding: 2vh; width: 42vh; max-width: 92vw;
  animation: subir var(--t-cartao) var(--mov-entrada);
}
@keyframes subir { from { opacity: 0; transform: translateY(1.6vh); } to { opacity: 1; transform: none; } }
.pop-menu__t { display: block; font-family: 'Archivo Black', sans-serif; font-size: max(2.1vh, 16.8px); margin-bottom: 1.4vh; }
.pop-menu__dica { margin: 1.4vh 0 0; font-size: max(1.5vh, 12.0px); line-height: 1.45; color: var(--ink-soft); }
.pop-menu__dica kbd, #help kbd { font-family: inherit; }

.pop-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: .8vh; }
.pop-grid--4 { grid-template-columns: repeat(4, 1fr); }
.pop-grid--3 { grid-template-columns: repeat(3, 1fr); }
.pop-grid--2 { grid-template-columns: repeat(2, 1fr); }
.pop-grid--1 { grid-template-columns: 1fr; }
.pop-grid--5 { grid-template-columns: repeat(5, 1fr); }

/* O desenho de verdade no lugar do emoji, no tamanho que o emoji
   ocupava. A cor vem da paleta logo abaixo do grupo: o botao mostra o
   que entrega, inclusive na cor. */
/* Altura fixa, e nao `auto`: o clipe tem o quadro mais alto que os
   outros (40x60 contra 40x44), e com a altura livre ele empurrava o
   proprio rotulo para baixo e desalinhava a fileira. Com os dois lados
   presos, o SVG se encaixa dentro sozinho, centrado e sem distorcer —
   e o desenho mais estreito so ganha folga dos lados. */
.pin-mini {
  width: max(3vh, 24px); height: max(3vh, 24px); display: block;
  --pin: var(--cor-pin, #d42a4c);
}
.pop-grid button {
  display: flex; flex-direction: column; align-items: center; gap: .5vh;
  padding: 1.2vh .6vh; border-radius: 1.1vh; background: #f5f8fc;
  font-size: max(1.35vh, 10.8px); font-weight: 700; color: var(--ink); text-align: center;
  transition: all var(--t-botao) var(--mov-padrao); line-height: 1.2;
}
.pop-grid--1 button, .pop-grid--2 button { flex-direction: row; justify-content: flex-start; gap: 1.2vh; font-size: max(1.6vh, 12.8px); }
.pop-grid button span { font-size: max(2.6vh, 20.8px); }
/* A capa que e desenho, e nao emoji, ocupa a mesma caixa do glifo: a
   fileira do menu nao pode ficar com um botao mais alto que os
   outros so porque a arte dele e de verdade. */
.capa-vetor { display: grid; place-items: center; width: 1em; height: 1em; }
.capa-vetor svg { width: 100%; height: 100%; display: block; }
.pop-grid button:hover { background: var(--ink); color: #fff; transform: translateY(-.3vh); }

/* Dez por fileira, sempre: as fortes em cima, os pasteis embaixo,
   e a roda fechando a segunda. Grade, e nao flex, para as colunas
   ficarem alinhadas entre as duas fileiras. */
.pop-cores {
  display: grid; grid-template-columns: repeat(10, 1fr);
  gap: .5vh; margin-top: 1.4vh;
}
.pop-cores .cor {
  width: 100%; aspect-ratio: 1; height: auto;
  border-radius: 50%; border: .24vh solid #fff;
  box-shadow: 0 0 0 .16vh #dde4ee; transition: transform var(--t-botao) var(--mov-padrao);
}
.pop-cores .cor:hover { transform: scale(1.15); }
.pop-cores .cor.on { box-shadow: 0 0 0 .38vh var(--ink); transform: scale(1.1); }

.campo { display: block; font-size: max(1.6vh, 12.8px); font-weight: 700; margin-bottom: 1.4vh; color: var(--ink); }
.campo span { float: right; color: var(--red-deep); }
.campo input[type="range"] { width: 100%; margin-top: .6vh; accent-color: var(--red); }
.campo input[type="date"], .campo select {
  width: 100%; margin-top: .6vh; padding: 1vh; font: inherit; font-size: max(1.7vh, 13.6px);
  border: .22vh solid #dde4ee; border-radius: .9vh; background: #fff;
}
.pop-acoes { display: flex; gap: .8vh; margin-top: 1.6vh; }
.btn {
  flex: 1; padding: 1.2vh; border-radius: 1vh; background: #f0f3f8;
  font-weight: 800; font-size: max(1.6vh, 12.8px); transition: all var(--t-botao) var(--mov-padrao);
}
.btn:hover { background: #e2e8f2; }
.btn--ok { background: var(--ink); color: #fff; }
.btn--ok:hover { background: #000; }

/* roda de emojis */
.pop-menu--roda { width: 30vh; }
.roda { position: relative; width: 220px; height: 220px; margin: 0 auto; }
.roda__item {
  position: absolute; width: 42px; height: 42px; margin: -21px 0 0 -21px;
  border-radius: 50%; background: #f5f8fc; font-size: 22px; line-height: 1;
  display: grid; place-items: center;
  transition: transform var(--t-botao) var(--mov-padrao), background var(--t-botao) var(--mov-padrao);
  animation: emoPulsa 3s ease-in-out infinite;
}
.roda__item:hover { transform: scale(1.35); background: var(--yellow); z-index: 2; }
.roda::after {
  content: '😀'; position: absolute; left: 50%; top: 50%;
  transform: translate(-50%,-50%); font-size: 30px; opacity: .28;
}

/* bolinhas numeradas — no topo, para nao brigar com a barra de baixo */
#dots {
  top: 2.6vh; bottom: auto; left: 0; right: 0;
  margin: 0 auto; width: max-content; max-width: 60vw;
  /* NUNCA QUEBRA EM DUAS LINHAS. Com dezesseis paginas os numeros
     empurravam os icones para baixo e a barra dobrava de altura —
     medido: 841px de altura numa barra que tem 56. Quem cede espaco e
     o trilho de numeros, que ja rola por dentro; os icones ficam
     sempre no mesmo lugar, que e o que se espera de uma barra de
     ferramentas. */
  flex-wrap: nowrap; justify-content: center;
}
#dots button { width: auto; min-width: 2.6vh; height: 2.6vh; border-radius: 1vh;
  font-size: max(1.3vh, 10.4px); font-weight: 800; color: #7c8a9e; padding: 0 .5vh; }
#dots button.on { width: auto; background: var(--red); color: #fff; padding: 0 1vh; }

/* ==========================================================
   6. Selecao, alcas e marquee
   ========================================================== */
/* ---- as miras do ima ----
   Acima do #selecao (81) de proposito: a linha diz onde a peca vai
   encaixar, e ficar por baixo da caixa de selecao esconderia ela
   justamente no encaixe certo, que e quando ela importa.

   Magenta, e nao a cor da selecao: as duas aparecem juntas na tela e
   precisam se distinguir de relance — azul e o que voce pegou, rosa e
   o que a pagina esta oferecendo. */
#miras { position: fixed; inset: 0; z-index: 82; pointer-events: none; }
.mira { position: absolute; display: none; background: #ff00b8; }
.mira--v { width: 1px; }
.mira--h { height: 1px; }
.mira.ativa { display: block; }

#selecao { position: fixed; inset: 0; z-index: 81; pointer-events: none; display: none; }
#selecao.ativo { display: block; }
.sel-box {
  position: absolute; border: .26vh solid var(--blue);
  box-shadow: 0 0 0 .12vh rgba(255,255,255,.9);
  pointer-events: none;
}
#selecao.multi .sel-box { border-style: dashed; border-color: var(--purple); }
.alca {
  position: absolute; width: 2.2vh; height: 2.2vh; margin: -1.1vh 0 0 -1.1vh;
  background: #fff; border: .26vh solid var(--blue); border-radius: .5vh;
  pointer-events: auto; box-shadow: var(--shadow-sm);
  transition: transform var(--t-toque) var(--mov-padrao), background var(--t-toque) var(--mov-padrao);
}
.alca:hover { transform: scale(1.25); background: var(--blue); }
.alca--rot { border-radius: 50%; border-color: var(--green-dp); cursor: grab; }
.alca--rot::after {
  content: ''; position: absolute; left: 50%; top: 100%; width: .2vh; height: 2vh;
  background: var(--green-dp); transform: translateX(-50%);
}
/* Canto redondo, lado comprido.

   A forma diz o que a alca faz antes de qualquer cursor aparecer: o
   circulo mexe nos dois eixos, a pilulinha deitada mexe so na
   largura, a em pe so na altura. Com oito alcas em volta de uma peca
   pequena, distinguir pelo formato e mais rapido que ler a posicao. */
.alca--e, .alca--w { cursor: ew-resize; width: 1.1vh; height: 2.6vh; margin: -1.3vh 0 0 -.55vh; border-radius: .55vh; }
.alca--n, .alca--s { cursor: ns-resize; width: 2.6vh; height: 1.1vh; margin: -.55vh 0 0 -1.3vh; border-radius: .55vh; }
.alca--nw, .alca--ne, .alca--sw, .alca--se { border-radius: 50%; }
.alca--nw, .alca--se { cursor: nwse-resize; }
.alca--ne, .alca--sw { cursor: nesw-resize; }
/* O canto de baixo-direita continua vermelho: e a alca que estava
   sozinha ali antes, e a mao ja sabe onde ela fica. */
.alca--se { border-color: var(--red); }
.alca--se:hover { background: var(--red); }
.panel > .sel { outline: none !important; }

/* ==========================================================
   7. Objetos inseridos
   ========================================================== */
.obj {
  position: absolute; z-index: 30; transform-origin: center;
  font-family: 'Outfit', sans-serif;
}

/* O grupo e uma caixa que so existe para conter. Sem fundo, sem
   borda e sem recorte: quem tem de aparecer sao as pecas de dentro, e
   um `overflow: hidden` aqui cortaria a sombra e o sangramento que
   elas ja tinham antes de entrar.

   `pointer-events` fica no padrao: o clique atravessa o vazio dele
   porque nao ha nada pintado ali, e acerta a peca quando ha. Quem
   decide se o alvo e o grupo ou a peca e a cadeia de selecao, e nao o
   CSS. */
.obj--grupo { background: none; border: 0; overflow: visible; }
/* Aqui o estouro FICA. Um objeto caindo no mural e o unico momento
   fisico do site: ele pousa, passa um fio do lugar e assenta, como
   uma peca largada na mesa. Nos menus a mesma curva vira tique
   nervoso, repetido dezenas de vezes por sessao; aqui acontece uma vez
   por objeto e e o que da peso ao gesto. */
.obj--entrando { animation: objEntra var(--t-cartao) var(--mov-estouro); }
@keyframes objEntra { from { opacity: 0; } to { opacity: 1; } }
/* A BARRA DE ROLAGEM SAI DE VISTA, A ROLAGEM FICA.

   O texto que nao cabe na peca continua rolando — o que sai e o
   trilho cinza desenhado por cima do papel, que nao e parte do
   post-it e ainda come largura da linha. E o mesmo tratamento que o
   proprio mural ja usa no `#board`. */
.obj .txt { outline: none; cursor: text; min-height: 1em; scrollbar-width: none; }
.obj .txt::-webkit-scrollbar { width: 0; height: 0; }
.obj .txt[contenteditable="true"] {
  box-shadow: 0 0 0 .26vh var(--blue); border-radius: .5vh; background: rgba(255,255,255,.7);
}
.obj .txt:empty::before { content: attr(data-ph); opacity: .45; }
.obj .txt--linha { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* post-it */
.obj--postit {
  background: var(--yellow); padding: 16px 16px 20px;
  box-shadow: var(--shadow-md);
  font-family: 'Caveat', cursive; font-size: 24px; line-height: 1.24; color: #2b2410;
}
/* A DOBRA DO PAPEL (#172): "corrija a arte da pontinha do post-it". O
   canto de baixo à direita é cortado na diagonal — o papel de cada post-it
   é pintado por um degradê que deixa a ponta transparente (ver
   `.jan--postit` e `.postit-f--retangular`), e a sombra da caixa continua —
   e, no lugar, fica a aba: um triângulo do mesmo papel (`--papel`), um
   tom mais escuro, com o ângulo reto para dentro. */
.obj-dobra {
  position: absolute; right: 0; bottom: 0;
  width: var(--dobra, 34px); height: var(--dobra, 34px);
  background: var(--papel, var(--amarelo-papel));
  filter: brightness(.86) saturate(1.08);
  clip-path: polygon(0 0, 100% 0, 0 100%);
  pointer-events: none;
}

/* polaroid */
.obj--polaroid { background: #fff; padding: 10px 10px 8px; box-shadow: var(--shadow-lg); }
.obj--polaroid .midia {
  height: 150px; background: #f2f5f9; border-radius: 3px; overflow: hidden;
  display: grid; place-items: center; font-size: 11px; color: #8b98a9; text-align: center; padding: 8px;
}
.obj--polaroid .midia:not(.tem-midia)::after { content: attr(data-ph); }
.obj--polaroid .txt { font-family: 'Caveat', cursive; font-size: 20px; text-align: center; padding: 6px 2px 2px; color: #3a3f4a; }

/* midia generica */
.midia { position: relative; overflow: hidden; }
.midia img, .midia video, .midia iframe {
  width: 100%; height: 100%; object-fit: cover; display: block; border: 0;
}
.obj--imagem .midia { border-radius: 6px; overflow: hidden; box-shadow: var(--shadow-md); }
.obj--imagem .midia img { height: auto; }
/* E QUEM TEM ALFA NAO TEM MOLDURA. A sombra e o canto sao
   tracados no retangulo da imagem, entao num recorte eles
   desenham a caixa — que e justamente o que o recorte nao tem.
   Mesma ideia da figurinha logo abaixo; muda so quem descobre
   que a imagem e recorte, que ali e o tipo da peca e aqui e o
   proprio arquivo. */
.obj--imagem[data-vazado] .midia { border-radius: 0; box-shadow: none; }
/* Figurinha e recorte puro: sem moldura, sem fundo, sem cantos
   arredondados. So a sombra acompanhando o desenho. */
/* Figurinha e recorte puro: sem moldura, sem fundo, sem cantos
   arredondados. So a sombra acompanhando o desenho. */
.obj--figurinha .midia {
  border: 0; border-radius: 0; background: none; overflow: visible;
  box-shadow: none;
  filter: drop-shadow(0 6px 10px rgba(0,0,0,.28));
}
/* MAS A SOMBRA NAO ACOMPANHAVA O DESENHO NUM GIF.

   `drop-shadow` deveria seguir o alfa, e e por isso que ela esta
   ali em vez de um `box-shadow`. MEDIDO num recorte redondo: a
   sombra sai RETANGULAR, do tamanho da caixa da peca — "problema
   com fundo transparente no GIF importado".

   Quando a peca ja se sabe vazada — e ela se sabe, a mesma marca que
   tira a moldura da imagem recortada —, a sombra sai inteira. Entre
   uma sombra que desenha uma caixa que nao existe e nenhuma sombra,
   nenhuma e o que se pediu nas duas vezes. */
.obj--figurinha[data-vazado] .midia { filter: none; }
.obj--figurinha .midia img { height: auto; border-radius: 0; }

/* ---------- os quatro (+) da caixinha de tarefa ----------
   Mesmo desenho do (+) do mapa mental, e pelo mesmo motivo: ele cria a
   vizinha no eixo exato. A cor vem do proprio objeto, para os botoes
   nao brigarem com a caixinha que os mostra. */
.check-mais {
  position: absolute;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--cor-check, #1fbf6b); color: #fff;
  font-size: 15px; font-weight: 800; line-height: 1;
  display: grid; place-items: center; cursor: pointer; border: 0; padding: 0;
  box-shadow: 0 3px 7px rgba(20,22,26,.28);
  /* ESCONDIDO E ESCONDIDO, inclusive para o ponteiro.

     `opacity: 0` apaga o botao mas nao o tira do caminho: os quatro
     continuavam sendo alvo de clique, e como eles se projetam 11px
     para fora da caixinha, havia uma moldura invisivel em volta dela
     que engolia o clique. Clicar rente a borda para SAIR da selecao
     acertava um (+) — a selecao nao saia e ainda nascia uma caixinha
     que ninguem pediu.

     Voltam a receber o ponteiro junto com a opacidade, na mesma
     regra: assim as duas coisas nunca discordam. */
  opacity: 0; pointer-events: none;
  transition: opacity var(--t-botao) var(--mov-padrao),
              transform var(--t-botao) var(--mov-padrao);
}
.check-mais--cima, .check-mais--baixo { left: 50%; margin-left: -11px; }
.check-mais--cima  { top: -11px; }
.check-mais--baixo { bottom: -11px; }
.check-mais--esquerda, .check-mais--direita { top: 50%; margin-top: -11px; }
.check-mais--esquerda { left: -11px; }
.check-mais--direita  { right: -11px; }
.obj--check:hover .check-mais,
.obj--check:focus-within .check-mais { opacity: 1; pointer-events: auto; }
.check-mais:hover { transform: scale(1.15); }

/* ---------- travado ainda deixa marcar a tarefa ----------
   O cadeado congela o mural: `.obj[data-travado]` perde os eventos de
   ponteiro inteiros, e com eles ia tambem o unico gesto que uma lista
   de tarefas existe para receber. Marcar uma tarefa nao muda o
   desenho de lugar nem reescreve nada — e o que se faz COM o mural
   pronto, e nao nele.

   So a caixinha volta a responder. O texto continua trancado, porque
   `contenteditable` aceita digitacao sem passar por selecao nenhuma.

   E os (+) somem: com a caixinha clicavel o `:hover` do objeto volta a
   valer, e eles reapareceriam sem poder fazer nada — um botao visivel
   que nao funciona mente mais do que um ausente. */
.obj--check[data-travado] .obj-check__box { pointer-events: auto; }

/* O CADEADO TRANCA A PEÇA, E NÃO O TEXTO DELA.

   Mesmo caso da caixinha de tarefas, e pelo mesmo motivo: o cadeado
   existe para o mural parar de se mexer enquanto se desenha por cima,
   e não para emudecer o que está escrito. Travado, o box continua
   travado — não seleciona, não arrasta, não redimensiona —, e o duplo
   clique no texto abre a edição como sempre.

   `user-select: text` vem junto porque o `.obj[data-travado]` também
   proíbe selecionar, e sem poder selecionar não há como escrever no
   meio de uma frase. */
/* Só o cadeado GERAL deixa o texto vivo. A peça presa não: ali o
   pedido é justamente o contrário — "como se ele não tivesse ali" —,
   e um parágrafo que ainda pega o clique fura o buraco por onde o
   arrasto deveria passar. */
.obj[data-travado]:not([data-preso]) .txt { pointer-events: auto; user-select: text; }
.obj--check[data-travado] .check-mais { display: none; }

/* ==========================================================
   JANELAS E PAPÉIS
   ==========================================================
   Quinze molduras em volta do mesmo par de textos. O que muda de uma
   para outra é só a casca: a peça, o texto editável e a medida são as
   mesmas em todas.

   O CORPO ROLA E QUEBRA em todas, porque em todas ele é o mesmo
   `.jan-corpo`. Sem isso, escrever demais numa delas derramaria o
   texto para fora da moldura — e cada estilo precisaria da sua regra
   para o mesmo problema. */
.obj--janela {
  display: flex; flex-direction: column; overflow: hidden;
  border-radius: 10px; background: #fff;
  box-shadow: 0 14px 40px rgba(20,22,26,.22);
}
/* ---------- A BARRA DA JANELA NAO SE PINTA ----------
   A cor chegou a valer para as quatro molduras, e visto na tela
   ficou claro que nao era isso: o editor de codigo com a barra das
   abas vermelha e a janela do Mac com o topo colorido deixam de
   parecer o que sao. A graca delas e imitar um programa de verdade,
   e num programa de verdade essa barra nao se pinta. Quem pinta e o
   Lembrete, que e papel — e papel existe em cores. */
.jan-topo {
  flex: none; display: flex; align-items: center; gap: 10px;
  padding: 0 14px; height: 40px;
  background: #3a3a3c; color: #fff;
}
.jan-titulo {
  font-family: Outfit, sans-serif; font-weight: 800; font-size: 15px;
  letter-spacing: .01em;
}
.jan-corpo {
  flex: 1; min-height: 0; overflow: auto; padding: 18px 22px;
  font-family: Outfit, sans-serif; font-size: 17px; line-height: 1.5;
  color: #14161a; white-space: pre-wrap; overflow-wrap: anywhere;
}
.jan-corpo--colado { padding: 0; background: none; }
.jan-recheio { flex: 1; min-height: 0; display: flex; overflow: hidden; }
.jan-recheio > .jan-corpo { flex: 1; }

/* As três luzes são desenho pintado, e não emoji: emoji muda de cara
   em cada sistema, e aqui a graça é parecer com a janela que todo
   mundo reconhece. */
.jan-luzes { display: flex; gap: 7px; flex: none; }
.jan-luzes i { width: 12px; height: 12px; border-radius: 50%; display: block; }
.jan-luzes i:nth-child(1) { background: #ff5f57; }
.jan-luzes i:nth-child(2) { background: #febc2e; }
.jan-luzes i:nth-child(3) { background: #28c840; }
.jan-botoes { margin-left: auto; display: flex; gap: 14px; font-size: 13px; opacity: .85; }
.jan-botoes i { font-style: normal; }

/* ---------- Mac ---------- */
.jan--mac .jan-topo { justify-content: space-between; }
.jan--mac .jan-titulo { margin-left: auto; }

/* ---------- Bloco de notas ---------- */
.jan--notepad { border-radius: 4px; }
.jan-topo--notepad { background: #f0f0f0; color: #1a1a1a; height: 34px; border-bottom: 1px solid #d6d6d6; }
.jan-menus {
  flex: none; display: flex; gap: 16px; padding: 4px 12px;
  background: #f7f7f7; border-bottom: 1px solid #e2e2e2;
  font-family: Outfit, sans-serif; font-size: 13px; color: #3a3a3a;
}
.jan--notepad .jan-corpo { font-family: Consolas, 'Courier New', monospace; font-size: 15px; }

/* ---------- Lembrete ---------- */
.jan--postit {
  /* A UNICA JANELA QUE SE PINTA. Papel existe em cores, e escolher a
     cor de um post-it e o gesto mais natural que ha. O amarelo de
     fabrica continua sendo um degrade; a cor escolhida entra
     chapada, e a tinta acompanha pela conta de luminancia — papel
     azul-marinho com letra marrom nao se le. */
  --papel: var(--cor-obj, var(--amarelo-papel));
  --dobra: 38px;
  /* O CANTO E CORTADO DE VERDADE, com `clip-path`, e nao pintado de
     transparente — ver o porque inteiro no `.postit-f--retangular`.
     A sombra vira `drop-shadow` para seguir a silhueta cortada.

     O CORTE MORA NO PAPEL, E NAO NA PECA (#279). `clip-path` corta tudo
     o que a peca desenha, inclusive o `filter` dela — e a luz de
     recorte e um `drop-shadow` que acende do lado de FORA da silhueta.
     Cortada na peca, a luz sumia ("nao funciona no post-it"), e a
     sombra de fabrica logo abaixo tambem nunca aparecia. O papel e o
     corte vao para o `::before`; a peca fica inteira, e o filtro dela
     segue a silhueta do papel sem ser cortado. */
  background: transparent;
  border-radius: 2px;
  isolation: isolate;
  box-shadow: none;
  filter: drop-shadow(0 6px 14px rgba(120,90,10,.26));
}
.jan--postit::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  border-radius: inherit; pointer-events: none;
  background: var(--papel);
  clip-path: polygon(0 0, 100% 0,
                     100% calc(100% - var(--dobra)),
                     calc(100% - var(--dobra)) 100%, 0 100%);
}
.jan--postit .jan-recheio { flex-direction: column; padding: 20px 22px; }
.jan--postit .jan-titulo {
  font-size: 22px; color: var(--tinta-obj, #2b2410); margin-bottom: 8px;
}
.jan--postit .jan-corpo {
  padding: 0; font-family: Caveat, cursive; font-size: 24px;
  color: var(--tinta-obj, #2b2410);
}

/* ---------- Terminal ---------- */
.jan--terminal { background: #12141a; }
.jan-topo--terminal { background: #23262e; height: 36px; }
.jan-topo--terminal .jan-titulo { margin-left: auto; margin-right: auto; font-size: 13px; opacity: .8; }
.jan-recheio--mono { padding: 14px 16px; gap: 10px; }
.jan-prompt { flex: none; color: #4ade80; font-family: Consolas, monospace; font-size: 15px; }
.jan--terminal .jan-corpo { color: #d7dbe3; font-family: Consolas, 'Courier New', monospace; font-size: 15px; }

/* ---------- Navegador ---------- */
.jan-topo--browser { background: #dee1e6; color: #1f2733; height: 42px; align-items: flex-end; padding-bottom: 0; }
.jan-aba {
  background: #fff; border-radius: 9px 9px 0 0; padding: 7px 18px;
  font-family: Outfit, sans-serif; font-weight: 700; font-size: 13px; color: #1f2733;
}
.jan-url {
  flex: none; display: flex; align-items: center; gap: 12px;
  padding: 8px 14px; background: #fff; border-bottom: 1px solid #e3e6ea;
}
.jan-url__bolas { display: flex; gap: 8px; }
.jan-url__bolas i { width: 8px; height: 8px; border-radius: 50%; background: #c3c8d0; display: block; }
.jan-url .jan-titulo {
  flex: 1; background: #f1f3f4; border-radius: 999px; padding: 6px 14px;
  font-weight: 600; font-size: 13px; color: #3c4043;
}

/* ---------- Editor de código ---------- */
.jan--codigo { background: #1e1f29; }
.jan-topo--codigo { background: #16171f; height: 38px; padding: 0; align-items: stretch; }
.jan-aba--viva {
  display: flex; align-items: center; background: #1e1f29; border-radius: 0;
  border-top: 2px solid #7c8cff; color: #cfd3e3;
}
.jan--codigo .jan-titulo { font-family: Consolas, monospace; font-weight: 600; font-size: 13px; }
.jan-linhas {
  flex: none; color: #4b5068; font-family: Consolas, monospace; font-size: 15px;
  line-height: 1.5; text-align: right; white-space: pre; user-select: none;
}
.jan--codigo .jan-corpo { color: #e6e8f2; font-family: Consolas, monospace; font-size: 15px; }

/* ---------- Folha de papel ---------- */
.jan--folha { border-radius: 2px; box-shadow: 0 18px 50px rgba(20,22,26,.2); }
.jan-recheio--folha { flex-direction: column; padding: 56px 60px; }
.jan--folha .jan-titulo { font-size: 26px; color: #14161a; margin-bottom: 14px; }
.jan--folha .jan-corpo { padding: 0; }

/* ---------- Caderno e ficha ----------
   A pauta é um gradiente repetido, e não linhas desenhadas uma a uma:
   assim ela acompanha qualquer altura sem ninguém contar quantas
   cabem. */
.jan--caderno { background: #fffdf5; border-radius: 4px; }
.jan-espiral {
  position: absolute; left: 0; top: 0; bottom: 0; width: 34px;
  background: repeating-linear-gradient(#0000 0 14px, #c7ccd4 14px 20px, #0000 20px 34px);
  border-right: 2px solid #f0b8b8;
}
.jan-recheio--pautado {
  flex-direction: column; padding: 26px 30px 26px 58px;
  background: repeating-linear-gradient(#0000 0 31px, #dbe6f2 31px 32px);
  background-position: 0 26px;
}
.jan--caderno .jan-titulo, .jan--ficha .jan-titulo { font-size: 20px; color: #2b3442; margin-bottom: 6px; }
.jan--caderno .jan-corpo, .jan--ficha .jan-corpo {
  padding: 0; font-family: Caveat, cursive; font-size: 24px; line-height: 32px; color: #22304a;
}
.jan--ficha { background: #fffefa; border-radius: 3px; border: 1px solid #e6e0cf; }
.jan-recheio--ficha { padding: 18px 20px; }
.jan--ficha .jan-titulo { border-bottom: 2px solid #f0a8a8; padding-bottom: 4px; }

/* ---------- Conversa ---------- */
.jan--chat { background: #eef1f6; }
.jan-recheio--chat { flex-direction: column; gap: 10px; padding: 18px; justify-content: flex-end; }
.jan-balao {
  max-width: 78%; padding: 12px 16px; border-radius: 18px;
  font-family: Outfit, sans-serif; font-size: 16px; line-height: 1.4;
}
.jan-balao--outro { align-self: flex-start; background: #fff; color: #14161a; border-bottom-left-radius: 5px; }
.jan-balao--eu { align-self: flex-end; background: var(--primaria); color: #fff; border-bottom-right-radius: 5px; }
.jan--chat .jan-titulo { font-weight: 600; font-size: 16px; color: inherit; }
.jan--chat .jan-corpo { color: inherit; font-size: 16px; }

/* ---------- E-mail ---------- */
.jan-topo--email { background: #fff; color: #14161a; border-bottom: 1px solid #e3e6ea; height: 48px; }
.jan-topo--email .jan-titulo { font-size: 19px; }
.jan-campos {
  flex: none; display: flex; flex-direction: column; gap: 2px;
  padding: 10px 14px; background: #fafbfc; border-bottom: 1px solid #e8ebef;
  font-family: Outfit, sans-serif; font-size: 13px; color: #5a6472;
}
.jan-campos b { color: #98a2b0; font-weight: 700; margin-right: 8px; }

/* ---------- Máquina de escrever ---------- */
.jan--datilografo { background: #f7f3e8; border-radius: 1px; }
.jan-recheio--datilo { flex-direction: column; padding: 54px 58px; }
.jan--datilografo .jan-titulo,
.jan--datilografo .jan-corpo {
  font-family: 'Courier New', Courier, monospace; color: #2a2620;
}
.jan--datilografo .jan-titulo { font-size: 18px; letter-spacing: .14em; margin-bottom: 20px; }
.jan--datilografo .jan-corpo { padding: 0; font-size: 17px; line-height: 1.9; }

/* ---------- Windows 95 ----------
   As bordas 3D são duas sombras internas, e não quatro bordas: com
   bordas de cor diferente por lado, os cantos saem em bisel e o
   desenho perde o ar de caixa levantada. */
.jan--win95 {
  background: #c0c0c0; border-radius: 0;
  box-shadow: inset 2px 2px 0 #fff, inset -2px -2px 0 #4a4a4a, 4px 4px 0 rgba(0,0,0,.35);
  padding: 3px;
}
.jan-topo--win95 {
  background: linear-gradient(90deg, #000080, #1084d0); height: 26px;
  padding: 0 4px 0 6px;
}
.jan-topo--win95 .jan-titulo { font-family: Outfit, sans-serif; font-size: 13px; }
.jan-botoes--win95 { gap: 3px; }
.jan-botoes--win95 i {
  width: 18px; height: 18px; display: grid; place-items: center; font-size: 11px;
  background: #c0c0c0; color: #000;
  box-shadow: inset 1px 1px 0 #fff, inset -1px -1px 0 #4a4a4a;
}
.jan-menus--win95 { background: #c0c0c0; border: 0; padding: 3px 6px; font-size: 12px; color: #000; }
.jan-recheio--afundado {
  margin: 0 3px 3px; background: #fff;
  box-shadow: inset 2px 2px 0 #4a4a4a, inset -2px -2px 0 #fff;
  padding: 8px;
}
.jan--win95 .jan-corpo { font-family: 'MS Sans Serif', Tahoma, sans-serif; font-size: 14px; }

/* ---------- Pixel ---------- */
.jan--pixel {
  background: #f4f4f4; border-radius: 0;
  box-shadow: 0 0 0 4px #14161a, 8px 8px 0 #14161a;
  image-rendering: pixelated;
}
.jan-topo--pixel {
  background: #14161a; height: 34px; justify-content: center;
  box-shadow: inset 0 -4px 0 #3a3f4a;
}
.jan--pixel .jan-titulo { font-size: 14px; letter-spacing: .2em; }
.jan-recheio--pixel { padding: 16px; }
.jan--pixel .jan-corpo { font-size: 16px; line-height: 1.6; }

/* ---------- Vidro ----------
   O `backdrop-filter` desfoca o que está ATRÁS da peça, e não ela: é
   isso que faz o mural aparecer embaçado por dentro dela, que é o que
   distingue vidro de um branco translúcido. */
.jan--vidro {
  background: rgba(255,255,255,.42);
  backdrop-filter: blur(18px) saturate(1.4);
  -webkit-backdrop-filter: blur(18px) saturate(1.4);
  border: 1px solid rgba(255,255,255,.7);
  border-radius: 18px;
  box-shadow: 0 20px 60px rgba(20,22,26,.22), inset 0 1px 0 rgba(255,255,255,.9);
}
.jan-topo--vidro {
  background: rgba(255,255,255,.35); color: #14161a;
  border-bottom: 1px solid rgba(255,255,255,.6);
}
.jan-topo--vidro .jan-titulo { margin-left: auto; }
.jan--vidro .jan-corpo { color: #1b2230; }

/* ---------- a galeria do menu ---------- */
.jan-galeria {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: .6vh;
  margin-bottom: 1.2vh; max-height: 44vh; overflow-y: auto;
}
.jan-galeria button {
  display: block; width: 100%; min-width: 0; cursor: pointer;
  padding: .5vh .4vh .4vh; border-radius: .9vh;
  border: .1vh solid var(--borda); background: #fff;
}
.jan-galeria button:hover { border-color: var(--primaria-tinta); background: #f5f9ff; }
/* O nome da janela na GALERIA e interface, e nao a janela: ele vai na
   tinta do tema. O titulo de dentro da janela de verdade continua
   escuro, porque aquela peca tem papel branco proprio. */
.jan-galeria .jan-nome {
  display: block; font-style: normal; font-size: max(1.1vh, 8.8px);
  font-weight: 700; color: var(--ink); text-align: center; margin-top: .3vh;
}
/* A peca tem a largura do mural e, se contasse para o layout,
   esticaria a grade ate estourar o menu. Ancorada no meio e puxada
   meio corpo para tras, ela fica centrada em qualquer escala. */
.jan-mini {
  position: relative; display: block; width: 100%; height: 6.4vh;
  overflow: hidden; border-radius: .5vh; background: #f5f7fb;
}
.jan-mini__palco {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%); transform-origin: center center;
  pointer-events: none;
}
/* Dentro da miniatura e da previa a peca e retrato: nao e objeto do
   mural, entao nada do que a faz arrastavel vale ali.

   O PAPEL ENTROU NA MESMA REGRA quando a galeria virou uma so. Ele
   ficou de fora um tempo e o efeito era discreto o bastante para
   passar: absoluto dentro do palco, o retrato se ancorava no canto
   em vez do meio, e o coracao e o marca-paginas saiam deslocados na
   pastilha enquanto as quatro molduras ficavam centradas. */
.jan-mini .obj--janela, .previa-colar .obj--janela,
.jan-mini .obj--postit, .previa-colar .obj--postit {
  position: static; transform: none; cursor: default;
}
.previa-encaixe--jan { width: 13vh; height: 9vh; background: none; border: 0; }

/* pins */
.obj--pin { z-index: 45; }
/* Sem `drop-shadow`: a sombra preta com opacidade saiu dos marcadores
   a pedido. Ela tentava fingir que a peca estava pousada sobre o
   mural, e o que entregava era uma mancha cinza embaixo de cada
   desenho — junto com as elipses que cada simbolo trazia no pe, e que
   sairam pelo mesmo motivo. O vetor fica chapado, que e o desenho que
   ele e.

   Elas voltaram uma vez, quando os pins ganharam relevo, e sairam de
   novo pelo mesmo motivo — e agora ha um segundo: QUEM FAZ SOMBRA E A
   LAMPADA. Sombra desenhada dentro do vetor aponta sempre para o
   mesmo lado, entao ela brigava com a que a luz do mural projeta, e
   as duas juntas diziam que havia dois sois. Sem lampada acesa nao ha
   sombra nenhuma, que e o certo: a peca e um desenho, e nao uma
   fotografia. */
.obj--pin svg { width: 100%; height: auto; }
/* O CLIPE SOLTO E O PRESO (#147): os dois desenhos no mesmo svg, e
   prender é cruzar a opacidade de um para o outro. O clipe de antes desta
   versão tem um desenho só, sem classe, e continua aparecendo. */
.clipe__solto, .clipe__preso { transition: opacity .22s ease; }
.clipe__preso { opacity: 0; }
.obj--pin-clipe[data-clipado] .clipe__solto { opacity: 0; }
.obj--pin-clipe[data-clipado] .clipe__preso { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .clipe__solto, .clipe__preso { transition: none; } }
/* O PIN DE AGULHA FINCADO (#148): tachinha, alfinete e bandeira levam o
   desenho inteiro e o fincado, com a agulha cortada onde entra no papel e
   o furo na entrada. Grudar numa peça é cruzar um para o outro, enquanto
   o pin assenta. O de antes desta versão tem um desenho só e ganha o
   segundo quando gruda pela primeira vez. */
.pin__solto, .pin__fincado { transition: opacity .2s ease; }
.pin__fincado { opacity: 0; }
.obj--pin[data-grudado] .pin__solto { opacity: 0; }
.obj--pin[data-grudado] .pin__fincado { opacity: 1; }

/* ---------- O PIN NA MAO SAI INTEIRO (#252) ----------

   "Ao retirar o pin que estava fixado no objeto ele permanece como se
   tivesse fincado, faca a animacao dele saindo inteiro ao arrastar e
   fincar so quando soltar."

   Quem poe e tira o `data-grudado` e o `grudarPin`, e ele so roda
   QUANDO O ARRASTE TERMINA (`N.ao('soltou')`). Ate la o pin viajava
   pela tela com a agulha cortada, como se ainda estivesse enfiado em
   alguma coisa.

   APAGAR O `data-grudado` NO COMECO DO ARRASTE NAO SERVE: duas
   decisoes do `grudarPin` leem esse mesmo estado — se a peca dona
   veio junto (e entao o pin nao assenta de novo) e se a mudanca entra
   no historico. O estado tem de continuar; o que muda e so o desenho.

   E NENHUMA MARCA NOVA, de proposito. Uma marca posta no inicio do
   arraste vazaria: o `soltou` so e emitido para quem ANDOU, entao um
   clique sem mover deixaria o pin parecendo solto para sempre — pior
   que o defeito que se veio consertar. `body.mexendo` ja existe e o
   nucleo sempre a tira no `pointerup`; `.sel` ja marca o que esta
   selecionado. Um pin grudado e selecionado enquanto algo e mexido e
   exatamente "o pin que esta na mao da pessoa".

   A transicao de opacidade la em cima e quem faz a animacao: o
   desenho cortado cruza para o inteiro em 200ms.

   O CASO DE CANTO, DITO NA FRENTE: selecionando o pin E a peca dona
   juntos, o pin tambem sai inteiro durante o movimento, embora nao
   esteja saindo de lugar nenhum. Separar esse caso pediria perguntar
   quem e o dono no inicio de cada arraste e guardar a resposta — o
   estado que esta regra evita. Sao 200ms, e a leitura continua de pe:
   enquanto a pessoa mexe nele, ele esta na mao dela. */
body.mexendo .obj--pin.sel[data-grudado] .pin__solto { opacity: 1; }
body.mexendo .obj--pin.sel[data-grudado] .pin__fincado { opacity: 0; }

/* O CLIPE PELO MESMO MOTIVO: preso, ele se encaixa na borda da peca,
   e arrastado ele volta a ser um clipe aberto na mao. */
body.mexendo .obj--pin-clipe.sel[data-clipado] .clipe__solto { opacity: 1; }
body.mexendo .obj--pin-clipe.sel[data-clipado] .clipe__preso { opacity: 0; }

@media (prefers-reduced-motion: reduce) { .pin__solto, .pin__fincado { transition: none; } }

/* formas */
.obj--shape { width: 180px; height: 180px; }
/* CANTO RETO de saida. A forma nascia com 10px de arredondamento, e
   quem quisesse o canto vivo tinha de ir tira-lo — o contrario do
   esperado, ja que retangulo e retangulo. Arredondar continua a um
   clique, na ferramenta de cantos, que escreve `data-raio` e vence
   esta regra. */
.obj--shape .shape-corpo, .obj--shape .midia {
  position: absolute; inset: 0; border-radius: 0; overflow: hidden;
}
.obj--shape .midia { background: none; }
/* O TEXTO ENTRA NA LISTA, como nas outras treze.

   Estas tres sao as formas mais antigas, e nasceram antes de a forma
   poder ter texto por cima. As outras treze moram juntas no clean.css
   e recortam as TRES camadas — corpo, midia e texto —; estas
   recortavam duas, e o texto ficava com o retangulo inteiro.

   Numa forma vazia ninguem via. Numa forma com foto e texto, que e
   como uma imagem do menu inserir chega, trocar para circulo,
   triangulo ou losango recortava a foto e deixava o texto cobrindo o
   retangulo todo por cima — parecia que a troca nao tinha acontecido. */
.shape--circulo .shape-corpo, .shape--circulo .midia, .shape--circulo .shape-texto {
  border-radius: 50%;
}
.shape--triangulo .shape-corpo, .shape--triangulo .midia, .shape--triangulo .shape-texto {
  clip-path: polygon(50% 0%, 100% 100%, 0% 100%); border-radius: 0;
}
.shape--losango .shape-corpo, .shape--losango .midia, .shape--losango .shape-texto {
  clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); border-radius: 0;
}

/* A barra: a largura vale quando ela esta de pe, a altura quando esta
   deitada. Uma regra por lado, e o `order` diz se ela vem antes ou
   depois do resto. */
/* O RETRATO E REDONDO E SE ARRASTA.

   O quadro tem tamanho fixo e `overflow: hidden`; quem se move e a
   imagem dentro dele, pelo `object-position`. Assim arrastar muda o
   ENQUADRAMENTO e nao o lugar do quadro — que e o que se quer de uma
   foto de perfil: a cara no meio do circulo. */
/* ---------- desenho da pena vetorial ----------
   As tres camadas da forma, como nas outras: o preenchimento embaixo,
   a midia no meio e o contorno por cima. O recorte e um
   clip-path: polygon() em PORCENTAGEM, e por isso a peca se estica
   pelas alcas sem ninguem recalcular a lista de pontos. */
.obj--vetor { width: 240px; height: 180px; }
.obj--vetor > .shape-corpo, .obj--vetor > .midia {
  position: absolute; inset: 0; overflow: hidden; background: none;
}
/* O contorno nao recebe ponteiro: quem se pega e a peca, e uma linha
   de 6px seria a unica parte agarravel de um desenho vazio. */
.vetor-linha {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none; overflow: visible;
}

/* O rascunho da pena vive por cima da tela inteira, fora do #board:
   assim a gravacao isolada nao o filma — ele e andaime de quem
   desenha, e nao parte do mural. */
.pena-rascunho {
  position: fixed; inset: 0; width: 100vw; height: 100vh;
  pointer-events: none; z-index: 120;
}
body.com-pena #board { cursor: crosshair; }

/* ---------- pontos de luz ----------
   A lampada e andaime: ela nao sai no arquivo, so a luz que ela faz.
   O halo em volta e o que diz de longe ate onde ela alcanca. */
.obj--luz {
  width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--cor-obj, #ffe9b0);
  box-shadow: 0 0 0 3px rgba(255,255,255,.7), 0 0 26px 6px var(--cor-obj, #ffe9b0);
}
.luz-bulbo { width: 26px; height: 26px; color: #6b5a1f; }
.luz-halo { position: absolute; inset: -10px; border-radius: 50%;
  border: 2px dashed color-mix(in srgb, var(--cor-obj, #ffe9b0) 70%, transparent);
  opacity: 0; transition: opacity var(--t-botao) var(--mov-padrao); }
.obj--luz:hover .luz-halo, .obj--luz.sel .luz-halo { opacity: 1; }
/* O RAIO DA CÂMERA (#342): a lâmpada que acende ou apaga quando a câmera
   passa troca só se o caminho entre os pontos cruzar este anel. Como o
   anel do ponto que revela, só aparece com ela na mão, que é quando a
   pessoa está regulando. O azul é o dos pontos de câmera: é deles que o
   anel fala, e não da luz. */
.obj--luz[data-camera].sel::after {
  content: ''; position: absolute; left: 50%; top: 50%;
  width: calc(var(--raio-camera, 300px) * 2); height: calc(var(--raio-camera, 300px) * 2);
  margin: calc(var(--raio-camera, 300px) * -1) 0 0 calc(var(--raio-camera, 300px) * -1);
  /* a linha tem a mesma grossura na tela em qualquer zoom: a 30% os
     2 px do palco viravam um fio de 0,6 px que mal se via */
  border: calc(2px / var(--zoom, 1)) dashed rgba(37,99,235,.7); border-radius: 50%;
  pointer-events: none;
}
/* APAGADA PELO ATALHO A (#190): a lâmpada continua no lugar, mais fraca,
   para quem está editando saber que ela existe e está desligada. */
body.lampadas-apagadas .obj--luz { background: #c9ccd2; box-shadow: 0 0 0 3px rgba(255,255,255,.7); }
body.lampadas-apagadas .luz-bulbo { color: #6b7280; }
/* ESCONDIDO, MAS AINDA MEDÍVEL. Estas peças somem da gravação, do
   ensaio e da exportação porque são andaime — mas `display: none`
   apaga a CAIXA junto com o desenho, e a posição delas é lida do
   retângulo na tela.

   O estrago era grande e só aparecia gravando: com a caixa em zero,
   `getBoundingClientRect` devolvia o canto, e as duas miras que valem
   5447,5447 e 6347,5747 viravam as duas 5120,5120. A câmera voava
   sempre para o mesmo lugar errado, longe das páginas, e ao parar a
   gravação a tela ficava preta — não havia nada ali para ver.

   `visibility: hidden` tira a tinta e deixa a caixa: some do vídeo do
   mesmo jeito, e continua sabendo onde está. */
body.gravando .obj--luz, body.ensaiando .obj--luz { visibility: hidden; }

/* O AVISO DO PROJETO DE TESTE (#167): um cartão na primeira página, sobre
   o título, nas medidas da página (o zoom do mural vale para ele). Por
   cima das peças, e fora do filme e do ensaio, como a lâmpada. */
/* UMA LINHA SÓ (#376): a pílula clara acima do título, e não mais o
   cartão escuro de três linhas por cima dele. O botão de criar conta é
   o vermelho da ação principal (#373); o × continua fechando. */
.aviso-teste {
  position: absolute; z-index: 9000; box-sizing: border-box;
  display: flex; align-items: center; gap: 14px;
  padding: 10px 12px 10px 22px; border-radius: 999px;
  background: #fff; color: #1f2733; border: 2px solid #e3e8f0;
  box-shadow: 0 10px 28px rgba(15, 18, 24, .14);
  cursor: default; white-space: nowrap;
}
.aviso-teste p {
  margin: 0;
  font: 700 22px/1.2 'Outfit', system-ui, sans-serif; text-align: left;
}
.aviso-teste__conta {
  flex: none; padding: 9px 18px; border: 0; border-radius: 999px; cursor: pointer;
  background: var(--red); color: #fff; font: 700 19px/1 'Outfit', system-ui, sans-serif;
}
.aviso-teste__conta:hover { background: var(--red-deep); }
.aviso-teste__x {
  flex: none; width: 40px; height: 40px;
  display: grid; place-items: center; padding: 0;
  border: 0; border-radius: 50%; background: #eef1f6; color: #1f2733;
  cursor: pointer;
}
.aviso-teste__x:hover { background: #e3e8f0; }
.aviso-teste__conta:focus-visible, .aviso-teste__x:focus-visible { outline: 3px solid var(--primaria-tinta); outline-offset: 3px; }
.aviso-teste__x svg { width: 20px; height: 20px; }
body.gravando .aviso-teste, body.ensaiando .aviso-teste { visibility: hidden; }

.previa-colar .luz-mini {
  width: 3.4vh; height: 3.4vh; border-radius: 50%;
  background: var(--cor-obj, #ffe9b0);
  box-shadow: 0 0 0 .25vh rgba(255,255,255,.7), 0 0 2vh .6vh var(--cor-obj, #ffe9b0);
}

/* O VEU VIVE DENTRO DO PALCO, e nao por cima da tela: assim ele rola
   e amplia junto com o mural, e a poca de luz continua sobre o mesmo
   pedaco do desenho em qualquer aproximacao.

   Ele cobre o palco inteiro, que ja e do tamanho do mural com a folga
   toda. E nao recebe ponteiro: e uma camada de aparencia, e nao um
   objeto. */
/* O VÉU É UMA TELA FIXA DO TAMANHO DA JANELA.

   Ele já foi um `div` dentro do palco, com máscaras de gradiente, e
   dois problemas o tiraram de lá. O primeiro: máscara de CSS não faz
   cone, e um facho de lanterna é um cone. O segundo veio antes — o
   véu estava num degrau fixo de `z-index`, e a altura de uma peça não
   é fixa: cada uma nasce acima da mais alta que existe, então bastava
   um segundo alfinete para ele passar POR CIMA da escuridão.

   Fixo na janela e fora do palco, os dois somem: ele não disputa
   altura com peça nenhuma, e o canvas desenha o que a máscara não
   desenhava. O preço é repintar ao rolar, que é o mesmo preço que o
   `#pen-canvas` paga há muito tempo. */
.veu-luz {
  /* ATRAS DAS PAGINAS. Ele mora no `#board` antes do `#stage`, e o
     degrau 0 o poe acima da grade do fundo e abaixo das paginas (que
     vem depois na ordem do documento). Escurece o chao e nunca a
     peca: e a peca que acende ou apaga no proprio corpo, pelo
     `--sombra-luz` abaixo. Ja esteve no degrau 80, por cima de tudo —
     e era isso que fazia a luz parecer um filtro sobre a cena. */
  position: fixed; inset: 0; z-index: 0;
  /* O TAMANHO E DITO, e nao deduzido do `inset`. Canvas e elemento
     substituido: com largura `auto` ele aparece no tamanho dos
     PIXELS dele, e eles sao a janela vezes a densidade da tela. Numa
     tela a 125%, o veu saia 25% maior que a janela, e cada poca de
     luz caia deslocada — tanto mais longe quanto mais para a direita
     e para baixo estava a lampada. */
  width: 100%; height: 100%;
  pointer-events: none;
}

/* O brilho, o recorte e a sombra de cada peca sao escritos pelo
   motor, peca a peca. Fora do modo iluminado a variavel nem existe, e
   o filtro sai do caminho. */
body.com-luz #stage .obj { filter: var(--sombra-luz, none); }
/* Com efeito de luz rodando, cada peça vira camada: o brilho que muda a
   cada quadro é refeito pela placa de vídeo (ver `luzEmMovimento`, #191). */
body.com-luz.luz-em-movimento #stage .obj { will-change: filter; }

/* ---------- marcos de camera ----------
   Bolinha colorida com o numero dentro. Ela e andaime de quem monta o
   percurso, e nao parte do mural: por isso some da gravacao e da
   exportacao, junto com o resto da interface. */
.obj--marco {
  width: 54px; height: 54px; border-radius: 50%;
  background: var(--cor-obj, #2563eb);
  display: grid; place-items: center;
  box-shadow: 0 6px 16px rgba(20,22,26,.3), 0 0 0 4px rgba(255,255,255,.85);
}
.marco-num {
  font-family: Outfit, sans-serif; font-weight: 800; font-size: 26px;
  color: #fff; line-height: 1;
}
body.gravando .obj--marco, body.ensaiando .obj--marco,
body.exportando .obj--marco { visibility: hidden; }

/* O ANDAIME FICA EM CIMA DE TODA PEÇA (#281). Ponto de câmera e lâmpada
   são de quem monta o mural, e não do mural: embaixo de uma peça, não
   há como achá-los para mexer — "o pin está indo para baixo dos
   objetos". O degrau é do CSS, e não do `z-index` escrito em cada um,
   porque assim vale também para os murais antigos, cujas peças já
   passaram do 9050 que o ponto tinha.

   E O PONTO FICA ACIMA ATÉ DA LÂMPADA (#348): "a regra é clara, os pins
   numéricos devem sempre estar por cima de tudo, nunca embaixo, sempre
   em cima!". A lâmpada ficava um degrau acima dele, e uma posta em cima
   de um ponto o escondia.

   E VALE NO MURAL INTEIRO, e não só dentro da página: a página deixou de
   ser uma camada própria (ver `.panel` em mural.css), e uma peça de
   outra página arrastada para cima desta fica embaixo do ponto também.
   Com o cadeado em "página" ou "faixa", cada página recorta o que passa
   da borda dela, e a peça de outra página nem chega a cobrir o ponto. */
#stage .obj--luz { z-index: 1000000 !important; }
#stage .obj--marco { z-index: 1000001 !important; }

/* A previa de mirar e a mesma bolinha, com o numero que ela vai ter. */
.previa-colar .marco-mini {
  width: 3.4vh; height: 3.4vh; border-radius: 50%;
  display: grid; place-items: center;
  font-family: Outfit, sans-serif; font-weight: 800;
  font-size: 1.8vh; color: #fff;
  box-shadow: 0 0 0 .25vh rgba(255,255,255,.85);
}

/* Durante o voo nada responde ao ponteiro: clicar no meio de um
   movimento de camera acertaria a peca que estava passando. */
body.em-voo #stage { pointer-events: none; }
body.em-voo #board { cursor: progress; }

/* emoji solto */
.obj--emoji { z-index: 40; }
.emo--solto { font-size: 54px; line-height: 1; display: block; animation: emoPulsa 3s ease-in-out infinite; }
/* o emoji que entrou com "Animado" desligado (#222) */
.emo--solto.emo--parado { animation: none; }

/* ==========================================================
   8. Mapa mental
   ========================================================== */
.obj--mapa { z-index: 35; }
.mapa-linhas { position: absolute; inset: 0; overflow: visible; pointer-events: none; }
.mapa-nos { position: absolute; inset: 0; }
.mapa-no {
  position: absolute; height: 46px; display: flex; align-items: center; justify-content: center;
  background: #fff; border: 2.5px solid currentColor; border-radius: 12px;
  color: #2f6bff; box-shadow: 0 4px 10px rgba(20,22,26,.10);
  font-size: 15px; font-weight: 700;
}
/* O BALAO E BRANCO NOS DOIS TEMAS, ENTAO A TINTA DELE E ESCURA NOS
   DOIS. Estava `var(--ink)`, que no escuro vira quase branco: letra
   branca em balao branco, invisivel — na previa fantasma e no mapa ja
   posto no mural. Quem fixa o fundo fixa a tinta; o tema so manda em
   quem o acompanha. */
.mapa-no .mapa-txt { color: #1b2331; padding: 0 8px; text-align: center; width: 100%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* A IDEIA CENTRAL SEGUE A COR DO MAPA.

   Aqui havia `border-color: #2f6bff` e uma sombra azul fixa — o azul
   padrão, cravado. Trocar a cor do mapa repintava os ramos e as linhas
   e deixava o balão do meio azul, sozinho no meio de tudo roxo.

   Os outros balões já acertavam porque `.mapa-no` usa
   `currentColor`, e o `desenharMapa` escreve a cor escolhida no
   `color` de cada nó. Tirando o `border-color` daqui, a raiz passa a
   usar o mesmo caminho; o que ela guarda de próprio é a borda mais
   grossa, que é o que a distingue.

   A sombra sai da mesma cor, com a transparência de antes. */
.mapa-no--raiz {
  border-width: 3px;
  box-shadow: 0 6px 16px color-mix(in srgb, currentColor 22%, transparent);
}
.mapa-no--raiz .mapa-txt { font-family: 'Archivo Black', sans-serif; font-size: 16px; }
/* A prévia de pôr o mapa: o balão de verdade, reduzido (ver
   O.previaMapa). Mora depois das regras do balão para ser lida como
   o que é — um ajuste delas para o retrato. A caixa tem a proporção
   do balão e não corta a sombra dele. */
.previa-encaixe--mapa {
  width: 14vh; height: 4.6vh; background: none; border: 0; overflow: visible;
}
.mapa-retrato { display: block; position: static; transform: none; }
.mapa-retrato .mapa-no--raiz { position: relative; }
.mapa-mais {
  position: absolute; top: 50%; width: 22px; height: 22px; margin-top: -11px;
  border-radius: 50%; background: #2f6bff; color: #fff;
  font-size: 15px; font-weight: 800; line-height: 1;
  display: grid; place-items: center; box-shadow: 0 3px 7px rgba(47,107,255,.4);
  transition: transform var(--t-botao) var(--mov-padrao), background var(--t-botao) var(--mov-padrao);
}
.mapa-mais--dir { right: -11px; }
.mapa-mais--esq { left: -11px; }
.mapa-mais:hover { transform: scale(1.25); background: #14161a; }

/* ==========================================================
   11. Audio
   ========================================================== */
.obj--audio { background: #fff; border: 2.5px solid var(--ink); border-radius: 16px; padding: 12px; box-shadow: 5px 5px 0 var(--ink); }
.audio-topo { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.audio-ico { font-size: 20px; }
.audio-nome { font-weight: 800; font-size: 14px; flex: 1; }
.obj--audio audio { width: 100%; height: 34px; }
.audio-vazio { font-size: 13px; color: var(--red); font-weight: 700; padding: 8px 0; }
@keyframes gravaPulsa { 0%,100% { opacity: 1; } 50% { opacity: .72; } }
.audio-vel { display: flex; gap: 5px; margin-top: 8px; }
.audio-vel button { flex: 1; padding: 5px; border-radius: 7px; background: #f0f3f8; font-size: 12px; font-weight: 800; }
.audio-vel button.on { background: var(--ink); color: #fff; }
@keyframes flutua { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-.9vh); } }

/* ==========================================================
   14. Barra de rolagem do topo
   ========================================================== */
#scrub {
  position: fixed; top: 0; left: 0; right: 0; height: 1.4vh; z-index: 96;
  background: #eef2f8; cursor: pointer;
}
#scrub-fill {
  position: absolute; left: 0; top: 0; bottom: 0; width: 0;
  background: linear-gradient(90deg, var(--red), var(--yellow-dp));
}
#scrub-knob {
  position: absolute; top: 50%; width: 2.4vh; height: 2.4vh; margin: -1.2vh 0 0 -1.2vh;
  background: #fff; border: .3vh solid var(--red); border-radius: 50%;
  box-shadow: var(--shadow-sm); transition: transform var(--t-botao) var(--mov-padrao);
}
#scrub:hover #scrub-knob, #scrub.puxando #scrub-knob { transform: scale(1.25); }
#scrub.puxando { background: #e4eaf3; }

/* ==========================================================
   15. Avisos
   ========================================================== */
/* O AVISO FICA POR CIMA DE TUDO (#166), menos do tour. Na camada 99 ele
   ficava atrás da estante (400): "ao tentar apagar não vejo aviso
   nenhum" — todo aviso dado na estante saía escondido. Ele não pega
   clique (`pointer-events: none`), então estar por cima não tapa nada. */
#aviso {
  position: fixed; left: 50%; bottom: 13vh; transform: translate(-50%, 1.6vh);
  z-index: 710; background: var(--ink); color: #fff;
  padding: 1.2vh 2.4vh; border-radius: 10vh; font-size: max(1.7vh, 13.6px); font-weight: 700;
  box-shadow: var(--shadow-lg); opacity: 0; transition: all var(--t-cartao) var(--mov-estouro);
  pointer-events: none; max-width: 70vw; text-align: center;
}
#aviso.ver { opacity: 1; transform: translate(-50%, 0); }
#aviso.erro { background: var(--red-deep); }

/* ==========================================================
   16. Ajuda
   ========================================================== */
/* AS TRES MEDIDAS DAQUI ERAM DO CARTAO FLUTUANTE: uma largura que se
   ajustava ao conteudo, um fundo acima da barra de ferramentas e uma
   altura maxima para sobrar tela. O painel lateral vai de cima a baixo
   na borda da direita e tem a largura do painel de propriedades, e as
   tres deixaram de ter o que dizer.

   `.help__cols` e `.help__fechar` sairam com elas: a lista virou uma
   pilha de secoes e o "ocultar" virou a aba na beirada, a mesma do
   painel de propriedades. */
/* A linha final nao e de nenhuma secao: ela fala da propria lista. */
.help__pe {
  margin-top: .4vh; padding-top: 1.2vh;
  border-top: .1vh solid var(--borda);
}

/* ==========================================================
   17. Impressao (PDF)
   ========================================================== */
@media print {
  @page { size: landscape; margin: 0; }
  body { overflow: visible; }
  #toolbar, #dots, #scrub, #help,
  #selecao, #aviso, #brand, .pop-menu, #pen-canvas { display: none !important; }
  #board { overflow: visible; height: auto; width: auto; background: #fff; }
  #stage { zoom: 1 !important; display: block; width: auto; padding: 0 !important; }
  .panel {
    page-break-after: always; break-after: page;
    width: 297mm; height: 209mm; padding: 10mm 12mm 12mm;
  }
  .panel::after { display: none; }
  .js .pop { opacity: 1 !important; animation: none !important; }
  .panel .bar__col { height: var(--h, 50%) !important; }
  body.imprimir-um .panel { display: none !important; }
  body.imprimir-um .panel.imprimir-este { display: block !important; page-break-after: avoid; }
  * { animation: none !important; transition: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  .doodle--arrow path, .doodle--spark path,
  .emo, .sticker::after, .roda__item { animation: none !important; }
}

/* ==========================================================
   18. Acoes rapidas do que esta selecionado
   ========================================================== */
.sel-acoes {
  position: absolute; display: none; gap: .5vh;
  pointer-events: auto; z-index: 2;
}
#selecao.ativo .sel-acoes { display: flex; }
.sel-acoes button {
  width: 3.4vh; height: 3.4vh; border-radius: .9vh;
  background: #fff; border: .22vh solid var(--ink);
  box-shadow: 0 .4vh 1vh rgba(20,22,26,.22);
  display: grid; place-items: center; font-size: max(1.9vh, 15.2px); color: var(--ink);
  transition: transform var(--t-botao) var(--mov-padrao), background var(--t-botao) var(--mov-padrao);
}
.sel-acoes button svg { width: 1.9vh; height: 1.9vh; }
.sel-acoes button:hover { transform: translateY(-.3vh) scale(1.08); background: var(--ink); color: #fff; }
.sel-acoes button[data-sel="excluir"]:hover { background: var(--red); border-color: var(--red); }

/* ==========================================================
   19. Painel da ferramenta de texto
   ========================================================== */
.pop-menu--texto { width: 50vh; max-height: 82vh; overflow-y: auto; }
/* SEM RISCO EM CIMA. A classe e definida duas vezes — aqui e no
   clean.css — e o risco estava nas duas; tirar so de uma deixava a
   linha na tela, que foi o que aconteceu na primeira tentativa. O
   rotulo maiusculo e espacado ja separa a secao sozinho. */
.pop-menu__sub {
  display: block; margin: 1.8vh 0 1vh; font-size: max(1.4vh, 11.2px); font-weight: 800;
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink-soft);
}
.linha-txt { display: flex; gap: 1.2vh; align-items: flex-end; margin-bottom: 1.2vh; }
.linha-txt .campo { flex: 1; margin-bottom: 0; }
.campo--peso { flex: 1.4; }
.campo--cor { flex: 0 0 auto; }
.campo--cor input[type="color"] {
  width: 6vh; height: 4vh; padding: 0; border: .22vh solid #dde4ee;
  border-radius: .9vh; background: none; cursor: pointer; margin-top: .6vh;
}
.campo--num .passo { display: flex; align-items: center; gap: .4vh; margin-top: .6vh; }
.campo--num input[type="number"] {
  width: 100%; min-width: 0; padding: .9vh; font: inherit; font-size: max(1.7vh, 13.6px);
  text-align: center; border: .22vh solid #dde4ee; border-radius: .9vh;
}
.campo--num .passo button {
  flex: 0 0 auto; width: 3.6vh; height: 3.6vh; border-radius: .8vh;
  background: #f0f3f8; font-weight: 800; font-size: max(2vh, 16.0px); line-height: 1;
}
.campo--num .passo button:hover { background: var(--ink); color: #fff; }

.grupo-btn { display: flex; gap: .4vh; }
.grupo-btn button {
  width: 4vh; height: 4vh; border-radius: .9vh; background: #f0f3f8;
  font-size: max(1.8vh, 14.4px); font-weight: 700; color: var(--ink);
  display: grid; place-items: center; transition: all var(--t-botao) var(--mov-padrao);
}
.grupo-btn button:hover { background: #e2e8f2; }
.grupo-btn button.on { background: var(--ink); color: #fff; }

#pop-texto select {
  width: 100%; margin-top: .6vh; padding: 1vh; font: inherit; font-size: max(1.7vh, 13.6px);
  border: .22vh solid #dde4ee; border-radius: .9vh; background: #fff;
}
#cores-texto { margin-top: 1vh; }

/* o texto solto ja nasce com o estilo escolhido no painel */

/* A CAIXA ABRAÇA A LETRA, E NÃO A LINHA TIPOGRÁFICA.

   Medido em Archivo Black a 100px, "GRANDE TEXTO": a caixa tinha
   165px para uma letra de 71px — 49px de sobra só em cima. Ela vinha
   de três lugares somados: o `padding: .2em`, a metade da entrelinha
   que sobra acima da primeira linha, e o trecho da subida da fonte
   que fica acima da maiúscula (a fonte reserva espaço para acentos
   que a palavra nem sempre tem).

   O padding vertical sai, e o `text-box` apara o resto: `cap` em cima
   corta até o topo da maiúscula, e `text` embaixo para na descida da
   fonte — assim o "g" e o "p" continuam DENTRO da caixa, que é o que
   `alphabetic` não garantiria. Resultado medido: 100px de caixa, com
   a sobra de cima em zero.

   Num navegador sem `text-box` nada quebra: fica só o padding fora, e
   a caixa continua menor do que era. */
.obj--texto .txt {
  background: none; padding: 0 .1em; border-radius: .3vh;
  min-width: 2ch; word-break: break-word;
  text-box: trim-both cap text;
  /* O `min-height: 1em` de `.obj .txt` virava PISO: por mais que o
     `text-box` aparasse, a caixa parava numa altura de fonte inteira
     e sobrava justo embaixo da letra. Vazio o texto ainda tem o
     tamanho do lugar onde se escreve, porque o aviso "escreva aqui"
     ocupa uma linha. */
  min-height: 0;

  /* AQUI NÃO ENTRA `overflow: clip`.

     Eu já tinha posto, para conter a faixa azul da seleção — quem a
     pinta é o navegador, e ele pinta a LINHA tipográfica inteira, que
     continua alta depois do aperto. Funcionava, e cortou texto de
     verdade na tela de quem usa.

     A razão é estrutural, e vale como regra: a caixa é decidida por
     MEDIÇÃO (a linha da maiúscula, a descida, o acento), e medição
     erra — a fonte pode não ter carregado ainda, a família de teste
     pode não ser a que o navegador escolheu, o `letter-spacing` entra
     na conta de um lado e não do outro. Sem recorte, um erro desses
     deixa a moldura um fio larga ou estreita. Com recorte, o mesmo
     erro APAGA pedaço de letra.

     Faixa azul mal cortada é feio; letra cortada é defeito. */
}
body.modo-texto #board { cursor: text; }

/* status do painel de texto: diz se voce esta editando ou criando */
.txt-alvo {
  font-size: max(1.5vh, 12.0px); font-weight: 700; color: var(--green-dp);
  background: #eafaf1; border-radius: .8vh; padding: .8vh 1.2vh;
  margin-bottom: 1.4vh;
}
.txt-alvo--novo { color: var(--ink-soft); background: #f3f6fa; }

/* O texto da peça, editável aqui. Cresce até quatro linhas e depois
   rola: um campo que empurra o painel inteiro para baixo a cada
   parágrafo esconde o que vem embaixo dele. */
.txt-conteudo {
  display: block; width: 100%; margin-bottom: 1.4vh;
  font: inherit; font-size: max(1.6vh, 13.0px); line-height: 1.35;
  color: var(--ink); background: #f3f6fa;
  border: .16vh solid var(--borda); border-radius: .8vh;
  padding: .9vh 1.1vh; resize: vertical;
  min-height: 5vh; max-height: 18vh;
}
.txt-conteudo:focus {
  outline: none; background: #fff;
  border-color: var(--blue); box-shadow: 0 0 0 .3vh rgba(37,99,235,.18);
}
/* Desligado quer dizer "não há uma peça só para mostrar aqui" — e
   isso tem de se ver antes de clicar. */
.txt-conteudo:disabled { color: var(--ink-soft); background: #f7f9fb; cursor: not-allowed; }
body.noite .txt-conteudo { background: #212029; color: #e4e4ec; border-color: #343340; }
body.noite .txt-conteudo:focus { background: #2b2a33; }
body.noite .txt-conteudo:disabled { background: #1d1c22; color: var(--ink-soft); }

/* ==========================================================
   20. Menu do topo
   ========================================================== */
#brand {
  gap: .4vh;
  padding: .7vh .7vh .7vh 2vh;
  font-size: max(1.7vh, 13.6px); font-weight: 600;
  border-color: #eef2f7;
  box-shadow: 0 .5vh 1.6vh rgba(20,22,26,.10);
}
.brand__link {
  padding: .9vh 1.5vh; border-radius: 10vh;
  font-size: max(1.7vh, 13.6px); font-weight: 600; color: #3f4854;
  transition: background var(--t-botao) var(--mov-padrao), color var(--t-botao) var(--mov-padrao);
  white-space: nowrap;
}
.brand__link:hover { background: #f1f4f9; color: var(--ink); }
.brand__cta {
  margin-left: .8vh;
  padding: 1.1vh 2.2vh; border-radius: 10vh;
  background: #e8232a; color: #fff;
  font-size: max(1.7vh, 13.6px); font-weight: 700; white-space: nowrap;
  box-shadow: 0 .4vh 1.2vh rgba(232,35,42,.32);
  transition: background var(--t-botao) var(--mov-padrao), transform var(--t-botao) var(--mov-padrao);
}
.brand__cta:hover { background: #cf1c23; transform: translateY(-.2vh); }

/* AS PEÇAS MUDAM DE FILTRO E DE OPACIDADE SEM ESTALO: a luz da cena e a
   transparência da camada mexem nos dois. (Foi também a transição do
   esfumaçado do olho do ponto, que saiu no #363.) */
#stage .obj { transition: filter .7s ease, opacity .7s ease; }
/* arrastando a barra de opacidade das camadas, a peça responde na hora (#194) */
body.mexendo-na-camada #stage .obj { transition: none; }

/* ==========================================================
   A PEÇA PRESA
   ==========================================================
   Presa, ela nao devolve NADA ao clique: nem moldura, nem barra, nem
   anel ao passar o mouse. Foi o pedido — "eles vao ficar como se nao
   existissem 100%" —, e e o que torna a tranca util: uma peca presa
   existe para parar de atrapalhar, e qualquer marca que ela ainda
   devolva e o atrapalho que se queria tirar.

   O que havia aqui — `#selecao.presa` com a barra encolhida no
   cadeado vermelho e a moldura pontilhada — saiu inteiro, junto com
   o codigo que acendia a classe. Quem solta agora e a lista do botao
   de cadeado da barra de baixo.

   O `pointer-events: none` que faz a peca sumir do ponteiro mora no
   clean.css, com as outras regras do objeto. */
[data-sel="prender"].on { background: var(--red); color: #fff; }

/* ---------- traço de caneta como peça (ADR-004) ----------
   A peça não recebe ponteiro: quem recebe é o caminho invisível com a
   forma do traço. Assim o clique no vazio de um desenho grande
   atravessa para o que está embaixo. */
.obj--traco { pointer-events: none; }
.obj--traco .traco-img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  display: block; pointer-events: none; user-select: none; -webkit-user-drag: none;
}
.obj--traco .traco-alvo { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.obj--traco .traco-alvo path {
  fill: none; stroke: transparent; stroke-linecap: round; stroke-linejoin: round;
  pointer-events: stroke; cursor: move;
}
/* desenhando, o caminho não pega o ponteiro: quem desenha é a tela da caneta */
body.modo-pen .obj--traco .traco-alvo path, body.modo-erase .obj--traco .traco-alvo path { pointer-events: none; }
/* o marca-texto escurece o que está embaixo, como fazia na tela única */
.obj--traco[data-pincel="marcatexto"] { mix-blend-mode: multiply; }
