// Unity build - include all src files here
// -mta
#ifdef __APPLE__
#include <mach/mach_time.h>
#endif
// [h]
#include "base/base_inc.h"
#include "platform/platform.h"
#include "renderer/renderer.h"
#include "midi/midi.h"
#include "audio/audio.h"
#include "ui/ui_core.h"
#include "ui/ui_icons.h"
#include "ui/ui_widgets.h"

// [cpp]
#include "base/base_inc.cpp"
#include "ui/ui_core.cpp"
#include "ui/ui_icons.cpp"
#include "ui/ui_widgets.cpp"
#ifdef __APPLE__
#include "platform/platform_macos.mm"
#include "renderer/renderer_metal.mm"
#include "midi/midi_coremidi.cpp"
#include "audio/audio_coreaudio.cpp"
#else
#include "platform/platform_win32.cpp"
#include "renderer/renderer_dx12.cpp"
#include "midi/midi_win32.cpp"
#include "audio/audio_asio.cpp"
#endif
#include "menus.cpp"

////////////////////////////////
// Clay text config helpers

static Clay_TextElementConfig g_text_config_normal;
static Clay_TextElementConfig g_text_config_title;
static Clay_TextElementConfig g_text_config_dim;

static void init_text_configs() {
    g_text_config_normal = {};
    g_text_config_normal.textColor = g_theme.text;
    g_text_config_normal.fontSize = 15;
    g_text_config_normal.wrapMode = CLAY_TEXT_WRAP_NONE;

    g_text_config_title = {};
    g_text_config_title.textColor = g_theme.text;
    g_text_config_title.fontSize = 15;
    g_text_config_title.wrapMode = CLAY_TEXT_WRAP_NONE;

    g_text_config_dim = {};
    g_text_config_dim.textColor = g_theme.text_dim;
    g_text_config_dim.fontSize = 15;
    g_text_config_dim.wrapMode = CLAY_TEXT_WRAP_NONE;
}

////////////////////////////////
// App state — all mutable state the frame function needs

struct AppState {
    PlatformWindow *window;
    Renderer       *renderer;
    MidiEngine     *midi;
    AudioEngine    *audio;
    UI_Context     *ui;
    S32             last_w, last_h;
    B32             show_browser;
    B32             show_props;
    B32             show_log;
    B32             show_midi_devices;
#ifdef __APPLE__
    U64        freq_numer;
    U64        freq_denom;
    U64        last_time;
#else
    LARGE_INTEGER   freq;
    LARGE_INTEGER   last_time;
#endif

    // Tab state
    S32             right_panel_tab;   // 0 = Properties, 1 = MIDI Devices
    S32             bottom_panel_tab;  // 0 = Item Editor, 1 = Sample Mapper

    // Piano state
    S32             piano_mouse_note;  // MIDI note held by mouse click (-1 = none)

    // Demo widget state
    B32             demo_checkbox_a;
    B32             demo_checkbox_b;
    S32             demo_radio_sel;
    S32             demo_dropdown_sel;
    char            demo_text_a[128];
    char            demo_text_b[128];
    S32             demo_button_count;

    // Modal / window demo state
    B32             show_settings_window;
    B32             show_about_window;
    B32             show_confirm_dialog;
    S32             settings_theme_sel;
    S32             settings_theme_prev;
    B32             settings_vsync;
    B32             settings_autosave;

    // Accent color selection
    S32             accent_sel;
    S32             accent_prev;

    // Corner radius selection
    S32             radius_sel;

    // Settings dialog tab
    S32             settings_tab;  // 0=Audio, 1=Midi, 2=Keyboard Shortcuts, 3=Appearance

    // Knob demo state
    F32             demo_knob_unsigned;
    F32             demo_knob_signed;

    // Slider/fader demo state
    F32             demo_slider_h;
    F32             demo_slider_v;
    F32             demo_fader;

    // Scrollbar drag state
    B32             scrollbar_dragging;
    F32             scrollbar_drag_start_y;
    F32             scrollbar_drag_start_scroll;

    // Audio device selection
    S32             audio_device_sel;   // dropdown index: 0 = None, 1+ = device
    S32             audio_device_prev;  // previous selection for change detection

    // UI scale (Cmd+/Cmd- to zoom)
    F32             ui_scale;

    // Panel sizes (in unscaled px, will be multiplied by uis())
    F32             browser_width;    // default 200
    F32             right_col_width;  // default 250
    F32             log_height;       // default 180

    // Panel drag state
    S32             panel_drag;             // 0=none, 1=browser, 2=right, 3=log
    F32             panel_drag_start_mouse; // mouse X or Y when drag started
    F32             panel_drag_start_size;  // panel size when drag started

    // Master layout: 0 = Edit, 1 = Mix, 2 = Patch
    S32             master_layout;

    // Mix view fader state (8 channels + master)
    F32             mix_faders[8];
    F32             mix_pans[8];
    F32             mix_master_pan;

    // Patch view state
    S32             patch_tab;            // 0 = Matrix, 1 = Graph
    B32             patch_matrix[32][33]; // internal routing: 32 inputs x (Master + 32 outputs)
    B32             hw_matrix[32][32];    // hardware routing: 32 channel outputs x 32 hw outputs
};

////////////////////////////////
// Piano helpers

#define PIANO_FIRST_NOTE 21   // A0
#define PIANO_LAST_NOTE  108  // C8
#define PIANO_BLACK_W    11.0f
#define PIANO_BLACK_H_PCT 0.6f

static B32 piano_is_black_key(S32 note) {
    S32 n = note % 12;
    return n == 1 || n == 3 || n == 6 || n == 8 || n == 10;
}

// Velocity-based color: blue (vel 0) → green (mid) → red (vel 127)
static Clay_Color velocity_color(S32 velocity) {
    F32 t = (F32)velocity / 127.0f;
    F32 r, g, b;
    if (t < 0.5f) {
        F32 s = t * 2.0f;
        r = 40.0f  + s * (76.0f  - 40.0f);
        g = 120.0f + s * (175.0f - 120.0f);
        b = 220.0f + s * (80.0f  - 220.0f);
    } else {
        F32 s = (t - 0.5f) * 2.0f;
        r = 76.0f  + s * (220.0f - 76.0f);
        g = 175.0f + s * (50.0f  - 175.0f);
        b = 80.0f  + s * (40.0f  - 80.0f);
    }
    return Clay_Color{r, g, b, 255};
}

// Piano input: handle mouse clicks on piano keys
static void update_piano_input(AppState *app) {
    if (app->master_layout != 0) return;
    PlatformInput input = g_wstate.input;

    if (!input.mouse_down) {
        app->piano_mouse_note = -1;
        return;
    }

    // Find hovered piano key — check black keys first (they're on top)
    S32 hovered_note = -1;
    for (S32 note = PIANO_FIRST_NOTE; note <= PIANO_LAST_NOTE; note++) {
        if (piano_is_black_key(note) && Clay_PointerOver(CLAY_IDI("PKey", note))) {
            hovered_note = note;
            break;
        }
    }
    if (hovered_note == -1) {
        for (S32 note = PIANO_FIRST_NOTE; note <= PIANO_LAST_NOTE; note++) {
            if (!piano_is_black_key(note) && Clay_PointerOver(CLAY_IDI("PKey", note))) {
                hovered_note = note;
                break;
            }
        }
    }

    if (hovered_note != -1) {
        app->piano_mouse_note = hovered_note;
    }
}

////////////////////////////////
// Panel builders

static void build_browser_panel(AppState *app) {
    if (!app->show_browser) return;

    Clay_Color bp_top = g_theme.bg_medium;
    Clay_Color bp_bot = {(F32)Max((S32)bp_top.r-8,0), (F32)Max((S32)bp_top.g-8,0), (F32)Max((S32)bp_top.b-8,0), 255};
    CustomGradientData *bp_grad = alloc_gradient(bp_top, bp_bot);

    CLAY(CLAY_ID("BrowserPanel"),
        .layout = {
            .sizing = { .width = CLAY_SIZING_FIXED(uis(app->browser_width)), .height = CLAY_SIZING_GROW() },
            .layoutDirection = CLAY_TOP_TO_BOTTOM,
        },
        .backgroundColor = bp_top,
        .custom = { .customData = bp_grad },
    ) {
        {
            S32 sel = 0;
            static const char *browser_tabs[] = { "Browser" };
            ui_tab_bar("BrowserTabRow", browser_tabs, 1, &sel);
        }

        CLAY(CLAY_ID("BrowserContent"),
            .layout = {
                .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
                .padding = { uip(8), uip(8), uip(6), uip(6) },
                .childGap = uip(4),
                .layoutDirection = CLAY_TOP_TO_BOTTOM,
            }
        ) {
            // Top highlight (beveled edge)
            CLAY(CLAY_ID("BrowserHighlight"),
                .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
                .backgroundColor = g_theme.bg_lighter
            ) {}
            CLAY_TEXT(CLAY_STRING("Instruments"), &g_text_config_normal);
        }
    }
}

