8.1 Render Loop

void d3tui_term_render(d3tui_terminal_t *term) {
    d3tui_render_ctx_t *ctx = term->render_ctx;
    
    // Clear if needed
    if (term->dirty_full) {
        d3tui_render_clear(ctx);
        term->dirty_full = false;
    }
    
    // Render visible screen
    for (uint16_t row = 0; row < term->height; row++) {
        for (uint16_t col = 0; col < term->width; col++) {
            const d3tui_cell_t *cell = d3tui_term_get_cell(term, row, col);
            if (cell->dirty) {
                uint16_t x = col * ctx->cell_w;
                uint16_t y = row * ctx->cell_h;
                d3tui_render_set_colors(ctx, 
                    palette[cell->fg_color], 
                    palette[cell->bg_color]);
                d3tui_render_char(ctx, x, y, cell->codepoint);
                cell->dirty = false;
            }
        }
    }
    
    // Render cursor
    if (term->cursor_visible) {
        uint16_t x = term->cursor_col * ctx->cell_w;
        uint16_t y = term->cursor_row * ctx->cell_h;
        d3tui_render_cursor(ctx, x, y, ctx->cell_w, ctx->cell_h);
    }
    
    d3tui_render_flush(ctx);
}