use ratatui::prelude::*;
use ratatui::widgets::Paragraph;
pub const FRAMES: usize = 30;
const FILL_FRAMES: usize = 20;
const GOLD: Color = Color::Rgb(212, 175, 55);
const SEAM: Color = Color::Rgb(90, 90, 90);
const TAGLINE: &str = "a local-first safety layer for AI coding agents";
const GLYPHS: &[[&str; 5]] = &[
["█ █", "█ █ ", "██ ", "█ █ ", "█ █"], ["███", " █ ", " █ ", " █ ", "███"], ["█ █", "██ █", "█ ██", "█ █", "█ █"], ["█████", " █ ", " █ ", " █ ", " █ "], [" ███", "█ ", " ██ ", " █", "███ "], ["█ █", "█ █", "█ █", "█ █", " ██ "], [" ███", "█ ", "█ ██", "█ █", " ███"], ["███", " █ ", " █ ", " █ ", "███"], ];
fn wordmark_rows() -> [String; 5] {
let mut rows: [String; 5] = Default::default();
for (gi, g) in GLYPHS.iter().enumerate() {
for (r, row) in rows.iter_mut().enumerate() {
if gi > 0 {
row.push(' ');
}
row.push_str(g[r]);
}
}
rows
}
pub fn render(f: &mut Frame, area: Rect, frame: usize, color: bool) {
let rows = wordmark_rows();
let width = rows[0].chars().count();
if (area.width as usize) < width + 2 {
let lines = vec![
Line::from(""),
Line::from(Span::styled(
"KINTSUGI",
style_if(color, Style::default().fg(GOLD)).add_modifier(Modifier::BOLD),
)),
Line::from(Span::styled(TAGLINE, dim_if(color))),
];
f.render_widget(
Paragraph::new(lines).alignment(Alignment::Center),
centered(area, 3),
);
return;
}
let fill = (frame.min(FILL_FRAMES) as f32 / FILL_FRAMES as f32 * width as f32).round() as usize;
let done = frame >= FILL_FRAMES;
let mut lines: Vec<Line> = Vec::new();
if area.height >= 16 {
for ml in mark_lines(color) {
lines.push(ml);
}
lines.push(Line::from(""));
}
for row in &rows {
let mut spans = Vec::new();
for (col, ch) in row.chars().enumerate() {
if ch == '█' {
let filled = col < fill;
let glyph = if filled || done { "█" } else { "░" };
let style = if !color {
Style::default()
} else if filled || done {
Style::default().fg(GOLD).add_modifier(Modifier::BOLD)
} else {
Style::default().fg(SEAM)
};
spans.push(Span::styled(glyph.to_string(), style));
} else {
spans.push(Span::raw(" "));
}
}
lines.push(Line::from(spans));
}
lines.push(Line::from(""));
if fill * 2 >= width {
lines.push(Line::from(Span::styled(TAGLINE, dim_if(color))));
} else {
lines.push(Line::from(""));
}
lines.push(Line::from(""));
if done {
lines.push(Line::from(Span::styled("press any key", dim_if(color))));
} else {
lines.push(Line::from(""));
}
let content_height = lines.len() as u16;
f.render_widget(
Paragraph::new(lines).alignment(Alignment::Center),
centered(area, content_height),
);
}
fn mark_lines(color: bool) -> Vec<Line<'static>> {
let frame_style = if color {
Style::default().fg(SEAM)
} else {
Style::default()
};
let gold = if color {
Style::default().fg(GOLD).add_modifier(Modifier::BOLD)
} else {
Style::default()
};
let row = |left: &'static str, seam: &'static str, right: &'static str| {
Line::from(vec![
Span::styled(left, frame_style),
Span::styled(seam, gold),
Span::styled(right, frame_style),
])
};
vec![
Line::from(Span::styled("╭───────╮", frame_style)),
row("│ ", "╲", " │"),
row("│ ", "╲ ╱", " │"),
row("│ ", "╳", " │"),
row("│ ", "╱ ╲", " │"),
row("│ ", "╱", " │"),
Line::from(Span::styled("╰───────╯", frame_style)),
]
}
fn centered(area: Rect, height: u16) -> Rect {
let h = height.min(area.height);
let y = area.y + (area.height.saturating_sub(h)) / 2;
Rect {
x: area.x,
y,
width: area.width,
height: h,
}
}
fn dim_if(color: bool) -> Style {
style_if(color, Style::default().add_modifier(Modifier::DIM))
}
fn style_if(color: bool, s: Style) -> Style {
if color {
s
} else {
Style::default()
}
}
#[cfg(test)]
mod tests {
use super::*;
use ratatui::backend::TestBackend;
use ratatui::Terminal;
fn frame_text(frame: usize, color: bool, w: u16, h: u16) -> String {
let mut term = Terminal::new(TestBackend::new(w, h)).unwrap();
term.draw(|f| render(f, f.area(), frame, color)).unwrap();
let buf = term.backend().buffer().clone();
buf.content().iter().map(|c| c.symbol()).collect()
}
#[test]
fn wordmark_rows_are_aligned() {
let rows = wordmark_rows();
let w = rows[0].chars().count();
assert!(rows.iter().all(|r| r.chars().count() == w), "rows ragged");
assert!(w >= 30, "banner should be a real width");
}
#[test]
fn early_frame_shows_unfilled_seam_glyph() {
let text = frame_text(0, true, 80, 24);
assert!(text.contains('░'), "expected unfilled seam at frame 0");
}
#[test]
fn final_frame_is_fully_filled_and_prompts() {
let text = frame_text(FRAMES, true, 80, 24);
assert!(text.contains('█'), "expected filled blocks at the end");
assert!(!text.contains('░'), "nothing should remain unfilled");
assert!(text.contains("press any key"));
assert!(text.contains("safety layer"));
}
#[test]
fn mono_animation_still_sweeps_without_color() {
let early = frame_text(0, false, 80, 24);
let late = frame_text(FRAMES, false, 80, 24);
assert!(early.contains('░'));
assert!(!late.contains('░'));
}
#[test]
fn narrow_terminal_degrades_without_panic() {
let text = frame_text(10, true, 24, 10);
assert!(text.contains("KINTSUGI"));
}
#[test]
fn brand_mark_is_a_perfect_rectangle() {
let lines = mark_lines(false);
let widths: Vec<usize> = lines
.iter()
.map(|l| l.spans.iter().map(|s| s.content.chars().count()).sum())
.collect();
assert!(
widths.windows(2).all(|w| w[0] == w[1]),
"tile rows ragged: {widths:?}"
);
}
}