static void build_main_panel(AppState *app) {
    Clay_Color mp_top = g_theme.bg_light;
    Clay_Color mp_bot = {(F32)Max((S32)mp_top.r-8,0), (F32)Max((S32)mp_top.g-8,0), (F32)Max((S32)mp_top.b-8,0), 255};
    CustomGradientData *mp_grad = alloc_gradient(mp_top, mp_bot);

    CLAY(CLAY_ID("MainPanel"),
        .layout = {
            .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
            .layoutDirection = CLAY_TOP_TO_BOTTOM,
        },
        .backgroundColor = mp_top,
        .custom = { .customData = mp_grad }
    ) {
        {
            S32 sel = 0;
            static const char *main_tabs[] = { "Main" };
            ui_tab_bar("MainTabRow", main_tabs, 1, &sel);
        }

        CLAY(CLAY_ID("MainScrollArea"),
            .layout = {
                .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
                .layoutDirection = CLAY_LEFT_TO_RIGHT,
            }
        ) {
        CLAY(CLAY_ID("MainContent"),
            .layout = {
                .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
                .padding = { uip(16), uip(16), uip(12), uip(12) },
                .childGap = uip(12),
                .layoutDirection = CLAY_TOP_TO_BOTTOM,
            },
            .clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() },
        ) {
            // Top highlight (beveled edge)
            CLAY(CLAY_ID("MainHighlight"),
                .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
                .backgroundColor = g_theme.bg_lighter
            ) {}
            // Section: Buttons
            ui_label("LblButtons", "Buttons");
            CLAY(CLAY_ID("ButtonRow"),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
                    .childGap = uip(8),
                    .layoutDirection = CLAY_LEFT_TO_RIGHT,
                }
            ) {
                if (ui_button("BtnHello", "Click Me")) {
                    app->demo_button_count++;
                }
                if (ui_button("BtnReset", "Reset")) {
                    app->demo_button_count = 0;
                }
            }
            // Show click count
            static char btn_count_buf[64];
            snprintf(btn_count_buf, sizeof(btn_count_buf), "Button clicked %d times", app->demo_button_count);
            ui_label("LblBtnCount", btn_count_buf);

            // Separator
            CLAY(CLAY_ID("Sep1"),
                .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
                .backgroundColor = g_theme.border
            ) {}

            // Section: Checkboxes
            ui_label("LblCheckboxes", "Checkboxes");
            ui_checkbox("ChkA", "Enable feature A", &app->demo_checkbox_a);
            ui_checkbox("ChkB", "Enable feature B", &app->demo_checkbox_b);

            CLAY(CLAY_ID("Sep2"),
                .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
                .backgroundColor = g_theme.border
            ) {}

            // Section: Radio buttons
            ui_label("LblRadio", "Output Format");
            static const char *radio_options[] = { "WAV", "AIFF", "FLAC" };
            ui_radio_group("RadioFmt", radio_options, 3, &app->demo_radio_sel);

            CLAY(CLAY_ID("Sep3"),
                .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
                .backgroundColor = g_theme.border
            ) {}

            // Section: Text inputs
            ui_label("LblText", "Text Inputs");
            CLAY(CLAY_ID("TextRow"),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIT() },
                    .childGap = uip(8),
                    .layoutDirection = CLAY_LEFT_TO_RIGHT,
                }
            ) {
                CLAY(CLAY_ID("TextCol1"),
                    .layout = {
                        .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIT() },
                        .childGap = uip(4),
                        .layoutDirection = CLAY_TOP_TO_BOTTOM,
                    }
                ) {
                    ui_label("LblName", "Name:");
                    ui_text_input("TxtName", app->demo_text_a, sizeof(app->demo_text_a));
                }
                CLAY(CLAY_ID("TextCol2"),
                    .layout = {
                        .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIT() },
                        .childGap = uip(4),
                        .layoutDirection = CLAY_TOP_TO_BOTTOM,
                    }
                ) {
                    ui_label("LblPath", "Output Path:");
                    ui_text_input("TxtPath", app->demo_text_b, sizeof(app->demo_text_b));
                }
            }

            CLAY(CLAY_ID("Sep4"),
                .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
                .backgroundColor = g_theme.border
            ) {}

            // Section: Dropdown
            ui_label("LblDropdown", "Sample Rate");
            CLAY(CLAY_ID("DropdownWrapper"),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_FIXED(uis(200)), .height = CLAY_SIZING_FIT() },
                }
            ) {
                static const char *rate_options[] = { "44100 Hz", "48000 Hz", "88200 Hz", "96000 Hz", "192000 Hz" };
                ui_dropdown("DropRate", rate_options, 5, &app->demo_dropdown_sel);
            }

            CLAY(CLAY_ID("Sep5"),
                .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
                .backgroundColor = g_theme.border
            ) {}

            // Section: Knobs
            ui_label("LblKnobs", "Knobs");
            CLAY(CLAY_ID("KnobRow"),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
                    .childGap = uip(16),
                    .layoutDirection = CLAY_LEFT_TO_RIGHT,
                }
            ) {
                ui_knob("KnobVolume", "Volume", &app->demo_knob_unsigned, 100.0f, 0, 75.0f, 1);
                ui_knob("KnobPan", "Pan", &app->demo_knob_signed, 50.0f, 1, 0.0f, 1);
            }

            CLAY(CLAY_ID("Sep6"),
                .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
                .backgroundColor = g_theme.border
            ) {}

            // Section: Sliders
            ui_label("LblSliders", "Sliders");
            CLAY(CLAY_ID("SliderHRow"),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
                    .childGap = uip(16),
                    .layoutDirection = CLAY_LEFT_TO_RIGHT,
                }
            ) {
                ui_slider_h("SliderH", "Horizontal", &app->demo_slider_h, 100.0f, 0, 50.0f, 1);
            }
            CLAY(CLAY_ID("SliderVRow"),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
                    .childGap = uip(24),
                    .childAlignment = { .y = CLAY_ALIGN_Y_TOP },
                    .layoutDirection = CLAY_LEFT_TO_RIGHT,
                }
            ) {
                ui_slider_v("SliderV", "Vertical", &app->demo_slider_v, 100.0f, 0, 75.0f, 1);
                ui_fader("Fader1", "Fader", &app->demo_fader, 50.0f, 1, 0.0f, 1);
            }

            CLAY(CLAY_ID("Sep7"),
                .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
                .backgroundColor = g_theme.border
            ) {}

            // Section: Windows & Modals
            ui_label("LblWindows", "Windows & Modals");
            CLAY(CLAY_ID("WindowBtnRow"),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
                    .childGap = uip(8),
                    .layoutDirection = CLAY_LEFT_TO_RIGHT,
                }
            ) {
                if (ui_button("BtnAbout", "About")) {
                    app->show_about_window = 1;
                }
                if (ui_button("BtnConfirm", "Confirm Dialog")) {
                    app->show_confirm_dialog = 1;
                }
            }
        }

        // Scrollbar
        {
            Clay_ScrollContainerData scroll_data = Clay_GetScrollContainerData(CLAY_ID("MainContent"));
            if (scroll_data.found && scroll_data.contentDimensions.height > scroll_data.scrollContainerDimensions.height) {
                F32 track_h = scroll_data.scrollContainerDimensions.height;
                F32 content_h = scroll_data.contentDimensions.height;
                F32 visible_ratio = track_h / content_h;
                F32 thumb_h = Max(visible_ratio * track_h, uis(24));
                F32 scroll_range = content_h - track_h;
                F32 scroll_pct = scroll_range > 0 ? -scroll_data.scrollPosition->y / scroll_range : 0;
                F32 thumb_y = scroll_pct * (track_h - thumb_h);
                F32 bar_w = uis(8);

                // Handle scrollbar drag
                Clay_ElementId thumb_id = CLAY_ID("MainScrollThumb");
                Clay_ElementId track_id = CLAY_ID("MainScrollTrack");
                B32 thumb_hovered = Clay_PointerOver(thumb_id);
                B32 track_hovered = Clay_PointerOver(track_id);
                PlatformInput input = g_wstate.input;
                B32 mouse_clicked = input.mouse_down && !input.was_mouse_down;

                if (mouse_clicked && thumb_hovered) {
                    app->scrollbar_dragging = true;
                    app->scrollbar_drag_start_y = input.mouse_pos.y;
                    app->scrollbar_drag_start_scroll = scroll_data.scrollPosition->y;
                } else if (mouse_clicked && track_hovered && !thumb_hovered) {
                    // Click on track: jump scroll position so thumb centers on click
                    Clay_BoundingBox track_bb = Clay_GetElementData(track_id).boundingBox;
                    F32 click_rel = input.mouse_pos.y - track_bb.y;
                    F32 target_pct = (click_rel - thumb_h / 2) / (track_h - thumb_h);
                    if (target_pct < 0) target_pct = 0;
                    if (target_pct > 1) target_pct = 1;
                    scroll_data.scrollPosition->y = -target_pct * scroll_range;
                    // Start dragging from new position
                    app->scrollbar_dragging = true;
                    app->scrollbar_drag_start_y = input.mouse_pos.y;
                    app->scrollbar_drag_start_scroll = scroll_data.scrollPosition->y;
                }

                if (!input.mouse_down) {
                    app->scrollbar_dragging = false;
                }

                if (app->scrollbar_dragging) {
                    F32 dy = input.mouse_pos.y - app->scrollbar_drag_start_y;
                    F32 scroll_per_px = scroll_range / (track_h - thumb_h);
                    F32 new_scroll = app->scrollbar_drag_start_scroll - dy * scroll_per_px;
                    if (new_scroll > 0) new_scroll = 0;
                    if (new_scroll < -scroll_range) new_scroll = -scroll_range;
                    scroll_data.scrollPosition->y = new_scroll;
                }

                // Thumb color: highlight on hover or drag
                Clay_Color thumb_color = g_theme.scrollbar_grab;
                if (app->scrollbar_dragging || thumb_hovered) {
                    thumb_color = Clay_Color{
                        (F32)Min((S32)thumb_color.r + 30, 255),
                        (F32)Min((S32)thumb_color.g + 30, 255),
                        (F32)Min((S32)thumb_color.b + 30, 255),
                        thumb_color.a
                    };
                }

                CLAY(track_id,
                    .layout = {
                        .sizing = { .width = CLAY_SIZING_FIXED(bar_w), .height = CLAY_SIZING_GROW() },
                    },
                    .backgroundColor = g_theme.scrollbar_bg
                ) {
                    CLAY(thumb_id,
                        .layout = {
                            .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(thumb_h) },
                        },
                        .backgroundColor = thumb_color,
                        .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
                        .floating = {
                            .offset = { 0, thumb_y },
                            .attachPoints = {
                                .element = CLAY_ATTACH_POINT_LEFT_TOP,
                                .parent = CLAY_ATTACH_POINT_LEFT_TOP,
                            },
                            .attachTo = CLAY_ATTACH_TO_PARENT,
                        },
                    ) {}
                }
            } else {
                app->scrollbar_dragging = false;
            }
        }
        } // MainScrollArea
    }
}

