/* AUTO-GENERATED by GUI Editor — do not edit manually */
#include "gui_generated.h"
#include "lvgl.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

/* Fonts */
LV_FONT_DECLARE(montserrat_16_ru_en)

/* Images */
LV_IMG_DECLARE(img_valve)
LV_IMG_DECLARE(img_fan)
LV_IMG_DECLARE(img_channel)
LV_IMG_DECLARE(img_heater)
LV_IMG_DECLARE(img_cooler)
LV_IMG_DECLARE(img_pipe)
LV_IMG_DECLARE(img_electric_heater)
LV_IMG_DECLARE(img_filter_g4)
LV_IMG_DECLARE(img_filter_h13)

/* Color scheme - minimalistic dark theme */
#define COLOR_BG_DARK       0x0F1419  /* Очень темный фон */
#define COLOR_BG_PANEL      0x1A1F26  /* Фон панелей */
#define COLOR_BG_MODULE     0x252B33  /* Фон модулей */
#define COLOR_BG_BTN        0x2D333B  /* Фон кнопок */
#define COLOR_BORDER        0x3D444D  /* Границы */
#define COLOR_TEXT          0xD0D4D8  /* Светлый текст */
#define COLOR_TEXT_DIM      0x6E7681  /* Приглушенный текст */
#define COLOR_TEXT_ACCENT   0x58A6FF  /* Акцентный текст */
#define COLOR_ACCENT        0x3FB950  /* Зеленый для активных */
#define COLOR_WARNING       0xD29922  /* Желтый для предупреждений */
#define COLOR_DANGER        0xF85149  /* Красный для аварий */

lv_obj_t *scr_main = NULL;
lv_obj_t *scr_screen1 = NULL;  /* Меню */
lv_obj_t *scr_screen2 = NULL;  /* Журнал */
lv_obj_t *scr_screen3 = NULL;  /* Уставка параметров */
lv_obj_t *scr_screen4 = NULL;  /* Настройки (после пароля) */

/* System state structure (like ModBus data) */
typedef struct {
    int16_t temp_room;        /* Температура комнаты x10 */
    int16_t hum_room;         /* Влажность комнаты x10 */
    int16_t temp_channel;     /* Температура канала x10 */
    int16_t hum_channel;      /* Влажность канала x10 */
    uint16_t room_num;        /* Номер комнаты */
    uint8_t is_master;        /* 1=Мастер, 0=Слейв */
    uint8_t has_signal;       /* Есть ли сигнал при слейве */
    uint8_t season;           /* 0=Зима, 1=Лето, 2=Переход */
    uint8_t mode;             /* 0=Остановка, 1=Дежурный, 2=Рабочий */
    uint8_t valve_inlet;      /* Входной клапан 0-100% */
    uint8_t valve_recirc;     /* Клапан рециркуляции 0-100% */
    uint8_t filter_g4_clean;  /* 0=Грязный, 1=Чистый */
    uint8_t kws_valve;        /* KWS клапан 0-100% */
    uint8_t kws_mode;         /* 0=Охлаждение, 1=Нагрев */
    uint8_t pww_valve;        /* PWW клапан 0-100% */
    uint8_t pww_mode;         /* 0=Охлаждение, 1=Нагрев */
    uint8_t heater_on;        /* Электронагреватель 0=Выкл, 1=Вкл */
    uint8_t fan_on;           /* Вентилятор 0=Выкл, 1=Вкл */
    uint8_t filter_h13_clean; /* 0=Грязный, 1=Чистый */
    uint16_t year;
    uint8_t month;
    uint8_t day;
    uint8_t hour;
    uint8_t minute;
} SysState_t;

static SysState_t state = {
    .temp_room = 220,
    .hum_room = 450,
    .temp_channel = 200,
    .hum_channel = 500,
    .room_num = 101,
    .is_master = 1,
    .has_signal = 1,
    .season = 0,
    .mode = 1,
    .valve_inlet = 75,
    .valve_recirc = 25,
    .filter_g4_clean = 0,  /* Фильтр загрязнен для демонстрации */
    .kws_valve = 50,
    .kws_mode = 1,
    .pww_valve = 30,
    .pww_mode = 0,  /* PWW в режиме охлаждения для демонстрации */
    .heater_on = 0,
    .fan_on = 1,
    .filter_h13_clean = 1,
    .year = 2026,
    .month = 2,
    .day = 26,
    .hour = 12,
    .minute = 30
};

/* Module configuration for drag&drop */
typedef enum {
    MODULE_VALVE_INLET = 0,
    MODULE_VALVE_RECIRC,
    MODULE_FILTER_G4,
    MODULE_KWS,
    MODULE_PWW,
    MODULE_HEATER,
    MODULE_FAN,
    MODULE_FILTER_H13,
    MODULE_CHANNEL,
    MODULE_COUNT
} module_type_t;

typedef struct {
    module_type_t type;
    int enabled;      /* 1=активен (на линии), 0=неактивен (внизу) */
    int position;     /* позиция в ряду (0-7) */
    lv_obj_t *obj;    /* указатель на объект */
    lv_obj_t *img;    /* указатель на изображение */
    lv_obj_t *label_name;  /* название модуля */
    lv_obj_t *label_value; /* указатель на значение */
    lv_obj_t *pipe_placeholder; /* труба-заглушка когда модуль отключен */
} module_config_t;

static module_config_t modules[MODULE_COUNT] = {
    {MODULE_VALVE_INLET, 1, 0, NULL, NULL, NULL, NULL, NULL},
    {MODULE_VALVE_RECIRC, 1, 1, NULL, NULL, NULL, NULL, NULL},
    {MODULE_FILTER_G4, 1, 2, NULL, NULL, NULL, NULL, NULL},
    {MODULE_KWS, 1, 3, NULL, NULL, NULL, NULL, NULL},
    {MODULE_PWW, 1, 4, NULL, NULL, NULL, NULL, NULL},
    {MODULE_HEATER, 1, 5, NULL, NULL, NULL, NULL, NULL},
    {MODULE_FAN, 1, 6, NULL, NULL, NULL, NULL, NULL},
    {MODULE_FILTER_H13, 1, 7, NULL, NULL, NULL, NULL, NULL},
    {MODULE_CHANNEL, 1, 8, NULL, NULL, NULL, NULL, NULL},
};

/* Module dimensions and positions */
#define MODULE_WIDTH       70
#define MODULE_HEIGHT      95
#define MODULE_SPACING     3
#define MODULES_ACTIVE_Y   20
#define MODULES_INACTIVE_Y 125
#define MODULE_SCALE       140  /* Scale factor: 256=100%, 140~55% for 64x64 images */

/* Panel for schema (needed globally for drag) */
static lv_obj_t *schema_panel = NULL;

/* Pipe placeholders for inactive modules in active line */
static lv_obj_t *pipe_placeholders[MODULE_COUNT] = {NULL};

/* Drag state for modules */
static lv_obj_t *dragged_module = NULL;
static int dragged_module_idx = -1;
static lv_point_t drag_start_pos;

/* Alarm log structure */
#define MAX_ALARMS 20
typedef struct {
    char message[80];
    char timestamp[20];
    int active;
} alarm_entry_t;

static alarm_entry_t alarm_log[MAX_ALARMS];
static int alarm_count = 0;

/* Settings/Setpoints for Work and Standby modes */
typedef struct {
    float temp;          /* Температура */
    float hum;           /* Влажность */
    float valve_inlet;   /* Клапан притока */
    float valve_recirc;  /* Клапан рециркуляции */
    uint8_t heater;      /* 0=ВЫКЛ, 1=ВКЛ, 2=АВТО */
    uint8_t fan;         /* 0=ВЫКЛ, 1=ВКЛ */
    uint8_t kws_auto;    /* 1=АВТО, 0=ручной режим */
    float kws_manual;    /* Значение для ручного режима */
    uint8_t pww_auto;    /* 1=АВТО, 0=ручной режим */
    float pww_manual;    /* Значение для ручного режима */
} setpoint_mode_t;

static setpoint_mode_t setpoint_work = {
    .temp = 22.0f, .hum = 50.0f, .valve_inlet = 75.0f, .valve_recirc = 25.0f,
    .heater = 2, .fan = 1, .kws_auto = 1, .kws_manual = 0, .pww_auto = 1, .pww_manual = 0
};

static setpoint_mode_t setpoint_standby = {
    .temp = 18.0f, .hum = 45.0f, .valve_inlet = 35.0f, .valve_recirc = 40.0f,
    .heater = 0, .fan = 1, .kws_auto = 1, .kws_manual = 0, .pww_auto = 1, .pww_manual = 0
};

/* Configuration parameters (Настройки - с паролем) */
typedef struct {
    float temp_room_offset;
    float hum_room_offset;
    float temp_channel_offset;
    float hum_channel_offset;
    float valve_inlet_offset;
    float valve_recirc_offset;
    uint8_t has_recirc_valve;
    uint8_t has_heater;
    float pid_pww_kp;
    float pid_pww_ti;
    float pid_pww_d;
    float pid_kws_kp;
    float pid_kws_ti;
    float pid_kws_d;
    uint8_t force_mode_enabled;
    uint8_t force_mode_value;
    uint8_t key_swap_enabled;
} config_t;

static config_t config = {
    .temp_room_offset = 0.0f,
    .hum_room_offset = 0.0f,
    .temp_channel_offset = 0.0f,
    .hum_channel_offset = 0.0f,
    .valve_inlet_offset = 0.0f,
    .valve_recirc_offset = 0.0f,
    .has_recirc_valve = 1,
    .has_heater = 1,
    .pid_pww_kp = 1.0f,
    .pid_pww_ti = 10.0f,
    .pid_pww_d = 0.0f,
    .pid_kws_kp = 1.0f,
    .pid_kws_ti = 10.0f,
    .pid_kws_d = 0.0f,
    .force_mode_enabled = 0,
    .force_mode_value = 1,
    .key_swap_enabled = 1
};

/* Filter replacement dates */
static char filter_g4_date[12] = "01.01.2026";
static char filter_h13_date[12] = "01.01.2026";

/* Password and settings */
#define PASSWORD "1234"
static char password_input[10] = "";
static lv_obj_t *popup_password = NULL;
static lv_obj_t *lbl_password_display = NULL;
static int password_target = 0; /* 0=настройки, 1=очистка журнала фильтров */

/* Parameter editor */
static lv_obj_t *popup_param_editor = NULL;
static lv_obj_t *lbl_param_value = NULL;
static char param_value_str[20] = "";
static float *param_being_edited = NULL;
static char param_name[50] = "";
static int param_is_percentage = 0;

/* Configuration parameters */
/* (moved to config_t structure above) */

/* UI element references for updates */
static lv_obj_t *lbl_temp_room = NULL;
static lv_obj_t *lbl_hum_room = NULL;
static lv_obj_t *lbl_temp_channel = NULL;
static lv_obj_t *lbl_hum_channel = NULL;
static lv_obj_t *lbl_room_num = NULL;
static lv_obj_t *lbl_master_slave = NULL;
static lv_obj_t *lbl_season = NULL;
static lv_obj_t *lbl_mode = NULL;
static lv_obj_t *lbl_datetime = NULL;

/* Equipment UI references */
static lv_obj_t *panel_schema = NULL;

/* Popup windows */
static lv_obj_t *popup_readings = NULL;
static lv_obj_t *popup_alarm = NULL;

/* Setpoints screen UI */
static lv_obj_t *lbl_work_temp = NULL;
static lv_obj_t *lbl_work_hum = NULL;
static lv_obj_t *lbl_standby_temp = NULL;
static lv_obj_t *lbl_standby_hum = NULL;

/* Forward declarations */
static void create_popup_readings(void);
static void create_popup_alarm(const char *message);
static void add_alarm_to_log(const char *message, int active);
static void btn_log_cb(lv_event_t *e);
static void btn_settings_cb(lv_event_t *e);
static void btn_config_cb(lv_event_t *e);
static void create_popup_password(int target);
static void password_keypad_cb(lv_event_t *e);
static void create_popup_param_editor(const char *name, float *param_ptr, int is_percentage);
static void param_keypad_cb(lv_event_t *e);
static void close_popup_cb(lv_event_t *e);
static void btn_back_to_main_cb(lv_event_t *e);
static void create_screen_config(void);
static void create_screen_screen2(void);
static void module_drag_cb(lv_event_t *e);
static void update_module_display(int module_idx);
static void refresh_setpoints_display(void);
static void btn_reset_alarm_cb(lv_event_t *e);
static void btn_clear_log_cb(lv_event_t *e);
static lv_obj_t* create_module_widget(lv_obj_t *parent, int module_idx, int x, int y);
static void update_module_positions(void);

/* Get image for module type */
static const lv_image_dsc_t* get_module_image(int module_idx) {
    switch (module_idx) {
        case MODULE_VALVE_INLET:
        case MODULE_VALVE_RECIRC:
            return &img_valve;
        case MODULE_FILTER_G4:
            return &img_filter_g4;
        case MODULE_KWS:
            return state.kws_mode ? &img_heater : &img_cooler;
        case MODULE_PWW:
            return state.pww_mode ? &img_heater : &img_cooler;
        case MODULE_HEATER:
            return &img_electric_heater;
        case MODULE_FAN:
            return &img_fan;
        case MODULE_FILTER_H13:
            return &img_filter_h13;
        case MODULE_CHANNEL:
            return &img_channel;
        default:
            return &img_pipe;
    }
}

