diff --git a/.editorconfig b/.editorconfig
index 54d8ffe..0388b6f 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,30 +1,30 @@
-root = true
-
-[*]
-charset = utf-8
-end_of_line = lf
-insert_final_newline = true
-indent_style = space
-indent_size = 2
-trim_trailing_whitespace = true
-
-[*.md]
-trim_trailing_whitespace = false
-
-[*.py]
-indent_size = 4
-
-[*.rs]
-indent_size = 4
-
-[*.yml]
-indent_size = 2
-
-[*.yaml]
-indent_size = 2
-
-[*.json]
-indent_size = 2
-
-[*.toml]
-indent_size = 2
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+indent_style = space
+indent_size = 2
+trim_trailing_whitespace = true
+
+[*.md]
+trim_trailing_whitespace = false
+
+[*.py]
+indent_size = 4
+
+[*.rs]
+indent_size = 4
+
+[*.yml]
+indent_size = 2
+
+[*.yaml]
+indent_size = 2
+
+[*.json]
+indent_size = 2
+
+[*.toml]
+indent_size = 2
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 30d8ab3..388d8cd 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1 +1 @@
-* @ZFordDev
+* @ZFordDev
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index ce4ec41..8a2b69b 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,2 +1,2 @@
-github: ZFordDev
-ko_fi: zforddev
+github: ZFordDev
+ko_fi: zforddev
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 62998a8..08584e8 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -1,51 +1,51 @@
-name: Bug Report
-description: Report a reproducible issue in SchedPlus
-labels: [bug]
-body:
- - type: markdown
- attributes:
- value: |
- Thank you for helping improve SchedPlus!
- Please provide as much detail as possible so we can reproduce the issue.
-
- - type: input
- id: version
- attributes:
- label: SchedPlus Version
- placeholder: e.g., 0.1.0, 0.2.0-dev
-
- - type: input
- id: os
- attributes:
- label: Operating System
- placeholder: e.g., Windows 11, Ubuntu 22.04
-
- - type: textarea
- id: steps
- attributes:
- label: Steps to Reproduce
- description: List each step clearly.
- placeholder: |
- 1. Open SchedPlus
- 2. Add a new task
- 3. Save the schedule
- 4. Reopen the app and load tasks
- 5. Error occurs
-
- - type: textarea
- id: expected
- attributes:
- label: Expected Behavior
- placeholder: Describe what you expected to happen.
-
- - type: textarea
- id: actual
- attributes:
- label: Actual Behavior
- placeholder: Describe what actually happened.
-
- - type: textarea
- id: logs
- attributes:
- label: Logs / Screenshots (optional)
- description: Attach anything helpful.
+name: Bug Report
+description: Report a reproducible issue in SchedPlus
+labels: [bug]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thank you for helping improve SchedPlus!
+ Please provide as much detail as possible so we can reproduce the issue.
+
+ - type: input
+ id: version
+ attributes:
+ label: SchedPlus Version
+ placeholder: e.g., 0.1.0, 0.2.0-dev
+
+ - type: input
+ id: os
+ attributes:
+ label: Operating System
+ placeholder: e.g., Windows 11, Ubuntu 22.04
+
+ - type: textarea
+ id: steps
+ attributes:
+ label: Steps to Reproduce
+ description: List each step clearly.
+ placeholder: |
+ 1. Open SchedPlus
+ 2. Add a new task
+ 3. Save the schedule
+ 4. Reopen the app and load tasks
+ 5. Error occurs
+
+ - type: textarea
+ id: expected
+ attributes:
+ label: Expected Behavior
+ placeholder: Describe what you expected to happen.
+
+ - type: textarea
+ id: actual
+ attributes:
+ label: Actual Behavior
+ placeholder: Describe what actually happened.
+
+ - type: textarea
+ id: logs
+ attributes:
+ label: Logs / Screenshots (optional)
+ description: Attach anything helpful.
diff --git a/.github/ISSUE_TEMPLATE/documentation.yml b/.github/ISSUE_TEMPLATE/documentation.yml
index 605d74a..a65563d 100644
--- a/.github/ISSUE_TEMPLATE/documentation.yml
+++ b/.github/ISSUE_TEMPLATE/documentation.yml
@@ -1,15 +1,15 @@
-name: Documentation Update
-description: Suggest improvements to documentation or examples
-labels: [documentation]
-body:
- - type: textarea
- id: update
- attributes:
- label: What needs to be updated?
- placeholder: |
- Describe the missing, unclear, or incorrect documentation.
- Examples:
- - A function is undocumented
- - A UI mode is unclear
- - A screenshot is outdated
- - A section needs clarification
+name: Documentation Update
+description: Suggest improvements to documentation or examples
+labels: [documentation]
+body:
+ - type: textarea
+ id: update
+ attributes:
+ label: What needs to be updated?
+ placeholder: |
+ Describe the missing, unclear, or incorrect documentation.
+ Examples:
+ - A function is undocumented
+ - A UI mode is unclear
+ - A screenshot is outdated
+ - A section needs clarification
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
index b4c66b5..272e948 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.yml
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -1,34 +1,34 @@
-name: Feature Request
-description: Suggest an improvement or new feature for SchedPlus
-labels: [enhancement]
-body:
- - type: markdown
- attributes:
- value: |
- Thanks for your idea!
- SchedPlus aims to stay simple, predictable, and local‑first.
- Please describe the problem your feature solves.
-
- - type: textarea
- id: problem
- attributes:
- label: Problem / Use Case
- placeholder: What problem does this solve? What workflow is blocked or inefficient?
-
- - type: textarea
- id: proposal
- attributes:
- label: Proposed Solution
- placeholder: Describe the feature, interaction, or workflow improvement.
-
- - type: textarea
- id: alternatives
- attributes:
- label: Alternatives Considered (optional)
- placeholder: Any other approaches you thought about?
-
- - type: textarea
- id: notes
- attributes:
- label: Additional Notes (optional)
- placeholder: Screenshots, examples, or extra context.
+name: Feature Request
+description: Suggest an improvement or new feature for SchedPlus
+labels: [enhancement]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for your idea!
+ SchedPlus aims to stay simple, predictable, and local‑first.
+ Please describe the problem your feature solves.
+
+ - type: textarea
+ id: problem
+ attributes:
+ label: Problem / Use Case
+ placeholder: What problem does this solve? What workflow is blocked or inefficient?
+
+ - type: textarea
+ id: proposal
+ attributes:
+ label: Proposed Solution
+ placeholder: Describe the feature, interaction, or workflow improvement.
+
+ - type: textarea
+ id: alternatives
+ attributes:
+ label: Alternatives Considered (optional)
+ placeholder: Any other approaches you thought about?
+
+ - type: textarea
+ id: notes
+ attributes:
+ label: Additional Notes (optional)
+ placeholder: Screenshots, examples, or extra context.
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 61373d7..abe3e9d 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -1,17 +1,17 @@
-# Dependabot configuration for MathPlus
-# Updates Cargo dependencies and GitHub Actions workflows.
-# See documentation for all configuration options:
-# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
-
-version: 2
-updates:
- - package-ecosystem: "pip"
- directory: "/"
- schedule:
- interval: "weekly"
- open-pull-requests-limit: 5
-
- - package-ecosystem: "github-actions"
- directory: "/"
- schedule:
- interval: "weekly"
+# Dependabot configuration for MathPlus
+# Updates Cargo dependencies and GitHub Actions workflows.
+# See documentation for all configuration options:
+# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
+
+version: 2
+updates:
+ - package-ecosystem: "pip"
+ directory: "/"
+ schedule:
+ interval: "weekly"
+ open-pull-requests-limit: 5
+
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "weekly"
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index b3a0242..17ac6f8 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1,56 +1,56 @@
-# Pull Request
-
-Thank you for contributing to SchedPlus!
-Please complete the sections below to help us review your PR.
-
----
-
-## Summary
-
-Describe what this PR changes and why.
-
----
-
-## Type of Change
-
-- [ ] Bug fix
-- [ ] New feature
-- [ ] Workflow improvement
-- [ ] UI/UX improvement
-- [ ] Documentation update
-- [ ] Refactor / cleanup
-
----
-
-## Details
-
-Explain the implementation, any decisions made, and any side effects.
-If the change affects task storage, JSON handling, Tkinter/PyQt UI behaviour, or cross‑platform compatibility, please describe it clearly.
-
----
-
-## Testing
-
-Describe how you tested your changes:
-
-- [ ] Runs successfully
-- [ ] Tested on Windows
-- [ ] Tested on Linux
-- [ ] Tkinter UI behaves as expected
-- [ ] PyQt UI behaves as expected (if applicable)
-- [ ] JSON save/load works correctly
-- [ ] No regressions found
-
----
-
-## Related Issues
-
-Link any related issues or discussions:
-
-`Fixes #123` or `Related to #456`
-
----
-
-## Additional Notes (optional)
-
-Anything else reviewers should know.
+# Pull Request
+
+Thank you for contributing to SchedPlus!
+Please complete the sections below to help us review your PR.
+
+---
+
+## Summary
+
+Describe what this PR changes and why.
+
+---
+
+## Type of Change
+
+- [ ] Bug fix
+- [ ] New feature
+- [ ] Workflow improvement
+- [ ] UI/UX improvement
+- [ ] Documentation update
+- [ ] Refactor / cleanup
+
+---
+
+## Details
+
+Explain the implementation, any decisions made, and any side effects.
+If the change affects task storage, JSON handling, Tkinter/PyQt UI behaviour, or cross‑platform compatibility, please describe it clearly.
+
+---
+
+## Testing
+
+Describe how you tested your changes:
+
+- [ ] Runs successfully
+- [ ] Tested on Windows
+- [ ] Tested on Linux
+- [ ] Tkinter UI behaves as expected
+- [ ] PyQt UI behaves as expected (if applicable)
+- [ ] JSON save/load works correctly
+- [ ] No regressions found
+
+---
+
+## Related Issues
+
+Link any related issues or discussions:
+
+`Fixes #123` or `Related to #456`
+
+---
+
+## Additional Notes (optional)
+
+Anything else reviewers should know.
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 5664960..47fc44b 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,33 +1,33 @@
-name: SchedPlus CI
-
-on:
- push:
- branches:
- - main
- pull_request:
-
-jobs:
- lint_and_test:
- name: Lint & Validate
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout repository
- uses: actions/checkout@v6
-
- - name: Set up Python
- uses: actions/setup-python@v6
- with:
- python-version: "3.14"
-
- - name: Install dependencies
- run: |
- pip install -r requirements.txt
- pip install pyflakes
-
- - name: Lint (pyflakes)
- run: pyflakes src/
-
- - name: Validate project structure
- run: |
- echo "Project structure OK"
+name: SchedPlus CI
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+
+jobs:
+ lint_and_test:
+ name: Lint & Validate
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v6
+
+ - name: Set up Python
+ uses: actions/setup-python@v6
+ with:
+ python-version: "3.14"
+
+ - name: Install dependencies
+ run: |
+ pip install -r requirements.txt
+ pip install pyflakes
+
+ - name: Lint (pyflakes)
+ run: pyflakes src/
+
+ - name: Validate project structure
+ run: |
+ echo "Project structure OK"
diff --git a/.gitignore b/.gitignore
index effd886..d4a3cf2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,66 +1,66 @@
-# ────────────────────────────────────────────────
-# Python
-# ────────────────────────────────────────────────
-__pycache__/
-*.pyc
-*.pyo
-*.pyd
-*.pdb
-*.pkl
-
-# Virtual environments
-venv/
-env/
-.venv/
-
-# Python tooling caches
-.pytest_cache/
-.mypy_cache/
-.ruff_cache/
-.coverage
-
-# ────────────────────────────────────────────────
-# Editor / IDE
-# ────────────────────────────────────────────────
-.vscode/
-.idea/
-*.swp
-*.swo
-
-# ────────────────────────────────────────────────
-# OS Files
-# ────────────────────────────────────────────────
-.DS_Store
-Thumbs.db
-desktop.ini
-
-# ────────────────────────────────────────────────
-# Packaging (Snap, Debian, PyInstaller)
-# ────────────────────────────────────────────────
-
-# Snapcraft
-snap/.snapcraft/
-parts/
-prime/
-stage/
-
-# Debian packaging
-packaging/deb/usr/
-packaging/deb/DEBIAN/
-
-# PyInstaller / Windows builds
-dist/
-build/
-*.spec
-*.exe
-
-# ────────────────────────────────────────────────
-# App Data
-# ────────────────────────────────────────────────
-tasks.json
-*.log
-
-# ────────────────────────────────────────────────
-# Ecosystem Standards
-# ────────────────────────────────────────────────
-temp_notes.md
+# ────────────────────────────────────────────────
+# Python
+# ────────────────────────────────────────────────
+__pycache__/
+*.pyc
+*.pyo
+*.pyd
+*.pdb
+*.pkl
+
+# Virtual environments
+venv/
+env/
+.venv/
+
+# Python tooling caches
+.pytest_cache/
+.mypy_cache/
+.ruff_cache/
+.coverage
+
+# ────────────────────────────────────────────────
+# Editor / IDE
+# ────────────────────────────────────────────────
+.vscode/
+.idea/
+*.swp
+*.swo
+
+# ────────────────────────────────────────────────
+# OS Files
+# ────────────────────────────────────────────────
+.DS_Store
+Thumbs.db
+desktop.ini
+
+# ────────────────────────────────────────────────
+# Packaging (Snap, Debian, PyInstaller)
+# ────────────────────────────────────────────────
+
+# Snapcraft
+snap/.snapcraft/
+parts/
+prime/
+stage/
+
+# Debian packaging
+packaging/deb/usr/
+packaging/deb/DEBIAN/
+
+# PyInstaller / Windows builds
+dist/
+build/
+*.spec
+*.exe
+
+# ────────────────────────────────────────────────
+# App Data
+# ────────────────────────────────────────────────
+tasks.json
+*.log
+
+# ────────────────────────────────────────────────
+# Ecosystem Standards
+# ────────────────────────────────────────────────
+temp_notes.md
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index 6045fd5..0b04c69 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -1,103 +1,103 @@
-
-
-
-
-
-
-
-
-
-
-
-# Code of Conduct
-
-The ZFordDev ecosystem is built on clarity, simplicity, and long‑term maintainability.
-To keep our community healthy and welcoming, all contributors are expected to follow the guidelines below.
-
-This Code of Conduct applies to all project spaces, including GitHub Issues, Discussions, pull requests, and any community interactions related to ZFordDev projects.
-
----
-
-## Our Principles
-
-We strive to create an environment where contributors can collaborate respectfully and productively.
-We expect all participants to:
-
-- Be kind, patient, and constructive
-- Respect differing viewpoints and experiences
-- Give and receive feedback gracefully
-- Focus on improving the project, not winning arguments
-- Assume good intentions
-- Keep discussions technical, not personal
-
----
-
-## Unacceptable Behavior
-
-The following behaviors are not allowed in any ZFordDev project:
-
-- Harassment, insults, or personal attacks
-- Discriminatory language or exclusionary behavior
-- Trolling, baiting, or intentionally derailing discussions
-- Publishing private information without permission
-- Aggressive or hostile communication
-- Repeatedly ignoring project standards or maintainers’ guidance
-
----
-
-## Responsibilities of Maintainers
-
-Project maintainers are responsible for:
-
-- Clarifying standards and expectations
-- Reviewing contributions fairly
-- Providing constructive feedback
-- Taking action when behavior violates this Code
-- Keeping the community safe and welcoming
-
-Maintainers may remove comments, close issues, or reject contributions that violate these guidelines.
-
----
-
-## Reporting Issues
-
-If you experience or witness behavior that violates this Code of Conduct:
-
-- Open a private issue if appropriate
-- Or contact the project maintainer directly through GitHub
-
-All reports will be reviewed promptly and handled respectfully.
-
----
-
-## Enforcement
-
-Consequences for violating this Code may include:
-
-- A private warning
-- Temporary or permanent removal from project spaces
-- Rejection of contributions
-- Escalation to GitHub moderation if necessary
-
-Enforcement decisions are made by project maintainers and are final.
-
----
-
-## SchedPlus‑Specific Notes
-
-SchedPlus is a tiny, focused scheduler built in Python.
-Contributions and discussions should reflect that philosophy:
-
-- Keep discussions respectful, constructive, and solution‑oriented
-- Maintain the lightweight, minimal nature of the app
-- Avoid proposing features that introduce unnecessary complexity or bloat
-- Preserve the clean, predictable UI and simple interaction patterns
-- Keep the codebase approachable — SchedPlus is also a learning reference
-- Ensure new ideas align with the “simple, local‑first, predictable” philosophy
-
----
-
-## Acknowledgment
-
-This Code of Conduct is inspired by the Contributor Covenant but rewritten to better fit the ZFordDev ecosystem’s tone and values.
-
+
+
+
+
+
+
+
+
+
+
+
+# Code of Conduct
+
+The ZFordDev ecosystem is built on clarity, simplicity, and long‑term maintainability.
+To keep our community healthy and welcoming, all contributors are expected to follow the guidelines below.
+
+This Code of Conduct applies to all project spaces, including GitHub Issues, Discussions, pull requests, and any community interactions related to ZFordDev projects.
+
+---
+
+## Our Principles
+
+We strive to create an environment where contributors can collaborate respectfully and productively.
+We expect all participants to:
+
+- Be kind, patient, and constructive
+- Respect differing viewpoints and experiences
+- Give and receive feedback gracefully
+- Focus on improving the project, not winning arguments
+- Assume good intentions
+- Keep discussions technical, not personal
+
+---
+
+## Unacceptable Behavior
+
+The following behaviors are not allowed in any ZFordDev project:
+
+- Harassment, insults, or personal attacks
+- Discriminatory language or exclusionary behavior
+- Trolling, baiting, or intentionally derailing discussions
+- Publishing private information without permission
+- Aggressive or hostile communication
+- Repeatedly ignoring project standards or maintainers’ guidance
+
+---
+
+## Responsibilities of Maintainers
+
+Project maintainers are responsible for:
+
+- Clarifying standards and expectations
+- Reviewing contributions fairly
+- Providing constructive feedback
+- Taking action when behavior violates this Code
+- Keeping the community safe and welcoming
+
+Maintainers may remove comments, close issues, or reject contributions that violate these guidelines.
+
+---
+
+## Reporting Issues
+
+If you experience or witness behavior that violates this Code of Conduct:
+
+- Open a private issue if appropriate
+- Or contact the project maintainer directly through GitHub
+
+All reports will be reviewed promptly and handled respectfully.
+
+---
+
+## Enforcement
+
+Consequences for violating this Code may include:
+
+- A private warning
+- Temporary or permanent removal from project spaces
+- Rejection of contributions
+- Escalation to GitHub moderation if necessary
+
+Enforcement decisions are made by project maintainers and are final.
+
+---
+
+## SchedPlus‑Specific Notes
+
+SchedPlus is a tiny, focused scheduler built in Python.
+Contributions and discussions should reflect that philosophy:
+
+- Keep discussions respectful, constructive, and solution‑oriented
+- Maintain the lightweight, minimal nature of the app
+- Avoid proposing features that introduce unnecessary complexity or bloat
+- Preserve the clean, predictable UI and simple interaction patterns
+- Keep the codebase approachable — SchedPlus is also a learning reference
+- Ensure new ideas align with the “simple, local‑first, predictable” philosophy
+
+---
+
+## Acknowledgment
+
+This Code of Conduct is inspired by the Contributor Covenant but rewritten to better fit the ZFordDev ecosystem’s tone and values.
+
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 28a90c2..b7d3ed1 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,151 +1,151 @@
-
-
-
-
-
-
-
-
-
-
-
-# Contributing to ZFordDev Projects
-
-Thank you for your interest in contributing!
-All ZFordDev projects follow a shared set of standards designed to keep the ecosystem consistent, maintainable, and welcoming.
-
-This document explains how to contribute code, documentation, bug reports, and feature requests across the ecosystem.
-
-For ecosystem‑wide expectations, please read:
-
-👉 [**STANDARDS.md**](https://github.com/ZFordDev/ZFordDev/blob/main/STANDARDS.md)
-(Clarity • Simplicity • Maintainability • Long‑term stability)
-
----
-
-## Ways to Contribute
-
-You can contribute in many ways:
-
-- Reporting bugs
-- Suggesting new features
-- Improving documentation
-- Submitting pull requests
-- Reviewing existing issues
-- Helping refine UX or workflows
-- Testing on different platforms
-
-All contributions are appreciated — even small ones.
-
----
-
-## Code of Conduct
-
-By participating in this project, you agree to follow:
-
-👉 [**CODE_OF_CONDUCT.md**](CODE_OF_CONDUCT.md)
-
-Respect, clarity, and constructive collaboration are core values of the ecosystem.
-
----
-
-## Before You Start
-
-Please check:
-
-- The **Issues** tab for existing reports
-- The **Roadmap** (if present)
-- The **Discussions** tab for ongoing ideas
-- The **STANDARDS.md** file for ecosystem rules
-- The **project‑specific section** below for details unique to this repository
-
-If you’re unsure whether an idea fits, open a Discussion first — it saves everyone time.
-
----
-
-## Pull Request Guidelines
-
-To keep contributions consistent:
-
-1. **Fork the repository**
-2. **Create a feature branch**
- - `feature/your-feature-name`
- - `fix/your-bug-name`
-3. **Keep PRs focused**
- - One feature or fix per PR
- - Avoid unrelated formatting changes
-4. **Follow the coding style of the project**
- - Naming conventions
- - File structure
- - Module layout
-5. **Test your changes**
- - Ensure the app builds
- - Ensure no regressions
-6. **Write clear commit messages**
- - Present tense
- - Short and descriptive
-7. **Describe your PR clearly**
- - What changed
- - Why it changed
- - Any side effects or considerations
-
-Small, focused PRs are easier to review and merge.
-
----
-
-## Reporting Bugs
-
-When reporting a bug, please include:
-
-- OS and version
-- App version
-- Steps to reproduce
-- Expected behavior
-- Actual behavior
-- Screenshots or logs (if helpful)
-
-Clear reports help us fix issues faster.
-
----
-
-## Suggesting Features
-
-Feature requests should:
-
-- Explain the problem, not just the solution
-- Describe the use case
-- Fit the project’s philosophy (see STANDARDS.md)
-- Avoid scope creep or IDE‑level complexity
-
-If unsure, open a Discussion first.
-
----
-
-## Project‑Specific Guidelines
-
-Each project may have additional rules, workflows, or architectural notes.
-
-### SchedPlus‑Specific Notes
-
-SchedPlus is a small, Python‑based desktop scheduler.
-Contributions should reflect its lightweight, minimal, and predictable design:
-
-- UI changes should follow the existing layout and interaction patterns
-- Avoid introducing heavy dependencies — keep the project simple and easy to install
-- JSON storage must remain safe, local, and predictable
-- Do not add features that turn SchedPlus into a full productivity suite unless scoped and discussed
-- PyQt‑related changes should be tested on Windows and Linux when possible
-- Keep the codebase beginner‑friendly — SchedPlus is also a learning reference
-- Maintain the clean, distraction‑free feel of the interface
-- Ensure new features align with the “simple, local‑first, predictable” philosophy
-- Avoid complex background services, cloud sync, or account systems
-- Follow the existing module layout in `src/`
-
----
-
-## Thank You
-
-Your contributions help strengthen the entire ZFordDev ecosystem.
-Whether you’re fixing a typo or building a major feature — you’re part of the project’s future.
-
-
+
+
+
+
+
+
+
+
+
+
+
+# Contributing to ZFordDev Projects
+
+Thank you for your interest in contributing!
+All ZFordDev projects follow a shared set of standards designed to keep the ecosystem consistent, maintainable, and welcoming.
+
+This document explains how to contribute code, documentation, bug reports, and feature requests across the ecosystem.
+
+For ecosystem‑wide expectations, please read:
+
+👉 [**STANDARDS.md**](https://github.com/ZFordDev/ZFordDev/blob/main/STANDARDS.md)
+(Clarity • Simplicity • Maintainability • Long‑term stability)
+
+---
+
+## Ways to Contribute
+
+You can contribute in many ways:
+
+- Reporting bugs
+- Suggesting new features
+- Improving documentation
+- Submitting pull requests
+- Reviewing existing issues
+- Helping refine UX or workflows
+- Testing on different platforms
+
+All contributions are appreciated — even small ones.
+
+---
+
+## Code of Conduct
+
+By participating in this project, you agree to follow:
+
+👉 [**CODE_OF_CONDUCT.md**](CODE_OF_CONDUCT.md)
+
+Respect, clarity, and constructive collaboration are core values of the ecosystem.
+
+---
+
+## Before You Start
+
+Please check:
+
+- The **Issues** tab for existing reports
+- The **Roadmap** (if present)
+- The **Discussions** tab for ongoing ideas
+- The **STANDARDS.md** file for ecosystem rules
+- The **project‑specific section** below for details unique to this repository
+
+If you’re unsure whether an idea fits, open a Discussion first — it saves everyone time.
+
+---
+
+## Pull Request Guidelines
+
+To keep contributions consistent:
+
+1. **Fork the repository**
+2. **Create a feature branch**
+ - `feature/your-feature-name`
+ - `fix/your-bug-name`
+3. **Keep PRs focused**
+ - One feature or fix per PR
+ - Avoid unrelated formatting changes
+4. **Follow the coding style of the project**
+ - Naming conventions
+ - File structure
+ - Module layout
+5. **Test your changes**
+ - Ensure the app builds
+ - Ensure no regressions
+6. **Write clear commit messages**
+ - Present tense
+ - Short and descriptive
+7. **Describe your PR clearly**
+ - What changed
+ - Why it changed
+ - Any side effects or considerations
+
+Small, focused PRs are easier to review and merge.
+
+---
+
+## Reporting Bugs
+
+When reporting a bug, please include:
+
+- OS and version
+- App version
+- Steps to reproduce
+- Expected behavior
+- Actual behavior
+- Screenshots or logs (if helpful)
+
+Clear reports help us fix issues faster.
+
+---
+
+## Suggesting Features
+
+Feature requests should:
+
+- Explain the problem, not just the solution
+- Describe the use case
+- Fit the project’s philosophy (see STANDARDS.md)
+- Avoid scope creep or IDE‑level complexity
+
+If unsure, open a Discussion first.
+
+---
+
+## Project‑Specific Guidelines
+
+Each project may have additional rules, workflows, or architectural notes.
+
+### SchedPlus‑Specific Notes
+
+SchedPlus is a small, Python‑based desktop scheduler.
+Contributions should reflect its lightweight, minimal, and predictable design:
+
+- UI changes should follow the existing layout and interaction patterns
+- Avoid introducing heavy dependencies — keep the project simple and easy to install
+- JSON storage must remain safe, local, and predictable
+- Do not add features that turn SchedPlus into a full productivity suite unless scoped and discussed
+- PyQt‑related changes should be tested on Windows and Linux when possible
+- Keep the codebase beginner‑friendly — SchedPlus is also a learning reference
+- Maintain the clean, distraction‑free feel of the interface
+- Ensure new features align with the “simple, local‑first, predictable” philosophy
+- Avoid complex background services, cloud sync, or account systems
+- Follow the existing module layout in `src/`
+
+---
+
+## Thank You
+
+Your contributions help strengthen the entire ZFordDev ecosystem.
+Whether you’re fixing a typo or building a major feature — you’re part of the project’s future.
+
+
diff --git a/LICENSE b/LICENSE
index ea0df50..75b8a6b 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,21 +1,21 @@
-MIT License
-
-Copyright (c) 2026 ZFordDev
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+MIT License
+
+Copyright (c) 2026 ZFordDev
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
\ No newline at end of file
diff --git a/README.md b/README.md
index e0364b3..faff5e9 100644
--- a/README.md
+++ b/README.md
@@ -1,234 +1,234 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-[](https://docs.zford.dev)
-
-
-
-
-
-
-
-
-
-
-
-# SchedPlus
-
-> A lightweight, local‑first desktop scheduler built in Python.
-> **Status:** Alpha • Actively Maintained • Accepting Contributions
-
----
-
-## Why This Exists
-
-Most scheduling tools try to do everything — calendars, reminders, syncing, accounts, cloud dashboards — and end up feeling heavy, slow, or overly complex.
-
-SchedPlus was built to be the opposite:
-
-- **simple**
-- **local‑first**
-- **lightweight**
-- **predictable**
-- **no accounts**
-- **no cloud**
-- **no unnecessary features**
-
-It focuses on one job: helping you plan your day without getting in your way.
-
-SchedPlus is also a great **learning reference**, showing how a real desktop app evolves over time — from a quick Tkinter prototype to a structured Python application and eventually a full PyQt desktop experience.
-
----
-
-## Overview
-
-SchedPlus is a simple, predictable desktop scheduler built for people who want structure without the noise.
-
-It focuses on:
-
-- fast startup
-- a clean, minimal interface
-- local‑only task storage
-- a small, readable Python codebase
-- an offline‑first workflow
-
-It’s intentionally lightweight — ideal for daily planning, learning Python UI development, or experimenting with how real desktop apps evolve over time.
-
-SchedPlus currently ships with a stable Tkinter UI, while a full PyQt migration is actively underway to bring a more modern, cross‑platform experience.
-
----
-
-## Features
-
-* Local task creation and management
-* JSON‑based save/load
-* Offline‑first workflow
-* Tkinter UI (stable)
-* PyQt UI (in development)
-* Clean logic/storage separation
-* Beginner‑friendly codebase
-
----
-
-## Requirements
-
-SchedPlus is currently a source‑only project.
-To run or develop it, you’ll need:
-
-> Python 3.14+
-> pip (latest)
-> Tkinter (included with most Python installs)
-> PyQt6 (optional, for the new UI)
-
-**Supported environments:**
-
-> Windows 10+
-> Linux (Ubuntu 22.04+)
-
----
-
-## Quick Start
-
-```bash
-git clone https://github.com/ZFordDev/schedplus.git
-cd schedplus
-
-pip install -r requirements.txt
-
-python3 src/main.py
-```
-
-> *Recommended: use a `.venv`.*
-
----
-
-## Installation
-
-SchedPlus currently has no build pipeline yet — please wait for the beta release.
-
----
-
-## Usage
-
-Basic usage:
-
-```bash
-python3 src/main.py
-```
-
-The UI will open and allow you to create, edit, and save tasks locally.
-
----
-
-## Project Structure
-
-SchedPlus uses a simple, predictable layout designed to keep UI, logic, and data clearly separated.
-
-```text
-schedplus/
-├── src/
-│ ├── assets/ # Icons and UI assets
-│ ├── data/ # Local task storage
-│ ├── logic/ # Core scheduling logic
-│ ├── startup/ # NEW — startup
-│ ├── ui/ # Tkinter + PyQt interfaces
-│ └── main.py # Application entry point
-│
-└── packaging/ # Future packaging targets
- ├── snap/
- ├── deb/
- └── windows/
-```
-
----
-
-## Roadmap
-
-* [ ] Full PyQt migration
-* [ ] Cross‑platform packaging
-* [ ] Windows installer
-* [ ] Improved task management
-* [ ] UI backend experimentation
-* [ ] Multi‑platform releases
-
----
-
-## Screenshots
-
-
-
-
-
-
----
-
-## Known Issues
-
-* PyQt UI is incomplete
-* Packaging is experimental
-* macOS support not yet available
-
----
-
-## Related Projects
-
-- **MathPlus** — a lightweight desktop calculator
- [https://github.com/ZFordDev/MathPlus](https://github.com/ZFordDev/MathPlus)
-
----
-
-## Support
-
-You can support SchedPlus by:
-
-* Leaving a ⭐ on GitHub
-* Reporting bugs
-* Suggesting new features
-* Improving documentation
-* Contributing code
-
----
-
-## Contributing
-
-Contributions, bug reports, feature requests, and feedback are welcome.
-
-See `CONTRIBUTING.md` for project‑specific guidelines.
-For ecosystem‑wide expectations, see [STANDARDS.md](https://github.com/ZFordDev/ZFordDev/blob/main/STANDARDS.md).
-
----
-
-## Security
-
-See `SECURITY.md` for vulnerability reporting guidelines.
-If no security policy is present, please report issues responsibly via GitHub Issues.
-
----
-
-## License
-
-Released under the MIT License.
-See `LICENSE` for details.
-
----
-
-## About ZFordDev
-
-This project is part of the ZFordDev ecosystem — a collection of lightweight, practical tools built with clarity, simplicity, and long‑term maintainability in mind.
-
-For ecosystem‑wide standards, see [STANDARDS.md](https://github.com/ZFordDev/ZFordDev/blob/main/STANDARDS.md).
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+[](https://docs.zford.dev)
+
+
+
+
+
+
+
+
+
+
+
+# SchedPlus
+
+> A lightweight, local‑first desktop scheduler built in Python.
+> **Status:** Alpha • Actively Maintained • Accepting Contributions
+
+---
+
+## Why This Exists
+
+Most scheduling tools try to do everything — calendars, reminders, syncing, accounts, cloud dashboards — and end up feeling heavy, slow, or overly complex.
+
+SchedPlus was built to be the opposite:
+
+- **simple**
+- **local‑first**
+- **lightweight**
+- **predictable**
+- **no accounts**
+- **no cloud**
+- **no unnecessary features**
+
+It focuses on one job: helping you plan your day without getting in your way.
+
+SchedPlus is also a great **learning reference**, showing how a real desktop app evolves over time — from a quick Tkinter prototype to a structured Python application and eventually a full PyQt desktop experience.
+
+---
+
+## Overview
+
+SchedPlus is a simple, predictable desktop scheduler built for people who want structure without the noise.
+
+It focuses on:
+
+- fast startup
+- a clean, minimal interface
+- local‑only task storage
+- a small, readable Python codebase
+- an offline‑first workflow
+
+It’s intentionally lightweight — ideal for daily planning, learning Python UI development, or experimenting with how real desktop apps evolve over time.
+
+SchedPlus currently ships with a stable Tkinter UI, while a full PyQt migration is actively underway to bring a more modern, cross‑platform experience.
+
+---
+
+## Features
+
+* Local task creation and management
+* JSON‑based save/load
+* Offline‑first workflow
+* Tkinter UI (stable)
+* PyQt UI (in development)
+* Clean logic/storage separation
+* Beginner‑friendly codebase
+
+---
+
+## Requirements
+
+SchedPlus is currently a source‑only project.
+To run or develop it, you’ll need:
+
+> Python 3.14+
+> pip (latest)
+> Tkinter (included with most Python installs)
+> PyQt6 (optional, for the new UI)
+
+**Supported environments:**
+
+> Windows 10+
+> Linux (Ubuntu 22.04+)
+
+---
+
+## Quick Start
+
+```bash
+git clone https://github.com/ZFordDev/schedplus.git
+cd schedplus
+
+pip install -r requirements.txt
+
+python3 src/main.py
+```
+
+> *Recommended: use a `.venv`.*
+
+---
+
+## Installation
+
+SchedPlus currently has no build pipeline yet — please wait for the beta release.
+
+---
+
+## Usage
+
+Basic usage:
+
+```bash
+python3 src/main.py
+```
+
+The UI will open and allow you to create, edit, and save tasks locally.
+
+---
+
+## Project Structure
+
+SchedPlus uses a simple, predictable layout designed to keep UI, logic, and data clearly separated.
+
+```text
+schedplus/
+├── src/
+│ ├── assets/ # Icons and UI assets
+│ ├── data/ # Local task storage
+│ ├── logic/ # Core scheduling logic
+│ ├── startup/ # NEW — startup
+│ ├── ui/ # Tkinter + PyQt interfaces
+│ └── main.py # Application entry point
+│
+└── packaging/ # Future packaging targets
+ ├── snap/
+ ├── deb/
+ └── windows/
+```
+
+---
+
+## Roadmap
+
+* [ ] Full PyQt migration
+* [ ] Cross‑platform packaging
+* [ ] Windows installer
+* [ ] Improved task management
+* [ ] UI backend experimentation
+* [ ] Multi‑platform releases
+
+---
+
+## Screenshots
+
+
+
+
+
+
+---
+
+## Known Issues
+
+* PyQt UI is incomplete
+* Packaging is experimental
+* macOS support not yet available
+
+---
+
+## Related Projects
+
+- **MathPlus** — a lightweight desktop calculator
+ [https://github.com/ZFordDev/MathPlus](https://github.com/ZFordDev/MathPlus)
+
+---
+
+## Support
+
+You can support SchedPlus by:
+
+* Leaving a ⭐ on GitHub
+* Reporting bugs
+* Suggesting new features
+* Improving documentation
+* Contributing code
+
+---
+
+## Contributing
+
+Contributions, bug reports, feature requests, and feedback are welcome.
+
+See `CONTRIBUTING.md` for project‑specific guidelines.
+For ecosystem‑wide expectations, see [STANDARDS.md](https://github.com/ZFordDev/ZFordDev/blob/main/STANDARDS.md).
+
+---
+
+## Security
+
+See `SECURITY.md` for vulnerability reporting guidelines.
+If no security policy is present, please report issues responsibly via GitHub Issues.
+
+---
+
+## License
+
+Released under the MIT License.
+See `LICENSE` for details.
+
+---
+
+## About ZFordDev
+
+This project is part of the ZFordDev ecosystem — a collection of lightweight, practical tools built with clarity, simplicity, and long‑term maintainability in mind.
+
+For ecosystem‑wide standards, see [STANDARDS.md](https://github.com/ZFordDev/ZFordDev/blob/main/STANDARDS.md).
+
---
\ No newline at end of file
diff --git a/SECURITY.md b/SECURITY.md
index ba1efde..8b9c290 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -1,104 +1,104 @@
-
-
-
-
-
-
-
-
-
-
-
-# Security Policy
-
-The ZFordDev ecosystem values stability, safety, and long‑term maintainability.
-We take security seriously and appreciate responsible disclosure of any vulnerabilities.
-
-This document explains how to report security issues and what to expect during the process.
-
----
-
-## Supported Versions
-
-Security updates are provided for:
-
-- **Current stable releases**
-- **Active development branches**
-- **Classic versions**, where applicable
-
-Older or archived versions may not receive fixes.
-
----
-
-## Reporting a Vulnerability
-
-If you discover a security issue, please report it responsibly.
-
-### **How to report**
-- Open a **private GitHub security advisory** (preferred)
-- Or contact the project maintainer directly through GitHub
-
-Please **do not** open a public issue for security vulnerabilities.
-
-### **Include the following information**
-- Description of the issue
-- Steps to reproduce
-- Impact or potential risk
-- Affected versions
-- Any relevant logs or screenshots
-
-Clear reports help us respond quickly.
-
----
-
-## Response Process
-
-When a report is received:
-
-1. The maintainer will acknowledge the report
-2. The issue will be investigated
-3. A fix or mitigation will be prepared
-4. A patched release will be published
-5. A security advisory will be issued (if applicable)
-
-We aim to handle all reports respectfully and promptly.
-
----
-
-## Scope
-
-This policy applies to:
-
-- All ZFordDev repositories
-- All official releases
-- All ecosystem tools and modules
-
-It does **not** apply to:
-
-- Third‑party dependencies
-- Forks or modified builds
-- Unofficial distributions
-
----
-
-## SchedPlus‑Specific Notes
-
-SchedPlus is a lightweight Python application with a local‑only workflow.
-When reporting security issues, please consider the following:
-
-- SchedPlus does not load or execute remote content
-- All data is stored locally in simple JSON files (`data/tasks.json`)
-- No networking, syncing, or cloud communication is performed
-- The Tkinter UI is stable; the PyQt UI is in active development and may behave differently across platforms
-- SchedPlus does not collect telemetry or send user data anywhere
-- The application does not run background services or scheduled tasks
-
-If a vulnerability involves JSON handling, UI behaviour, file access, or platform‑specific issues, please include clear reproduction steps for both Windows and Linux (when applicable).
-
----
-
-
-## Thank You
-
-Responsible disclosure helps keep the entire ZFordDev ecosystem safe.
-We appreciate your effort and your commitment to improving the project.
+
+
+
+
+
+
+
+
+
+
+
+# Security Policy
+
+The ZFordDev ecosystem values stability, safety, and long‑term maintainability.
+We take security seriously and appreciate responsible disclosure of any vulnerabilities.
+
+This document explains how to report security issues and what to expect during the process.
+
+---
+
+## Supported Versions
+
+Security updates are provided for:
+
+- **Current stable releases**
+- **Active development branches**
+- **Classic versions**, where applicable
+
+Older or archived versions may not receive fixes.
+
+---
+
+## Reporting a Vulnerability
+
+If you discover a security issue, please report it responsibly.
+
+### **How to report**
+- Open a **private GitHub security advisory** (preferred)
+- Or contact the project maintainer directly through GitHub
+
+Please **do not** open a public issue for security vulnerabilities.
+
+### **Include the following information**
+- Description of the issue
+- Steps to reproduce
+- Impact or potential risk
+- Affected versions
+- Any relevant logs or screenshots
+
+Clear reports help us respond quickly.
+
+---
+
+## Response Process
+
+When a report is received:
+
+1. The maintainer will acknowledge the report
+2. The issue will be investigated
+3. A fix or mitigation will be prepared
+4. A patched release will be published
+5. A security advisory will be issued (if applicable)
+
+We aim to handle all reports respectfully and promptly.
+
+---
+
+## Scope
+
+This policy applies to:
+
+- All ZFordDev repositories
+- All official releases
+- All ecosystem tools and modules
+
+It does **not** apply to:
+
+- Third‑party dependencies
+- Forks or modified builds
+- Unofficial distributions
+
+---
+
+## SchedPlus‑Specific Notes
+
+SchedPlus is a lightweight Python application with a local‑only workflow.
+When reporting security issues, please consider the following:
+
+- SchedPlus does not load or execute remote content
+- All data is stored locally in simple JSON files (`data/tasks.json`)
+- No networking, syncing, or cloud communication is performed
+- The Tkinter UI is stable; the PyQt UI is in active development and may behave differently across platforms
+- SchedPlus does not collect telemetry or send user data anywhere
+- The application does not run background services or scheduled tasks
+
+If a vulnerability involves JSON handling, UI behaviour, file access, or platform‑specific issues, please include clear reproduction steps for both Windows and Linux (when applicable).
+
+---
+
+
+## Thank You
+
+Responsible disclosure helps keep the entire ZFordDev ecosystem safe.
+We appreciate your effort and your commitment to improving the project.
diff --git a/assets/icon.svg b/assets/icon.svg
index a5c45bd..39d9eeb 100644
--- a/assets/icon.svg
+++ b/assets/icon.svg
@@ -1,44 +1,44 @@
-
+
diff --git a/config/README.md b/config/README.md
index 8da6cfa..f865439 100644
--- a/config/README.md
+++ b/config/README.md
@@ -1,9 +1,9 @@
-# Config Directory
-
-This folder stores user‑specific configuration files for SchedPlus.
-
-- These files are **local to your machine**.
-- They are **not tracked by Git** and are safe to modify.
-- The contents here act as **templates** for personal settings, saved tasks, and future features like authentication or database configuration.
-
-As SchedPlus evolves, this directory will remain the home for all user‑level config and state files.
+# Config Directory
+
+This folder stores user‑specific configuration files for SchedPlus.
+
+- These files are **local to your machine**.
+- They are **not tracked by Git** and are safe to modify.
+- The contents here act as **templates** for personal settings, saved tasks, and future features like authentication or database configuration.
+
+As SchedPlus evolves, this directory will remain the home for all user‑level config and state files.
diff --git a/config/tasks.json b/config/tasks.json
index e09d31f..368ea5e 100644
--- a/config/tasks.json
+++ b/config/tasks.json
@@ -1,20 +1,20 @@
-[
- {
- "id": "task1",
- "name": "Task 1",
- "description": "This is the first task.",
- "status": "pending"
- },
- {
- "id": "task2",
- "name": "Task 2",
- "description": "This is the second task.",
- "status": "in_progress"
- },
- {
- "id": "task3",
- "name": "Task 3",
- "description": "This is the third task.",
- "status": "completed"
- }
+[
+ {
+ "id": "task1",
+ "name": "Task 1",
+ "description": "This is the first task.",
+ "status": "pending"
+ },
+ {
+ "id": "task2",
+ "name": "Task 2",
+ "description": "This is the second task.",
+ "status": "in_progress"
+ },
+ {
+ "id": "task3",
+ "name": "Task 3",
+ "description": "This is the third task.",
+ "status": "completed"
+ }
]
\ No newline at end of file
diff --git a/docs/schema.md b/docs/schema.md
index 8b87297..5a276d0 100644
--- a/docs/schema.md
+++ b/docs/schema.md
@@ -1,40 +1,40 @@
-# Task JSON Schema
-
-SchedPlus stores scheduled tasks in JSON using a simple versioned schema.
-
-## Task Object Structure
-
-Each task is represented as an object with the following fields:
-
-- `id` — unique task identifier (string, `uuid4` recommended)
-- `date` — ISO date in `YYYY-MM-DD` format
-- `time` — 24-hour time in `HH:MM` format
-- `text` — task description
-- `createdAt` — creation timestamp in epoch milliseconds
-- `updatedAt` — last update timestamp in epoch milliseconds
-
-## Full File Layout
-
-The top-level file contains a `version` field and a `tasks` array.
-
-```json
-{
- "version": 1,
- "tasks": [
- {
- "id": "uuid",
- "date": "2026-05-04",
- "time": "14:30",
- "text": "Example task",
- "createdAt": 1714820000000,
- "updatedAt": 1714820000000
- }
- ]
-}
-```
-
-## Notes
-
-- The `version` field supports future migrations.
-- The schema uses ISO date/time formats for clarity.
-- The file is intentionally simple and beginner-friendly.
+# Task JSON Schema
+
+SchedPlus stores scheduled tasks in JSON using a simple versioned schema.
+
+## Task Object Structure
+
+Each task is represented as an object with the following fields:
+
+- `id` — unique task identifier (string, `uuid4` recommended)
+- `date` — ISO date in `YYYY-MM-DD` format
+- `time` — 24-hour time in `HH:MM` format
+- `text` — task description
+- `createdAt` — creation timestamp in epoch milliseconds
+- `updatedAt` — last update timestamp in epoch milliseconds
+
+## Full File Layout
+
+The top-level file contains a `version` field and a `tasks` array.
+
+```json
+{
+ "version": 1,
+ "tasks": [
+ {
+ "id": "uuid",
+ "date": "2026-05-04",
+ "time": "14:30",
+ "text": "Example task",
+ "createdAt": 1714820000000,
+ "updatedAt": 1714820000000
+ }
+ ]
+}
+```
+
+## Notes
+
+- The `version` field supports future migrations.
+- The schema uses ISO date/time formats for clarity.
+- The file is intentionally simple and beginner-friendly.
diff --git a/requirements.txt b/requirements.txt
index 22779d0..65a6327 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,3 @@
-# SchedPlus dependencies
-
+# SchedPlus dependencies
+
PyQt6
\ No newline at end of file
diff --git a/src/startup/controller.py b/src/startup/controller.py
index 61fbdf3..29ea8a4 100644
--- a/src/startup/controller.py
+++ b/src/startup/controller.py
@@ -89,7 +89,7 @@ def _launch_mode(mode: StartupMode):
if mode == StartupMode.TK:
try:
- from ui.tkinter_ui import run_ui
+ from ui.tk import run_ui
except Exception:
print("Tkinter UI is not available on this system.")
return
diff --git a/src/ui/tk/__init__.py b/src/ui/tk/__init__.py
new file mode 100644
index 0000000..56b9ea1
--- /dev/null
+++ b/src/ui/tk/__init__.py
@@ -0,0 +1,7 @@
+"""
+Tkinter UI package for SchedPlus.
+
+Exposes the run_ui() entrypoint used by the startup controller.
+"""
+
+from .main_window import run_ui
diff --git a/src/ui/tk/add_task_dialog.py b/src/ui/tk/add_task_dialog.py
new file mode 100644
index 0000000..f39cd3c
--- /dev/null
+++ b/src/ui/tk/add_task_dialog.py
@@ -0,0 +1,119 @@
+"""
+add_task_dialog.py
+------------------
+Improved modal dialog for adding a task.
+
+- Pre-fills date/time with current values
+- Adds keyboard shortcuts (Enter/Esc)
+- Adds simple validation
+- Cleaner layout and spacing
+"""
+
+import tkinter as tk
+from tkinter import ttk
+from datetime import datetime
+
+
+class AddTaskDialog(tk.Toplevel):
+ """Modal dialog for entering task details."""
+
+ def __init__(self, parent):
+ super().__init__(parent)
+ self.title("Add Task")
+ self.resizable(False, False)
+
+ self.result = None
+
+ # ---------------------------------------------------------
+ # Frame
+ # ---------------------------------------------------------
+ frame = ttk.Frame(self, padding=15)
+ frame.grid(row=0, column=0)
+
+ # ---------------------------------------------------------
+ # Default values
+ # ---------------------------------------------------------
+ now = datetime.now()
+ default_date = now.strftime("%Y-%m-%d")
+ default_time = now.strftime("%H:%M")
+
+ # ---------------------------------------------------------
+ # Date
+ # ---------------------------------------------------------
+ ttk.Label(frame, text="Date (YYYY-MM-DD):").grid(row=0, column=0, sticky="w", pady=4)
+ self.date_entry = ttk.Entry(frame, width=25)
+ self.date_entry.insert(0, default_date)
+ self.date_entry.grid(row=0, column=1, pady=4)
+
+ # ---------------------------------------------------------
+ # Time
+ # ---------------------------------------------------------
+ ttk.Label(frame, text="Time (HH:MM):").grid(row=1, column=0, sticky="w", pady=4)
+ self.time_entry = ttk.Entry(frame, width=25)
+ self.time_entry.insert(0, default_time)
+ self.time_entry.grid(row=1, column=1, pady=4)
+
+ # ---------------------------------------------------------
+ # Task title
+ # ---------------------------------------------------------
+ ttk.Label(frame, text="Task:").grid(row=2, column=0, sticky="w", pady=4)
+ self.text_entry = ttk.Entry(frame, width=25)
+ self.text_entry.grid(row=2, column=1, pady=4)
+
+ # ---------------------------------------------------------
+ # Buttons
+ # ---------------------------------------------------------
+ btn_frame = ttk.Frame(frame)
+ btn_frame.grid(row=3, column=0, columnspan=2, pady=(12, 0))
+
+ ttk.Button(btn_frame, text="Cancel", command=self._cancel).grid(row=0, column=0, padx=6)
+ ttk.Button(btn_frame, text="Add", command=self._on_add).grid(row=0, column=1, padx=6)
+
+ # ---------------------------------------------------------
+ # Keyboard shortcuts
+ # ---------------------------------------------------------
+ self.bind("", lambda e: self._on_add())
+ self.bind("", lambda e: self._cancel())
+
+ # ---------------------------------------------------------
+ # Focus
+ # ---------------------------------------------------------
+ self.text_entry.focus()
+
+ # Modal behavior
+ self.grab_set()
+ self.wait_window()
+
+ # -------------------------------------------------------------
+ # Actions
+ # -------------------------------------------------------------
+ def _cancel(self):
+ self.result = None
+ self.destroy()
+
+ def _on_add(self):
+ """Validate, collect values, and close dialog."""
+ date = self.date_entry.get().strip()
+ time = self.time_entry.get().strip()
+ text = self.text_entry.get().strip()
+
+ # Simple validation
+ if not (date and time and text):
+ self._flash_error()
+ return
+
+ self.result = (date, time, text)
+ self.destroy()
+
+ # -------------------------------------------------------------
+ # UX: Flash red border on invalid input
+ # -------------------------------------------------------------
+ def _flash_error(self):
+ for widget in (self.date_entry, self.time_entry, self.text_entry):
+ widget.configure(style="Error.TEntry")
+
+ self.after(150, self._clear_error)
+
+ def _clear_error(self):
+ for widget in (self.date_entry, self.time_entry, self.text_entry):
+ widget.configure(style="TEntry")
diff --git a/src/ui/tk/connector.py b/src/ui/tk/connector.py
new file mode 100644
index 0000000..90e2224
--- /dev/null
+++ b/src/ui/tk/connector.py
@@ -0,0 +1,54 @@
+"""
+connector.py
+------------
+Thin wrapper between Tkinter UI and the scheduler.
+
+Keeps UI code clean and storage-agnostic.
+"""
+
+from .utils import build_due_date
+
+
+class TkConnector:
+ """
+ Provides UI-friendly access to scheduler operations.
+
+ The connector:
+ - Validates UI input
+ - Converts UI date/time → ISO format
+ - Delegates all logic to the scheduler
+ - Keeps UI code simple and logic-free
+ """
+
+ def __init__(self, scheduler):
+ self.scheduler = scheduler
+
+ # ---------------------------------------------------------
+ # Read operations
+ # ---------------------------------------------------------
+ def list_tasks(self):
+ """Return all tasks from the scheduler."""
+ return self.scheduler.list_tasks()
+
+ # ---------------------------------------------------------
+ # Write operations
+ # ---------------------------------------------------------
+ def add_task(self, date: str, time: str, title: str) -> bool:
+ """
+ Validate and add a new task.
+
+ Returns:
+ bool: True if task was added, False if validation failed.
+ """
+ if not (date and time and title):
+ return False
+
+ due_date = build_due_date(date, time)
+
+ self.scheduler.add_task(
+ title=title,
+ description=None,
+ due_date=due_date,
+ )
+
+ return True
diff --git a/src/ui/tk/main_window.py b/src/ui/tk/main_window.py
new file mode 100644
index 0000000..a005bc9
--- /dev/null
+++ b/src/ui/tk/main_window.py
@@ -0,0 +1,180 @@
+"""
+main_window.py
+--------------
+Primary Tkinter window for SchedPlus (Basic Mode).
+
+A modernized task manager UI with modal task entry, a refreshed task table,
+and improved keyboard shortcuts for faster task handling.
+"""
+
+import tkinter as tk
+from tkinter import ttk
+
+from .add_task_dialog import AddTaskDialog
+from .connector import TkConnector
+from .utils import split_due_date
+
+
+def run_ui(scheduler):
+ """Entry point called by startup controller."""
+ connector = TkConnector(scheduler)
+
+ root = tk.Tk()
+ root.title("SchedPlus")
+ root.geometry("560x560")
+ root.minsize(520, 520)
+ root.configure(bg="#edf2fb")
+
+ style = ttk.Style(root)
+ style.theme_use("clam")
+ style.configure("Root.TFrame", background="#edf2fb")
+ style.configure("Card.TFrame", background="#ffffff", relief="flat")
+ style.configure("Header.TLabel", background="#edf2fb", font=("Segoe UI", 16, "bold"), foreground="#1f2937")
+ style.configure("SubHeader.TLabel", background="#edf2fb", font=("Segoe UI", 10), foreground="#4b5563")
+ style.configure("Accent.TButton", font=("Segoe UI", 10, "bold"), foreground="#ffffff", background="#4f46e5", padding=10)
+ style.map("Accent.TButton", background=[("active", "#4338ca"), ("pressed", "#3730a3")])
+ style.configure("Secondary.TButton", font=("Segoe UI", 10), foreground="#111827", background="#f3f4f6", padding=8)
+ style.configure("Task.Treeview", background="#ffffff", fieldbackground="#ffffff", highlightthickness=0, bordercolor="#d1d5db", borderwidth=1)
+ style.configure("Task.Treeview.Heading", font=("Segoe UI", 10, "bold"), foreground="#111827")
+ style.map("Task.Treeview", background=[("selected", "#e0e7ff")])
+
+ root.columnconfigure(0, weight=1)
+ root.rowconfigure(0, weight=1)
+
+ container = ttk.Frame(root, style="Root.TFrame", padding=(18, 18, 18, 12))
+ container.grid(row=0, column=0, sticky="nsew")
+ container.columnconfigure(0, weight=1)
+ container.rowconfigure(3, weight=1)
+
+ header_frame = ttk.Frame(container, style="Root.TFrame")
+ header_frame.grid(row=0, column=0, sticky="ew", pady=(0, 14))
+ header_frame.columnconfigure(0, weight=1)
+
+ heading = ttk.Label(header_frame, text="SchedPlus", style="Header.TLabel")
+ heading.grid(row=0, column=0, sticky="w")
+
+ subtitle = ttk.Label(
+ header_frame,
+ text="A clean way to add tasks, track due times, and stay organized.",
+ style="SubHeader.TLabel"
+ )
+ subtitle.grid(row=1, column=0, sticky="w", pady=(6, 0))
+
+ # Quick action row.
+ action_frame = ttk.Frame(container, style="Card.TFrame", padding=14)
+ action_frame.grid(row=1, column=0, sticky="ew", pady=(0, 14))
+ action_frame.columnconfigure(0, weight=1)
+ action_frame.columnconfigure(1, weight=0)
+
+ info_text = ttk.Label(
+ action_frame,
+ text="Use the button below to add a task with full date, time, and title.",
+ style="SubHeader.TLabel",
+ wraplength=360,
+ justify="left"
+ )
+ info_text.grid(row=0, column=0, sticky="w")
+
+ add_button = ttk.Button(action_frame, text="Add Task", style="Accent.TButton")
+ add_button.grid(row=0, column=1, sticky="e")
+
+ control_frame = ttk.Frame(container, style="Root.TFrame")
+ control_frame.grid(row=2, column=0, sticky="ew", pady=(0, 10))
+ control_frame.columnconfigure(0, weight=1)
+ control_frame.columnconfigure(1, weight=0)
+ control_frame.columnconfigure(2, weight=0)
+
+ task_count_label = ttk.Label(control_frame, text="0 tasks", style="SubHeader.TLabel")
+ task_count_label.grid(row=0, column=0, sticky="w")
+
+ refresh_button = ttk.Button(control_frame, text="Refresh", style="Secondary.TButton")
+ refresh_button.grid(row=0, column=1, sticky="e", padx=(0, 8))
+
+ help_button = ttk.Button(control_frame, text="Help", style="Secondary.TButton")
+ help_button.grid(row=0, column=2, sticky="e")
+
+ list_frame = ttk.Frame(container, style="Card.TFrame", padding=12)
+ list_frame.grid(row=3, column=0, sticky="nsew")
+ list_frame.columnconfigure(0, weight=1)
+ list_frame.rowconfigure(0, weight=1)
+
+ task_table = ttk.Treeview(
+ list_frame,
+ columns=("date", "time", "task"),
+ show="headings",
+ style="Task.Treeview",
+ selectmode="browse",
+ height=14,
+ )
+ task_table.heading("date", text="Date")
+ task_table.heading("time", text="Time")
+ task_table.heading("task", text="Task")
+ task_table.column("date", width=100, anchor="center")
+ task_table.column("time", width=80, anchor="center")
+ task_table.column("task", anchor="w")
+ task_table.grid(row=0, column=0, sticky="nsew")
+
+ scrollbar = ttk.Scrollbar(list_frame, orient="vertical", command=task_table.yview)
+ scrollbar.grid(row=0, column=1, sticky="ns", padx=(8, 0))
+ task_table.configure(yscrollcommand=scrollbar.set)
+
+ empty_state = ttk.Label(
+ list_frame,
+ text="No tasks yet. Click Add Task to create your first item.",
+ style="SubHeader.TLabel",
+ anchor="center"
+ )
+ empty_state.grid(row=0, column=0, sticky="nsew")
+
+ def _update_empty_state():
+ has_tasks = len(task_table.get_children()) > 0
+ empty_state.lift() if not has_tasks else empty_state.lower()
+
+ def refresh_task_list():
+ task_table.delete(*task_table.get_children())
+ for index, entry in enumerate(connector.list_tasks()):
+ date, time = split_due_date(entry.due_date)
+ tag = "evenrow" if index % 2 == 0 else "oddrow"
+ task_table.insert("", tk.END, values=(date, time, entry.title), tags=(tag,))
+
+ task_table.tag_configure("evenrow", background="#ffffff")
+ task_table.tag_configure("oddrow", background="#f8fafc")
+ task_count_label.configure(text=f"{len(task_table.get_children())} tasks")
+ _update_empty_state()
+
+ def open_add_task_dialog(event=None):
+ dialog = AddTaskDialog(root)
+ if not dialog.result:
+ return
+
+ date, time, title = dialog.result
+ if connector.add_task(date, time, title):
+ refresh_task_list()
+
+ def show_help():
+ help_text = (
+ "Enter a date in YYYY-MM-DD format, a time in HH:MM format,\n"
+ "and a short task title. Use Add Task to save it. \n"
+ "Refresh updates the task list when changes occur."
+ )
+ help_dialog = tk.Toplevel(root)
+ help_dialog.title("Help")
+ help_dialog.resizable(False, False)
+ help_frame = ttk.Frame(help_dialog, padding=16)
+ help_frame.grid(row=0, column=0)
+ ttk.Label(help_frame, text="How to use SchedPlus", font=("Segoe UI", 12, "bold")).grid(row=0, column=0, sticky="w", pady=(0, 10))
+ ttk.Label(help_frame, text=help_text, font=("Segoe UI", 10), foreground="#374151", justify="left").grid(row=1, column=0, sticky="w")
+ ttk.Button(help_frame, text="Close", command=help_dialog.destroy, style="Accent.TButton").grid(row=2, column=0, pady=(14, 0), sticky="e")
+ help_dialog.grab_set()
+ help_dialog.transient(root)
+ help_dialog.wait_window()
+
+ add_button.configure(command=open_add_task_dialog)
+ refresh_button.configure(command=refresh_task_list)
+ help_button.configure(command=show_help)
+
+ root.bind("", open_add_task_dialog)
+ root.bind("", lambda event: refresh_task_list())
+
+ refresh_task_list()
+ root.mainloop()
diff --git a/src/ui/tk/utils.py b/src/ui/tk/utils.py
new file mode 100644
index 0000000..696fd3f
--- /dev/null
+++ b/src/ui/tk/utils.py
@@ -0,0 +1,29 @@
+"""
+utils.py
+--------
+Small helper functions shared across Tkinter UI files.
+"""
+
+def split_due_date(due_date: str) -> tuple[str, str]:
+ """
+ Convert ISO 'YYYY-MM-DDTHH:MM' → ('YYYY-MM-DD', 'HH:MM').
+
+ Returns empty strings if the input is missing or malformed.
+ """
+ if not due_date:
+ return ("", "")
+
+ if "T" not in due_date:
+ return ("", "")
+
+ date, time = due_date.split("T", 1)
+ return (date, time)
+
+
+def build_due_date(date: str, time: str) -> str:
+ """
+ Build ISO timestamp from separate date + time fields.
+
+ Does not validate the values — validation happens in the connector/UI.
+ """
+ return f"{date}T{time}"
diff --git a/src/ui/tkinter_ui.py b/src/ui/tkinter_ui.py
index b642504..05d36e7 100644
--- a/src/ui/tkinter_ui.py
+++ b/src/ui/tkinter_ui.py
@@ -1,10 +1,9 @@
"""
-tkinter_ui.py (v0.5)
---------------------
-Improved teaching Tkinter UI for SchedPlus.
+tkinter_ui.py (v0.5 - DB compatible MVP)
+----------------------------------------
+Minimal compatibility update for the new DB-backed scheduler.
-Still intentionally simple, but with cleaner layout,
-better spacing, and more readable structure.
+Full UI overhaul will happen in a separate issue.
"""
import tkinter as tk
@@ -16,21 +15,17 @@ def run_ui(scheduler):
root = tk.Tk()
root.title("SchedPlus v0.5 (Tkinter)")
- # Center window
root.geometry("420x420")
- # --- Main container ---
container = ttk.Frame(root, padding=15)
container.grid(row=0, column=0, sticky="nsew")
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
- # --- Heading ---
heading = ttk.Label(container, text="Add a Task", font=("Segoe UI", 12, "bold"))
heading.grid(row=0, column=0, columnspan=2, pady=(0, 10))
- # --- Input fields ---
ttk.Label(container, text="Date (YYYY-MM-DD):").grid(row=1, column=0, sticky="w", pady=3)
date_entry = ttk.Entry(container, width=25)
date_entry.grid(row=1, column=1, sticky="ew", pady=3)
@@ -43,11 +38,9 @@ def run_ui(scheduler):
task_entry = ttk.Entry(container, width=25)
task_entry.grid(row=3, column=1, sticky="ew", pady=3)
- # --- Add Task button ---
add_button = ttk.Button(container, text="Add Task")
add_button.grid(row=4, column=0, columnspan=2, pady=(10, 15))
- # --- Task list frame ---
list_frame = ttk.LabelFrame(container, text="Tasks", padding=10)
list_frame.grid(row=5, column=0, columnspan=2, sticky="nsew")
@@ -55,30 +48,34 @@ def run_ui(scheduler):
list_frame.rowconfigure(0, weight=1)
list_frame.columnconfigure(0, weight=1)
- # --- Task list ---
task_list = tk.Listbox(list_frame, width=50, height=10, borderwidth=1, relief="solid")
task_list.grid(row=0, column=0, sticky="nsew")
- # Populate existing tasks
- for task in scheduler.get_tasks():
- task_list.insert(tk.END, f"{task.date} {task.time} - {task.text}")
+ # --- Populate tasks from DB ---
+ for entry in scheduler.list_tasks():
+ # entry.due_date is ISO: "YYYY-MM-DDTHH:MM"
+ date, time = _split_due_date(entry.due_date)
+ task_list.insert(tk.END, f"{date} {time} - {entry.title}")
# --- Add Task logic ---
def add_task():
date = date_entry.get().strip()
time = time_entry.get().strip()
- text = task_entry.get().strip()
+ title = task_entry.get().strip()
- if date and time and text:
- scheduler.add_task(date, time, text)
- new_task = scheduler.get_tasks()[-1]
+ if date and time and title:
+ due_date = f"{date}T{time}"
- task_list.insert(tk.END, f"{new_task.date} {new_task.time} - {new_task.text}")
+ scheduler.add_task(
+ title=title,
+ description=None,
+ due_date=due_date,
+ )
- try:
- scheduler.save_tasks()
- except Exception:
- pass
+ new_entry = scheduler.list_tasks()[-1]
+ new_date, new_time = _split_due_date(new_entry.due_date)
+
+ task_list.insert(tk.END, f"{new_date} {new_time} - {new_entry.title}")
task_entry.delete(0, tk.END)
@@ -86,3 +83,12 @@ def add_task():
bind_enter_key([date_entry, time_entry, task_entry], add_task)
root.mainloop()
+
+
+def _split_due_date(due_date: str):
+ """
+ Helper: Convert ISO "YYYY-MM-DDTHH:MM" → ("YYYY-MM-DD", "HH:MM")
+ """
+ if due_date and "T" in due_date:
+ return due_date.split("T", 1)
+ return ("", "")
diff --git a/temp_notes.md b/temp_notes.md
index 734344d..c72e84a 100644
--- a/temp_notes.md
+++ b/temp_notes.md
@@ -1,11 +1,11 @@
-> [!NOTE]
-> **ZFordDev Standard: Temp Notes**
->
-> This file is included in every repository as part of the ZFordDev ecosystem
-> standards. It provides a safe local-only space for scratch notes, planning,
-> and quick thoughts while working.
->
-> This file is ignored by Git (see `.gitignore`) and will never be committed
-> or pushed to the repository.
-
-# ***NOTES***
+> [!NOTE]
+> **ZFordDev Standard: Temp Notes**
+>
+> This file is included in every repository as part of the ZFordDev ecosystem
+> standards. It provides a safe local-only space for scratch notes, planning,
+> and quick thoughts while working.
+>
+> This file is ignored by Git (see `.gitignore`) and will never be committed
+> or pushed to the repository.
+
+# ***NOTES***