static void build_right_panel(AppState *app) {
    static const char *right_tabs[] = { "Properties", "MIDI Devices" };

    Clay_Color rp_top = g_theme.bg_medium;
    Clay_Color rp_bot = {(F32)Max((S32)rp_top.r-8,0), (F32)Max((S32)rp_top.g-8,0), (F32)Max((S32)rp_top.b-8,0), 255};
    CustomGradientData *rp_grad = alloc_gradient(rp_top, rp_bot);

    CLAY(CLAY_ID("RightPanel"),
        .layout = {
            .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
            .layoutDirection = CLAY_TOP_TO_BOTTOM,
        },
        .backgroundColor = rp_top,
        .custom = { .customData = rp_grad }
    ) {
        ui_tab_bar("RightTabs", right_tabs, 2, &app->right_panel_tab);

        if (app->right_panel_tab == 0) {
            // Properties content
            CLAY(CLAY_ID("PropertiesContent"),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
                    .padding = { uip(8), uip(8), uip(6), uip(6) },
                    .childGap = uip(4),
                    .layoutDirection = CLAY_TOP_TO_BOTTOM,
                }
            ) {
                // Top highlight (beveled edge)
                CLAY(CLAY_ID("PropsHighlight"),
                    .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
                    .backgroundColor = g_theme.bg_lighter
                ) {}
                CLAY_TEXT(CLAY_STRING("Details"), &g_text_config_normal);
            }
        } else {
            // MIDI Devices content
            MidiEngine *midi = app->midi;
            CLAY(CLAY_ID("MidiContent"),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
                    .padding = { uip(8), uip(8), uip(6), uip(6) },
                    .childGap = uip(6),
                    .layoutDirection = CLAY_TOP_TO_BOTTOM,
                }
            ) {
                // Top highlight (beveled edge)
                CLAY(CLAY_ID("MidiHighlight"),
                    .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
                    .backgroundColor = g_theme.bg_lighter
                ) {}
                // Refresh button
                Clay_ElementId refresh_eid = CLAY_ID("MidiRefreshBtn");
                B32 refresh_hovered = Clay_PointerOver(refresh_eid);
                CLAY(refresh_eid,
                    .layout = {
                        .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIXED(uis(28)) },
                        .padding = { uip(12), uip(12), 0, 0 },
                        .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
                    },
                    .backgroundColor = refresh_hovered ? g_theme.accent_hover : g_theme.bg_lighter,
                    .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS)
                ) {
                    CLAY_TEXT(CLAY_STRING("Refresh"), &g_text_config_normal);
                }
                if (refresh_hovered && g_wstate.mouse_clicked) {
                    midi_refresh_devices(midi);
                }

                static char device_bufs[64][128];
                S32 device_count = midi_get_device_count(midi);

                // --- Inputs section ---
                CLAY_TEXT(CLAY_STRING("Inputs"), &g_text_config_dim);

                static const char *note_names[] = {"C","Db","D","Eb","E","F","Gb","G","Ab","A","Bb","B"};
                static char note_bufs[64][8];
                static char vel_bufs[64][8];
                static Clay_TextElementConfig box_text_config;
                box_text_config = {};
                box_text_config.textColor = Clay_Color{255, 255, 255, 255};
                box_text_config.fontSize = FONT_SIZE_SMALL;
                box_text_config.wrapMode = CLAY_TEXT_WRAP_NONE;

                B32 has_inputs = 0;
                for (S32 i = 0; i < device_count && i < 64; i++) {
                    MidiDeviceInfo *dev = midi_get_device(midi, i);
                    if (!dev->is_input) continue;
                    has_inputs = 1;

                    S32 len = snprintf(device_bufs[i], sizeof(device_bufs[i]), "%s", dev->name);
                    Clay_String device_str = { .isStaticallyAllocated = false, .length = len, .chars = device_bufs[i] };

                    // Velocity-based color: blue (vel 0) → green (mid) → red (vel 127)
                    // Idle = dark gray
                    Clay_Color box_color;
                    if (dev->active) {
                        box_color = velocity_color(dev->velocity);
                    } else if (dev->releasing) {
                        box_color = Clay_Color{255, 255, 255, 255};
                    } else {
                        box_color = Clay_Color{60, 60, 60, 255};
                    }

                    // Box text: note name when held, "OFF" when releasing, "---" when idle
                    S32 nlen;
                    if (dev->active) {
                        S32 pitch = dev->note % 12;
                        S32 octave = (dev->note / 12) - 1;
                        nlen = snprintf(note_bufs[i], sizeof(note_bufs[i]), "%s%d", note_names[pitch], octave);
                    } else if (dev->releasing) {
                        nlen = snprintf(note_bufs[i], sizeof(note_bufs[i]), "OFF");
                    } else {
                        nlen = snprintf(note_bufs[i], sizeof(note_bufs[i]), "---");
                    }
                    Clay_String note_str = { .isStaticallyAllocated = false, .length = nlen, .chars = note_bufs[i] };

                    // Box text color: dark for white bg (releasing), white otherwise
                    Clay_TextElementConfig *box_txt = &box_text_config;
                    static Clay_TextElementConfig box_text_dark;
                    box_text_dark = box_text_config;
                    box_text_dark.textColor = Clay_Color{30, 30, 30, 255};
                    if (dev->releasing) box_txt = &box_text_dark;

                    // Velocity text
                    S32 vlen;
                    if (dev->active)
                        vlen = snprintf(vel_bufs[i], sizeof(vel_bufs[i]), "%d", dev->velocity);
                    else
                        vlen = snprintf(vel_bufs[i], sizeof(vel_bufs[i]), "");
                    Clay_String vel_str = { .isStaticallyAllocated = false, .length = vlen, .chars = vel_bufs[i] };

                    CLAY(CLAY_IDI("MidiIn", i),
                        .layout = {
                            .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIT() },
                            .padding = { uip(4), uip(4), uip(2), uip(2) },
                            .childGap = uip(6),
                            .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
                            .layoutDirection = CLAY_LEFT_TO_RIGHT,
                        }
                    ) {
                        // Note name box (colored by velocity)
                        CLAY(CLAY_IDI("MidiInNote", i),
                            .layout = {
                                .sizing = { .width = CLAY_SIZING_FIXED(uis(36)), .height = CLAY_SIZING_FIXED(uis(18)) },
                                .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
                            },
                            .backgroundColor = box_color,
                            .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS)
                        ) {
                            CLAY_TEXT(note_str, box_txt);
                        }
                        // Velocity number
                        CLAY_TEXT(vel_str, &g_text_config_dim);
                        // Device name
                        CLAY_TEXT(device_str, &g_text_config_normal);
                    }
                }
                if (!has_inputs) {
                    CLAY_TEXT(CLAY_STRING("  No MIDI inputs"), &g_text_config_dim);
                }

                // --- Outputs section ---
                CLAY_TEXT(CLAY_STRING("Outputs"), &g_text_config_dim);

                B32 has_outputs = 0;
                for (S32 i = 0; i < device_count && i < 64; i++) {
                    MidiDeviceInfo *dev = midi_get_device(midi, i);
                    if (dev->is_input) continue;
                    has_outputs = 1;

                    S32 len = snprintf(device_bufs[i], sizeof(device_bufs[i]), "%s", dev->name);
                    Clay_String device_str = { .isStaticallyAllocated = false, .length = len, .chars = device_bufs[i] };

                    CLAY(CLAY_IDI("MidiOut", i),
                        .layout = {
                            .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIT() },
                            .padding = { uip(4), uip(4), uip(2), uip(2) },
                        }
                    ) {
                        CLAY_TEXT(device_str, &g_text_config_normal);
                    }
                }
                if (!has_outputs) {
                    CLAY_TEXT(CLAY_STRING("  No MIDI outputs"), &g_text_config_dim);
                }
            }
        }
    }
}

static void build_log_panel(AppState *app) {
    if (!app->show_log) return;

    Clay_Color lp_top = g_theme.bg_medium;
    Clay_Color lp_bot = {(F32)Max((S32)lp_top.r-8,0), (F32)Max((S32)lp_top.g-8,0), (F32)Max((S32)lp_top.b-8,0), 255};
    CustomGradientData *lp_grad = alloc_gradient(lp_top, lp_bot);

    CLAY(CLAY_ID("LogPanel"),
        .layout = {
            .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(uis(app->log_height)) },
            .layoutDirection = CLAY_TOP_TO_BOTTOM,
        },
        .backgroundColor = lp_top,
        .custom = { .customData = lp_grad },
    ) {
        static const char *bottom_tabs[] = { "Item Editor", "Sample Mapper" };
        ui_tab_bar("BottomTabRow", bottom_tabs, 2, &app->bottom_panel_tab);

        if (app->bottom_panel_tab == 0) {
            // Item Editor tab
            CLAY(CLAY_ID("ItemEditorContent"),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
                    .padding = { uip(8), uip(8), uip(6), uip(6) },
                    .childGap = uip(4),
                    .layoutDirection = CLAY_TOP_TO_BOTTOM,
                }
            ) {
                CLAY(CLAY_ID("ItemEditorHighlight"),
                    .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
                    .backgroundColor = g_theme.bg_lighter
                ) {}
                CLAY_TEXT(CLAY_STRING("Item Editor"), &g_text_config_normal);
            }
        } else {
            // Sample Mapper tab — 88-key piano
            CLAY(CLAY_ID("SampleMapperContent"),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
                    .padding = { uip(4), uip(4), uip(4), uip(4) },
                    .layoutDirection = CLAY_TOP_TO_BOTTOM,
                }
            ) {
                Clay_ElementId piano_id = CLAY_ID("PianoContainer");
                CLAY(piano_id,
                    .layout = {
                        .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
                        .layoutDirection = CLAY_LEFT_TO_RIGHT,
                    }
                ) {
                    // Compute black key size proportional to white keys
                    F32 piano_avail_h = uis(app->log_height) - TAB_HEIGHT - uip(8);
                    F32 black_key_h = piano_avail_h * PIANO_BLACK_H_PCT;
                    if (black_key_h < uis(20)) black_key_h = uis(20);

                    F32 white_key_w = ((F32)app->last_w - uip(8)) / 52.0f;
                    F32 black_key_w = white_key_w * 0.6f;
                    if (black_key_w < uis(8)) black_key_w = uis(8);

                    // White keys (grow to fill width and height)
                    for (S32 note = PIANO_FIRST_NOTE; note <= PIANO_LAST_NOTE; note++) {
                        if (piano_is_black_key(note)) continue;

                        B32 midi_held = midi_is_note_held(app->midi, note);
                        B32 mouse_held = app->piano_mouse_note == note;
                        Clay_Color bg;
                        if (midi_held) {
                            bg = velocity_color(midi_get_note_velocity(app->midi, note));
                        } else if (mouse_held) {
                            bg = g_theme.accent;
                        } else {
                            bg = Clay_Color{240, 240, 240, 255};
                        }

                        CLAY(CLAY_IDI("PKey", note),
                            .layout = {
                                .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
                            },
                            .backgroundColor = bg,
                            .border = { .color = {190, 190, 190, 255}, .width = { .right = 1 } },
                        ) {}
                    }

                    // Black keys (floating, attached to left white key)
                    for (S32 note = PIANO_FIRST_NOTE; note <= PIANO_LAST_NOTE; note++) {
                        if (!piano_is_black_key(note)) continue;

                        Clay_ElementId parent_wkey = CLAY_IDI("PKey", note - 1);
                        B32 midi_held = midi_is_note_held(app->midi, note);
                        B32 mouse_held = app->piano_mouse_note == note;
                        Clay_Color bg;
                        if (midi_held) {
                            bg = velocity_color(midi_get_note_velocity(app->midi, note));
                        } else if (mouse_held) {
                            bg = g_theme.accent;
                        } else {
                            bg = Clay_Color{25, 25, 30, 255};
                        }

                        CLAY(CLAY_IDI("PKey", note),
                            .layout = {
                                .sizing = {
                                    .width = CLAY_SIZING_FIXED(black_key_w),
                                    .height = CLAY_SIZING_FIXED(black_key_h),
                                },
                            },
                            .backgroundColor = bg,
                            .cornerRadius = { .topLeft = 0, .topRight = 0, .bottomLeft = uis(2), .bottomRight = uis(2) },
                            .floating = {
                                .parentId = parent_wkey.id,
                                .zIndex = 100,
                                .attachPoints = {
                                    .element = CLAY_ATTACH_POINT_CENTER_TOP,
                                    .parent = CLAY_ATTACH_POINT_RIGHT_TOP,
                                },
                                .attachTo = CLAY_ATTACH_TO_ELEMENT_WITH_ID,
                            },
                        ) {}
                    }
                }
            }
        }
    }
}