/* Get name for module type */
static const char* get_module_name(int module_idx) {
    switch (module_idx) {
        case MODULE_VALVE_INLET:
            return "Вход";
        case MODULE_VALVE_RECIRC:
            return "Рецирк";
        case MODULE_FILTER_G4:
            return "G4";
        case MODULE_KWS:
            return "KWS";
        case MODULE_PWW:
            return "PWW";
        case MODULE_HEATER:
            return "Нагрев";
        case MODULE_FAN:
            return "Вент";
        case MODULE_FILTER_H13:
            return "H13";
        case MODULE_CHANNEL:
            return "Канал";
        default:
            return "";
    }
}

/* Module drag event handler */
static void module_drag_cb(lv_event_t *e) {
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t *obj = lv_event_get_target(e);
    int module_idx = (int)(intptr_t)lv_event_get_user_data(e);

    if (code == LV_EVENT_PRESSING) {
        lv_indev_t *indev = lv_indev_active();
        if (indev == NULL) return;

        lv_point_t vect;
        lv_indev_get_vect(indev, &vect);

        lv_coord_t x = lv_obj_get_x(obj) + vect.x;
        lv_coord_t y = lv_obj_get_y(obj) + vect.y;
        lv_obj_set_pos(obj, x, y);
    }
    else if (code == LV_EVENT_RELEASED) {
        /* Check if module should be enabled/disabled based on Y position */
        lv_coord_t y = lv_obj_get_y(obj);
        int threshold = (MODULES_ACTIVE_Y + MODULES_INACTIVE_Y) / 2;
        
        if (y < threshold) {
            modules[module_idx].enabled = 1;
        } else {
            modules[module_idx].enabled = 0;
        }
        
        /* Reposition all modules */
        update_module_positions();
    }
}

/* Update positions of all modules (pipe line is continuous background) */
static void update_module_positions(void) {
    int active_x = 50;  /* Start after the inlet pipe */
    int inactive_x = 10;
    
    for (int i = 0; i < MODULE_COUNT; i++) {
        if (modules[i].obj == NULL) continue;
        
        if (modules[i].enabled) {
            /* Module is active - position it on the active line */
            lv_obj_set_pos(modules[i].obj, active_x, MODULES_ACTIVE_Y);
            active_x += MODULE_WIDTH + MODULE_SPACING;
        } else {
            /* Module is inactive - move to inactive area, pipe line shows through */
            active_x += MODULE_WIDTH + MODULE_SPACING;  /* Reserve space on pipe line */
            
            lv_obj_set_pos(modules[i].obj, inactive_x, MODULES_INACTIVE_Y);
            inactive_x += MODULE_WIDTH + MODULE_SPACING;
        }
    }
}

/* Create a module widget with image */
static lv_obj_t* create_module_widget(lv_obj_t *parent, int module_idx, int x, int y) {
    /* Container for module */
    lv_obj_t *cont = lv_obj_create(parent);
    lv_obj_set_pos(cont, x, y);
    lv_obj_set_size(cont, MODULE_WIDTH, MODULE_HEIGHT);
    lv_obj_set_style_bg_color(cont, lv_color_hex(COLOR_BG_MODULE), 0);
    lv_obj_set_style_radius(cont, 5, 0);
    lv_obj_set_style_border_width(cont, 1, 0);
    lv_obj_set_style_border_color(cont, lv_color_hex(COLOR_BORDER), 0);
    lv_obj_set_style_pad_all(cont, 2, 0);
    lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE);
    
    /* Add drag flag */
    lv_obj_add_flag(cont, LV_OBJ_FLAG_CLICKABLE);
    lv_obj_add_event_cb(cont, module_drag_cb, LV_EVENT_PRESSING, (void*)(intptr_t)module_idx);
    lv_obj_add_event_cb(cont, module_drag_cb, LV_EVENT_RELEASED, (void*)(intptr_t)module_idx);

    /* Module name label at top */
    lv_obj_t *lbl_name = lv_label_create(cont);
    lv_label_set_text(lbl_name, get_module_name(module_idx));
    lv_obj_align(lbl_name, LV_ALIGN_TOP_MID, 0, 0);
    lv_obj_set_style_text_color(lbl_name, lv_color_hex(COLOR_TEXT_DIM), 0);
    lv_obj_set_style_text_font(lbl_name, &montserrat_16_ru_en, 0);

    /* Image */
    lv_obj_t *img = lv_image_create(cont);
    lv_image_set_src(img, get_module_image(module_idx));
    lv_image_set_scale(img, MODULE_SCALE);
    lv_obj_align(img, LV_ALIGN_CENTER, 0, 5);
    
    /* Value label at bottom */
    lv_obj_t *lbl_value = lv_label_create(cont);
    lv_obj_align(lbl_value, LV_ALIGN_BOTTOM_MID, 0, -2);
    lv_obj_set_style_text_color(lbl_value, lv_color_hex(COLOR_TEXT_ACCENT), 0);
    lv_obj_set_style_text_font(lbl_value, &montserrat_16_ru_en, 0);
    
    modules[module_idx].obj = cont;
    modules[module_idx].img = img;
    modules[module_idx].label_name = lbl_name;
    modules[module_idx].label_value = lbl_value;
    
    return cont;
}

/* Apply setpoints to system state based on current mode */
static void apply_mode_setpoints(void) {
    setpoint_mode_t *sp = (state.mode == 2) ? &setpoint_work : &setpoint_standby;
    
    if (state.mode == 0) {
        /* Остановка - выключаем только активные элементы (вентилятор, нагреватель) */
        /* Клапаны остаются на своих позициях */
        state.heater_on = 0;
        state.fan_on = 0;
    } else {
        /* Дежурный или Рабочий режим - применяем уставки */
        state.valve_inlet = (uint8_t)sp->valve_inlet;
        state.valve_recirc = (uint8_t)sp->valve_recirc;
        
        /* Вентилятор по уставке */
        state.fan_on = sp->fan;
        
        /* Электронагреватель по уставке */
        if (sp->heater == 0) {
            state.heater_on = 0;  /* ВЫКЛ */
        } else if (sp->heater == 1) {
            state.heater_on = 1;  /* ВКЛ */
        }
        /* heater == 2 (АВТО) - управляется автоматикой */
        
        /* KWS и PWW */
        if (!sp->kws_auto) {
            state.kws_valve = (uint8_t)sp->kws_manual;
        }
        if (!sp->pww_auto) {
            state.pww_valve = (uint8_t)sp->pww_manual;
        }
    }
}

/* Button callbacks */
static void btn_stop_cb(lv_event_t *e) {
    (void)e;
    state.mode = 0;
    apply_mode_setpoints();
    gui_update_values();
}

static void btn_standby_cb(lv_event_t *e) {
    (void)e;
    state.mode = 1;
    apply_mode_setpoints();
    gui_update_values();
}

static void btn_work_cb(lv_event_t *e) {
    (void)e;
    state.mode = 2;
    apply_mode_setpoints();
    gui_update_values();
}

static void btn_menu_cb(lv_event_t *e) {
    (void)e;
    if (scr_screen1) lv_scr_load(scr_screen1);
}

static void btn_back_to_main_cb(lv_event_t *e) {
    (void)e;
    if (scr_main) lv_scr_load(scr_main);
}

static void btn_readings_cb(lv_event_t *e) {
    (void)e;
    create_popup_readings();
}

static void btn_reset_alarm_cb(lv_event_t *e) {
    (void)e;
    /* Reset first active alarm */
    for (int i = 0; i < alarm_count; i++) {
        if (alarm_log[i].active) {
            alarm_log[i].active = 0;
            break;
        }
    }
    /* Refresh journal screen */
    if (scr_screen2) {
        lv_obj_del(scr_screen2);
        scr_screen2 = NULL;
    }
    create_screen_screen2();
    lv_scr_load(scr_screen2);
}

static void btn_clear_log_cb(lv_event_t *e) {
    (void)e;
    /* Check if any active alarms */
    int has_active = 0;
    for (int i = 0; i < alarm_count; i++) {
        if (alarm_log[i].active) {
            has_active = 1;
            break;
        }
    }
    if (!has_active) {
        alarm_count = 0;
        /* Refresh journal screen */
        if (scr_screen2) {
            lv_obj_del(scr_screen2);
            scr_screen2 = NULL;
        }
        create_screen_screen2();
        lv_scr_load(scr_screen2);
    }
}

static void close_popup_cb(lv_event_t *e) {
    lv_obj_t *popup = lv_event_get_user_data(e);
    if (popup) {
        lv_obj_del(popup);
    }
    if (popup == popup_readings) popup_readings = NULL;
    if (popup == popup_alarm) popup_alarm = NULL;
    if (popup == popup_password) {
        popup_password = NULL;
        memset(password_input, 0, sizeof(password_input));
    }
    if (popup == popup_param_editor) {
        popup_param_editor = NULL;
        memset(param_value_str, 0, sizeof(param_value_str));
        param_being_edited = NULL;
    }
}

static void btn_log_cb(lv_event_t *e) {
    (void)e;
    if (scr_screen2) lv_scr_load(scr_screen2);
}

static void btn_settings_cb(lv_event_t *e) {
    (void)e;
    if (scr_screen3) lv_scr_load(scr_screen3);
}

static void btn_config_cb(lv_event_t *e) {
    (void)e;
    password_target = 0;
    create_popup_password(0);
}

/* Edit parameter callbacks - Work mode */
static void edit_work_temp_cb(lv_event_t *e) {
    (void)e;
    create_popup_param_editor("Темп.", &setpoint_work.temp, 0);
}

static void edit_work_hum_cb(lv_event_t *e) {
    (void)e;
    create_popup_param_editor("Влажность (Рабочий)", &setpoint_work.hum, 1);
}

static void edit_work_valve_inlet_cb(lv_event_t *e) {
    (void)e;
    create_popup_param_editor("Клапан притока (Рабочий)", &setpoint_work.valve_inlet, 1);
}

static void edit_work_valve_recirc_cb(lv_event_t *e) {
    (void)e;
    create_popup_param_editor("Клапан рециркуляции (Рабочий)", &setpoint_work.valve_recirc, 1);
}

/* Edit parameter callbacks - Standby mode */
static void edit_standby_temp_cb(lv_event_t *e) {
    (void)e;
    create_popup_param_editor("Температура (Дежурный)", &setpoint_standby.temp, 0);
}

static void edit_standby_hum_cb(lv_event_t *e) {
    (void)e;
    create_popup_param_editor("Влажность (Дежурный)", &setpoint_standby.hum, 1);
}

static void edit_standby_valve_inlet_cb(lv_event_t *e) {
    (void)e;
    create_popup_param_editor("Клапан притока (Дежурный)", &setpoint_standby.valve_inlet, 1);
}

static void edit_standby_valve_recirc_cb(lv_event_t *e) {
    (void)e;
    create_popup_param_editor("Клапан рециркуляции (Дежурный)", &setpoint_standby.valve_recirc, 1);
}

/* Heater mode callbacks */
static void edit_work_heater_cb(lv_event_t *e) {
    (void)e;
    setpoint_work.heater = (setpoint_work.heater + 1) % 3;
    /* Apply immediately if in work mode */
    if (state.mode == 2) {
        if (setpoint_work.heater == 0) state.heater_on = 0;
        else if (setpoint_work.heater == 1) state.heater_on = 1;
        gui_update_values();
    }
    refresh_setpoints_display();
}

static void edit_standby_heater_cb(lv_event_t *e) {
    (void)e;
    setpoint_standby.heater = (setpoint_standby.heater + 1) % 3;
    /* Apply immediately if in standby mode */
    if (state.mode == 1) {
        if (setpoint_standby.heater == 0) state.heater_on = 0;
        else if (setpoint_standby.heater == 1) state.heater_on = 1;
        gui_update_values();
    }
    refresh_setpoints_display();
}

/* Fan toggle callbacks */
static void edit_work_fan_cb(lv_event_t *e) {
    (void)e;
    setpoint_work.fan = !setpoint_work.fan;
    /* Apply immediately if in work mode */
    if (state.mode == 2) {
        state.fan_on = setpoint_work.fan;
        gui_update_values();
    }
    refresh_setpoints_display();
}

static void edit_standby_fan_cb(lv_event_t *e) {
    (void)e;
    setpoint_standby.fan = !setpoint_standby.fan;
    /* Apply immediately if in standby mode */
    if (state.mode == 1) {
        state.fan_on = setpoint_standby.fan;
        gui_update_values();
    }
    refresh_setpoints_display();
}

/* KWS mode callbacks */
static void edit_work_kws_cb(lv_event_t *e) {
    (void)e;
    if (setpoint_work.kws_auto) {
        setpoint_work.kws_auto = 0;
        setpoint_work.kws_manual = 50.0f;
        /* Apply immediately if in work mode */
        if (state.mode == 2) {
            state.kws_valve = (uint8_t)setpoint_work.kws_manual;
            gui_update_values();
        }
        refresh_setpoints_display();
    } else {
        create_popup_param_editor("KWS ручной (Рабочий)", &setpoint_work.kws_manual, 1);
    }
}

static void edit_standby_kws_cb(lv_event_t *e) {
    (void)e;
    if (setpoint_standby.kws_auto) {
        setpoint_standby.kws_auto = 0;
        setpoint_standby.kws_manual = 50.0f;
        /* Apply immediately if in standby mode */
        if (state.mode == 1) {
            state.kws_valve = (uint8_t)setpoint_standby.kws_manual;
            gui_update_values();
        }
        refresh_setpoints_display();
    } else {
        create_popup_param_editor("KWS ручной (Дежурный)", &setpoint_standby.kws_manual, 1);
    }
}

