From ec69f6b20a99c3db0baf19e5229b0577c1b88b3e Mon Sep 17 00:00:00 2001 From: Siddesh Devarakonda Date: Tue, 19 Dec 2023 17:21:13 +0530 Subject: [PATCH] Add Tooltips for all sub-components --- tooltips.toml => config/tooltip.toml | 10 +++++----- harden/tooltip_file.py | 8 ++++++++ main.py | 7 ++++--- ui/components/hardware/file_systems.py | 9 ++++++++- ui/components/hardware/physical_ports.py | 7 ++++++- ui/components/network/firewall.py | 5 ++++- ui/components/network/network.py | 6 +++++- ui/components/software/apparmor.py | 6 +++++- ui/components/software/gdm.py | 15 ++++++++++----- ui/components/software/processes.py | 5 ++++- ui/components/software/service_clients.py | 5 ++++- ui/components/software/services.py | 5 ++++- ui/components/software/time_sync.py | 7 ++++++- ui/page.py | 10 +++++----- ui/pages/hardware_page.py | 7 ++++--- ui/pages/network_page.py | 7 ++++--- ui/pages/software_page.py | 15 ++++++++------- ui/qss/{style.qss => dark.qss} | 9 +++++++++ ui/qss/light.qss | 0 19 files changed, 103 insertions(+), 40 deletions(-) rename tooltips.toml => config/tooltip.toml (94%) create mode 100644 harden/tooltip_file.py rename ui/qss/{style.qss => dark.qss} (94%) create mode 100644 ui/qss/light.qss diff --git a/tooltips.toml b/config/tooltip.toml similarity index 94% rename from tooltips.toml rename to config/tooltip.toml index 4bf721d..1100ae3 100644 --- a/tooltips.toml +++ b/config/tooltip.toml @@ -1,6 +1,6 @@ [physical-ports] enable = "defines a point of entry for communication " -device-rules = "dynamically creates and removes nodes for hardware devices." +device-rules = "dynamically creates and removes nodes for hardware devices." port-rules ="lets administrators manage network services on Ubuntu systems by opening and closing ports." @@ -21,7 +21,7 @@ disable_error_reporting = "counts, analyzes, and aggregates the crashes in your restrict_core_dumps = "he system provides the ability to set a soft limit for core dumps, but this can be overridden by the user." [apparmor] # Mandatory Access Control -enable = "a Linux Security Module implementation of name-based mandatory access controls" +enable = "a Linux Security Module implementation of name-based mandatory access controls" mode = "enforces the SELinux policy and denies access based on SELinux policy rules" [gdm] # GNOME Display Manager @@ -30,7 +30,7 @@ disable_user_list = "controls if a list of users is displayed on the login scree lock_on_idle = "screen inactivity idle time interval" no_override_lockscreen = "override the static lock screen image with a snapshot of your current live wallpaper." disable_automount = "prevents Windows from automatically mounting or assigning drive letters to any new basic volumes that are visible to the system" -lock_automonut = "Installs autofs mount points and associates the information in the automaster" +lock_automount = "Installs autofs mount points and associates the information in the automaster" disable_autorun = "Windows will no longer open these devices automatically." no_override_autorun = "The NoDriveAutoRun value disables AutoRun for specified drive letters" @@ -76,12 +76,12 @@ ignore_bogus_icmp_errors = "prevents the kernel from logging bogus responses (RF enable_rp_filter = "protects against spoofed source addresses by causing the system to discard packets" enable_syn_cookies = " a technique used to resist SYN flood attacks" reject_ipv6_router_adv = "allows devices to use a much larger number of unique IP addresses" -disable_protocols ="a standardized set of rules for formatting and processing data." +disable_protocols = {dccp = "true", sctp = "true", rds = "true", tipc = "true"} [firewall] # Firewall enable = "a way to protect machines from any unwanted traffic from outside." -configure_loopback = "a virtual network interface that doesn't represent any physical or hardware device." +configure_loopback_traffic = "a virtual network interface that doesn't represent any physical or hardware device." enable_default_deny = " Deny all traffic by default " [ssh] diff --git a/harden/tooltip_file.py b/harden/tooltip_file.py new file mode 100644 index 0000000..f77680f --- /dev/null +++ b/harden/tooltip_file.py @@ -0,0 +1,8 @@ +import tomlkit +import os + +FILE_PATH = os.path.join(os.path.dirname(__file__), "../config/tooltip.toml") + +def read(): + with open(FILE_PATH, "r") as f: + return tomlkit.load(f) \ No newline at end of file diff --git a/main.py b/main.py index 963a7a5..0ae35a3 100644 --- a/main.py +++ b/main.py @@ -4,13 +4,14 @@ from ui.sidebar import Sidebar from ui.page import Pages from ui.toolbar import ToolBar -from harden import config_file +from harden import config_file, tooltip_file import sys class MainWindow(QMainWindow): def __init__(self): super().__init__() self.config = config_file.init() + self.tooltip = tooltip_file.read() self.init_ui() def init_ui(self): @@ -20,7 +21,7 @@ def init_ui(self): self.toolbar = ToolBar(self.config) self.addToolBar(self.toolbar) - self.pages = Pages(self.config) + self.pages = Pages(self.config, self.tooltip) self.pages.setObjectName("page") self.toolbar.import_signal.connect(self.pages.refresh_config) @@ -41,7 +42,7 @@ def init_ui(self): def main(): app = QApplication(sys.argv) - app.setStyleSheet(open("ui/qss/style.qss", "r").read()) + app.setStyleSheet(open("ui/qss/dark.qss", "r").read()) window = MainWindow() window.show() app.exec() diff --git a/ui/components/hardware/file_systems.py b/ui/components/hardware/file_systems.py index 99b7bbe..c4b953e 100644 --- a/ui/components/hardware/file_systems.py +++ b/ui/components/hardware/file_systems.py @@ -5,10 +5,12 @@ from harden import config_file class FileSystems(QWidget): - def __init__(self, config): + def __init__(self, config, tooltip): super().__init__() self.config = config + self.tooltip = tooltip self.toml_file_systems = self.config['file-systems'] + self.file_systems_tooltip = self.tooltip['file-systems'] self.init_ui() self.refresh_config(config) @@ -41,6 +43,7 @@ def init_ui(self): self.block_checkboxes = {} for name, state in self.toml_file_systems['block'].items(): checkbox = QCheckBox(f'Block {name}') + checkbox.setToolTip(self.file_systems_tooltip['block'][name]) checkbox.stateChanged.connect(lambda state, name=name: self.save_checkbox_state(state, 'block', name)) self.container_layout.addWidget(checkbox) self.block_checkboxes[name] = checkbox @@ -54,6 +57,7 @@ def init_ui(self): self.configure_fs_checkboxes = {} for name, state in self.toml_file_systems['configure_fs'].items(): checkbox = QCheckBox(f"Configure /{name.replace('_', '/')}") + checkbox.setToolTip(self.file_systems_tooltip['configure_fs'][name]) checkbox.stateChanged.connect(lambda state, name=name: self.save_checkbox_state(state, 'configure_fs', name)) self.container_layout.addWidget(checkbox) self.configure_fs_checkboxes[name] = checkbox @@ -64,6 +68,7 @@ def init_ui(self): hlayout.setContentsMargins(0, 0, 0, 0) hlayout.setAlignment(Qt.AlignmentFlag.AlignLeft) self.configure_label = QLabel('Configure /tmp size (in GB):') + self.configure_label.setToolTip(self.file_systems_tooltip['tmp_size']) self.size_input = QLineEdit() # self.size_input.setFixedWidth(100) validator = QIntValidator() @@ -77,6 +82,7 @@ def init_ui(self): # disable_automount self.disable_auto_mount = QCheckBox('Disable Auto-Mount') + self.disable_auto_mount.setToolTip(self.file_systems_tooltip['disable_automount']) self.disable_auto_mount.stateChanged.connect(lambda state: self.save_checkbox_state(state, 'disable_automount', None)) self.container_layout.addWidget(self.disable_auto_mount) @@ -87,6 +93,7 @@ def init_ui(self): self.enable_aide = QCheckBox('Enable AIDE (Advanced Intrusion Detection Environment)') + self.enable_aide.setToolTip(self.file_systems_tooltip['enable_aide']) self.enable_aide.stateChanged.connect(lambda state: self.save_checkbox_state(state, 'enable_aide', None)) self.container_layout.addWidget(self.enable_aide) diff --git a/ui/components/hardware/physical_ports.py b/ui/components/hardware/physical_ports.py index 951738f..4c34202 100644 --- a/ui/components/hardware/physical_ports.py +++ b/ui/components/hardware/physical_ports.py @@ -4,10 +4,12 @@ from PyQt6.QtCore import Qt class PhysicalPorts(QWidget): - def __init__(self, config): + def __init__(self, config, tooltip): super().__init__() self.config = config + self.tooltip = tooltip self.toml_physical_ports = self.config['physical-ports'] + self.physical_ports_tooltip = self.tooltip['physical-ports'] self.init_ui() self.refresh_config(config) @@ -44,6 +46,7 @@ def init_ui(self): # enable checkbox self.main_checkbox = QCheckBox("Enable USB Blocking") + self.main_checkbox.setToolTip(self.physical_ports_tooltip['enable']) self.container_layout.addWidget(self.main_checkbox) self.main_checkbox.stateChanged.connect(self.enable_checkbox_clicked) @@ -55,6 +58,7 @@ def init_ui(self): def block_devices_table(self): self.block_devices_label = QLabel("Block Devices") + self.block_devices_label.setToolTip(self.physical_ports_tooltip['device-rules']) self.container_layout.addWidget(self.block_devices_label) self.block_devices_label.setObjectName("sub-component-title") @@ -81,6 +85,7 @@ def add_device_rows(self): def block_ports_table(self): self.block_ports_label = QLabel("Block Ports") + self.block_ports_label.setToolTip(self.physical_ports_tooltip['port-rules']) self.container_layout.addWidget(self.block_ports_label) self.block_ports_label.setObjectName("sub-component-title") diff --git a/ui/components/network/firewall.py b/ui/components/network/firewall.py index cb9befa..100fb46 100644 --- a/ui/components/network/firewall.py +++ b/ui/components/network/firewall.py @@ -2,10 +2,12 @@ from harden import config_file class Firewall(QWidget): - def __init__(self, config): + def __init__(self, config, tooltip): super().__init__() self.config = config + self.tooltip = tooltip self.toml_firewall = self.config['firewall'] + self.firewall_tooltip = self.tooltip['firewall'] self.init_ui() self.refresh_config(config) @@ -31,6 +33,7 @@ def init_ui(self): self.checkboxes = {} for name, state in self.toml_firewall.items(): checkbox = QCheckBox(name.replace('_', ' ').title()) + checkbox.setToolTip(self.firewall_tooltip[name]) checkbox.stateChanged.connect(lambda state, name=name: self.save_checkbox_state(state, name)) self.container_layout.addWidget(checkbox) self.checkboxes[name] = checkbox diff --git a/ui/components/network/network.py b/ui/components/network/network.py index a6091e0..8cd15ef 100644 --- a/ui/components/network/network.py +++ b/ui/components/network/network.py @@ -2,10 +2,12 @@ from harden import config_file class Net(QWidget): - def __init__(self, config): + def __init__(self, config, tooltip): super().__init__() self.config = config + self.tooltip = tooltip self.toml_net = self.config['network'] + self.net_tooltip = self.tooltip['network'] self.init_ui() self.refresh_config(config) @@ -33,6 +35,7 @@ def init_ui(self): if name == "disable_protocols": continue checkbox = QCheckBox(f"{name.replace('_',' ').title()}") + checkbox.setToolTip(self.net_tooltip[name]) checkbox.stateChanged.connect(lambda state, name = name: self.save_checkbox_state(name, state)) self.toml_net_checkboxes[name] = checkbox self.container_layout.addWidget(checkbox) @@ -44,6 +47,7 @@ def init_ui(self): self.protocols_checkboxes = {} for name, state in self.toml_net['disable_protocols'].items(): checkbox = QCheckBox(f"{name.replace('_',' ').title()}") + checkbox.setToolTip(self.net_tooltip['disable_protocols'][name]) checkbox.stateChanged.connect(lambda state, name=name: self.save_checkbox_state_protocols(state, 'disable_protocols', name)) checkbox.setProperty('class', 'in-checkbox') self.container_layout.addWidget(checkbox) diff --git a/ui/components/software/apparmor.py b/ui/components/software/apparmor.py index 195541d..0c4e763 100644 --- a/ui/components/software/apparmor.py +++ b/ui/components/software/apparmor.py @@ -3,10 +3,12 @@ from harden import config_file class AppArmor(QWidget): - def __init__(self, config): + def __init__(self, config, tooltip): super().__init__() self.config = config + self.tooltip = tooltip self.toml_apparmor = self.config['apparmor'] + self.apparmor_tooltip = self.tooltip['apparmor'] self.init_ui() self.refresh_config(config) @@ -31,6 +33,7 @@ def init_ui(self): # Enable Checkbox self.enable_checkbox = QCheckBox('Enable') + self.enable_checkbox.setToolTip(self.apparmor_tooltip['enable']) self.enable_checkbox.stateChanged.connect(self.save_checkbox_state) self.container_layout.addWidget(self.enable_checkbox) @@ -39,6 +42,7 @@ def init_ui(self): # Select Mode Label self.mode_label = QLabel('Select mode:') + self.mode_label.setToolTip(self.apparmor_tooltip['mode']) self.mode_label.setProperty('class', 'normal-label-for') # Mode Dropdown diff --git a/ui/components/software/gdm.py b/ui/components/software/gdm.py index 20e8065..a34faa0 100644 --- a/ui/components/software/gdm.py +++ b/ui/components/software/gdm.py @@ -4,10 +4,12 @@ from harden import config_file class GDM(QWidget): - def __init__(self, config): + def __init__(self, config, tooltip): super().__init__() self.config = config + self.tooltip = tooltip self.toml_gdm = self.config['gdm'] + self.gdm_tooltip = self.tooltip['gdm'] self.init_ui() self.refresh_config(config) @@ -32,15 +34,17 @@ def init_ui(self): self.container_widget.setObjectName("container-widget") self.toml_gdm_checkboxes = {} - remove_checkbox = QCheckBox('Remove') - remove_checkbox.stateChanged.connect(lambda state, name = 'remove': self.save_checkbox_state(name, state)) - self.toml_gdm_checkboxes['remove'] = remove_checkbox - self.container_layout.addWidget(remove_checkbox) + self.remove_checkbox = QCheckBox('Remove') + self.remove_checkbox.setToolTip(self.gdm_tooltip['remove']) + self.remove_checkbox.stateChanged.connect(lambda state, name = 'remove': self.save_checkbox_state(name, state)) + self.toml_gdm_checkboxes['remove'] = self.remove_checkbox + self.container_layout.addWidget(self.remove_checkbox) hlayout = QHBoxLayout() # Lock on Idle Label self.lockon_lable = QLabel('Lock on Idle(seconds)') + self.lockon_lable.setToolTip(self.gdm_tooltip['lock_on_idle']) self.lockon_lable.setProperty('class', 'normal-label-for') self.time_input = QLineEdit() @@ -58,6 +62,7 @@ def init_ui(self): continue state = self.toml_gdm[name] checkbox = QCheckBox(f"{name.replace('_',' ').title()}") + checkbox.setToolTip(self.gdm_tooltip[name]) checkbox.stateChanged.connect(lambda state, name = name: self.save_checkbox_state(name, state)) self.toml_gdm_checkboxes[name] = checkbox self.container_layout.addWidget(checkbox) diff --git a/ui/components/software/processes.py b/ui/components/software/processes.py index 871138d..297570b 100644 --- a/ui/components/software/processes.py +++ b/ui/components/software/processes.py @@ -2,10 +2,12 @@ from harden import config_file class Processes(QWidget): - def __init__(self, config): + def __init__(self, config, tooltip): super().__init__() self.config = config + self.tooltip = tooltip self.toml_processes = self.config['processes'] + self.processes_tooltip = self.tooltip['processes'] self.init_ui() self.refresh_config(config) @@ -31,6 +33,7 @@ def init_ui(self): self.checkboxes = {} for name, state in self.toml_processes.items(): checkbox = QCheckBox(name.replace('_', ' ').title().replace('Aslr', 'ASLR')) + checkbox.setToolTip(self.processes_tooltip[name]) checkbox.stateChanged.connect(lambda state, name=name: self.save_checkbox_state(state, name)) self.container_layout.addWidget(checkbox) self.checkboxes[name] = checkbox diff --git a/ui/components/software/service_clients.py b/ui/components/software/service_clients.py index b15f71d..d521aeb 100644 --- a/ui/components/software/service_clients.py +++ b/ui/components/software/service_clients.py @@ -3,10 +3,12 @@ from harden import config_file class ServiceClients(QWidget): - def __init__(self, config): + def __init__(self, config, tooltip): super().__init__() self.config = config + self.tooltip = tooltip self.toml_service_clients = self.config['service_clients'] + self.service_clients_tooltip = self.tooltip['service_clients'] self.init_ui() self.refresh_config(config) @@ -32,6 +34,7 @@ def init_ui(self): self.toml_service_clients_checkboxes = {} for name, state in self.toml_service_clients.items(): checkbox = QCheckBox(f"{name.replace('_',' ').title()}") + checkbox.setToolTip(self.service_clients_tooltip[name]) checkbox.stateChanged.connect(lambda state, name = name: self.save_checkbox_state(name, state)) self.toml_service_clients_checkboxes[name] = checkbox self.container_layout.addWidget(checkbox) diff --git a/ui/components/software/services.py b/ui/components/software/services.py index 2917d5c..83a9403 100644 --- a/ui/components/software/services.py +++ b/ui/components/software/services.py @@ -3,10 +3,12 @@ from harden import config_file class Services(QWidget): - def __init__(self, config): + def __init__(self, config, tooltip): super().__init__() self.config = config + self.tooltip = tooltip self.toml_services = self.config['services'] + self.services_tooltip = self.tooltip['services'] self.init_ui() self.refresh_config(config) @@ -32,6 +34,7 @@ def init_ui(self): self.toml_services_checkboxes = {} for name, state in self.toml_services.items(): checkbox = QCheckBox(f"{name.replace('_',' ').title()}") + checkbox.setToolTip(self.services_tooltip[name]) checkbox.stateChanged.connect(lambda state, name = name: self.save_checkbox_state(name, state)) self.toml_services_checkboxes[name] = checkbox self.container_layout.addWidget(checkbox) diff --git a/ui/components/software/time_sync.py b/ui/components/software/time_sync.py index 303cb53..bbf1b77 100644 --- a/ui/components/software/time_sync.py +++ b/ui/components/software/time_sync.py @@ -3,10 +3,12 @@ from harden import config_file class TimeSync(QWidget): - def __init__(self, config): + def __init__(self, config, tooltip): super().__init__() self.config = config + self.tooltip = tooltip self.toml_time_sync = self.config['time-sync'] + self.time_sync_tooltip = self.tooltip['time-sync'] self.init_ui() self.refresh_config(config) @@ -31,14 +33,17 @@ def init_ui(self): #enable ntp checkbox self.enable_ntp = QCheckBox('Enable NTP') + self.enable_ntp.setToolTip(self.time_sync_tooltip['enable_ntp']) self.enable_ntp.stateChanged.connect(lambda state, name = 'enable_ntp': self.save_checkbox_state(name, state)) self.container_layout.addWidget(self.enable_ntp) self.enable_user = QCheckBox('Enable NTP user') + self.enable_user.setToolTip(self.time_sync_tooltip['enable_ntp_user']) self.enable_user.stateChanged.connect(lambda state, name = 'enable_ntp_user': self.save_checkbox_state(name, state)) self.container_layout.addWidget(self.enable_user) ntp_server_lable = QLabel('NTP Servers') + ntp_server_lable.setToolTip(self.time_sync_tooltip['ntp_servers']) ntp_server_lable.setProperty('class', 'normal-label-for') self.container_layout.addWidget(ntp_server_lable) diff --git a/ui/page.py b/ui/page.py index 95e5f77..3ed32b2 100644 --- a/ui/page.py +++ b/ui/page.py @@ -6,13 +6,13 @@ from ui.pages.welcome_page import Welcome class Pages(QScrollArea): - def __init__(self, config): + def __init__(self, config, tooltip): super().__init__() self.config = config + self.tooltip = tooltip self.setWidgetResizable(True) self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn) self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff) - # self.setProperty("class", "scroll-area") self.init_ui() def init_ui(self): @@ -20,9 +20,9 @@ def init_ui(self): self.setWidget(self.StackedWidget) self.welcome = Welcome() - self.hardware = Hardware(self.config) - self.software = Software(self.config) - self.network = Network(self.config) + self.hardware = Hardware(self.config, self.tooltip) + self.software = Software(self.config, self.tooltip) + self.network = Network(self.config, self.tooltip) self.StackedWidget.addWidget(self.welcome) self.StackedWidget.addWidget(self.hardware) diff --git a/ui/pages/hardware_page.py b/ui/pages/hardware_page.py index 375212d..8df0bde 100644 --- a/ui/pages/hardware_page.py +++ b/ui/pages/hardware_page.py @@ -4,9 +4,10 @@ from PyQt6.QtCore import Qt class Hardware(QWidget): - def __init__(self, config): + def __init__(self, config, tooltip): super().__init__() self.config = config + self.tooltip = tooltip self.init_ui() def init_ui(self): @@ -16,8 +17,8 @@ def init_ui(self): self.layout.setContentsMargins(0, 0, 0, 0) self.layout.setAlignment(Qt.AlignmentFlag.AlignTop | Qt.AlignmentFlag.AlignLeft) - self.physical_ports = PhysicalPorts(self.config) - self.file_systems = FileSystems(self.config) + self.physical_ports = PhysicalPorts(self.config, self.tooltip) + self.file_systems = FileSystems(self.config, self.tooltip) self.layout.addWidget(self.physical_ports) self.layout.addWidget(self.file_systems) diff --git a/ui/pages/network_page.py b/ui/pages/network_page.py index 069a987..1bd9a79 100644 --- a/ui/pages/network_page.py +++ b/ui/pages/network_page.py @@ -4,9 +4,10 @@ from ui.components.network.network import Net class Network(QWidget): - def __init__(self, config): + def __init__(self, config, tooltip): super().__init__() self.config = config + self.tooltip = tooltip self.init_ui() def init_ui(self): @@ -16,8 +17,8 @@ def init_ui(self): self.layout.setContentsMargins(0, 0, 0, 0) self.layout.setAlignment(Qt.AlignmentFlag.AlignTop | Qt.AlignmentFlag.AlignLeft) - self.firewall = Firewall(self.config) - self.net = Net(self.config) + self.firewall = Firewall(self.config, self.tooltip) + self.net = Net(self.config, self.tooltip) self.layout.addWidget(self.firewall) self.layout.addWidget(self.net) diff --git a/ui/pages/software_page.py b/ui/pages/software_page.py index 801c7ff..2d79981 100644 --- a/ui/pages/software_page.py +++ b/ui/pages/software_page.py @@ -9,9 +9,10 @@ class Software(QWidget): - def __init__(self, config): + def __init__(self, config, tooltip): super().__init__() self.config = config + self.tooltip = tooltip self.init_ui() def init_ui(self): @@ -21,12 +22,12 @@ def init_ui(self): self.layout.setContentsMargins(0, 0, 0, 0) self.layout.setAlignment(Qt.AlignmentFlag.AlignTop | Qt.AlignmentFlag.AlignLeft) - self.process_hardening = Processes(self.config) - self.apparmor = AppArmor(self.config) - self.gdm = GDM(self.config) - self.time_sync =TimeSync(self.config) - self.services = Services(self.config) - self.service_clients = ServiceClients(self.config) + self.process_hardening = Processes(self.config, self.tooltip) + self.apparmor = AppArmor(self.config, self.tooltip) + self.gdm = GDM(self.config, self.tooltip) + self.time_sync =TimeSync(self.config, self.tooltip) + self.services = Services(self.config, self.tooltip) + self.service_clients = ServiceClients(self.config, self.tooltip) self.layout.addWidget(self.process_hardening) self.layout.addWidget(self.apparmor) diff --git a/ui/qss/style.qss b/ui/qss/dark.qss similarity index 94% rename from ui/qss/style.qss rename to ui/qss/dark.qss index 74fea63..cd6f0dd 100644 --- a/ui/qss/style.qss +++ b/ui/qss/dark.qss @@ -157,4 +157,13 @@ QScrollArea QStackedWidget { .in-checkbox { margin-left: 30px; +} + +QToolTip { + background-color: transparent; + color: white; + border: 1px solid #45475a; + border-radius: 10px; + font: 15px; + padding: 2px 5px; } \ No newline at end of file diff --git a/ui/qss/light.qss b/ui/qss/light.qss new file mode 100644 index 0000000..e69de29