////////////////////////////////
// Corner radius presets (indexed by AppState::radius_sel)
static const F32 radius_values[] = { 0.0f, 4.0f, 6.0f, 10.0f };

// Window content callbacks

static void settings_window_content(void *user_data) {
    AppState *app = (AppState *)user_data;

    static const char *settings_tabs[] = { "Audio", "MIDI", "Keyboard Shortcuts", "Appearance" };
    ui_tab_bar("SettingsTabs", settings_tabs, 4, &app->settings_tab);

    // Tab content area with some top padding
    CLAY(CLAY_ID("SettingsTabContent"),
        .layout = {
            .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIT() },
            .padding = { 0, 0, uip(8), 0 },
            .childGap = uip(6),
            .layoutDirection = CLAY_TOP_TO_BOTTOM,
        }
    ) {
        if (app->settings_tab == 0) {
            // === Audio tab ===
            ui_label("SettingsLblAudio", "Audio Device");

            static const char *audio_options[AUDIO_MAX_DEVICES + 1];
            S32 audio_count = audio_get_device_count(app->audio);
            audio_options[0] = "None";
            for (S32 i = 0; i < audio_count && i < AUDIO_MAX_DEVICES; i++) {
                AudioDeviceInfo *dev = audio_get_device(app->audio, i);
                audio_options[i + 1] = dev ? dev->name : "???";
            }

            CLAY(CLAY_ID("SettingsAudioWrap"),
                .layout = { .sizing = { .width = CLAY_SIZING_FIXED(uis(260)), .height = CLAY_SIZING_FIT() } }
            ) {
                ui_dropdown("SettingsAudio", audio_options, audio_count + 1, &app->audio_device_sel);
            }

            if (app->audio_device_sel != app->audio_device_prev) {
                audio_close_device(app->audio);
                if (app->audio_device_sel > 0) {
                    audio_open_device(app->audio, app->audio_device_sel - 1);
                }
                app->audio_device_prev = app->audio_device_sel;
            }

            CLAY(CLAY_ID("SettingsAudioBtnRow"),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
                    .childGap = uip(8),
                    .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
                    .layoutDirection = CLAY_LEFT_TO_RIGHT,
                }
            ) {
                B32 device_open = (app->audio_device_sel > 0);
                B32 tone_playing = audio_is_test_tone_playing(app->audio);

                if (device_open && !tone_playing) {
                    if (ui_button("BtnTestTone", "Play Test Tone")) {
                        audio_play_test_tone(app->audio);
                    }
                } else {
                    Clay_ElementId btn_eid = CLAY_ID("BtnTestToneDisabled");
                    CLAY(btn_eid,
                        .layout = {
                            .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIXED(uis(28)) },
                            .padding = { uip(12), uip(12), 0, 0 },
                            .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
                        },
                        .backgroundColor = g_theme.disabled_bg,
                        .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS)
                    ) {
                        static Clay_TextElementConfig disabled_text = {};
                        disabled_text.textColor = g_theme.disabled_text;
                        disabled_text.fontSize = FONT_SIZE_NORMAL;
                        disabled_text.wrapMode = CLAY_TEXT_WRAP_NONE;
                        CLAY_TEXT(CLAY_STRING("Play Test Tone"), &disabled_text);
                    }
                }

                if (tone_playing) {
                    ui_label("SettingsLblPlaying", "Playing...");
                }
            }

            ui_checkbox("SettingsVsync", "V-Sync", &app->settings_vsync);

        } else if (app->settings_tab == 1) {
            // === MIDI tab ===
            ui_label("SettingsLblMidi", "MIDI settings will go here.");

        } else if (app->settings_tab == 2) {
            // === Keyboard Shortcuts tab ===
            ui_label("SettingsLblKeys", "Keyboard shortcut settings will go here.");

        } else if (app->settings_tab == 3) {
            // === Appearance tab ===
            ui_label("SettingsLblTheme", "Theme");
            static const char *theme_options[] = { "Dark", "Light" };
            CLAY(CLAY_ID("SettingsThemeWrap"),
                .layout = { .sizing = { .width = CLAY_SIZING_FIXED(uis(220)), .height = CLAY_SIZING_FIT() } }
            ) {
                ui_dropdown("SettingsTheme", theme_options, 2, &app->settings_theme_sel);
            }

            ui_label("SettingsLblAccent", "Accent Color");
            static const char *accent_options[] = { "Blue", "Turquoise", "Orange", "Purple", "Pink", "Red", "Green" };
            CLAY(CLAY_ID("SettingsAccentWrap"),
                .layout = { .sizing = { .width = CLAY_SIZING_FIXED(uis(220)), .height = CLAY_SIZING_FIT() } }
            ) {
                ui_dropdown("SettingsAccent", accent_options, 7, &app->accent_sel);
            }

            ui_label("SettingsLblRadius", "Corner Radius");
            static const char *radius_options[] = { "None", "Small", "Medium", "Large" };
            CLAY(CLAY_ID("SettingsRadiusWrap"),
                .layout = { .sizing = { .width = CLAY_SIZING_FIXED(uis(220)), .height = CLAY_SIZING_FIT() } }
            ) {
                if (ui_dropdown("SettingsRadius", radius_options, 4, &app->radius_sel)) {
                    g_theme.corner_radius = radius_values[app->radius_sel];
                }
            }

            ui_checkbox("SettingsAutosave", "Autosave", &app->settings_autosave);
        }
    }
}

static void about_window_content(void *user_data) {
    (void)user_data;
    ui_label("AboutLbl1", "autosample v0.1");
    ui_label("AboutLbl2", "An audio sampling workstation.");
    ui_label("AboutLbl3", "Built with Clay UI.");
}

////////////////////////////////
// Panel splitter drag logic (called each frame before build_ui)

static void update_panel_splitters(AppState *app) {
    if (app->master_layout != 0) { platform_set_cursor(PLATFORM_CURSOR_ARROW); return; }
    PlatformInput input = g_wstate.input;
    B32 mouse_clicked = input.mouse_down && !input.was_mouse_down;
    B32 mouse_released = !input.mouse_down && input.was_mouse_down;
    PlatformCursor cursor = PLATFORM_CURSOR_ARROW;

    // Check hover on splitter elements with expanded hit area (splitters are 1px)
    F32 grab_margin = uis(3);
    F32 mx = input.mouse_pos.x, my = input.mouse_pos.y;

    B32 hover_browser = false, hover_right = false, hover_log = false;
    {
        Clay_ElementData d = Clay_GetElementData(CLAY_ID("SplitBrowser"));
        if (d.found) {
            Clay_BoundingBox b = d.boundingBox;
            hover_browser = mx >= b.x - grab_margin && mx <= b.x + b.width + grab_margin &&
                            my >= b.y && my <= b.y + b.height;
        }
    }
    {
        Clay_ElementData d = Clay_GetElementData(CLAY_ID("SplitRight"));
        if (d.found) {
            Clay_BoundingBox b = d.boundingBox;
            hover_right = mx >= b.x - grab_margin && mx <= b.x + b.width + grab_margin &&
                          my >= b.y && my <= b.y + b.height;
        }
    }
    {
        Clay_ElementData d = Clay_GetElementData(CLAY_ID("SplitLog"));
        if (d.found) {
            Clay_BoundingBox b = d.boundingBox;
            hover_log = mx >= b.x && mx <= b.x + b.width &&
                        my >= b.y - grab_margin && my <= b.y + b.height + grab_margin;
        }
    }

    // Start drag
    if (mouse_clicked && app->panel_drag == 0) {
        if (hover_browser) {
            app->panel_drag = 1;
            app->panel_drag_start_mouse = input.mouse_pos.x;
            app->panel_drag_start_size = app->browser_width;
        } else if (hover_right) {
            app->panel_drag = 2;
            app->panel_drag_start_mouse = input.mouse_pos.x;
            app->panel_drag_start_size = app->right_col_width;
        } else if (hover_log) {
            app->panel_drag = 3;
            app->panel_drag_start_mouse = input.mouse_pos.y;
            app->panel_drag_start_size = app->log_height;
        }
    }

    // During drag
    if (app->panel_drag == 1) {
        F32 delta = (input.mouse_pos.x - app->panel_drag_start_mouse) / g_ui_scale;
        app->browser_width = Clamp(100.0f, app->panel_drag_start_size + delta, 500.0f);
        cursor = PLATFORM_CURSOR_SIZE_WE;
    } else if (app->panel_drag == 2) {
        F32 delta = (input.mouse_pos.x - app->panel_drag_start_mouse) / g_ui_scale;
        // Right panel: dragging left increases width, right decreases
        app->right_col_width = Clamp(150.0f, app->panel_drag_start_size - delta, 500.0f);
        cursor = PLATFORM_CURSOR_SIZE_WE;
    } else if (app->panel_drag == 3) {
        F32 delta = (input.mouse_pos.y - app->panel_drag_start_mouse) / g_ui_scale;
        // Log panel: dragging up increases height, down decreases
        app->log_height = Clamp(80.0f, app->panel_drag_start_size - delta, 500.0f);
        cursor = PLATFORM_CURSOR_SIZE_NS;
    }

    // End drag
    if (mouse_released) {
        app->panel_drag = 0;
    }

    // Set cursor on hover (when not dragging)
    if (app->panel_drag == 0) {
        if (hover_browser || hover_right) cursor = PLATFORM_CURSOR_SIZE_WE;
        else if (hover_log) cursor = PLATFORM_CURSOR_SIZE_NS;
    }

    platform_set_cursor(cursor);
}