/* PWW mode callbacks */
static void edit_work_pww_cb(lv_event_t *e) {
    (void)e;
    if (setpoint_work.pww_auto) {
        setpoint_work.pww_auto = 0;
        setpoint_work.pww_manual = 50.0f;
        /* Apply immediately if in work mode */
        if (state.mode == 2) {
            state.pww_valve = (uint8_t)setpoint_work.pww_manual;
            gui_update_values();
        }
        refresh_setpoints_display();
    } else {
        create_popup_param_editor("PWW ручной (Рабочий)", &setpoint_work.pww_manual, 1);
    }
}

static void edit_standby_pww_cb(lv_event_t *e) {
    (void)e;
    if (setpoint_standby.pww_auto) {
        setpoint_standby.pww_auto = 0;
        setpoint_standby.pww_manual = 50.0f;
        /* Apply immediately if in standby mode */
        if (state.mode == 1) {
            state.pww_valve = (uint8_t)setpoint_standby.pww_manual;
            gui_update_values();
        }
        refresh_setpoints_display();
    } else {
        create_popup_param_editor("PWW ручной (Дежурный)", &setpoint_standby.pww_manual, 1);
    }
}

/* Configuration edit callbacks */
static void edit_config_offset_cb(lv_event_t *e) {
    float *offset_ptr = (float*)lv_event_get_user_data(e);
    create_popup_param_editor("Коррекция", offset_ptr, 0);
}

static void toggle_recirc_valve_cb(lv_event_t *e) {
    (void)e;
    config.has_recirc_valve = !config.has_recirc_valve;
    refresh_setpoints_display();
}

static void toggle_heater_cb(lv_event_t *e) {
    (void)e;
    config.has_heater = !config.has_heater;
    refresh_setpoints_display();
}

static void edit_pid_pww_kp_cb(lv_event_t *e) {
    (void)e;
    create_popup_param_editor("PWW Kp", &config.pid_pww_kp, 0);
}

static void edit_pid_pww_ti_cb(lv_event_t *e) {
    (void)e;
    create_popup_param_editor("PWW Ti", &config.pid_pww_ti, 0);
}

static void edit_pid_pww_d_cb(lv_event_t *e) {
    (void)e;
    create_popup_param_editor("PWW D", &config.pid_pww_d, 0);
}

static void edit_pid_kws_kp_cb(lv_event_t *e) {
    (void)e;
    create_popup_param_editor("KWS Kp", &config.pid_kws_kp, 0);
}

static void edit_pid_kws_ti_cb(lv_event_t *e) {
    (void)e;
    create_popup_param_editor("KWS Ti", &config.pid_kws_ti, 0);
}

static void edit_pid_kws_d_cb(lv_event_t *e) {
    (void)e;
    create_popup_param_editor("KWS D", &config.pid_kws_d, 0);
}

static void toggle_force_mode_cb(lv_event_t *e) {
    (void)e;
    config.force_mode_enabled = !config.force_mode_enabled;
    refresh_setpoints_display();
}

static void toggle_key_swap_cb(lv_event_t *e) {
    (void)e;
    config.key_swap_enabled = !config.key_swap_enabled;
    refresh_setpoints_display();
}

/* Date/Time editor popup */
static lv_obj_t *popup_datetime = NULL;
static lv_obj_t *roller_day = NULL;
static lv_obj_t *roller_month = NULL;
static lv_obj_t *roller_year = NULL;
static lv_obj_t *roller_hour = NULL;
static lv_obj_t *roller_minute = NULL;

static void datetime_ok_cb(lv_event_t *e) {
    (void)e;
    if (roller_day && roller_month && roller_year && roller_hour && roller_minute) {
        state.day = lv_roller_get_selected(roller_day) + 1;
        state.month = lv_roller_get_selected(roller_month) + 1;
        state.year = 2024 + lv_roller_get_selected(roller_year);
        state.hour = lv_roller_get_selected(roller_hour);
        state.minute = lv_roller_get_selected(roller_minute);
    }
    if (popup_datetime) {
        lv_obj_del(popup_datetime);
        popup_datetime = NULL;
        roller_day = roller_month = roller_year = roller_hour = roller_minute = NULL;
    }
    /* Recreate config screen to show updated datetime */
    if (scr_screen4) {
        lv_obj_del(scr_screen4);
        scr_screen4 = NULL;
    }
    create_screen_config();
    lv_scr_load(scr_screen4);
}

static void datetime_close_cb(lv_event_t *e) {
    (void)e;
    if (popup_datetime) {
        lv_obj_del(popup_datetime);
        popup_datetime = NULL;
        roller_day = roller_month = roller_year = roller_hour = roller_minute = NULL;
    }
}

static void create_popup_datetime(void) {
    if (popup_datetime) return;

    popup_datetime = lv_obj_create(lv_screen_active());
    lv_obj_set_size(popup_datetime, 420, 280);
    lv_obj_center(popup_datetime);
    lv_obj_set_style_bg_color(popup_datetime, lv_color_hex(COLOR_BG_PANEL), 0);
    lv_obj_set_style_radius(popup_datetime, 8, 0);
    lv_obj_set_style_border_width(popup_datetime, 1, 0);
    lv_obj_set_style_border_color(popup_datetime, lv_color_hex(COLOR_BORDER), 0);
    lv_obj_clear_flag(popup_datetime, LV_OBJ_FLAG_SCROLLABLE);

    /* Title */
    lv_obj_t *lbl = lv_label_create(popup_datetime);
    lv_label_set_text(lbl, "Установка даты и времени");
    lv_obj_set_pos(lbl, 20, 10);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    /* Close button (X) */
    lv_obj_t *btn_close = lv_btn_create(popup_datetime);
    lv_obj_set_pos(btn_close, 370, 6);
    lv_obj_set_size(btn_close, 32, 32);
    lv_obj_set_style_bg_color(btn_close, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn_close, 4, 0);
    lbl = lv_label_create(btn_close);
    lv_label_set_text(lbl, "X");
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_DANGER), 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn_close, datetime_close_cb, LV_EVENT_CLICKED, NULL);

    /* Date section label */
    lbl = lv_label_create(popup_datetime);
    lv_label_set_text(lbl, "Дата:");
    lv_obj_set_pos(lbl, 20, 50);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    /* Day roller */
    char days[31*4];
    days[0] = '\0';
    for (int i = 1; i <= 31; i++) {
        char tmp[5];
        snprintf(tmp, sizeof(tmp), "%02d\n", i);
        strcat(days, tmp);
    }
    days[strlen(days)-1] = '\0';

    roller_day = lv_roller_create(popup_datetime);
    lv_roller_set_options(roller_day, days, LV_ROLLER_MODE_NORMAL);
    lv_roller_set_selected(roller_day, state.day - 1, LV_ANIM_OFF);
    lv_obj_set_pos(roller_day, 80, 45);
    lv_obj_set_size(roller_day, 60, 80);
    lv_obj_set_style_text_font(roller_day, &montserrat_16_ru_en, 0);
    lv_obj_set_style_bg_color(roller_day, lv_color_hex(COLOR_BG_BTN), 0);

    /* Month roller */
    roller_month = lv_roller_create(popup_datetime);
    lv_roller_set_options(roller_month, "01\n02\n03\n04\n05\n06\n07\n08\n09\n10\n11\n12", LV_ROLLER_MODE_NORMAL);
    lv_roller_set_selected(roller_month, state.month - 1, LV_ANIM_OFF);
    lv_obj_set_pos(roller_month, 150, 45);
    lv_obj_set_size(roller_month, 60, 80);
    lv_obj_set_style_text_font(roller_month, &montserrat_16_ru_en, 0);
    lv_obj_set_style_bg_color(roller_month, lv_color_hex(COLOR_BG_BTN), 0);

    /* Year roller (2024-2035) */
    roller_year = lv_roller_create(popup_datetime);
    lv_roller_set_options(roller_year, "2024\n2025\n2026\n2027\n2028\n2029\n2030\n2031\n2032\n2033\n2034\n2035", LV_ROLLER_MODE_NORMAL);
    lv_roller_set_selected(roller_year, state.year - 2024, LV_ANIM_OFF);
    lv_obj_set_pos(roller_year, 220, 45);
    lv_obj_set_size(roller_year, 80, 80);
    lv_obj_set_style_text_font(roller_year, &montserrat_16_ru_en, 0);
    lv_obj_set_style_bg_color(roller_year, lv_color_hex(COLOR_BG_BTN), 0);

    /* Time section label */
    lbl = lv_label_create(popup_datetime);
    lv_label_set_text(lbl, "Время:");
    lv_obj_set_pos(lbl, 20, 140);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    /* Hour roller */
    char hours[24*4];
    hours[0] = '\0';
    for (int i = 0; i < 24; i++) {
        char tmp[5];
        snprintf(tmp, sizeof(tmp), "%02d\n", i);
        strcat(hours, tmp);
    }
    hours[strlen(hours)-1] = '\0';

    roller_hour = lv_roller_create(popup_datetime);
    lv_roller_set_options(roller_hour, hours, LV_ROLLER_MODE_NORMAL);
    lv_roller_set_selected(roller_hour, state.hour, LV_ANIM_OFF);
    lv_obj_set_pos(roller_hour, 80, 135);
    lv_obj_set_size(roller_hour, 60, 80);
    lv_obj_set_style_text_font(roller_hour, &montserrat_16_ru_en, 0);
    lv_obj_set_style_bg_color(roller_hour, lv_color_hex(COLOR_BG_BTN), 0);

    lbl = lv_label_create(popup_datetime);
    lv_label_set_text(lbl, ":");
    lv_obj_set_pos(lbl, 145, 160);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    /* Minute roller */
    char minutes[60*4];
    minutes[0] = '\0';
    for (int i = 0; i < 60; i++) {
        char tmp[5];
        snprintf(tmp, sizeof(tmp), "%02d\n", i);
        strcat(minutes, tmp);
    }
    minutes[strlen(minutes)-1] = '\0';

    roller_minute = lv_roller_create(popup_datetime);
    lv_roller_set_options(roller_minute, minutes, LV_ROLLER_MODE_NORMAL);
    lv_roller_set_selected(roller_minute, state.minute, LV_ANIM_OFF);
    lv_obj_set_pos(roller_minute, 160, 135);
    lv_obj_set_size(roller_minute, 60, 80);
    lv_obj_set_style_text_font(roller_minute, &montserrat_16_ru_en, 0);
    lv_obj_set_style_bg_color(roller_minute, lv_color_hex(COLOR_BG_BTN), 0);

    /* OK button */
    lv_obj_t *btn_ok = lv_btn_create(popup_datetime);
    lv_obj_set_pos(btn_ok, 160, 230);
    lv_obj_set_size(btn_ok, 100, 40);
    lv_obj_set_style_bg_color(btn_ok, lv_color_hex(COLOR_ACCENT), 0);
    lv_obj_set_style_radius(btn_ok, 6, 0);
    lbl = lv_label_create(btn_ok);
    lv_label_set_text(lbl, "OK");
    lv_obj_set_style_text_color(lbl, lv_color_hex(0xFFFFFF), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn_ok, datetime_ok_cb, LV_EVENT_CLICKED, NULL);
}

static void edit_datetime_cb(lv_event_t *e) {
    (void)e;
    create_popup_datetime();
}

/* Password keypad callback */
static void password_keypad_cb(lv_event_t *e) {
    const char *key = lv_event_get_user_data(e);
    int len = strlen(password_input);

    if (strcmp(key, "C") == 0) {
        memset(password_input, 0, sizeof(password_input));
    } else if (strcmp(key, "OK") == 0) {
        if (strcmp(password_input, PASSWORD) == 0) {
            /* Correct password - close popup */
            if (popup_password) {
                lv_obj_del(popup_password);
                popup_password = NULL;
                lbl_password_display = NULL;
            }
            memset(password_input, 0, sizeof(password_input));

            /* Navigate to config screen */
            if (password_target == 0) {
                if (scr_screen4) lv_scr_load(scr_screen4);
            }
        } else {
            /* Wrong password */
            if (lbl_password_display) {
                lv_label_set_text(lbl_password_display, "НЕВЕРНЫЙ ПАРОЛЬ!");
                lv_obj_set_style_text_color(lbl_password_display, lv_color_hex(COLOR_DANGER), 0);
            }
            memset(password_input, 0, sizeof(password_input));
        }
    } else if (len < 8) {
        strcat(password_input, key);
    }

    /* Update display */
    if (lbl_password_display) {
        char display[20] = "";
        for (int i = 0; i < (int)strlen(password_input); i++) {
            strcat(display, "*");
        }
        if (strlen(display) == 0) {
            lv_label_set_text(lbl_password_display, "Введите пароль");
            lv_obj_set_style_text_color(lbl_password_display, lv_color_hex(COLOR_TEXT_DIM), 0);
        } else {
            lv_label_set_text(lbl_password_display, display);
            lv_obj_set_style_text_color(lbl_password_display, lv_color_hex(COLOR_ACCENT), 0);
        }
    }
}

