Logo única: guara.png e guara-s.png

A variante clara tinha artefatos; a arte escura recortada serve aos dois temas. Saem a troca de
variante por tema, os arquivos -light e a fonte clara; os arquivos escuros viram guara.png e
guara-s.png e o script, o app, o servidor do guara ui e o README usam só eles.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Lucas RayanandClaude Sonnet 5.5 committed 2026-10-23 11:58:39 -03:00
1 parent 9c09f5dd8a
commit 0a9622fb96
13 files changed
+32 -53

No files matched your search

+1 -1
View File
@@ -1,4 +1,4 @@
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="apps/gui/ui/guara-dark.png"><img src="apps/gui/ui/guara-light.png" width="300" alt="Guará"></picture></p>
<p align="center"><img src="apps/gui/ui/guara.png" width="300" alt="Guará"></p>
<h1 align="center">Guará</h1>
<p align="center">Free file recovery for hard drives, SSDs and USB sticks.<br>Terminal and graphical interface · Windows, Linux and macOS · read-only on the source.</p>
+1 -1
View File
@@ -1,4 +1,4 @@
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="apps/gui/ui/guara-dark.png"><img src="apps/gui/ui/guara-light.png" width="300" alt="Guará"></picture></p>
<p align="center"><img src="apps/gui/ui/guara.png" width="300" alt="Guará"></p>
<h1 align="center">Guará</h1>
<p align="center">Recuperação de arquivos livre e gratuita para HD, SSD e pendrive.<br>Terminal e interface gráfica · Windows, Linux e macOS · somente leitura na origem.</p>
+2 -9
View File
@@ -516,15 +516,8 @@ dialog.lightbox[open] { display: grid; }
.h-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; background: var(--ok); }
.h-dot.warning { background: var(--warn); } .h-dot.failing { background: var(--bad); }
/* logo: a variante clara ou a escura, conforme o tema escolhido no app (não só o do sistema) */
.logo-img { display: none; flex: none; }
.logo-img.light { display: block; }
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) .logo-img.light { display: none; }
:root:not([data-theme="light"]) .logo-img.dark { display: block; }
}
:root[data-theme="dark"] .logo-img.light { display: none; }
:root[data-theme="dark"] .logo-img.dark { display: block; }
/* logo: uma arte só (laranja sobre transparente) serve aos temas claro e escuro */
.logo-img { display: block; flex: none; }
/* atualização do app */
.update-card { position: fixed; right: 18px; bottom: 18px; z-index: 60; width: min(400px, calc(100vw - 36px)); display: grid; gap: 10px; padding: 16px 18px; border-radius: 18px; background: var(--surface); box-shadow: var(--shadow); border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent); }
+1 -1
View File
@@ -265,7 +265,7 @@ function renderHome() {
S.device = null; S.job = null;
renderSide();
main.innerHTML = `<div class="page">
<section class="hero"><img class="logo-img hero-logo dark" src="guara-dark.png" alt="Guará"><img class="logo-img hero-logo light" src="guara-light.png" alt="Guará"><h1>Encontre o que você achou que tinha perdido.</h1>
<section class="hero"><img class="logo-img hero-logo" src="guara.png" alt="Guará"><h1>Encontre o que você achou que tinha perdido.</h1>
<p>Escolha um disco, SSD ou pendrive ao lado. O Guará lê tudo: arquivos apagados, partições perdidas e espaço não particionado, sem escrever nada no disco de origem.</p></section>
<div class="cards">
<div class="card"><h3>Uma varredura, tudo junto</h3><p>Metadados do sistema de arquivos e busca por assinatura na mesma passada, sem duplicatas.</p></div>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 346 KiB

File renamed without changes.
File renamed without changes.
+3 -3
View File
@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="color-scheme" content="light dark">
<title>Guará</title>
<link rel="icon" href="guara-dark-s.png" type="image/png">
<link rel="icon" href="guara-s.png" type="image/png">
<link rel="stylesheet" href="app.css">
</head>
<body>
@@ -14,10 +14,10 @@
<button class="icon-btn" id="menuBtn" aria-label="Abrir menu" aria-expanded="false">
<svg viewBox="0 0 24 24" width="22" height="22"><path d="M4 7h16M4 12h16M4 17h16" stroke="currentColor" stroke-width="2" stroke-linecap="round" fill="none"/></svg>
</button>
<img class="logo-img dark" src="guara-dark-s.png" width="24" height="24" alt=""><img class="logo-img light" src="guara-light-s.png" width="24" height="24" alt=""><strong>Guará</strong>
<img class="logo-img" src="guara-s.png" width="24" height="24" alt=""><strong>Guará</strong>
</header>
<aside class="sidebar" id="sidebar" aria-label="Dispositivos e sessões">
<div class="brand"><img class="logo-img dark" src="guara-dark-s.png" width="30" height="30" alt=""><img class="logo-img light" src="guara-light-s.png" width="30" height="30" alt=""><div><strong>Guará</strong><small>Recuperação de arquivos</small></div></div>
<div class="brand"><img class="logo-img" src="guara-s.png" width="30" height="30" alt=""><div><strong>Guará</strong><small>Recuperação de arquivos</small></div></div>
<nav>
<div class="side-title">Dispositivos <button class="icon-btn small" id="refreshBtn" title="Atualizar lista" aria-label="Atualizar lista"><svg viewBox="0 0 24 24" width="16" height="16"><path d="M20 12a8 8 0 1 1-2.5-5.8M20 4v5h-5" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/></svg></button></div>
<ul id="deviceList" class="list"></ul>
File renamed without changes.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

+6 -14
View File
@@ -13,10 +13,8 @@ const PREVIEW_JS: &str = include_str!("../../../apps/gui/ui/preview.js");
const I18N_JS: &str = include_str!("../../../apps/gui/ui/i18n.js");
const I18N_EN_JS: &str = include_str!("../../../apps/gui/ui/i18n-en.js");
const EXPLORER_JS: &str = include_str!("../../../apps/gui/ui/explorer.js");
const LOGO_DARK: &[u8] = include_bytes!("../../../apps/gui/ui/guara-dark.png");
const LOGO_LIGHT: &[u8] = include_bytes!("../../../apps/gui/ui/guara-light.png");
const LOGO_DARK_S: &[u8] = include_bytes!("../../../apps/gui/ui/guara-dark-s.png");
const LOGO_LIGHT_S: &[u8] = include_bytes!("../../../apps/gui/ui/guara-light-s.png");
const LOGO: &[u8] = include_bytes!("../../../apps/gui/ui/guara.png");
const LOGO_S: &[u8] = include_bytes!("../../../apps/gui/ui/guara-s.png");
const PDF_JS: &str = include_str!("../../../apps/gui/ui/vendor/pdf.min.mjs");
const PDF_WORKER: &str = include_str!("../../../apps/gui/ui/vendor/pdf.worker.min.mjs");
@@ -100,17 +98,11 @@ fn handle(req: Request, eng: &Engine, token: &str, hosts: &[String]) {
Response::from_string(I18N_EN_JS).with_header(ct("text/javascript; charset=utf-8")),
);
}
(Method::Get, "/guara-dark.png") => {
let _ = req.respond(Response::from_data(LOGO_DARK).with_header(ct("image/png")));
(Method::Get, "/guara.png") => {
let _ = req.respond(Response::from_data(LOGO).with_header(ct("image/png")));
}
(Method::Get, "/guara-light.png") => {
let _ = req.respond(Response::from_data(LOGO_LIGHT).with_header(ct("image/png")));
}
(Method::Get, "/guara-dark-s.png") => {
let _ = req.respond(Response::from_data(LOGO_DARK_S).with_header(ct("image/png")));
}
(Method::Get, "/guara-light-s.png") => {
let _ = req.respond(Response::from_data(LOGO_LIGHT_S).with_header(ct("image/png")));
(Method::Get, "/guara-s.png") => {
let _ = req.respond(Response::from_data(LOGO_S).with_header(ct("image/png")));
}
(Method::Get, "/explorer.js") => {
let _ = req.respond(
+18 -24
View File
@@ -1,11 +1,11 @@
#!/usr/bin/env python3
"""Tira o fundo das logos do Guará e gera as variantes usadas no app, no README e nos ícones.
"""Tira o fundo da logo do Guará e gera os arquivos usados no app, no README e nos ícones.
Entrada (arte original, fundo sólido): assets/logo/guara-dark-fonte.png e guara-light-fonte.png.
Saída: apps/gui/ui/guara-dark.png e guara-light.png (768 px, fundo transparente, recortadas e
quadradas), guara-dark-s.png e guara-light-s.png (128 px, para barra lateral e favicon) e
apps/gui/src-tauri/icons/source.png (ícone do app, sobre o fundo escuro da arte; o CI gera o
resto com `tauri icon`).
Entrada (arte original, fundo sólido escuro): assets/logo/guara-fonte.png.
Saída: apps/gui/ui/guara.png (768 px, fundo transparente, recortada e quadrada), guara-s.png
(128 px, para a barra lateral e o favicon) e apps/gui/src-tauri/icons/source.png (ícone do app,
sobre o fundo escuro da arte; o CI gera o resto com `tauri icon`). Uma logo só serve aos temas
claro e escuro: o laranja lê bem nos dois.
O fundo é uma cor sólida: sai o que é parecido com ela e está ligado à borda da imagem (sombras
escuras dentro do desenho ficam). Na faixa de 3 px ao redor, a cor do desenho é estimada pelos
@@ -20,11 +20,9 @@ from PIL import Image
RAIZ = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")
UI = os.path.join(RAIZ, "apps/gui/ui")
ICONES = os.path.join(RAIZ, "apps/gui/src-tauri/icons")
# (arquivo de origem, cor do fundo, distância que ainda conta como fundo certo, não usado)
VARIANTES = {
"dark": ("assets/logo/guara-dark-fonte.png", (10, 16, 28), 9.0, None),
"light": ("assets/logo/guara-light-fonte.png", (254, 249, 240), 7.0, None),
}
FONTE = "assets/logo/guara-fonte.png"
FUNDO = (10, 16, 28) # cor do fundo sólido da arte original
LIMIAR = 9.0 # distância que ainda conta como fundo certo
def tirar_fundo(path, bg, d0, _d1=None):
@@ -161,22 +159,18 @@ def recortar_quadrado(im, margem=0.04, lado=1024):
def main():
feitas = {}
for nome, (src, bg, d0, _) in VARIANTES.items():
im = recortar_quadrado(tirar_fundo(os.path.join(RAIZ, src), bg, d0))
feitas[nome] = im
for sufixo, lado in (("", 768), ("-s", 128)):
im.resize((lado, lado), Image.LANCZOS).save(
os.path.join(UI, f"guara-{nome}{sufixo}.png"), optimize=True
)
print(f"guara-{nome}.png e guara-{nome}-s.png")
# ícone do app: a arte escura sobre o fundo escuro da própria arte, com cantos arredondados
logo = recortar_quadrado(tirar_fundo(os.path.join(RAIZ, FONTE), FUNDO, LIMIAR))
for sufixo, lado in (("", 768), ("-s", 128)):
logo.resize((lado, lado), Image.LANCZOS).save(os.path.join(UI, f"guara{sufixo}.png"), optimize=True)
print("guara.png e guara-s.png")
# ícone do app: a arte sobre o fundo escuro da própria arte, com cantos arredondados
from PIL import ImageDraw
lado = 1024
fundo = Image.new("RGBA", (lado, lado), VARIANTES["dark"][1] + (255,))
arte = feitas["dark"].resize((round(lado * 0.82),) * 2, Image.LANCZOS)
fundo = Image.new("RGBA", (lado, lado), FUNDO + (255,))
arte = logo.resize((round(lado * 0.82),) * 2, Image.LANCZOS)
fundo.paste(arte, ((lado - arte.width) // 2, (lado - arte.height) // 2), arte)
mascara = Image.new("L", (lado, lado), 0)
from PIL import ImageDraw
ImageDraw.Draw(mascara).rounded_rectangle((0, 0, lado - 1, lado - 1), radius=round(lado * 0.2237), fill=255)
icone = Image.new("RGBA", (lado, lado), (0, 0, 0, 0))
icone.paste(fundo, (0, 0), mascara)