////////////////////////////////
// Header bar — transport / layout toggle

static void build_header_bar(AppState *app) {
    Clay_Color bar_bg = g_theme.header_bg;
    Clay_Color border_bot = {(F32)Max((S32)bar_bg.r - 12, 0), (F32)Max((S32)bar_bg.g - 12, 0), (F32)Max((S32)bar_bg.b - 12, 0), 255};

    static Clay_TextElementConfig header_btn_active_text = {};
    header_btn_active_text.textColor = Clay_Color{255, 255, 255, 255};
    header_btn_active_text.fontSize = FONT_SIZE_NORMAL;
    header_btn_active_text.wrapMode = CLAY_TEXT_WRAP_NONE;

    static Clay_TextElementConfig header_clock_text = {};
    header_clock_text.textColor = g_theme.text;
    header_clock_text.fontSize = uifs(22);
    header_clock_text.wrapMode = CLAY_TEXT_WRAP_NONE;

    static Clay_TextElementConfig header_indicator_text = {};
    header_indicator_text.textColor = g_theme.text;
    header_indicator_text.fontSize = FONT_SIZE_NORMAL;
    header_indicator_text.wrapMode = CLAY_TEXT_WRAP_NONE;

    static Clay_TextElementConfig header_indicator_label = {};
    header_indicator_label.textColor = g_theme.text_dim;
    header_indicator_label.fontSize = FONT_SIZE_SMALL;
    header_indicator_label.wrapMode = CLAY_TEXT_WRAP_NONE;

    Clay_Color inset_bg = {(F32)Max((S32)bar_bg.r - 8, 0), (F32)Max((S32)bar_bg.g - 8, 0), (F32)Max((S32)bar_bg.b - 8, 0), 255};

    CLAY(CLAY_ID("HeaderBar"),
        .layout = {
            .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(uis(64)) },
            .padding = { uip(10), uip(10), uip(6), uip(6) },
            .childGap = uip(8),
            .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
            .layoutDirection = CLAY_LEFT_TO_RIGHT,
        },
        .backgroundColor = bar_bg,
        .border = { .color = border_bot, .width = { .bottom = 2 } },
    ) {
        // === LEFT: toolbar buttons ===
        CLAY(CLAY_ID("ToolbarGroup"),
            .layout = {
                .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
                .childGap = uip(4),
                .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
                .layoutDirection = CLAY_LEFT_TO_RIGHT,
            }
        ) {
            // Rewind
            CLAY(CLAY_ID("TbRewind"),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_FIXED(uis(32)), .height = CLAY_SIZING_FIXED(uis(32)) },
                    .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
                },
                .backgroundColor = g_theme.bg_lighter,
                .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
            ) { CLAY_TEXT(CLAY_STRING("<<"), &g_text_config_dim); }

            // Stop
            CLAY(CLAY_ID("TbStop"),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_FIXED(uis(32)), .height = CLAY_SIZING_FIXED(uis(32)) },
                    .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
                },
                .backgroundColor = g_theme.bg_lighter,
                .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
            ) { CLAY_TEXT(CLAY_STRING("[]"), &g_text_config_dim); }

            // Play
            CLAY(CLAY_ID("TbPlay"),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_FIXED(uis(32)), .height = CLAY_SIZING_FIXED(uis(32)) },
                    .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
                },
                .backgroundColor = g_theme.bg_lighter,
                .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
            ) { CLAY_TEXT(CLAY_STRING(">"), &g_text_config_dim); }

            // Record
            CLAY(CLAY_ID("TbRecord"),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_FIXED(uis(32)), .height = CLAY_SIZING_FIXED(uis(32)) },
                    .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
                },
                .backgroundColor = g_theme.bg_lighter,
                .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
            ) {
                static Clay_TextElementConfig rec_text = {};
                rec_text.textColor = Clay_Color{200, 60, 60, 255};
                rec_text.fontSize = FONT_SIZE_NORMAL;
                rec_text.wrapMode = CLAY_TEXT_WRAP_NONE;
                CLAY_TEXT(CLAY_STRING("O"), &rec_text);
            }
        }

        // Spacer
        CLAY(CLAY_ID("HeaderSpacerL"),
            .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } }
        ) {}

        // === CENTER: time display (nearly full header height) ===
        CLAY(CLAY_ID("TimeDisplay"),
            .layout = {
                .sizing = { .width = CLAY_SIZING_FIXED(uis(200)), .height = CLAY_SIZING_FIXED(uis(48)) },
                .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
            },
            .backgroundColor = inset_bg,
            .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
            .border = { .color = border_bot, .width = { .left = 1, .right = 1, .top = 1, .bottom = 1 } },
        ) {
            CLAY_TEXT(CLAY_STRING("00:00:00.000"), &header_clock_text);
        }

        // === Tempo & time sig indicators ===
        CLAY(CLAY_ID("IndicatorGroup"),
            .layout = {
                .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
                .childGap = uip(10),
                .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
                .layoutDirection = CLAY_LEFT_TO_RIGHT,
            }
        ) {
            // Tempo
            CLAY(CLAY_ID("TempoBox"),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIXED(uis(48)) },
                    .padding = { uip(10), uip(10), 0, 0 },
                    .childGap = uip(2),
                    .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
                    .layoutDirection = CLAY_TOP_TO_BOTTOM,
                },
                .backgroundColor = inset_bg,
                .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
                .border = { .color = border_bot, .width = { .left = 1, .right = 1, .top = 1, .bottom = 1 } },
            ) {
                CLAY_TEXT(CLAY_STRING("TEMPO"), &header_indicator_label);
                CLAY_TEXT(CLAY_STRING("120.00"), &header_indicator_text);
            }

            // Time Signature
            CLAY(CLAY_ID("TimeSigBox"),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIXED(uis(48)) },
                    .padding = { uip(10), uip(10), 0, 0 },
                    .childGap = uip(2),
                    .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
                    .layoutDirection = CLAY_TOP_TO_BOTTOM,
                },
                .backgroundColor = inset_bg,
                .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
                .border = { .color = border_bot, .width = { .left = 1, .right = 1, .top = 1, .bottom = 1 } },
            ) {
                CLAY_TEXT(CLAY_STRING("SIGNATURE"), &header_indicator_label);
                CLAY_TEXT(CLAY_STRING("4 / 4"), &header_indicator_text);
            }
        }

        // Spacer
        CLAY(CLAY_ID("HeaderSpacerR"),
            .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } }
        ) {}

        // === RIGHT: Edit / Mix buttons ===
        // Edit button
        {
            Clay_ElementId edit_eid = CLAY_ID("BtnLayoutEdit");
            B32 edit_hovered = Clay_PointerOver(edit_eid);
            B32 edit_active = (app->master_layout == 0);
            Clay_Color edit_bg = edit_active ? g_theme.accent : g_theme.bg_lighter;
            if (edit_hovered && !edit_active) edit_bg = g_theme.accent_hover;
            CLAY(edit_eid,
                .layout = {
                    .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIXED(uis(28)) },
                    .padding = { uip(14), uip(14), 0, 0 },
                    .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
                },
                .backgroundColor = edit_bg,
                .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
            ) {
                CLAY_TEXT(CLAY_STRING("Edit"), edit_active ? &header_btn_active_text : &g_text_config_normal);
            }
            if (edit_hovered && g_wstate.mouse_clicked) {
                app->master_layout = 0;
            }
        }

        // Mix button
        {
            Clay_ElementId mix_eid = CLAY_ID("BtnLayoutMix");
            B32 mix_hovered = Clay_PointerOver(mix_eid);
            B32 mix_active = (app->master_layout == 1);
            Clay_Color mix_bg = mix_active ? g_theme.accent : g_theme.bg_lighter;
            if (mix_hovered && !mix_active) mix_bg = g_theme.accent_hover;
            CLAY(mix_eid,
                .layout = {
                    .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIXED(uis(28)) },
                    .padding = { uip(14), uip(14), 0, 0 },
                    .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
                },
                .backgroundColor = mix_bg,
                .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
            ) {
                CLAY_TEXT(CLAY_STRING("Mix"), mix_active ? &header_btn_active_text : &g_text_config_normal);
            }
            if (mix_hovered && g_wstate.mouse_clicked) {
                app->master_layout = 1;
            }
        }

        // Patch button
        {
            Clay_ElementId patch_eid = CLAY_ID("BtnLayoutPatch");
            B32 patch_hovered = Clay_PointerOver(patch_eid);
            B32 patch_active = (app->master_layout == 2);
            Clay_Color patch_bg = patch_active ? g_theme.accent : g_theme.bg_lighter;
            if (patch_hovered && !patch_active) patch_bg = g_theme.accent_hover;
            CLAY(patch_eid,
                .layout = {
                    .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIXED(uis(28)) },
                    .padding = { uip(14), uip(14), 0, 0 },
                    .childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
                },
                .backgroundColor = patch_bg,
                .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
            ) {
                CLAY_TEXT(CLAY_STRING("Patch"), patch_active ? &header_btn_active_text : &g_text_config_normal);
            }
            if (patch_hovered && g_wstate.mouse_clicked) {
                app->master_layout = 2;
            }
        }
    }
}

////////////////////////////////
// Mix view — channel strip faders