/* Create password popup with keypad */
static void create_popup_password(int target) {
    if (popup_password) return;

    password_target = target;
    memset(password_input, 0, sizeof(password_input));

    popup_password = lv_obj_create(lv_screen_active());
    lv_obj_set_size(popup_password, 300, 420);
    lv_obj_center(popup_password);
    lv_obj_set_style_bg_color(popup_password, lv_color_hex(COLOR_BG_PANEL), 0);
    lv_obj_set_style_radius(popup_password, 8, 0);
    lv_obj_set_style_border_width(popup_password, 1, 0);
    lv_obj_set_style_border_color(popup_password, lv_color_hex(COLOR_BORDER), 0);
    lv_obj_clear_flag(popup_password, LV_OBJ_FLAG_SCROLLABLE);

    /* Title */
    lv_obj_t *lbl = lv_label_create(popup_password);
    lv_label_set_text(lbl, "Введите пароль");
    lv_obj_set_pos(lbl, 20, 10);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    /* Close button (X) - справа */
    lv_obj_t *btn_close = lv_btn_create(popup_password);
    lv_obj_set_pos(btn_close, 230, 6);
    lv_obj_set_size(btn_close, 32, 32);
    lv_obj_set_style_bg_color(btn_close, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn_close, 4, 0);
    lbl = lv_label_create(btn_close);
    lv_label_set_text(lbl, "X");
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_DANGER), 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn_close, close_popup_cb, LV_EVENT_CLICKED, popup_password);

    /* Password display */
    lbl_password_display = lv_label_create(popup_password);
    lv_label_set_text(lbl_password_display, "_ _ _ _");
    lv_obj_set_pos(lbl_password_display, 105, 50);
    lv_obj_set_style_text_color(lbl_password_display, lv_color_hex(COLOR_TEXT_DIM), 0);
    lv_obj_set_style_text_font(lbl_password_display, &montserrat_16_ru_en, 0);

    /* Numeric keypad 3x4 */
    const char *keys[12] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "C", "0", "OK"};
    int key_size = 60;
    int key_spacing = 8;
    int start_x = 30;
    int start_y = 90;

    for (int i = 0; i < 12; i++) {
        int row = i / 3;
        int col = i % 3;

        lv_obj_t *btn = lv_btn_create(popup_password);
        lv_obj_set_pos(btn, start_x + col * (key_size + key_spacing),
                           start_y + row * (key_size + key_spacing));
        lv_obj_set_size(btn, key_size, key_size);
        lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
        lv_obj_set_style_radius(btn, 6, 0);

        lbl = lv_label_create(btn);
        lv_label_set_text(lbl, keys[i]);
        if (strcmp(keys[i], "C") == 0) {
            lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0);
        } else if (strcmp(keys[i], "OK") == 0) {
            lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_ACCENT), 0);
        } else {
            lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
        }
        lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
        lv_obj_center(lbl);

        lv_obj_add_event_cb(btn, password_keypad_cb, LV_EVENT_CLICKED, (void*)keys[i]);
    }
}

/* Parameter editor keypad callback */
static void param_keypad_cb(lv_event_t *e) {
    const char *key = lv_event_get_user_data(e);
    int len = strlen(param_value_str);

    if (strcmp(key, "C") == 0) {
        memset(param_value_str, 0, sizeof(param_value_str));
    } else if (strcmp(key, "<") == 0) {
        /* Backspace - remove last character */
        if (len > 0) {
            param_value_str[len - 1] = '\0';
        }
    } else if (strcmp(key, ".") == 0) {
        if (strchr(param_value_str, '.') == NULL) {
            if (len == 0 || (len == 1 && param_value_str[0] == '-')) {
                strcat(param_value_str, "0.");
            } else {
                strcat(param_value_str, ".");
            }
        }
    } else if (strcmp(key, "-") == 0) {
        if (len == 0) {
            strcat(param_value_str, "-");
        } else if (param_value_str[0] == '-') {
            /* Remove minus */
            memmove(param_value_str, param_value_str + 1, strlen(param_value_str));
        } else {
            /* Add minus at beginning */
            memmove(param_value_str + 1, param_value_str, strlen(param_value_str) + 1);
            param_value_str[0] = '-';
        }
    } else if (strcmp(key, "OK") == 0) {
        if (param_being_edited && strlen(param_value_str) > 0) {
            float val = (float)atof(param_value_str);
            if (param_is_percentage) {
                if (val < 0.0f) val = 0.0f;
                if (val > 100.0f) val = 100.0f;
            }
            *param_being_edited = val;
        }
        if (popup_param_editor) {
            lv_obj_del(popup_param_editor);
            popup_param_editor = NULL;
            lbl_param_value = NULL;
        }
        memset(param_value_str, 0, sizeof(param_value_str));
        param_being_edited = NULL;
        refresh_setpoints_display();
        return;
    } else if (len < 10) {
        strcat(param_value_str, key);
    }

    if (lbl_param_value) {
        if (strlen(param_value_str) == 0) {
            lv_label_set_text(lbl_param_value, "0");
        } else {
            lv_label_set_text(lbl_param_value, param_value_str);
        }
    }
}

/* Create parameter editor popup */
static void create_popup_param_editor(const char *name, float *param_ptr, int is_percentage) {
    if (popup_param_editor) return;

    param_being_edited = param_ptr;
    param_is_percentage = is_percentage;
    strncpy(param_name, name, 49);
    param_name[49] = '\0';
    memset(param_value_str, 0, sizeof(param_value_str));
    snprintf(param_value_str, sizeof(param_value_str), "%.1f", *param_ptr);

    popup_param_editor = lv_obj_create(lv_screen_active());
    lv_obj_set_size(popup_param_editor, 360, 380);
    lv_obj_center(popup_param_editor);
    lv_obj_set_style_bg_color(popup_param_editor, lv_color_hex(COLOR_BG_PANEL), 0);
    lv_obj_set_style_radius(popup_param_editor, 8, 0);
    lv_obj_set_style_border_width(popup_param_editor, 1, 0);
    lv_obj_set_style_border_color(popup_param_editor, lv_color_hex(COLOR_BORDER), 0);
    lv_obj_clear_flag(popup_param_editor, LV_OBJ_FLAG_SCROLLABLE);

    /* Title - shorter */
    lv_obj_t *lbl = lv_label_create(popup_param_editor);
    lv_label_set_text(lbl, param_name);
    lv_obj_set_pos(lbl, 10, 10);
    lv_obj_set_width(lbl, 260);
    lv_label_set_long_mode(lbl, LV_LABEL_LONG_CLIP);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    /* Close button (X) - справа */
    lv_obj_t *btn_close = lv_btn_create(popup_param_editor);
    lv_obj_set_pos(btn_close, 290, 8);
    lv_obj_set_size(btn_close, 32, 32);
    lv_obj_set_style_bg_color(btn_close, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn_close, 4, 0);
    lbl = lv_label_create(btn_close);
    lv_label_set_text(lbl, "X");
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_DANGER), 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn_close, close_popup_cb, LV_EVENT_CLICKED, popup_param_editor);

    /* Value display with unit */
    lbl_param_value = lv_label_create(popup_param_editor);
    lv_label_set_text(lbl_param_value, param_value_str);
    lv_obj_set_pos(lbl_param_value, 130, 50);
    lv_obj_set_style_text_color(lbl_param_value, lv_color_hex(COLOR_ACCENT), 0);
    lv_obj_set_style_text_font(lbl_param_value, &montserrat_16_ru_en, 0);

    /* Unit label */
    lbl = lv_label_create(popup_param_editor);
    lv_label_set_text(lbl, is_percentage ? "%" : "°C");
    lv_obj_set_pos(lbl, 210, 50);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    /* Numeric keypad 4x4 with decimal, minus, backspace */
    const char *keys[16] = {"1", "2", "3", "C", "4", "5", "6", "<", "7", "8", "9", "-", "0", ".", "0", "."};
    int key_size = 55;
    int key_spacing = 6;
    int start_x = 25;
    int start_y = 85;

    /* First 3 rows (12 buttons) */
    for (int i = 0; i < 12; i++) {
        int row = i / 4;
        int col = i % 4;

        lv_obj_t *btn = lv_btn_create(popup_param_editor);
        lv_obj_set_pos(btn, start_x + col * (key_size + key_spacing),
                           start_y + row * (key_size + key_spacing));
        lv_obj_set_size(btn, key_size, key_size);
        lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
        lv_obj_set_style_radius(btn, 6, 0);

        lbl = lv_label_create(btn);
        lv_label_set_text(lbl, keys[i]);
        if (strcmp(keys[i], "C") == 0) {
            lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_DANGER), 0);
        } else if (strcmp(keys[i], "<") == 0 || strcmp(keys[i], ".") == 0 || strcmp(keys[i], "-") == 0) {
            lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0);
        } else {
            lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
        }
        lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
        lv_obj_center(lbl);

        lv_obj_add_event_cb(btn, param_keypad_cb, LV_EVENT_CLICKED, (void*)keys[i]);
    }

    /* Bottom row: 0, dot, OK */
    lv_obj_t *btn = lv_btn_create(popup_param_editor);
    lv_obj_set_pos(btn, start_x, start_y + 3 * (key_size + key_spacing));
    lv_obj_set_size(btn, key_size, key_size);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 6, 0);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "0");
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn, param_keypad_cb, LV_EVENT_CLICKED, (void*)"0");

    btn = lv_btn_create(popup_param_editor);
    lv_obj_set_pos(btn, start_x + (key_size + key_spacing), start_y + 3 * (key_size + key_spacing));
    lv_obj_set_size(btn, key_size, key_size);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 6, 0);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, ".");
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn, param_keypad_cb, LV_EVENT_CLICKED, (void*)".");

    btn = lv_btn_create(popup_param_editor);
    lv_obj_set_pos(btn, start_x + 2 * (key_size + key_spacing), start_y + 3 * (key_size + key_spacing));
    lv_obj_set_size(btn, key_size * 2 + key_spacing, key_size);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_ACCENT), 0);
    lv_obj_set_style_radius(btn, 6, 0);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "OK");
    lv_obj_set_style_text_color(lbl, lv_color_hex(0xFFFFFF), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn, param_keypad_cb, LV_EVENT_CLICKED, (void*)"OK");
}

/* Create popup window for sensor readings */
static void create_popup_readings(void) {
    if (popup_readings) return;

    popup_readings = lv_obj_create(lv_screen_active());
    lv_obj_set_size(popup_readings, 400, 280);
    lv_obj_center(popup_readings);
    lv_obj_set_style_bg_color(popup_readings, lv_color_hex(COLOR_BG_PANEL), 0);
    lv_obj_set_style_radius(popup_readings, 12, 0);
    lv_obj_set_style_border_width(popup_readings, 3, 0);
    lv_obj_set_style_border_color(popup_readings, lv_color_hex(COLOR_TEXT_ACCENT), 0);
    lv_obj_clear_flag(popup_readings, LV_OBJ_FLAG_SCROLLABLE);

    /* Title */
    lv_obj_t *lbl = lv_label_create(popup_readings);
    lv_label_set_text(lbl, "ПОКАЗАНИЯ ДАТЧИКОВ");
    lv_obj_set_pos(lbl, 10, 15);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    /* Close button (X) - справа */
    lv_obj_t *btn_close = lv_btn_create(popup_readings);
    lv_obj_set_pos(btn_close, 330, 10);
    lv_obj_set_size(btn_close, 35, 35);
    lv_obj_set_style_bg_color(btn_close, lv_color_hex(COLOR_DANGER), 0);
    lv_obj_set_style_radius(btn_close, 6, 0);
    lbl = lv_label_create(btn_close);
    lv_label_set_text(lbl, "X");
    lv_obj_set_style_text_color(lbl, lv_color_hex(0xFFFFFF), 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn_close, close_popup_cb, LV_EVENT_CLICKED, popup_readings);

    /* Room sensors */
    int y = 55;
    char buf[64];

    lbl = lv_label_create(popup_readings);
    lv_label_set_text(lbl, "КОМНАТА:");
    lv_obj_set_pos(lbl, 30, y);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    y += 28;
    lbl = lv_label_create(popup_readings);
    snprintf(buf, sizeof(buf), "Температура: %.1f°C", state.temp_room / 10.0f);
    lv_label_set_text(lbl, buf);
    lv_obj_set_pos(lbl, 40, y);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_DANGER), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    y += 26;
    lbl = lv_label_create(popup_readings);
    snprintf(buf, sizeof(buf), "Влажность: %.1f%%", state.hum_room / 10.0f);
    lv_label_set_text(lbl, buf);
    lv_obj_set_pos(lbl, 40, y);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_ACCENT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    /* Channel sensors */
    y += 35;
    lbl = lv_label_create(popup_readings);
    lv_label_set_text(lbl, "КАНАЛ ПРИТОКА:");
    lv_obj_set_pos(lbl, 30, y);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    y += 28;
    lbl = lv_label_create(popup_readings);
    snprintf(buf, sizeof(buf), "Температура: %.1f°C", state.temp_channel / 10.0f);
    lv_label_set_text(lbl, buf);
    lv_obj_set_pos(lbl, 40, y);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_DANGER), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    y += 26;
    lbl = lv_label_create(popup_readings);
    snprintf(buf, sizeof(buf), "Влажность: %.1f%%", state.hum_channel / 10.0f);
    lv_label_set_text(lbl, buf);
    lv_obj_set_pos(lbl, 40, y);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_ACCENT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
}

/* Add alarm to log */
static void add_alarm_to_log(const char *message, int active) {
    if (alarm_count < MAX_ALARMS) {
        strncpy(alarm_log[alarm_count].message, message, 79);
        alarm_log[alarm_count].message[79] = '\0';
        snprintf(alarm_log[alarm_count].timestamp, 20, "%02d.%02d.%04d %02d:%02d",
                 state.day, state.month, state.year, state.hour, state.minute);
        alarm_log[alarm_count].active = active;
        alarm_count++;
    }
}

/* Create alarm popup */
static void create_popup_alarm(const char *message) {
    if (popup_alarm) {
        lv_obj_del(popup_alarm);
    }

    add_alarm_to_log(message, 1);

    popup_alarm = lv_obj_create(lv_screen_active());
    lv_obj_set_size(popup_alarm, 400, 240);
    lv_obj_center(popup_alarm);
    lv_obj_set_style_bg_color(popup_alarm, lv_color_hex(COLOR_DANGER), 0);
    lv_obj_set_style_radius(popup_alarm, 12, 0);
    lv_obj_set_style_border_width(popup_alarm, 4, 0);
    lv_obj_set_style_border_color(popup_alarm, lv_color_hex(0xFF0000), 0);
    lv_obj_clear_flag(popup_alarm, LV_OBJ_FLAG_SCROLLABLE);

    /* Title */
    lv_obj_t *lbl = lv_label_create(popup_alarm);
    lv_label_set_text(lbl, "АВАРИЯ");
    lv_obj_set_pos(lbl, 20, 15);
    lv_obj_set_style_text_color(lbl, lv_color_hex(0xFFFFFF), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    /* Close button (X) - справа в углу */
    lv_obj_t *btn_close = lv_btn_create(popup_alarm);
    lv_obj_set_pos(btn_close, 330, 10);
    lv_obj_set_size(btn_close, 35, 35);
    lv_obj_set_style_bg_color(btn_close, lv_color_hex(0x800000), 0);
    lv_obj_set_style_radius(btn_close, 6, 0);
    lbl = lv_label_create(btn_close);
    lv_label_set_text(lbl, "X");
    lv_obj_set_style_text_color(lbl, lv_color_hex(0xFFFFFF), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn_close, close_popup_cb, LV_EVENT_CLICKED, popup_alarm);

    /* Message */
    lbl = lv_label_create(popup_alarm);
    lv_label_set_text(lbl, message);
    lv_obj_set_pos(lbl, 30, 70);
    lv_obj_set_width(lbl, 340);
    lv_obj_set_style_text_color(lbl, lv_color_hex(0xFFFFFF), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_label_set_long_mode(lbl, LV_LABEL_LONG_WRAP);
    lv_obj_set_style_text_align(lbl, LV_TEXT_ALIGN_CENTER, 0);
}

static void create_screen_main(void) {
    lv_obj_t *scr = lv_obj_create(NULL);
    scr_main = scr;
    lv_obj_set_style_bg_color(scr, lv_color_hex(COLOR_BG_DARK), 0);
    lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, 0);
    lv_obj_clear_flag(scr, LV_OBJ_FLAG_SCROLLABLE);

    /* === STATUS PANEL === (нижняя часть экрана) */
    lv_obj_t *panel_status = lv_obj_create(scr);
    lv_obj_set_pos(panel_status, 10, 255);
    lv_obj_set_size(panel_status, 240, 215);
    lv_obj_set_style_bg_color(panel_status, lv_color_hex(COLOR_BG_PANEL), 0);
    lv_obj_set_style_radius(panel_status, 6, 0);
    lv_obj_set_style_border_width(panel_status, 0, 0);
    lv_obj_clear_flag(panel_status, LV_OBJ_FLAG_SCROLLABLE);

    lv_obj_t *lbl = lv_label_create(panel_status);
    lv_label_set_text(lbl, "Состояние");
    lv_obj_set_pos(lbl, 10, 5);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    lbl_room_num = lv_label_create(panel_status);
    lv_label_set_text(lbl_room_num, "Комната: 101");
    lv_obj_set_pos(lbl_room_num, 10, 30);
    lv_obj_set_style_text_color(lbl_room_num, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl_room_num, &montserrat_16_ru_en, 0);

    lbl_master_slave = lv_label_create(panel_status);
    lv_label_set_text(lbl_master_slave, "Мастер");
    lv_obj_set_pos(lbl_master_slave, 10, 55);
    lv_obj_set_style_text_color(lbl_master_slave, lv_color_hex(COLOR_ACCENT), 0);
    lv_obj_set_style_text_font(lbl_master_slave, &montserrat_16_ru_en, 0);

    lbl_season = lv_label_create(panel_status);
    lv_label_set_text(lbl_season, "Сезон: Зима");
    lv_obj_set_pos(lbl_season, 10, 80);
    lv_obj_set_style_text_color(lbl_season, lv_color_hex(COLOR_TEXT_ACCENT), 0);
    lv_obj_set_style_text_font(lbl_season, &montserrat_16_ru_en, 0);

    lbl_mode = lv_label_create(panel_status);
    lv_label_set_text(lbl_mode, "Режим: Дежурный");
    lv_obj_set_pos(lbl_mode, 10, 105);
    lv_obj_set_style_text_color(lbl_mode, lv_color_hex(COLOR_WARNING), 0);
    lv_obj_set_style_text_font(lbl_mode, &montserrat_16_ru_en, 0);

    lbl_datetime = lv_label_create(panel_status);
    lv_label_set_text(lbl_datetime, "25.02.2025 09:25");
    lv_obj_set_pos(lbl_datetime, 10, 135);
    lv_obj_set_style_text_color(lbl_datetime, lv_color_hex(COLOR_TEXT_DIM), 0);
    lv_obj_set_style_text_font(lbl_datetime, &montserrat_16_ru_en, 0);

    /* === CLIMATE PANEL === */
    lv_obj_t *panel_climate = lv_obj_create(scr);
    lv_obj_set_pos(panel_climate, 260, 255);
    lv_obj_set_size(panel_climate, 230, 215);
    lv_obj_set_style_bg_color(panel_climate, lv_color_hex(COLOR_BG_PANEL), 0);
    lv_obj_set_style_radius(panel_climate, 6, 0);
    lv_obj_set_style_border_width(panel_climate, 0, 0);
    lv_obj_clear_flag(panel_climate, LV_OBJ_FLAG_SCROLLABLE);

    lbl = lv_label_create(panel_climate);
    lv_label_set_text(lbl, "Комната");
    lv_obj_set_pos(lbl, 10, 5);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    lbl = lv_label_create(panel_climate);
    lv_label_set_text(lbl, "Температура:");
    lv_obj_set_pos(lbl, 10, 35);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    lbl_temp_room = lv_label_create(panel_climate);
    lv_label_set_text(lbl_temp_room, "22.0°C");
    lv_obj_set_pos(lbl_temp_room, 130, 35);
    lv_obj_set_style_text_color(lbl_temp_room, lv_color_hex(COLOR_DANGER), 0);
    lv_obj_set_style_text_font(lbl_temp_room, &montserrat_16_ru_en, 0);

    lbl = lv_label_create(panel_climate);
    lv_label_set_text(lbl, "Влажность:");
    lv_obj_set_pos(lbl, 10, 65);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    lbl_hum_room = lv_label_create(panel_climate);
    lv_label_set_text(lbl_hum_room, "45%");
    lv_obj_set_pos(lbl_hum_room, 130, 65);
    lv_obj_set_style_text_color(lbl_hum_room, lv_color_hex(COLOR_TEXT_ACCENT), 0);
    lv_obj_set_style_text_font(lbl_hum_room, &montserrat_16_ru_en, 0);

    /* Channel info */
    lbl = lv_label_create(panel_climate);
    lv_label_set_text(lbl, "Канал:");
    lv_obj_set_pos(lbl, 10, 100);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    lbl_temp_channel = lv_label_create(panel_climate);
    lv_label_set_text(lbl_temp_channel, "20.0°C");
    lv_obj_set_pos(lbl_temp_channel, 70, 100);
    lv_obj_set_style_text_color(lbl_temp_channel, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl_temp_channel, &montserrat_16_ru_en, 0);

    lbl_hum_channel = lv_label_create(panel_climate);
    lv_label_set_text(lbl_hum_channel, "50%");
    lv_obj_set_pos(lbl_hum_channel, 150, 100);
    lv_obj_set_style_text_color(lbl_hum_channel, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl_hum_channel, &montserrat_16_ru_en, 0);

    /* === CONTROL BUTTONS === (правая часть нижней половины) */
    int btn_x = 500;
    int btn_y = 255;

    /* Stop button */
    lv_obj_t *btn = lv_btn_create(scr);
    lv_obj_set_pos(btn, btn_x, btn_y);
    lv_obj_set_size(btn, 140, 100);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 6, 0);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "ОСТАНОВ");
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_DANGER), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn, btn_stop_cb, LV_EVENT_CLICKED, NULL);

    /* Standby button */
    btn = lv_btn_create(scr);
    lv_obj_set_pos(btn, btn_x + 150, btn_y);
    lv_obj_set_size(btn, 140, 48);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 6, 0);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "Дежурный");
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn, btn_standby_cb, LV_EVENT_CLICKED, NULL);

    /* Work button */
    btn = lv_btn_create(scr);
    lv_obj_set_pos(btn, btn_x + 150, btn_y + 52);
    lv_obj_set_size(btn, 140, 48);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 6, 0);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "Рабочий");
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_ACCENT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn, btn_work_cb, LV_EVENT_CLICKED, NULL);

    /* Menu button */
    btn = lv_btn_create(scr);
    lv_obj_set_pos(btn, btn_x, btn_y + 108);
    lv_obj_set_size(btn, 140, 48);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 6, 0);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "Меню");
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn, btn_menu_cb, LV_EVENT_CLICKED, NULL);

    /* Readings button */
    btn = lv_btn_create(scr);
    lv_obj_set_pos(btn, btn_x + 150, btn_y + 108);
    lv_obj_set_size(btn, 140, 48);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 6, 0);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "Показания");
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_ACCENT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn, btn_readings_cb, LV_EVENT_CLICKED, NULL);

    /* === EQUIPMENT SCHEMA AREA === (верхняя половина экрана) */
    schema_panel = lv_obj_create(scr);
    lv_obj_set_pos(schema_panel, 10, 10);
    lv_obj_set_size(schema_panel, 780, 235);
    lv_obj_set_style_bg_color(schema_panel, lv_color_hex(COLOR_BG_PANEL), 0);
    lv_obj_set_style_radius(schema_panel, 6, 0);
    lv_obj_set_style_border_width(schema_panel, 0, 0);
    lv_obj_clear_flag(schema_panel, LV_OBJ_FLAG_SCROLLABLE);
    
    /* Hint labels */
    lv_obj_t *hint1 = lv_label_create(schema_panel);
    lv_label_set_text(hint1, "Активные модули (перетащите вниз для отключения):");
    lv_obj_set_pos(hint1, 10, 2);
    lv_obj_set_style_text_color(hint1, lv_color_hex(COLOR_TEXT_DIM), 0);
    lv_obj_set_style_text_font(hint1, &montserrat_16_ru_en, 0);
    
    lv_obj_t *hint2 = lv_label_create(schema_panel);
    lv_label_set_text(hint2, "Неактивные (перетащите вверх для включения):");
    lv_obj_set_pos(hint2, 10, 115);
    lv_obj_set_style_text_color(hint2, lv_color_hex(COLOR_TEXT_DIM), 0);
    lv_obj_set_style_text_font(hint2, &montserrat_16_ru_en, 0);

    /* Create continuous pipe background line FIRST (so modules appear on top) */
    /* Calculate total width needed for all module positions */
    int pipe_x = 5;
    int pipe_y = MODULES_ACTIVE_Y + 25;
    int pipe_segment_width = 35;  /* Scaled pipe image width approximately */
    int total_modules_width = 50 + MODULE_COUNT * (MODULE_WIDTH + MODULE_SPACING) + 50;
    
    /* Create pipe segments to form continuous line */
    for (int px = pipe_x; px < total_modules_width; px += pipe_segment_width) {
        lv_obj_t *pipe_seg = lv_image_create(schema_panel);
        lv_image_set_src(pipe_seg, &img_pipe);
        lv_image_set_scale(pipe_seg, MODULE_SCALE);
        lv_obj_set_pos(pipe_seg, px, pipe_y);
    }
    
    /* Create all modules (they will appear on top of pipe line) */
    int active_x = 50;  /* Start after the inlet pipe */
    int inactive_x = 10;
    
    for (int i = 0; i < MODULE_COUNT; i++) {
        int x_pos, y_pos;
        if (modules[i].enabled) {
            x_pos = active_x;
            y_pos = MODULES_ACTIVE_Y;
            active_x += MODULE_WIDTH + MODULE_SPACING;
        } else {
            x_pos = inactive_x;
            y_pos = MODULES_INACTIVE_Y;
            inactive_x += MODULE_WIDTH + MODULE_SPACING;
        }
        create_module_widget(schema_panel, i, x_pos, y_pos);
        
        /* No more individual pipe placeholders needed - continuous pipe line handles it */
        pipe_placeholders[i] = NULL;
    }
    
    /* Update all module displays with current values */
    for (int i = 0; i < MODULE_COUNT; i++) {
        update_module_display(i);
    }
}