static void build_mix_view(AppState *app) {
    Clay_Color mv_top = g_theme.bg_medium;
    Clay_Color mv_bot = {(F32)Max((S32)mv_top.r - 8, 0), (F32)Max((S32)mv_top.g - 8, 0), (F32)Max((S32)mv_top.b - 8, 0), 255};
    CustomGradientData *mv_grad = alloc_gradient(mv_top, mv_bot);

    CLAY(CLAY_ID("MixView"),
        .layout = {
            .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
            .padding = { uip(4), uip(4), uip(4), uip(4) },
            .childGap = 0,
            .layoutDirection = CLAY_LEFT_TO_RIGHT,
        },
        .backgroundColor = mv_top,
        .custom = { .customData = mv_grad },
    ) {
        static char ch_label_bufs[8][8];
        static char fader_id_bufs[8][16];
        static char pan_id_bufs[8][16];

        for (S32 i = 0; i < 8; i++) {
            snprintf(ch_label_bufs[i], sizeof(ch_label_bufs[i]), "Ch %d", i + 1);
            snprintf(fader_id_bufs[i], sizeof(fader_id_bufs[i]), "MixFader%d", i);
            snprintf(pan_id_bufs[i], sizeof(pan_id_bufs[i]), "MixPan%d", i);

            Clay_Color strip_bg = g_theme.bg_medium;

            CLAY(CLAY_IDI("MixStrip", i),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
                    .padding = { uip(8), uip(8), uip(8), uip(8) },
                    .childGap = uip(8),
                    .childAlignment = { .x = CLAY_ALIGN_X_CENTER },
                    .layoutDirection = CLAY_TOP_TO_BOTTOM,
                },
                .backgroundColor = strip_bg,
                .border = { .color = g_theme.border, .width = { .right = 1 } },
            ) {
                // Channel label
                S32 llen = snprintf(ch_label_bufs[i], sizeof(ch_label_bufs[i]), "Ch %d", i + 1);
                Clay_String ch_str = { .isStaticallyAllocated = false, .length = llen, .chars = ch_label_bufs[i] };
                CLAY_TEXT(ch_str, &g_text_config_dim);

                // SEND/RECV button
                Clay_ElementId sr_eid = CLAY_IDI("MixSendRecv", i);
                B32 sr_hovered = Clay_PointerOver(sr_eid);
                CLAY(sr_eid,
                    .layout = {
                        .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(uis(22)) },
                        .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
                    },
                    .backgroundColor = sr_hovered ? g_theme.accent_hover : g_theme.bg_lighter,
                    .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
                ) {
                    CLAY_TEXT(CLAY_STRING("SEND/RECV"), &g_text_config_dim);
                }

                // Spacer pushes pan + fader to bottom
                CLAY(CLAY_IDI("MixSpacer", i),
                    .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() } }
                ) {}

                // Pan knob
                ui_knob(pan_id_bufs[i], "Pan", &app->mix_pans[i], 50.0f, 1, 0.0f, 1);

                // Fader
                ui_fader(fader_id_bufs[i], ch_label_bufs[i], &app->mix_faders[i], 10.0f, 0, 0.0f, 1);
            }
        }

        // Master strip (slightly wider, accent-tinted)
        {
            Clay_Color master_bg = {
                (F32)Min((S32)g_theme.bg_medium.r + 6, 255),
                (F32)Min((S32)g_theme.bg_medium.g + 6, 255),
                (F32)Min((S32)g_theme.bg_medium.b + 6, 255),
                255
            };
            static F32 master_fader = 0.0f;

            CLAY(CLAY_ID("MixMaster"),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_GROW(0, uis(120)), .height = CLAY_SIZING_GROW() },
                    .padding = { uip(8), uip(8), uip(8), uip(8) },
                    .childGap = uip(8),
                    .childAlignment = { .x = CLAY_ALIGN_X_CENTER },
                    .layoutDirection = CLAY_TOP_TO_BOTTOM,
                },
                .backgroundColor = master_bg,
            ) {
                CLAY_TEXT(CLAY_STRING("Master"), &g_text_config_normal);

                // SEND/RECV button
                {
                    Clay_ElementId msr_eid = CLAY_ID("MixMasterSendRecv");
                    B32 msr_hovered = Clay_PointerOver(msr_eid);
                    CLAY(msr_eid,
                        .layout = {
                            .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(uis(22)) },
                            .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
                        },
                        .backgroundColor = msr_hovered ? g_theme.accent_hover : g_theme.bg_lighter,
                        .cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS),
                    ) {
                        CLAY_TEXT(CLAY_STRING("SEND/RECV"), &g_text_config_dim);
                    }
                }

                CLAY(CLAY_ID("MixMasterSpacer"),
                    .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() } }
                ) {}

                // Master pan knob
                ui_knob("MixMasterPan", "Pan", &app->mix_master_pan, 50.0f, 1, 0.0f, 1);

                ui_fader("MixMasterFader", "Master", &master_fader, 10.0f, 0, 0.0f, 1);
            }
        }
    }
}

////////////////////////////////
// Patch view — routing matrix / graph

static void build_patch_view(AppState *app) {
    Clay_Color pv_top = g_theme.bg_medium;
    Clay_Color pv_bot = {(F32)Max((S32)pv_top.r - 8, 0), (F32)Max((S32)pv_top.g - 8, 0), (F32)Max((S32)pv_top.b - 8, 0), 255};
    CustomGradientData *pv_grad = alloc_gradient(pv_top, pv_bot);

    CLAY(CLAY_ID("PatchView"),
        .layout = {
            .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
            .layoutDirection = CLAY_TOP_TO_BOTTOM,
        },
        .backgroundColor = pv_top,
        .custom = { .customData = pv_grad },
    ) {
        static const char *patch_tabs[] = { "Matrix", "Graph" };
        ui_tab_bar("PatchTabs", patch_tabs, 2, &app->patch_tab);

        if (app->patch_tab == 0) {
            // === Matrix routing view ===
            #define MATRIX_INPUTS  32
            #define MATRIX_OUTPUTS 33  // Master + Out 1..32
            #define HW_OUTPUTS     32

            static Clay_TextElementConfig matrix_hdr_text = {};
            matrix_hdr_text.textColor = g_theme.text_dim;
            matrix_hdr_text.fontSize = FONT_SIZE_SMALL;
            matrix_hdr_text.wrapMode = CLAY_TEXT_WRAP_NONE;

            static Clay_TextElementConfig matrix_axis_text = {};
            matrix_axis_text.textColor = g_theme.text;
            matrix_axis_text.fontSize = FONT_SIZE_SMALL;
            matrix_axis_text.wrapMode = CLAY_TEXT_WRAP_NONE;

            static Clay_TextElementConfig matrix_title_text = {};
            matrix_title_text.textColor = g_theme.text;
            matrix_title_text.fontSize = FONT_SIZE_NORMAL;
            matrix_title_text.wrapMode = CLAY_TEXT_WRAP_NONE;

            static Clay_TextElementConfig cell_x_text = {};
            cell_x_text.textColor = Clay_Color{255, 255, 255, 255};
            cell_x_text.fontSize = FONT_SIZE_SMALL;
            cell_x_text.wrapMode = CLAY_TEXT_WRAP_NONE;

            static Clay_TextElementConfig fb_text = {};
            fb_text.textColor = Clay_Color{80, 80, 80, 255};
            fb_text.fontSize = FONT_SIZE_SMALL;
            fb_text.wrapMode = CLAY_TEXT_WRAP_NONE;

            F32 cell_size = uis(20);
            F32 label_w = uis(48);

            // Scrollable container for both matrices side by side
            CLAY(CLAY_ID("MatrixScroll"),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
                    .padding = { uip(12), uip(12), uip(8), uip(8) },
                    .childGap = uip(32),
                    .layoutDirection = CLAY_LEFT_TO_RIGHT,
                },
                .clip = { .horizontal = true, .vertical = true, .childOffset = Clay_GetScrollOffset() },
            ) {
                // ============================================================
                // INTERNAL ROUTING matrix (32 inputs x 33 outputs)
                // ============================================================
                CLAY(CLAY_ID("InternalMatrix"),
                    .layout = {
                        .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
                        .childGap = uip(4),
                        .layoutDirection = CLAY_TOP_TO_BOTTOM,
                    }
                ) {
                    // Title
                    CLAY_TEXT(CLAY_STRING("Internal Routing"), &matrix_title_text);

                    // Axis label: "OUTPUT >"
                    CLAY(CLAY_ID("IntOutputLabel"),
                        .layout = {
                            .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
                            .padding = { (U16)label_w, 0, 0, 0 },
                        }
                    ) {
                        CLAY_TEXT(CLAY_STRING("OUTPUT >"), &matrix_axis_text);
                    }

                    // Grid
                    CLAY(CLAY_ID("IntGrid"),
                        .layout = {
                            .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
                            .layoutDirection = CLAY_TOP_TO_BOTTOM,
                        }
                    ) {
                        // Column headers
                        CLAY(CLAY_ID("IntHeaderRow"),
                            .layout = {
                                .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIXED(cell_size) },
                                .layoutDirection = CLAY_LEFT_TO_RIGHT,
                            }
                        ) {
                            CLAY(CLAY_ID("IntCorner"),
                                .layout = {
                                    .sizing = { .width = CLAY_SIZING_FIXED(label_w), .height = CLAY_SIZING_FIXED(cell_size) },
                                    .padding = { 0, uip(4), 0, 0 },
                                    .childAlignment = { .x = CLAY_ALIGN_X_RIGHT, .y = CLAY_ALIGN_Y_CENTER },
                                }
                            ) {
                                CLAY_TEXT(CLAY_STRING("INPUT v"), &matrix_axis_text);
                            }

                            static char int_dst_bufs[MATRIX_OUTPUTS][8];
                            for (S32 d = 0; d < MATRIX_OUTPUTS; d++) {
                                S32 dlen;
                                if (d == 0)
                                    dlen = snprintf(int_dst_bufs[d], sizeof(int_dst_bufs[d]), "Mst");
                                else
                                    dlen = snprintf(int_dst_bufs[d], sizeof(int_dst_bufs[d]), "%d", d);
                                Clay_String dst_str = { .isStaticallyAllocated = false, .length = dlen, .chars = int_dst_bufs[d] };

                                CLAY(CLAY_IDI("IntDstHdr", d),
                                    .layout = {
                                        .sizing = { .width = CLAY_SIZING_FIXED(cell_size), .height = CLAY_SIZING_FIXED(cell_size) },
                                        .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
                                    },
                                ) {
                                    CLAY_TEXT(dst_str, d == 0 ? &matrix_axis_text : &matrix_hdr_text);
                                }
                            }
                        }

                        // Rows
                        static char int_src_bufs[MATRIX_INPUTS][8];
                        for (S32 s = 0; s < MATRIX_INPUTS; s++) {
                            S32 slen = snprintf(int_src_bufs[s], sizeof(int_src_bufs[s]), "Ch %d", s + 1);
                            Clay_String src_str = { .isStaticallyAllocated = false, .length = slen, .chars = int_src_bufs[s] };

                            CLAY(CLAY_IDI("IntRow", s),
                                .layout = {
                                    .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIXED(cell_size) },
                                    .layoutDirection = CLAY_LEFT_TO_RIGHT,
                                }
                            ) {
                                CLAY(CLAY_IDI("IntSrcLbl", s),
                                    .layout = {
                                        .sizing = { .width = CLAY_SIZING_FIXED(label_w), .height = CLAY_SIZING_FIXED(cell_size) },
                                        .padding = { 0, uip(4), 0, 0 },
                                        .childAlignment = { .x = CLAY_ALIGN_X_RIGHT, .y = CLAY_ALIGN_Y_CENTER },
                                    },
                                ) {
                                    CLAY_TEXT(src_str, &matrix_hdr_text);
                                }

                                for (S32 d = 0; d < MATRIX_OUTPUTS; d++) {
                                    S32 cell_idx = s * MATRIX_OUTPUTS + d;
                                    Clay_ElementId cell_eid = CLAY_IDI("IntCell", cell_idx);
                                    B32 cell_hovered = Clay_PointerOver(cell_eid);

                                    B32 is_feedback = (d >= 1 && d == s + 1);
                                    if (is_feedback) app->patch_matrix[s][d] = 0;

                                    B32 active = app->patch_matrix[s][d];

                                    Clay_Color cell_bg;
                                    if (is_feedback) {
                                        cell_bg = Clay_Color{
                                            (F32)Max((S32)g_theme.bg_dark.r - 10, 0),
                                            (F32)Max((S32)g_theme.bg_dark.g - 10, 0),
                                            (F32)Max((S32)g_theme.bg_dark.b - 10, 0), 255
                                        };
                                    } else if (active) {
                                        cell_bg = g_theme.accent;
                                    } else if (cell_hovered) {
                                        cell_bg = g_theme.bg_lighter;
                                    } else if ((s + d) % 2 == 0) {
                                        cell_bg = g_theme.bg_dark;
                                    } else {
                                        cell_bg = Clay_Color{
                                            (F32)Min((S32)g_theme.bg_dark.r + 6, 255),
                                            (F32)Min((S32)g_theme.bg_dark.g + 6, 255),
                                            (F32)Min((S32)g_theme.bg_dark.b + 6, 255), 255
                                        };
                                    }

                                    if (d == 0 && !active && !cell_hovered && !is_feedback) {
                                        cell_bg = Clay_Color{
                                            (F32)Min((S32)cell_bg.r + 10, 255),
                                            (F32)Min((S32)cell_bg.g + 10, 255),
                                            (F32)Min((S32)cell_bg.b + 12, 255), 255
                                        };
                                    }

                                    CLAY(cell_eid,
                                        .layout = {
                                            .sizing = { .width = CLAY_SIZING_FIXED(cell_size), .height = CLAY_SIZING_FIXED(cell_size) },
                                            .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
                                        },
                                        .backgroundColor = cell_bg,
                                        .border = { .color = g_theme.border, .width = { .right = 1, .bottom = 1 } },
                                    ) {
                                        if (is_feedback) {
                                            CLAY_TEXT(CLAY_STRING("-"), &fb_text);
                                        } else if (active) {
                                            CLAY_TEXT(CLAY_STRING("X"), &cell_x_text);
                                        }
                                    }

                                    if (!is_feedback && cell_hovered && g_wstate.mouse_clicked) {
                                        app->patch_matrix[s][d] = !app->patch_matrix[s][d];
                                    }
                                }
                            }
                        }
                    }
                }

                // ============================================================
                // HARDWARE ROUTING matrix (32 ch outputs x 32 hw outputs)
                // ============================================================
                CLAY(CLAY_ID("HardwareMatrix"),
                    .layout = {
                        .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
                        .childGap = uip(4),
                        .layoutDirection = CLAY_TOP_TO_BOTTOM,
                    }
                ) {
                    // Title
                    CLAY_TEXT(CLAY_STRING("Hardware Routing"), &matrix_title_text);

                    // Axis label: "HW OUTPUT >"
                    CLAY(CLAY_ID("HwOutputLabel"),
                        .layout = {
                            .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
                            .padding = { (U16)label_w, 0, 0, 0 },
                        }
                    ) {
                        CLAY_TEXT(CLAY_STRING("HW OUTPUT >"), &matrix_axis_text);
                    }

                    // Grid
                    CLAY(CLAY_ID("HwGrid"),
                        .layout = {
                            .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
                            .layoutDirection = CLAY_TOP_TO_BOTTOM,
                        }
                    ) {
                        // Column headers
                        CLAY(CLAY_ID("HwHeaderRow"),
                            .layout = {
                                .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIXED(cell_size) },
                                .layoutDirection = CLAY_LEFT_TO_RIGHT,
                            }
                        ) {
                            CLAY(CLAY_ID("HwCorner"),
                                .layout = {
                                    .sizing = { .width = CLAY_SIZING_FIXED(label_w), .height = CLAY_SIZING_FIXED(cell_size) },
                                    .padding = { 0, uip(4), 0, 0 },
                                    .childAlignment = { .x = CLAY_ALIGN_X_RIGHT, .y = CLAY_ALIGN_Y_CENTER },
                                }
                            ) {
                                CLAY_TEXT(CLAY_STRING("CH OUT v"), &matrix_axis_text);
                            }

                            static char hw_dst_bufs[HW_OUTPUTS][8];
                            for (S32 d = 0; d < HW_OUTPUTS; d++) {
                                S32 dlen = snprintf(hw_dst_bufs[d], sizeof(hw_dst_bufs[d]), "%d", d + 1);
                                Clay_String dst_str = { .isStaticallyAllocated = false, .length = dlen, .chars = hw_dst_bufs[d] };

                                CLAY(CLAY_IDI("HwDstHdr", d),
                                    .layout = {
                                        .sizing = { .width = CLAY_SIZING_FIXED(cell_size), .height = CLAY_SIZING_FIXED(cell_size) },
                                        .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
                                    },
                                ) {
                                    CLAY_TEXT(dst_str, &matrix_hdr_text);
                                }
                            }
                        }

                        // Rows
                        static char hw_src_bufs[HW_OUTPUTS][8];
                        for (S32 s = 0; s < HW_OUTPUTS; s++) {
                            S32 slen = snprintf(hw_src_bufs[s], sizeof(hw_src_bufs[s]), "Out %d", s + 1);
                            Clay_String src_str = { .isStaticallyAllocated = false, .length = slen, .chars = hw_src_bufs[s] };

                            CLAY(CLAY_IDI("HwRow", s),
                                .layout = {
                                    .sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIXED(cell_size) },
                                    .layoutDirection = CLAY_LEFT_TO_RIGHT,
                                }
                            ) {
                                CLAY(CLAY_IDI("HwSrcLbl", s),
                                    .layout = {
                                        .sizing = { .width = CLAY_SIZING_FIXED(label_w), .height = CLAY_SIZING_FIXED(cell_size) },
                                        .padding = { 0, uip(4), 0, 0 },
                                        .childAlignment = { .x = CLAY_ALIGN_X_RIGHT, .y = CLAY_ALIGN_Y_CENTER },
                                    },
                                ) {
                                    CLAY_TEXT(src_str, &matrix_hdr_text);
                                }

                                for (S32 d = 0; d < HW_OUTPUTS; d++) {
                                    S32 cell_idx = s * HW_OUTPUTS + d;
                                    Clay_ElementId cell_eid = CLAY_IDI("HwCell", cell_idx);
                                    B32 cell_hovered = Clay_PointerOver(cell_eid);
                                    B32 active = app->hw_matrix[s][d];

                                    Clay_Color cell_bg;
                                    if (active) {
                                        cell_bg = g_theme.accent;
                                    } else if (cell_hovered) {
                                        cell_bg = g_theme.bg_lighter;
                                    } else if ((s + d) % 2 == 0) {
                                        cell_bg = g_theme.bg_dark;
                                    } else {
                                        cell_bg = Clay_Color{
                                            (F32)Min((S32)g_theme.bg_dark.r + 6, 255),
                                            (F32)Min((S32)g_theme.bg_dark.g + 6, 255),
                                            (F32)Min((S32)g_theme.bg_dark.b + 6, 255), 255
                                        };
                                    }

                                    CLAY(cell_eid,
                                        .layout = {
                                            .sizing = { .width = CLAY_SIZING_FIXED(cell_size), .height = CLAY_SIZING_FIXED(cell_size) },
                                            .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
                                        },
                                        .backgroundColor = cell_bg,
                                        .border = { .color = g_theme.border, .width = { .right = 1, .bottom = 1 } },
                                    ) {
                                        if (active) {
                                            CLAY_TEXT(CLAY_STRING("X"), &cell_x_text);
                                        }
                                    }

                                    if (cell_hovered && g_wstate.mouse_clicked) {
                                        app->hw_matrix[s][d] = !app->hw_matrix[s][d];
                                    }
                                }
                            }
                        }
                    }
                }
            }
        } else {
            // === Graph view (placeholder) ===
            CLAY(CLAY_ID("GraphContent"),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
                    .padding = { uip(16), uip(16), uip(12), uip(12) },
                    .childGap = 0,
                    .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
                }
            ) {
                CLAY_TEXT(CLAY_STRING("Graph view coming soon"), &g_text_config_dim);
            }
        }
    }
}

////////////////////////////////
// Build the full UI layout for one frame