static void create_screen_screen1(void) {
    lv_obj_t *scr = lv_obj_create(NULL);
    scr_screen1 = scr;
    lv_obj_set_style_bg_color(scr, lv_color_hex(COLOR_BG_DARK), 0);
    lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, 0);
    lv_obj_clear_flag(scr, LV_OBJ_FLAG_SCROLLABLE);

    /* Title */
    lv_obj_t *lbl = lv_label_create(scr);
    lv_label_set_text(lbl, "МЕНЮ");
    lv_obj_set_pos(lbl, 370, 30);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    int btn_width = 300;
    int btn_height = 55;
    int x = 250;
    int y = 90;
    int spacing = 15;

    /* Button: Back to Main Screen */
    lv_obj_t *btn = lv_btn_create(scr);
    lv_obj_set_pos(btn, x, y);
    lv_obj_set_size(btn, btn_width, btn_height);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 6, 0);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "Главный экран");
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_ACCENT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn, btn_back_to_main_cb, LV_EVENT_CLICKED, NULL);

    y += btn_height + spacing;

    /* Button: Log (Журнал) */
    btn = lv_btn_create(scr);
    lv_obj_set_pos(btn, x, y);
    lv_obj_set_size(btn, btn_width, btn_height);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 6, 0);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "Журнал аварий");
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn, btn_log_cb, LV_EVENT_CLICKED, NULL);

    y += btn_height + spacing;

    /* Button: Settings Parameters (Уставка параметров) */
    btn = lv_btn_create(scr);
    lv_obj_set_pos(btn, x, y);
    lv_obj_set_size(btn, btn_width, btn_height);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 6, 0);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "Уставка параметров");
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn, btn_settings_cb, LV_EVENT_CLICKED, NULL);

    y += btn_height + spacing;

    /* Button: Configuration (Настройки - требует пароль) */
    btn = lv_btn_create(scr);
    lv_obj_set_pos(btn, x, y);
    lv_obj_set_size(btn, btn_width, btn_height);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 6, 0);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "Настройки");
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_DANGER), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn, btn_config_cb, LV_EVENT_CLICKED, NULL);
}

static void create_screen_screen2(void) {
    lv_obj_t *scr = lv_obj_create(NULL);
    scr_screen2 = scr;
    lv_obj_set_style_bg_color(scr, lv_color_hex(0x2C3E50), 0);
    lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, 0);
    lv_obj_clear_flag(scr, LV_OBJ_FLAG_SCROLLABLE);

    /* Title */
    lv_obj_t *lbl = lv_label_create(scr);
    lv_label_set_text(lbl, "ЖУРНАЛ АВАРИЙ");
    lv_obj_set_pos(lbl, 300, 20);
    lv_obj_set_style_text_color(lbl, lv_color_hex(0xECF0F1), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    /* Date/Time display */
    char datetime_buf[32];
    snprintf(datetime_buf, sizeof(datetime_buf), "%02d.%02d.%04d %02d:%02d",
             state.day, state.month, state.year, state.hour, state.minute);
    lbl = lv_label_create(scr);
    lv_label_set_text(lbl, datetime_buf);
    lv_obj_set_pos(lbl, 620, 20);
    lv_obj_set_style_text_color(lbl, lv_color_hex(0xBDC3C7), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    /* Log panel */
    lv_obj_t *log_panel = lv_obj_create(scr);
    lv_obj_set_pos(log_panel, 20, 60);
    lv_obj_set_size(log_panel, 760, 300);
    lv_obj_set_style_bg_color(log_panel, lv_color_hex(0x34495E), 0);
    lv_obj_set_style_radius(log_panel, 8, 0);
    lv_obj_set_style_border_width(log_panel, 2, 0);
    lv_obj_set_style_border_color(log_panel, lv_color_hex(0x7F8C8D), 0);

    /* Display log entries */
    int y = 10;
    if (alarm_count == 0) {
        lbl = lv_label_create(log_panel);
        lv_label_set_text(lbl, "Аварий нет");
        lv_obj_set_pos(lbl, 320, 130);
        lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_ACCENT), 0);
        lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    } else {
        for (int i = 0; i < alarm_count && i < 8; i++) {
            char buf[150];
            snprintf(buf, sizeof(buf), "%s - %s",
                     alarm_log[i].message, alarm_log[i].timestamp);

            lbl = lv_label_create(log_panel);
            lv_label_set_text(lbl, buf);
            lv_obj_set_pos(lbl, 10, y);
            lv_obj_set_width(lbl, 730);
            if (alarm_log[i].active) {
                lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_DANGER), 0);
            } else {
                lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0);
            }
            lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
            y += 35;
        }
    }

    /* Buttons */
    int btn_y = 380;

    /* Clear Log button */
    lv_obj_t *btn = lv_btn_create(scr);
    lv_obj_set_pos(btn, 50, btn_y);
    lv_obj_set_size(btn, 160, 40);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 6, 0);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "Очистить журнал");
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_DANGER), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn, btn_clear_log_cb, LV_EVENT_CLICKED, NULL);

    /* Reset Alarm button */
    btn = lv_btn_create(scr);
    lv_obj_set_pos(btn, 230, btn_y);
    lv_obj_set_size(btn, 160, 40);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 6, 0);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "Сбросить аварию");
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn, btn_reset_alarm_cb, LV_EVENT_CLICKED, NULL);

    /* Back to Menu button */
    btn = lv_btn_create(scr);
    lv_obj_set_pos(btn, 600, btn_y);
    lv_obj_set_size(btn, 120, 40);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 6, 0);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "Меню");
    lv_obj_set_style_text_color(lbl, lv_color_hex(0xFFFFFF), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn, btn_menu_cb, LV_EVENT_CLICKED, NULL);
}

static void create_screen_screen3(void) {
    lv_obj_t *scr = lv_obj_create(NULL);
    scr_screen3 = scr;
    lv_obj_set_style_bg_color(scr, lv_color_hex(COLOR_BG_DARK), 0);
    lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, 0);
    lv_obj_clear_flag(scr, LV_OBJ_FLAG_SCROLLABLE);

    /* Title */
    lv_obj_t *lbl = lv_label_create(scr);
    lv_label_set_text(lbl, "УСТАВКА ПАРАМЕТРОВ");
    lv_obj_set_pos(lbl, 290, 10);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    char buf[64];
    int row_h = 34;

    /* Left panel - Work mode - SCROLLABLE */
    lv_obj_t *panel_work = lv_obj_create(scr);
    lv_obj_set_pos(panel_work, 15, 40);
    lv_obj_set_size(panel_work, 380, 310);
    lv_obj_set_style_bg_color(panel_work, lv_color_hex(COLOR_BG_PANEL), 0);
    lv_obj_set_style_radius(panel_work, 6, 0);
    lv_obj_set_style_border_width(panel_work, 0, 0);
    lv_obj_set_scroll_dir(panel_work, LV_DIR_VER);
    lv_obj_set_scrollbar_mode(panel_work, LV_SCROLLBAR_MODE_AUTO);

    lbl = lv_label_create(panel_work);
    lv_label_set_text(lbl, "РАБОЧИЙ");
    lv_obj_set_pos(lbl, 10, 8);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_ACCENT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    int y = 38;

    /* Temperature */
    lv_obj_t *btn = lv_btn_create(panel_work);
    lv_obj_set_pos(btn, 5, y);
    lv_obj_set_size(btn, 350, row_h);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    snprintf(buf, sizeof(buf), "Температура: %.1f°C", setpoint_work.temp);
    lbl_work_temp = lv_label_create(btn);
    lv_label_set_text(lbl_work_temp, buf);
    lv_obj_center(lbl_work_temp);
    lv_obj_set_style_text_color(lbl_work_temp, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl_work_temp, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_work_temp_cb, LV_EVENT_CLICKED, NULL);

    y += row_h + 6;
    /* Humidity */
    btn = lv_btn_create(panel_work);
    lv_obj_set_pos(btn, 5, y);
    lv_obj_set_size(btn, 350, row_h);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    snprintf(buf, sizeof(buf), "Влажность: %.1f%%", setpoint_work.hum);
    lbl_work_hum = lv_label_create(btn);
    lv_label_set_text(lbl_work_hum, buf);
    lv_obj_center(lbl_work_hum);
    lv_obj_set_style_text_color(lbl_work_hum, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl_work_hum, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_work_hum_cb, LV_EVENT_CLICKED, NULL);

    y += row_h + 6;
    /* Valve inlet */
    btn = lv_btn_create(panel_work);
    lv_obj_set_pos(btn, 5, y);
    lv_obj_set_size(btn, 350, row_h);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    snprintf(buf, sizeof(buf), "Клапан притока: %.1f%%", setpoint_work.valve_inlet);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, buf);
    lv_obj_center(lbl);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_work_valve_inlet_cb, LV_EVENT_CLICKED, NULL);

    y += row_h + 6;
    /* Valve recirc */
    btn = lv_btn_create(panel_work);
    lv_obj_set_pos(btn, 5, y);
    lv_obj_set_size(btn, 350, row_h);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    snprintf(buf, sizeof(buf), "Клапан рецирк: %.1f%%", setpoint_work.valve_recirc);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, buf);
    lv_obj_center(lbl);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_work_valve_recirc_cb, LV_EVENT_CLICKED, NULL);

    y += row_h + 6;
    /* Heater mode */
    btn = lv_btn_create(panel_work);
    lv_obj_set_pos(btn, 5, y);
    lv_obj_set_size(btn, 350, row_h);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    const char *heater_modes[] = {"ВЫКЛ", "ВКЛ", "АВТО"};
    snprintf(buf, sizeof(buf), "Электронагрев: %s", heater_modes[setpoint_work.heater]);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, buf);
    lv_obj_center(lbl);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_work_heater_cb, LV_EVENT_CLICKED, NULL);

    y += row_h + 6;
    /* Fan toggle */
    btn = lv_btn_create(panel_work);
    lv_obj_set_pos(btn, 5, y);
    lv_obj_set_size(btn, 350, row_h);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    snprintf(buf, sizeof(buf), "Вентилятор: %s", setpoint_work.fan ? "ВКЛ" : "ВЫКЛ");
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, buf);
    lv_obj_center(lbl);
    lv_obj_set_style_text_color(lbl, setpoint_work.fan ? lv_color_hex(COLOR_ACCENT) : lv_color_hex(COLOR_TEXT_DIM), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_work_fan_cb, LV_EVENT_CLICKED, NULL);

    y += row_h + 6;
    /* KWS mode */
    btn = lv_btn_create(panel_work);
    lv_obj_set_pos(btn, 5, y);
    lv_obj_set_size(btn, 350, row_h);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    if (setpoint_work.kws_auto) {
        snprintf(buf, sizeof(buf), "KWS: АВТО");
    } else {
        snprintf(buf, sizeof(buf), "KWS: %.1f%%", setpoint_work.kws_manual);
    }
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, buf);
    lv_obj_center(lbl);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_work_kws_cb, LV_EVENT_CLICKED, NULL);

    y += row_h + 6;
    /* PWW mode */
    btn = lv_btn_create(panel_work);
    lv_obj_set_pos(btn, 5, y);
    lv_obj_set_size(btn, 350, row_h);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    if (setpoint_work.pww_auto) {
        snprintf(buf, sizeof(buf), "PWW: АВТО");
    } else {
        snprintf(buf, sizeof(buf), "PWW: %.1f%%", setpoint_work.pww_manual);
    }
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, buf);
    lv_obj_center(lbl);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_work_pww_cb, LV_EVENT_CLICKED, NULL);

    /* Right panel - Standby mode - SCROLLABLE */
    lv_obj_t *panel_standby = lv_obj_create(scr);
    lv_obj_set_pos(panel_standby, 405, 40);
    lv_obj_set_size(panel_standby, 380, 310);
    lv_obj_set_style_bg_color(panel_standby, lv_color_hex(COLOR_BG_PANEL), 0);
    lv_obj_set_style_radius(panel_standby, 6, 0);
    lv_obj_set_style_border_width(panel_standby, 0, 0);
    lv_obj_set_scroll_dir(panel_standby, LV_DIR_VER);
    lv_obj_set_scrollbar_mode(panel_standby, LV_SCROLLBAR_MODE_AUTO);

    lbl = lv_label_create(panel_standby);
    lv_label_set_text(lbl, "ДЕЖУРНЫЙ");
    lv_obj_set_pos(lbl, 10, 8);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    y = 38;
    /* Standby Temperature */
    btn = lv_btn_create(panel_standby);
    lv_obj_set_pos(btn, 5, y);
    lv_obj_set_size(btn, 350, row_h);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    snprintf(buf, sizeof(buf), "Температура: %.1f°C", setpoint_standby.temp);
    lbl_standby_temp = lv_label_create(btn);
    lv_label_set_text(lbl_standby_temp, buf);
    lv_obj_center(lbl_standby_temp);
    lv_obj_set_style_text_color(lbl_standby_temp, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl_standby_temp, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_standby_temp_cb, LV_EVENT_CLICKED, NULL);

    y += row_h + 6;
    /* Standby Humidity */
    btn = lv_btn_create(panel_standby);
    lv_obj_set_pos(btn, 5, y);
    lv_obj_set_size(btn, 350, row_h);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    snprintf(buf, sizeof(buf), "Влажность: %.1f%%", setpoint_standby.hum);
    lbl_standby_hum = lv_label_create(btn);
    lv_label_set_text(lbl_standby_hum, buf);
    lv_obj_center(lbl_standby_hum);
    lv_obj_set_style_text_color(lbl_standby_hum, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl_standby_hum, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_standby_hum_cb, LV_EVENT_CLICKED, NULL);

    y += row_h + 6;
    /* Standby Valve inlet */
    btn = lv_btn_create(panel_standby);
    lv_obj_set_pos(btn, 5, y);
    lv_obj_set_size(btn, 350, row_h);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    snprintf(buf, sizeof(buf), "Клапан притока: %.1f%%", setpoint_standby.valve_inlet);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, buf);
    lv_obj_center(lbl);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_standby_valve_inlet_cb, LV_EVENT_CLICKED, NULL);

    y += row_h + 6;
    /* Standby Valve recirc */
    btn = lv_btn_create(panel_standby);
    lv_obj_set_pos(btn, 5, y);
    lv_obj_set_size(btn, 350, row_h);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    snprintf(buf, sizeof(buf), "Клапан рецирк: %.1f%%", setpoint_standby.valve_recirc);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, buf);
    lv_obj_center(lbl);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_standby_valve_recirc_cb, LV_EVENT_CLICKED, NULL);

    y += row_h + 6;
    /* Heater mode */
    btn = lv_btn_create(panel_standby);
    lv_obj_set_pos(btn, 5, y);
    lv_obj_set_size(btn, 350, row_h);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    snprintf(buf, sizeof(buf), "Электронагрев: %s", heater_modes[setpoint_standby.heater]);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, buf);
    lv_obj_center(lbl);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_standby_heater_cb, LV_EVENT_CLICKED, NULL);

    y += row_h + 6;
    /* Fan toggle */
    btn = lv_btn_create(panel_standby);
    lv_obj_set_pos(btn, 5, y);
    lv_obj_set_size(btn, 350, row_h);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    snprintf(buf, sizeof(buf), "Вентилятор: %s", setpoint_standby.fan ? "ВКЛ" : "ВЫКЛ");
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, buf);
    lv_obj_center(lbl);
    lv_obj_set_style_text_color(lbl, setpoint_standby.fan ? lv_color_hex(COLOR_ACCENT) : lv_color_hex(COLOR_TEXT_DIM), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_standby_fan_cb, LV_EVENT_CLICKED, NULL);

    y += row_h + 6;
    /* KWS mode */
    btn = lv_btn_create(panel_standby);
    lv_obj_set_pos(btn, 5, y);
    lv_obj_set_size(btn, 350, row_h);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    if (setpoint_standby.kws_auto) {
        snprintf(buf, sizeof(buf), "KWS: АВТО");
    } else {
        snprintf(buf, sizeof(buf), "KWS: %.1f%%", setpoint_standby.kws_manual);
    }
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, buf);
    lv_obj_center(lbl);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_standby_kws_cb, LV_EVENT_CLICKED, NULL);

    y += row_h + 6;
    /* PWW mode */
    btn = lv_btn_create(panel_standby);
    lv_obj_set_pos(btn, 5, y);
    lv_obj_set_size(btn, 350, row_h);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    if (setpoint_standby.pww_auto) {
        snprintf(buf, sizeof(buf), "PWW: АВТО");
    } else {
        snprintf(buf, sizeof(buf), "PWW: %.1f%%", setpoint_standby.pww_manual);
    }
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, buf);
    lv_obj_center(lbl);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_standby_pww_cb, LV_EVENT_CLICKED, NULL);

    /* Common parameters section */
    lv_obj_t *panel_common = lv_obj_create(scr);
    lv_obj_set_pos(panel_common, 15, 355);
    lv_obj_set_size(panel_common, 770, 70);
    lv_obj_set_style_bg_color(panel_common, lv_color_hex(COLOR_BG_PANEL), 0);
    lv_obj_set_style_radius(panel_common, 6, 0);
    lv_obj_set_style_border_width(panel_common, 0, 0);
    lv_obj_clear_flag(panel_common, LV_OBJ_FLAG_SCROLLABLE);

    lbl = lv_label_create(panel_common);
    lv_label_set_text(lbl, "Общие параметры:");
    lv_obj_set_pos(lbl, 10, 5);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    snprintf(buf, sizeof(buf), "Фильтр G4: %s", filter_g4_date);
    lbl = lv_label_create(panel_common);
    lv_label_set_text(lbl, buf);
    lv_obj_set_pos(lbl, 10, 28);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    snprintf(buf, sizeof(buf), "Фильтр H13: %s", filter_h13_date);
    lbl = lv_label_create(panel_common);
    lv_label_set_text(lbl, buf);
    lv_obj_set_pos(lbl, 250, 28);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    snprintf(buf, sizeof(buf), "%02d:%02d %02d.%02d.%d", state.hour, state.minute, state.day, state.month, state.year);
    lbl = lv_label_create(panel_common);
    lv_label_set_text(lbl, buf);
    lv_obj_set_pos(lbl, 510, 28);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_ACCENT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    
    lbl = lv_label_create(panel_common);
    lv_label_set_text(lbl, "(для ввода даты замены)");
    lv_obj_set_pos(lbl, 10, 48);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_DIM), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    /* Buttons row */
    int btn_y = 435;

    btn = lv_btn_create(scr);
    lv_obj_set_pos(btn, 200, btn_y);
    lv_obj_set_size(btn, 110, 38);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "Сохранить");
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_ACCENT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);

    btn = lv_btn_create(scr);
    lv_obj_set_pos(btn, 330, btn_y);
    lv_obj_set_size(btn, 140, 38);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "По умолчанию");
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);

    btn = lv_btn_create(scr);
    lv_obj_set_pos(btn, 490, btn_y);
    lv_obj_set_size(btn, 100, 38);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "Меню");
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn, btn_menu_cb, LV_EVENT_CLICKED, NULL);
}

/* ============ SCREEN 4: НАСТРОЙКИ (config, after password) ============ */
static void create_screen_config(void) {
    lv_obj_t *scr = lv_obj_create(NULL);
    scr_screen4 = scr;
    lv_obj_set_style_bg_color(scr, lv_color_hex(COLOR_BG_DARK), 0);
    lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, 0);
    lv_obj_clear_flag(scr, LV_OBJ_FLAG_SCROLLABLE);

    char buf[64];

    /* Header */
    lv_obj_t *lbl = lv_label_create(scr);
    lv_label_set_text(lbl, "НАСТРОЙКИ");
    lv_obj_set_pos(lbl, 340, 10);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    /* Left panel - Sensor corrections - SCROLLABLE */
    lv_obj_t *panel_left = lv_obj_create(scr);
    lv_obj_set_pos(panel_left, 10, 45);
    lv_obj_set_size(panel_left, 385, 340);
    lv_obj_set_style_bg_color(panel_left, lv_color_hex(COLOR_BG_PANEL), 0);
    lv_obj_set_style_radius(panel_left, 8, 0);
    lv_obj_set_style_border_width(panel_left, 0, 0);
    lv_obj_set_style_pad_all(panel_left, 8, 0);
    lv_obj_set_scroll_dir(panel_left, LV_DIR_VER);
    lv_obj_set_scrollbar_mode(panel_left, LV_SCROLLBAR_MODE_AUTO);

    lbl = lv_label_create(panel_left);
    lv_label_set_text(lbl, "Коррекция датчиков");
    lv_obj_set_pos(lbl, 10, 5);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    lv_obj_t *btn;
    int y = 35;
    const char *labels[] = {
        "Темп. помещения:",
        "Влажн. помещения:",
        "Темп. в канале:",
        "Влажн. в канале:",
        "Клапан притока:",
        "Клапан рецирк.:"
    };
    float *offsets[] = {
        &config.temp_room_offset,
        &config.hum_room_offset,
        &config.temp_channel_offset,
        &config.hum_channel_offset,
        &config.valve_inlet_offset,
        &config.valve_recirc_offset
    };

    for (int i = 0; i < 6; i++) {
        btn = lv_btn_create(panel_left);
        lv_obj_set_pos(btn, 0, y);
        lv_obj_set_size(btn, 350, 36);
        lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
        lv_obj_set_style_radius(btn, 4, 0);
        lv_obj_set_style_pad_all(btn, 0, 0);

        lv_obj_t *lbl_name = lv_label_create(btn);
        lv_label_set_text(lbl_name, labels[i]);
        lv_obj_align(lbl_name, LV_ALIGN_LEFT_MID, 10, 0);
        lv_obj_set_style_text_color(lbl_name, lv_color_hex(COLOR_TEXT), 0);
        lv_obj_set_style_text_font(lbl_name, &montserrat_16_ru_en, 0);

        snprintf(buf, sizeof(buf), "%+.1f", *offsets[i]);
        lv_obj_t *lbl_val = lv_label_create(btn);
        lv_label_set_text(lbl_val, buf);
        lv_obj_align(lbl_val, LV_ALIGN_RIGHT_MID, -10, 0);
        lv_obj_set_style_text_color(lbl_val, lv_color_hex(COLOR_ACCENT), 0);
        lv_obj_set_style_text_font(lbl_val, &montserrat_16_ru_en, 0);

        lv_obj_add_event_cb(btn, edit_config_offset_cb, LV_EVENT_CLICKED, offsets[i]);

        y += 40;
    }

    /* Toggles for equipment presence */
    y += 10;
    btn = lv_btn_create(panel_left);
    lv_obj_set_pos(btn, 0, y);
    lv_obj_set_size(btn, 350, 36);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    lv_obj_set_style_pad_all(btn, 0, 0);

    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "Клапан рецирк.:");
    lv_obj_align(lbl, LV_ALIGN_LEFT_MID, 10, 0);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, config.has_recirc_valve ? "ЕСТЬ" : "НЕТ");
    lv_obj_align(lbl, LV_ALIGN_RIGHT_MID, -10, 0);
    lv_obj_set_style_text_color(lbl, config.has_recirc_valve ? lv_color_hex(COLOR_ACCENT) : lv_color_hex(COLOR_TEXT_DIM), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, toggle_recirc_valve_cb, LV_EVENT_CLICKED, NULL);

    y += 40;
    btn = lv_btn_create(panel_left);
    lv_obj_set_pos(btn, 0, y);
    lv_obj_set_size(btn, 350, 36);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    lv_obj_set_style_pad_all(btn, 0, 0);

    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "Электронагрев.:");
    lv_obj_align(lbl, LV_ALIGN_LEFT_MID, 10, 0);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, config.has_heater ? "ЕСТЬ" : "НЕТ");
    lv_obj_align(lbl, LV_ALIGN_RIGHT_MID, -10, 0);
    lv_obj_set_style_text_color(lbl, config.has_heater ? lv_color_hex(COLOR_ACCENT) : lv_color_hex(COLOR_TEXT_DIM), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, toggle_heater_cb, LV_EVENT_CLICKED, NULL);

    /* Right panel - PID and mode settings - SCROLLABLE */
    lv_obj_t *panel_right = lv_obj_create(scr);
    lv_obj_set_pos(panel_right, 405, 45);
    lv_obj_set_size(panel_right, 385, 340);
    lv_obj_set_style_bg_color(panel_right, lv_color_hex(COLOR_BG_PANEL), 0);
    lv_obj_set_style_radius(panel_right, 8, 0);
    lv_obj_set_style_border_width(panel_right, 0, 0);
    lv_obj_set_style_pad_all(panel_right, 8, 0);
    lv_obj_set_scroll_dir(panel_right, LV_DIR_VER);
    lv_obj_set_scrollbar_mode(panel_right, LV_SCROLLBAR_MODE_AUTO);

    lbl = lv_label_create(panel_right);
    lv_label_set_text(lbl, "ПИД регуляторы");
    lv_obj_set_pos(lbl, 10, 5);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    y = 35;
    /* PWW PID - separate buttons for each parameter */
    lbl = lv_label_create(panel_right);
    lv_label_set_text(lbl, "PWW:");
    lv_obj_set_pos(lbl, 10, y);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_ACCENT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    y += 25;
    /* PWW Kp */
    btn = lv_btn_create(panel_right);
    lv_obj_set_pos(btn, 0, y);
    lv_obj_set_size(btn, 110, 32);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    lv_obj_set_style_pad_all(btn, 0, 0);
    snprintf(buf, sizeof(buf), "Kp=%.2f", config.pid_pww_kp);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, buf);
    lv_obj_center(lbl);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_pid_pww_kp_cb, LV_EVENT_CLICKED, NULL);

    /* PWW Ti */
    btn = lv_btn_create(panel_right);
    lv_obj_set_pos(btn, 115, y);
    lv_obj_set_size(btn, 110, 32);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    lv_obj_set_style_pad_all(btn, 0, 0);
    snprintf(buf, sizeof(buf), "Ti=%.2f", config.pid_pww_ti);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, buf);
    lv_obj_center(lbl);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_pid_pww_ti_cb, LV_EVENT_CLICKED, NULL);

    /* PWW D */
    btn = lv_btn_create(panel_right);
    lv_obj_set_pos(btn, 230, y);
    lv_obj_set_size(btn, 110, 32);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    lv_obj_set_style_pad_all(btn, 0, 0);
    snprintf(buf, sizeof(buf), "D=%.2f", config.pid_pww_d);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, buf);
    lv_obj_center(lbl);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_pid_pww_d_cb, LV_EVENT_CLICKED, NULL);

    y += 42;
    /* KWS PID - separate buttons for each parameter */
    lbl = lv_label_create(panel_right);
    lv_label_set_text(lbl, "KWS:");
    lv_obj_set_pos(lbl, 10, y);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_ACCENT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    y += 25;
    /* KWS Kp */
    btn = lv_btn_create(panel_right);
    lv_obj_set_pos(btn, 0, y);
    lv_obj_set_size(btn, 110, 32);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    lv_obj_set_style_pad_all(btn, 0, 0);
    snprintf(buf, sizeof(buf), "Kp=%.2f", config.pid_kws_kp);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, buf);
    lv_obj_center(lbl);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_pid_kws_kp_cb, LV_EVENT_CLICKED, NULL);

    /* KWS Ti */
    btn = lv_btn_create(panel_right);
    lv_obj_set_pos(btn, 115, y);
    lv_obj_set_size(btn, 110, 32);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    lv_obj_set_style_pad_all(btn, 0, 0);
    snprintf(buf, sizeof(buf), "Ti=%.2f", config.pid_kws_ti);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, buf);
    lv_obj_center(lbl);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_pid_kws_ti_cb, LV_EVENT_CLICKED, NULL);

    /* KWS D */
    btn = lv_btn_create(panel_right);
    lv_obj_set_pos(btn, 230, y);
    lv_obj_set_size(btn, 110, 32);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    lv_obj_set_style_pad_all(btn, 0, 0);
    snprintf(buf, sizeof(buf), "D=%.2f", config.pid_kws_d);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, buf);
    lv_obj_center(lbl);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_pid_kws_d_cb, LV_EVENT_CLICKED, NULL);

    y += 42;
    lbl = lv_label_create(panel_right);
    lv_label_set_text(lbl, "Режим работы");
    lv_obj_set_pos(lbl, 10, y);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    y += 30;
    btn = lv_btn_create(panel_right);
    lv_obj_set_pos(btn, 0, y);
    lv_obj_set_size(btn, 350, 36);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    lv_obj_set_style_pad_all(btn, 0, 0);

    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "Принуд. режим:");
    lv_obj_align(lbl, LV_ALIGN_LEFT_MID, 10, 0);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, config.force_mode_enabled ? "ВКЛ" : "ВЫКЛ");
    lv_obj_align(lbl, LV_ALIGN_RIGHT_MID, -10, 0);
    lv_obj_set_style_text_color(lbl, config.force_mode_enabled ? lv_color_hex(COLOR_WARNING) : lv_color_hex(COLOR_TEXT_DIM), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, toggle_force_mode_cb, LV_EVENT_CLICKED, NULL);

    y += 40;
    btn = lv_btn_create(panel_right);
    lv_obj_set_pos(btn, 0, y);
    lv_obj_set_size(btn, 350, 36);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    lv_obj_set_style_pad_all(btn, 0, 0);

    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "Перемена ключа:");
    lv_obj_align(lbl, LV_ALIGN_LEFT_MID, 10, 0);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, config.key_swap_enabled ? "ВКЛ" : "ВЫКЛ");
    lv_obj_align(lbl, LV_ALIGN_RIGHT_MID, -10, 0);
    lv_obj_set_style_text_color(lbl, config.key_swap_enabled ? lv_color_hex(COLOR_ACCENT) : lv_color_hex(COLOR_TEXT_DIM), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, toggle_key_swap_cb, LV_EVENT_CLICKED, NULL);

    y += 45;
    lbl = lv_label_create(panel_right);
    lv_label_set_text(lbl, "Дата и время");
    lv_obj_set_pos(lbl, 10, y);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_WARNING), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);

    y += 30;
    btn = lv_btn_create(panel_right);
    lv_obj_set_pos(btn, 0, y);
    lv_obj_set_size(btn, 350, 36);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_BG_BTN), 0);
    lv_obj_set_style_radius(btn, 4, 0);
    lv_obj_set_style_pad_all(btn, 0, 0);

    snprintf(buf, sizeof(buf), "%02d.%02d.%04d  %02d:%02d",
             state.day, state.month, state.year, state.hour, state.minute);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, buf);
    lv_obj_center(lbl);
    lv_obj_set_style_text_color(lbl, lv_color_hex(COLOR_TEXT_ACCENT), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_add_event_cb(btn, edit_datetime_cb, LV_EVENT_CLICKED, NULL);

    /* Buttons */
    btn = lv_btn_create(scr);
    lv_obj_set_pos(btn, 200, 410);
    lv_obj_set_size(btn, 120, 40);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_ACCENT), 0);
    lv_obj_set_style_radius(btn, 8, 0);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "Сохранить");
    lv_obj_set_style_text_color(lbl, lv_color_hex(0xFFFFFF), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);

    btn = lv_btn_create(scr);
    lv_obj_set_pos(btn, 340, 410);
    lv_obj_set_size(btn, 140, 40);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_WARNING), 0);
    lv_obj_set_style_radius(btn, 8, 0);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "По умолчанию");
    lv_obj_set_style_text_color(lbl, lv_color_hex(0xFFFFFF), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);

    btn = lv_btn_create(scr);
    lv_obj_set_pos(btn, 500, 410);
    lv_obj_set_size(btn, 100, 40);
    lv_obj_set_style_bg_color(btn, lv_color_hex(COLOR_TEXT_ACCENT), 0);
    lv_obj_set_style_radius(btn, 8, 0);
    lbl = lv_label_create(btn);
    lv_label_set_text(lbl, "Меню");
    lv_obj_set_style_text_color(lbl, lv_color_hex(0xFFFFFF), 0);
    lv_obj_set_style_text_font(lbl, &montserrat_16_ru_en, 0);
    lv_obj_center(lbl);
    lv_obj_add_event_cb(btn, btn_menu_cb, LV_EVENT_CLICKED, NULL);
}