static void build_ui(AppState *app) {
    CLAY(CLAY_ID("Root"),
        .layout = {
            .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
            .layoutDirection = CLAY_TOP_TO_BOTTOM,
        }
    ) {
        build_header_bar(app);

        if (app->master_layout == 0) {
            // === EDIT MODE (existing layout) ===
            CLAY(CLAY_ID("TopRow"),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
                    .layoutDirection = CLAY_LEFT_TO_RIGHT,
                }
            ) {
                build_browser_panel(app);

                // Browser splitter (vertical, 1px line)
                if (app->show_browser) {
                    CLAY(CLAY_ID("SplitBrowser"),
                        .layout = { .sizing = { .width = CLAY_SIZING_FIXED(1), .height = CLAY_SIZING_GROW() } },
                        .backgroundColor = g_theme.border
                    ) {}
                }

                build_main_panel(app);

                if (app->show_props || app->show_midi_devices) {
                    // Right splitter (vertical, 1px line)
                    CLAY(CLAY_ID("SplitRight"),
                        .layout = { .sizing = { .width = CLAY_SIZING_FIXED(1), .height = CLAY_SIZING_GROW() } },
                        .backgroundColor = g_theme.border
                    ) {}

                    CLAY(CLAY_ID("RightColumn"),
                        .layout = {
                            .sizing = { .width = CLAY_SIZING_FIXED(uis(app->right_col_width)), .height = CLAY_SIZING_GROW() },
                            .layoutDirection = CLAY_TOP_TO_BOTTOM,
                        },
                    ) {
                        build_right_panel(app);
                    }
                }
            }

            // Log splitter (horizontal, 1px line)
            if (app->show_log) {
                CLAY(CLAY_ID("SplitLog"),
                    .layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) } },
                    .backgroundColor = g_theme.border
                ) {}
            }

            build_log_panel(app);
        } else if (app->master_layout == 1) {
            // === MIX MODE ===
            build_mix_view(app);
        } else {
            // === PATCH MODE ===
            build_patch_view(app);
        }
    }

    // Draggable windows (rendered as floating elements above normal UI)
    ui_window("WinSettings", "Preferences", &app->show_settings_window,
              Vec2F32{100, 100}, Vec2F32{480, 0},
              settings_window_content, app);

    ui_window("WinAbout", "About", &app->show_about_window,
              Vec2F32{200, 150}, Vec2F32{260, 0},
              about_window_content, nullptr);

    // Modal confirmation dialog
    if (app->show_confirm_dialog) {
        static const char *confirm_buttons[] = { "Cancel", "OK" };
        S32 modal_result = ui_modal("ModalConfirm", "Confirm Action",
            "Are you sure you want to proceed? This action cannot be undone.",
            confirm_buttons, 2);
        if (modal_result != -1) {
            app->show_confirm_dialog = 0;
        }
    }
}

////////////////////////////////
// Render one frame: resize if needed, build UI, submit to GPU.
// Called from the main loop and from WM_SIZE during live resize.

static void do_frame(AppState *app) {
    // Timing
#ifdef __APPLE__
    U64 now = mach_absolute_time();
    F32 dt = (F32)(now - app->last_time) * (F32)app->freq_numer / ((F32)app->freq_denom * 1e9f);
    app->last_time = now;
#else
    LARGE_INTEGER now;
    QueryPerformanceCounter(&now);
    F32 dt = (F32)(now.QuadPart - app->last_time.QuadPart) / (F32)app->freq.QuadPart;
    app->last_time = now;
#endif
    if (dt > 0.1f) dt = 0.1f;

    // Resize
    S32 w, h;
    platform_get_size(app->window, &w, &h);
    if (w != app->last_w || h != app->last_h) {
        renderer_resize(app->renderer, w, h);
        app->last_w = w;
        app->last_h = h;
    }

    if (!renderer_begin_frame(app->renderer))
        return;

    // Update subsystems
    midi_update(app->midi, dt);
    audio_update(app->audio, dt);

    // Gather input
    PlatformInput input = platform_get_input(app->window);

    // Cmd+= / Cmd+- (or Ctrl on Windows) to zoom UI, Cmd+0 to reset
    for (S32 k = 0; k < input.key_count; k++) {
        if (input.ctrl_held) {
            if (input.keys[k] == PKEY_EQUAL) app->ui_scale *= 1.1f;
            if (input.keys[k] == PKEY_MINUS) app->ui_scale /= 1.1f;
            if (input.keys[k] == PKEY_0)     app->ui_scale = 1.0f;
        }
    }
    app->ui_scale = Clamp(0.5f, app->ui_scale, 3.0f);
    g_ui_scale = app->ui_scale;
    F32 dpi_scale = platform_get_dpi_scale(app->window);
    renderer_set_font_scale(app->renderer, app->ui_scale * dpi_scale);

    // Handle theme change
    if (app->settings_theme_sel != app->settings_theme_prev) {
        ui_set_theme(app->settings_theme_sel);
        ui_set_accent(app->accent_sel); // reapply accent on new base theme
        g_theme.corner_radius = radius_values[app->radius_sel]; // preserve user radius
        app->settings_theme_prev = app->settings_theme_sel;

        // Refresh all text configs with new theme colors
        g_text_config_normal.textColor = g_theme.text;
        g_text_config_title.textColor  = g_theme.text;
        g_text_config_dim.textColor    = g_theme.text_dim;
        ui_widgets_theme_changed();

        // Update renderer clear color to match theme
        renderer_set_clear_color(app->renderer,
            g_theme.bg_dark.r / 255.f, g_theme.bg_dark.g / 255.f, g_theme.bg_dark.b / 255.f);
    }

    // Handle accent change
    if (app->accent_sel != app->accent_prev) {
        ui_set_accent(app->accent_sel);
        app->accent_prev = app->accent_sel;

        g_text_config_normal.textColor = g_theme.text;
        g_text_config_title.textColor  = g_theme.text;
        g_text_config_dim.textColor    = g_theme.text_dim;
        ui_widgets_theme_changed();
    }

    // Update text configs when scale changes
    if (g_text_config_normal.fontSize != FONT_SIZE_NORMAL) {
        g_text_config_normal.fontSize = FONT_SIZE_NORMAL;
        g_text_config_title.fontSize  = FONT_SIZE_NORMAL;
        g_text_config_dim.fontSize    = FONT_SIZE_NORMAL;
    }

    ui_widgets_begin_frame(input);
    update_piano_input(app);
    update_panel_splitters(app);

    // Build UI with Clay
    ui_begin_frame(app->ui, (F32)w, (F32)h, input.mouse_pos, input.mouse_down,
                   input.scroll_delta, dt);
    build_ui(app);
    Clay_RenderCommandArray render_commands = ui_end_frame(app->ui);

    // Render
    renderer_end_frame(app->renderer, render_commands);
}

////////////////////////////////
// Platform frame callback for live resize

static void frame_callback(void *user_data) {
    do_frame((AppState *)user_data);
}

////////////////////////////////
// Entry point

int main(int argc, char **argv) {
    (void)argc;
    (void)argv;

    PlatformWindowDesc window_desc = {};
    PlatformWindow *window = platform_create_window(&window_desc);
    if (!window)
        return 1;

    S32 w, h;
    platform_get_size(window, &w, &h);

    RendererDesc renderer_desc = {};
    renderer_desc.window_handle = platform_get_native_handle(window);
    renderer_desc.width         = w;
    renderer_desc.height        = h;
    Renderer *renderer = renderer_create(&renderer_desc);
    if (!renderer) {
        platform_destroy_window(window);
        return 1;
    }

    MidiEngine *midi = midi_create();
    AudioEngine *audio = audio_create(platform_get_native_handle(window));

    // Initialize UI (Clay)
    ui_set_theme(0);
    UI_Context *ui = ui_create((F32)w, (F32)h);
    ui_set_measure_text_fn(ui, renderer_measure_text, renderer);
    init_text_configs();

    setup_menus(window);
    ui_widgets_init();

    // Rasterize icon atlas and upload to GPU
    {
        S32 iw, ih;
        U8 *icon_atlas = ui_icons_rasterize_atlas(&iw, &ih, 48);
        if (icon_atlas) {
            renderer_create_icon_atlas(renderer, icon_atlas, iw, ih);
            free(icon_atlas);
        }
    }

    AppState app = {};
    app.window            = window;
    app.renderer          = renderer;
    app.midi              = midi;
    app.audio             = audio;
    app.ui                = ui;
    app.last_w            = w;
    app.last_h            = h;
    app.ui_scale          = 1.0f;
    app.show_browser      = 1;
    app.show_props        = 1;
    app.show_log          = 1;
    app.show_midi_devices = 1;
    app.bottom_panel_tab  = 0;
    app.piano_mouse_note  = -1;
    app.demo_knob_unsigned = 75.0f;
    app.demo_knob_signed = 0.0f;
    app.demo_slider_h = 50.0f;
    app.demo_slider_v = 75.0f;
    app.demo_fader = 0.0f;
    app.demo_dropdown_sel = 1; // default to 48000 Hz
    app.radius_sel        = 1; // default to "Small" (4.0f)
    app.browser_width     = 200.0f;
    app.right_col_width   = 250.0f;
    app.log_height        = 180.0f;
    app.panel_drag        = 0;
    app.master_layout     = 0;
    for (S32 i = 0; i < 8; i++) { app.mix_faders[i] = 0.0f; app.mix_pans[i] = 0.0f; }
    app.mix_master_pan = 0.0f;
    app.patch_tab = 0;
    memset(app.patch_matrix, 0, sizeof(app.patch_matrix));
    memset(app.hw_matrix, 0, sizeof(app.hw_matrix));
    snprintf(app.demo_text_a, sizeof(app.demo_text_a), "My Instrument");
#ifdef __APPLE__
    snprintf(app.demo_text_b, sizeof(app.demo_text_b), "~/Samples/output");
    { mach_timebase_info_data_t tbi; mach_timebase_info(&tbi); app.freq_numer = tbi.numer; app.freq_denom = tbi.denom; }
    app.last_time = mach_absolute_time();
#else
    snprintf(app.demo_text_b, sizeof(app.demo_text_b), "C:\\Samples\\output");
    QueryPerformanceFrequency(&app.freq);
    QueryPerformanceCounter(&app.last_time);
#endif

    platform_set_frame_callback(window, frame_callback, &app);

    B32 running = 1;
    while (running && platform_poll_events(window)) {
        // Menu commands
        S32 menu_cmd = platform_poll_menu_command(window);
        switch (menu_cmd) {
        case MENU_FILE_EXIT:      running = 0; break;
        case MENU_VIEW_BROWSER:   app.show_browser = !app.show_browser; break;
        case MENU_VIEW_PROPERTIES:app.show_props   = !app.show_props;   break;
        case MENU_VIEW_LOG:       app.show_log     = !app.show_log;     break;
        case MENU_VIEW_MIDI_DEVICES: app.show_midi_devices = !app.show_midi_devices; break;
        case MENU_PREFERENCES_EDIT:  app.show_settings_window = 1; break;
        default: break;
        }

        if (running) do_frame(&app);
    }

    audio_destroy(audio);
    midi_destroy(midi);
    ui_destroy(ui);
    renderer_destroy(renderer);
    platform_destroy_window(window);
    return 0;
}