void gui_update_values(void) {
    char buf[64];

    /* Update room climate */
    if (lbl_temp_room) {
        snprintf(buf, sizeof(buf), "%.1f°C", state.temp_room / 10.0f);
        lv_label_set_text(lbl_temp_room, buf);
    }

    if (lbl_hum_room) {
        snprintf(buf, sizeof(buf), "%.1f%%", state.hum_room / 10.0f);
        lv_label_set_text(lbl_hum_room, buf);
    }

    /* Update channel climate */
    if (lbl_temp_channel) {
        snprintf(buf, sizeof(buf), "%.1f°C", state.temp_channel / 10.0f);
        lv_label_set_text(lbl_temp_channel, buf);
    }

    if (lbl_hum_channel) {
        snprintf(buf, sizeof(buf), "%.1f%%", state.hum_channel / 10.0f);
        lv_label_set_text(lbl_hum_channel, buf);
    }

    /* Update system status */
    if (lbl_room_num) {
        snprintf(buf, sizeof(buf), "Комната: %d", state.room_num);
        lv_label_set_text(lbl_room_num, buf);
    }

    if (lbl_master_slave) {
        if (state.is_master) {
            lv_label_set_text(lbl_master_slave, "Мастер");
            lv_obj_set_style_text_color(lbl_master_slave, lv_color_hex(COLOR_ACCENT), 0);
        } else {
            snprintf(buf, sizeof(buf), "Слейв %s", state.has_signal ? "(OK)" : "(НЕТ)");
            lv_label_set_text(lbl_master_slave, buf);
            lv_obj_set_style_text_color(lbl_master_slave,
                state.has_signal ? lv_color_hex(COLOR_WARNING) : lv_color_hex(COLOR_DANGER), 0);
        }
    }

    if (lbl_season) {
        const char *seasons[] = {"Зима", "Лето", "Переход"};
        const uint32_t colors[] = {COLOR_TEXT_ACCENT, COLOR_DANGER, COLOR_WARNING};
        snprintf(buf, sizeof(buf), "Сезон: %s", seasons[state.season % 3]);
        lv_label_set_text(lbl_season, buf);
        lv_obj_set_style_text_color(lbl_season, lv_color_hex(colors[state.season % 3]), 0);
    }

    if (lbl_mode) {
        const char *modes[] = {"Остановка", "Дежурный", "Рабочий"};
        const uint32_t colors[] = {COLOR_DANGER, COLOR_WARNING, COLOR_ACCENT};
        snprintf(buf, sizeof(buf), "Режим: %s", modes[state.mode % 3]);
        lv_label_set_text(lbl_mode, buf);
        lv_obj_set_style_text_color(lbl_mode, lv_color_hex(colors[state.mode % 3]), 0);
    }

    if (lbl_datetime) {
        snprintf(buf, sizeof(buf), "%02d.%02d.%04d %02d:%02d",
                 state.day, state.month, state.year, state.hour, state.minute);
        lv_label_set_text(lbl_datetime, buf);
    }

    /* Update equipment modules */
    for (int i = 0; i < MODULE_COUNT; i++) {
        update_module_display(i);
    }
}

/* Update display of a single module */
static void update_module_display(int module_idx) {
    if (module_idx < 0 || module_idx >= MODULE_COUNT) return;
    if (!modules[module_idx].label_value) return;

    char buf[32];

    switch (module_idx) {
        case MODULE_VALVE_INLET:
            snprintf(buf, sizeof(buf), "%d%%", state.valve_inlet);
            lv_label_set_text(modules[module_idx].label_value, buf);
            break;
        case MODULE_VALVE_RECIRC:
            snprintf(buf, sizeof(buf), "%d%%", state.valve_recirc);
            lv_label_set_text(modules[module_idx].label_value, buf);
            break;
        case MODULE_FILTER_G4:
            lv_label_set_text(modules[module_idx].label_value,
                              state.filter_g4_clean ? "OK" : "!");
            lv_obj_set_style_text_color(modules[module_idx].label_value,
                state.filter_g4_clean ? lv_color_hex(COLOR_ACCENT) : lv_color_hex(COLOR_DANGER), 0);
            break;
        case MODULE_KWS:
            snprintf(buf, sizeof(buf), "%d%%", state.kws_valve);
            lv_label_set_text(modules[module_idx].label_value, buf);
            break;
        case MODULE_PWW:
            snprintf(buf, sizeof(buf), "%d%%", state.pww_valve);
            lv_label_set_text(modules[module_idx].label_value, buf);
            break;
        case MODULE_HEATER:
            lv_label_set_text(modules[module_idx].label_value,
                              state.heater_on ? "ВКЛ" : "ВЫКЛ");
            lv_obj_set_style_text_color(modules[module_idx].label_value,
                state.heater_on ? lv_color_hex(COLOR_DANGER) : lv_color_hex(COLOR_TEXT_DIM), 0);
            break;
        case MODULE_FAN:
            lv_label_set_text(modules[module_idx].label_value,
                              state.fan_on ? "ВКЛ" : "ВЫКЛ");
            lv_obj_set_style_text_color(modules[module_idx].label_value,
                state.fan_on ? lv_color_hex(COLOR_ACCENT) : lv_color_hex(COLOR_DANGER), 0);
            break;
        case MODULE_FILTER_H13:
            lv_label_set_text(modules[module_idx].label_value,
                              state.filter_h13_clean ? "OK" : "!");
            lv_obj_set_style_text_color(modules[module_idx].label_value,
                state.filter_h13_clean ? lv_color_hex(COLOR_ACCENT) : lv_color_hex(COLOR_DANGER), 0);
            break;
        case MODULE_CHANNEL:
            /* Display channel temperature and humidity */
            snprintf(buf, sizeof(buf), "%.1f°\n%.0f%%", state.temp_channel / 10.0f, state.hum_channel / 10.0f);
            lv_label_set_text(modules[module_idx].label_value, buf);
            break;
    }
}

/* Refresh setpoints display on screen 3 */
static void refresh_setpoints_display(void) {
    /* Remember which screen was active */
    lv_obj_t *current_scr = lv_screen_active();
    int was_on_screen3 = (current_scr == scr_screen3);
    int was_on_screen4 = (current_scr == scr_screen4);
    
    /* Recreate screen 3 to show updated values */
    if (scr_screen3) {
        lv_obj_del(scr_screen3);
        scr_screen3 = NULL;
    }
    create_screen_screen3();
    
    /* Recreate screen 4 to show updated values */
    if (scr_screen4) {
        lv_obj_del(scr_screen4);
        scr_screen4 = NULL;
    }
    create_screen_config();
    
    /* Load appropriate screen */
    if (was_on_screen3) {
        lv_scr_load(scr_screen3);
    } else if (was_on_screen4) {
        lv_scr_load(scr_screen4);
    }
}

void gui_init(void) {
    /* Add some example alarms to the log */
    add_alarm_to_log("Система запущена", 0);
    add_alarm_to_log("Фильтр G4 заменен", 0);

    create_screen_main();
    create_screen_screen1();
    create_screen_screen2();
    create_screen_screen3();
    create_screen_config();
    lv_scr_load(scr_main);
    
    /* Проверка аварийных ситуаций после загрузки главного экрана */
    if (!state.filter_g4_clean) {
        create_popup_alarm("ФИЛЬТР G4 ЗАСОРИЛСЯ\n\nЗамените фильтр немедленно.\nСистема работает в аварийном режиме.");
        state.mode = 0;
    }
    
    if (state.temp_channel < 50) {
        create_popup_alarm("УГРОЗА ЗАМОРОЗКИ\n\nУстановка остановлена.\nПроверьте журнал и примите меры.");
        state.mode = 0;
    }
}

/* ── ModBus ──────────────────────────────────────── */

void gui_modbus_init(void) {
    /* No-op for simulation */
}

void gui_modbus_task(void *arg) {
    (void)arg;
    /* Simulation: update with dummy values */
    while (1) {
        state.temp_room = 220 + (rand() % 40);
        state.hum_room = 450 + (rand() % 100);
        state.temp_channel = 200 + (rand() % 30);
        state.hum_channel = 500 + (rand() % 80);

        /* Simulate valve changes based on mode */
        if (state.mode == 2) {
            state.valve_inlet = 70 + (rand() % 30);
            state.valve_recirc = 10 + (rand() % 20);
            state.kws_valve = 40 + (rand() % 30);
            state.pww_valve = 30 + (rand() % 25);
            state.fan_on = 1;
        } else if (state.mode == 1) {
            state.valve_inlet = 30 + (rand() % 20);
            state.valve_recirc = 40 + (rand() % 20);
            state.kws_valve = 20 + (rand() % 15);
            state.pww_valve = 15 + (rand() % 15);
            state.fan_on = 1;
        } else {
            state.valve_inlet = 0;
            state.valve_recirc = 0;
            state.kws_valve = 0;
            state.pww_valve = 0;
            state.fan_on = 0;
            state.heater_on = 0;
        }

        gui_update_values();
        /* Sleep simulation - requires FreeRTOS or use SDL delay */
    }
}
