# Worklog

Append only. One entry per logical change.

## Entries

Date: 2026-06-09
Type: FEATURE | DOCS
Title: Laravel 12 foundation and initial E-Voting scaffold
Status: DONE
Project Impact:
- Frontend: Added Bootstrap landing and dashboard views with a custom glassmorphism theme.
- Backend: Added organization repository/service scaffold, admin organization controller, and route foundation.
- Database: Added migrations for organizations, users, events, candidates, voters, votes, OTP codes, and audit logs; seeded a demo organization and super-admin.
- Docs: Kept the six-phase requirements, plan, database, implementation, test, and review docs as source of truth.
Plan:
- Bootstrap the Laravel app in the workspace.
- Add the core E-Voting domain tables and models.
- Add initial routes, views, and test coverage.
Execution:
- Installed Laravel 12 dependencies and generated a local app key.
- Implemented the first wave of models, repositories, services, controllers, and views.
- Added test and runtime environment files for SQLite-based development.
Testing:
- `php artisan test`
- `php artisan migrate --force`
- `php artisan migrate:fresh --seed --env=testing --force`
Review:
- The scaffold is runnable and the main routes pass tests.
- Remaining work is the actual organizer auth flow and CRUD modules.
Lessons Learned:
- Starting with the database contract and a real scaffold makes the next feature phases much safer.

Date: 2026-06-09
Type: FEATURE
Title: Organizer authentication flow
Status: DONE
Project Impact:
- Frontend: Added organizer login page and wired auth feedback into the shared Bootstrap layout.
- Backend: Added session login/logout controller, login request validation, and admin role middleware.
- Database: Reused the seeded super-admin and organizer-compatible role field; no schema change required.
- Docs: Kept the phase docs unchanged and recorded the auth milestone in the project worklog.
Plan:
- Add login and logout routes for organizer access.
- Protect dashboard and admin routes with auth plus role checks.
- Cover login, invalid login, logout, and guest redirect cases with tests.
Execution:
- Added an authenticated session controller and a login Form Request.
- Added an admin role middleware and registered it in the Laravel middleware alias map.
- Updated routes, landing CTAs, and admin layout links to the protected auth flow.
- Added feature tests for login, invalid login, logout, and dashboard access.
Testing:
- `php artisan test --filter=OrganizerAuthenticationTest`
- `php artisan test`
- `php -l app/Http/Controllers/Auth/AuthenticatedSessionController.php`
- `php -l app/Http/Middleware/EnsureAdminRole.php`
- `php -l routes/web.php`
- `php -l tests/Feature/Auth/OrganizerAuthenticationTest.php`
- `php -l tests/Feature/LandingAndDashboardTest.php`
Review:
- Login now only accepts organizer and super-admin roles.
- Logout clears the session and returns to the landing page with feedback.
- Guest access to dashboard is blocked as expected.
Lessons Learned:
- Keeping auth as a small dedicated step makes later CRUD modules much easier to secure.

Date: 2026-06-09
Type: FEATURE
Title: Organization CRUD module
Status: DONE
Project Impact:
- Frontend: Added create/edit organization pages and upgraded the index to use shared admin table and action components.
- Backend: Added store, update, and delete actions for organizations with service-layer handling and route protection.
- Database: Reused the existing organizations schema; soft delete behavior is now exercised by the module.
- Docs: The phase docs remain the source of truth; this worklog entry records the completed organization milestone.
Plan:
- Expand the organization controller into a full CRUD workflow.
- Reuse existing request validation, service, and repository layers.
- Add feature tests for index, create, edit, store, update, delete, and unique slug validation.
Execution:
- Added organization create/edit forms and routes.
- Extended the organization service with find, update, and delete methods.
- Reworked the index page to use shared admin table and action components.
- Added CRUD feature tests and kept the role guard intact.
Testing:
- `php artisan test --filter=OrganizationCrudTest`
- `php artisan test`
- `php -l app/Http/Controllers/Admin/OrganizationController.php`
- `php -l app/Services/OrganizationService.php`
- `php -l routes/web.php`
- `php -l tests/Feature/Admin/OrganizationCrudTest.php`
- `php -l app/Http/Requests/Admin/StoreOrganizationRequest.php`
- `php -l app/Http/Requests/Admin/UpdateOrganizationRequest.php`
Review:
- Organization CRUD is functional and protected behind organizer/super-admin access.
- Soft delete is respected on remove, and slug uniqueness is enforced.
- The module is ready for the next phase: event management.
Lessons Learned:
- Reusing the existing admin components keeps the CRUD flow consistent and faster to extend.

Date: 2026-06-09
Type: REFACTOR
Title: Resource structure aligned to pc-imm admin/frontend split
Status: DONE
Project Impact:
- Frontend: Moved the public landing page into `resources/views/frontend/` and introduced a dedicated frontend layout.
- Backend: Kept routes and controllers stable while pointing them to the new admin/frontend view split.
- Database: No schema changes.
- Docs: The project docs remain the source of truth; this entry records the view-structure migration.
Plan:
- Separate public and admin templates into distinct folders.
- Replace component-heavy and `_form`-based organization views with direct Blade pages.
- Align the admin page style with the simpler pc-imm pattern.
Execution:
- Created `resources/views/frontend/layouts/app.blade.php` and `resources/views/frontend/home.blade.php`.
- Rebuilt the admin shell in `resources/views/layouts/app.blade.php` and moved the dashboard to `resources/views/admin/index.blade.php`.
- Rewrote organization create/edit/index pages as direct Blade pages without `_form` or admin component wrappers.
- Removed unused component files and the old admin layout/view split.
Testing:
- `php artisan test`
- `php -l routes/web.php`
- `php -l app/Http/Controllers/DashboardController.php`
- `php -l app/Http/Controllers/Admin/OrganizationController.php`
- `php -l app/Services/OrganizationService.php`
Review:
- The resource tree now clearly separates `admin/`, `frontend/`, `auth/`, and `layouts/`.
- The organization module now uses direct Blade templates instead of split form/component pieces.
Lessons Learned:
- Matching the resource structure to an existing reference project reduces friction for future edits.

Date: 2026-06-09
Type: REFACTOR
Title: Integrate Sneat template and DataTables
Status: DONE
Project Impact:
- Frontend: Migrated layout (`resources/views/layouts/app.blade.php`), header navbar (`resources/views/admin/partials/header.blade.php`), login page (`resources/views/auth/login.blade.php`), dashboard (`resources/views/admin/index.blade.php`), and organization pages to use the Sneat Bootstrap 5 HTML Admin template.
- Frontend (DataTables): Added jQuery DataTables integration (via CDN) to style and enable client-side search, sort, and pagination on the organizations table (`resources/views/admin/organizations/index.blade.php`).
- Assets: Copied all Sneat template assets (CSS, JS, fonts, and libs) into the public folder at `public/assets/`.
- Docs: Updated project worklog to reflect the integration.
Plan:
- Copy Sneat template assets to `public/assets`.
- Implement Sneat-compatible vertical navbar container layout in `layouts/app.blade.php`.
- Re-architect admin header, login page, dashboard index, and organizations CRUD views to follow Sneat classes.
- Initialize jQuery DataTable on organizations table.
- Verify using php artisan test.
Execution:
- Successfully copied all assets recursively.
- Refactored all views to Sneat CSS and structure, resolving a test assertion mismatch on the login page.
- Initialized DataTable on `#organizations-table` with default sorting.
Testing:
- `php artisan test` - all 16 tests pass.
Review:
- The design looks premium, modern, and aligned with Sneat layout.
- DataTables handles sorting and search perfectly.
Lessons Learned:
- Copying assets directly into `public/` is very clean for template integrations in Laravel.
- Correcting test assertions early keeps the pipeline clean and green.

Date: 2026-06-09
Type: REFACTOR
Title: Integrate pc-imm frontend template for landing page
Status: DONE
Project Impact:
- Frontend: Migrated frontend base layout (`resources/views/frontend/layouts/app.blade.php`), header navbar (`resources/views/frontend/layouts/header.blade.php`), footer (`resources/views/frontend/layouts/footer.blade.php`), and home landing page (`resources/views/frontend/home.blade.php`) to use the pc-imm frontend Bootstrap 5 template structure.
- Assets: Copied frontend-update assets recursively into the public folder at `public/frontend-update/`.
- Docs: Updated project worklog to reflect frontend integration.
Plan:
- Copy pc-imm public/frontend-update assets to public/frontend-update.
- Implement frontend layout, header, footer in resources/views/frontend/layouts/.
- Re-architect home.blade.php landing view with pc-imm styled sections.
- Verify with php artisan test.
Execution:
- Copied assets and modularized frontend layout.
- Customized header navigation and footer branding/copyrights to match E-Voting instead of IMM.
- Adjusted home banner, capabilities facts, and stages tabs to fit E-Voting content.
Testing:
- `php artisan test` - all 16 tests passed.
Review:
- The landing page uses high-quality animations and layout structures.
Lessons Learned:
- Leveraging existing project templates makes creating landing pages with high aesthetic value very efficient.

Date: 2026-06-10
Type: CONFIG
Title: Configure SMTP email settings
Status: DONE
Project Impact:
- Environment: Updated `.env` file with SMTP settings for sending emails via smtp.gmail.com.
Plan:
- Update `.env` MAIL_* parameters with the provided SMTP configuration.
Execution:
- Updated `MAIL_MAILER`, `MAIL_HOST`, `MAIL_PORT`, `MAIL_USERNAME`, `MAIL_PASSWORD`, `MAIL_ENCRYPTION`, and `MAIL_FROM_ADDRESS` in `.env`.
Testing:
- Configuration is loaded via .env (no explicit test needed for config).
Review:
- The email system is now configured to use the provided Gmail SMTP credentials.
Lessons Learned:
- Simple environment updates can be done directly.

Date: 2026-06-10
Type: FIX
Title: Fix candidate photo variable rendering
Status: DONE
Project Impact:
- Frontend: Fixed candidate photo path references in the ballot view and modal.
- Admin: Fixed candidate photo path references in the results show view.
Plan:
- Change `$candidate->photo` to `$candidate->photo_path` in `ballot.blade.php` and `show.blade.php`.
Execution:
- Updated the Blade variables to properly read the `photo_path` stored in the database.
Testing:
- Checked the views and variables visually in the code.
Review:
- Candidate photos will now display correctly since they are referencing the correct database column.
Lessons Learned:
- Always ensure frontend views match the database column names updated in the backend services.

Date: 2026-06-10
Type: REFACTOR
Title: Redesign OTP email to match Musyawara branding
Status: DONE
Project Impact:
- Environment: Updated `APP_NAME` in `.env` to `"Musyawara"` to change sender name.
- Mail: Updated `VoterOtpMail.php` to set the email subject in Indonesian language ("Kode OTP Pemilihan Anda").
- Mail View: Completely redesigned `emails.voter.otp` blade template to match Musyawara minimalist UI layout, colors, and Indonesian copywriting.
Plan:
- Align OTP email design with branding parameters in `DESIGN.md`.
Execution:
- Updated `.env` and `VoterOtpMail.php` subject.
- Re-coded `otp.blade.php` with premium, clean HTML styling (Inter-inspired font, lots of white space, blue primary accents `#2563EB`, custom container shadow/border).
- Adjusted copy to Indonesian: replaced "Voting/Election" terms with "Pemilihan/Musyawarah" as per UX rules.
Testing:
- Ran `php artisan test` to verify no regressions (53/53 tests passed).
Review:
- The email format is now fully aligned with the "Musyawara" branding identity.
Lessons Learned:
- Applying consistent inline styles in HTML email templates ensures cross-client compatibility while adhering to web design systems.

Date: 2026-06-10
Type: REFACTOR
Title: Translate admin panel and update colors to Musyawara branding
Status: DONE
Project Impact:
- Frontend (Admin): Overrode CSS variable colors in `layouts/app.blade.php` to use Musyawara primary blue `#2563EB` instead of default Sneat purple `#696cff`.
- Localization: Translated admin sidebar links, layout footer, header breadcrumbs/profile menu items, and controller breadcrumb variables to Indonesian.
Plan:
- Change default colors in layouts/app.blade.php.
- Translate English terms in views and controllers to Indonesian equivalents.
Execution:
- Added `<style>` overrides for Bootstrap primary variables and Sneat components (buttons, links, active menu items) in `layouts/app.blade.php`.
- Translated app brand from "E-Voting" to "Musyawara", footer copyright text, and sidebar menu items.
- Translated navbar drop-downs and dynamic breadcrumbs in `partials/header.blade.php` and controllers.
- Updated hardcoded page headers (e.g. `Admin /` breadcrumbs) across 15+ admin views.
Testing:
- Updated `LandingAndDashboardTest` assertion expecting "Ruang Kontrol Musyawara" instead of "E-Voting Control Room".
- Ran `php artisan test` - all 53 tests passed successfully.
Review:
- The admin dashboard is now aligned with Musyawara branding assets while preserving the existing layout structure.
Lessons Learned:
- Injecting targeted CSS overrides is a clean way to change primary theme colors without refactoring multiple CSS build structures.

Date: 2026-06-10
Type: REFACTOR
Title: Translate module inner contents and DataTables to Indonesian
Status: DONE
Project Impact:
- Localization: Globally translated DataTables language components (search, pagination, empty states, entries info) in `layouts/app.blade.php`.
- Frontend (Admin): Translated table titles, headers, badge labels, action buttons, modals, and empty state messages in Event, Candidate, Voter, User, result index/show, and Audit Log modules.
Plan:
- Translate the remaining English text inside each admin module and add Indonesian translations for DataTables globally.
Execution:
- Added global $.extend DataTables defaults override in `layouts/app.blade.php`.
- Translated `index.blade.php` content for Organizations, Events, Candidates, Voters, Users, Audit Logs, and Results index/show.
- Swapped active status labels, form headers, alerts, delete confirmations, and modal parameters to Indonesian.
Testing:
- Updated `ResultFeatureTest` assertion expecting "Total Suara Masuk" instead of "Total Votes Cast".
- Ran `php artisan test` - all 53 tests passed successfully.
Review:
- The entire admin panel is now fully localized in Indonesian.
Lessons Learned:
- Using $.extend to globally override library defaults like DataTables saves massive duplicate code and translation effort.

Date: 2026-06-10
Type: REFACTOR
Title: Translate CRUD forms and update test assertions to Indonesian
Status: DONE
Project Impact:
- Frontend (Admin): Translated form field labels, page headers, help texts, placeholders, and buttons in user add and edit blades (`admin/users/create.blade.php`, `admin/users/edit.blade.php`), and translated toast messages helper text.
- Testing: Updated test assertions in `CandidateCrudTest.php`, `EventCrudTest.php`, and `OrganizationCrudTest.php` to verify translated Indonesian text instead of English labels.
Plan:
- Translate the remaining English text on user forms to Indonesian.
- Update related test cases to check for Indonesian phrases.
Execution:
- Swapped form fields (Name -> Nama, Password -> Kata Sandi, Role -> Peran, Organization -> Organisasi, etc.) in user forms.
- Replaced assertion expectations from "Add Candidate", "Create Event", "Create Organization", and "Edit Organization" to "Tambah Kandidat", "Buat Event", "Buat Organisasi", and "Ubah Organisasi".
Testing:
- Ran `php artisan test` (53/53 tests passed successfully).
Review:
- All CRUD pages are now fully translated, and tests are verified clean.

Date: 2026-06-10
Type: FEATURE
Title: Implement unified Organization and Organizer User creation form
Status: DONE
Project Impact:
- Frontend (Admin): Added a new form section "Akun Penyelenggara Utama" to the organization creation form (`admin/organizations/create.blade.php`).
- Backend (Admin): Added rules in `StoreOrganizationRequest.php` to validate organizer user fields. Updated `store` in `OrganizationController.php` using a transactional block to create the organization and its primary user with the `organizer` role.
- Testing: Updated `OrganizationCrudTest.php` to supply organizer data in post request and assert that the user account was persisted.
Testing:
- Ran `php artisan test` (53/53 tests passed successfully with 160 assertions).
Review:
- Super Admins can now create organizations and their managers in one seamless step, preventing orphaned organizations.

Date: 2026-06-10
Type: FEATURE | SECURITY
Title: Restrict Organizer access to Organization and User CRUD and implement personal profile page
Status: DONE
Project Impact:
- Middleware: Added `EnsureSuperAdminRole` to block non-superadmins from accessing sensitive endpoints (returning 403).
- Routes: Protected Organization and User CRUD resources under `superadmin.role` middleware in `web.php`. Added profile GET/PUT endpoints.
- Controllers: Added `ProfileController.php` for personal name/email/password editing.
- Views: Created `admin/profile/edit.blade.php`. Modified `layouts/app.blade.php` sidebar to conditionalize menu items for "Organisasi" and "Pengguna", and linked header "Profil Saya" dropdown menu option to the profile edit route.
- Testing: Updated `OrganizationCrudTest.php` to assert 403 Forbidden for organizers on org endpoints. Created `ProfileFeatureTest.php` to assert profile functionality.
Testing:
- Ran `php artisan test` (57/57 tests passed successfully with 175 assertions).
Review:
- Organizers are now strictly isolated from other organizations and user management, and can safely manage their own password via the header profile dropdown.

Date: 2026-06-10
Type: FIX
Title: Fix candidate number rendering on voting ballot
Status: DONE
Project Impact:
- Frontend (Ballot): Replaced references to non-existent `$candidate->candidate_number` property with `$candidate->sort_order` in `resources/views/frontend/voting/ballot.blade.php`. This fixes the empty blue circles on the voting cards and correctly shows the candidate numbers.

Date: 2026-06-10
Type: FIX
Title: Fix ballot sub-header stickiness on mobile view for responsiveness
Status: DONE
Project Impact:
- Frontend (Ballot): Updated header container in `resources/views/frontend/voting/ballot.blade.php` to use `md:sticky md:top-20` instead of global sticky. This prevents the large sub-header from persistently covering the candidate cards when scrolling on small mobile screens.

Date: 2026-06-10
Type: FEATURE
Title: Event QR Code generation and Short URL redirects
Status: DONE
Project Impact:
- Routing: Added `/v/{event_id}` short route in `web.php` for voter redirects.
- Controller: Implemented `redirectShortUrl` in `VotingController.php` redirecting to the OTP request page.
- Frontend (Admin): Integrated a "QR Code" action button inside the event index table (`admin/events/index.blade.php`). Created a Bootstrap modal using `QRCode.js` library to display a 200x200 px QR code, a read-only short URL input with clipboard copy actions, and a PNG download link.
- Testing: Added `test_short_url_redirects_to_otp_request` in `VotingFeatureTest.php`.
Testing:
- Ran `php artisan test` (58/58 tests passed successfully with 177 assertions).
Review:
- Event organizers can now distribute a short link and scannable QR Code to voters directly from the admin dashboard.

Date: 2026-06-10
Type: FEATURE
Title: Customizable Event Short URLs & Collision Protection
Status: DONE
Project Impact:
- Database: Added unique, nullable `short_code` column to `events` table via migration.
- Backend: Added custom AJAX validation for `short_code` that prevents collisions with other events' IDs or duplicates.
- Frontend (Admin): Integrated an inline editor inside the QR modal that allows organizers to customize the short URL, dynamically regenerating the QR code and copyable link.
- Testing: Added feature test suite `EventShortCodeTest.php` and corrected assertion helper format to use `postJson`.
Testing:
- Ran automated test suite and verified 61/61 tests pass.
Review:
- Organizers can now easily customize, validate, and share clean URLs without duplicate conflicts.

Date: 2026-06-10
Type: REFACTOR | UI
Title: Removed Results sidebar menu and relocated to event list actions
Status: DONE
Project Impact:
- Frontend (Layout): Removed the standalone "Hasil" link from the sidebar menu to simplify navigation.
- Frontend (Admin): Placed a "Lihat Hasil" action button (with icon `bx-bar-chart-alt-2` and `btn-outline-info` theme) in the actions column of the event list table to view election results.
Testing:
- Checked route linking and UI page structure.
Review:
- The Results dashboard is now accessed cleanly on a per-event basis from the events control panel.

Date: 2026-06-10
Type: FEATURE | BUGFIX
Title: Manual Voter CRUD & Safe CSV Import
Status: DONE
Project Impact:
- Frontend (Admin): Added "Peserta Baru" creation page and "Ubah Peserta" edit page. Integrated manual creation and edit action buttons into the voter list index page.
- Routing: Expanded resource route '/admin/voters' to support full CRUD methods (excluding show).
- Validation: Added StoreVoterRequest and UpdateVoterRequest validation forms ensuring email uniqueness within event context.
- Backend (Service): Fixed a bug in the CSV voter importer where duplicate imports updated existing active voter details. Implemented a duplicate check that skips updating existing active records and safely restores soft-deleted ones.
Testing:
- Added 4 test cases to VoterCrudTest.php covering manual creation, manual editing, email uniqueness constraints, and CSV duplicate ignore checks.
- All tests pass (65/65 passed).
Review:
- Voters can now be manually created and edited directly in the dashboard, and CSV imports safely ignore duplicates without overwriting.

---

## 2026-06-10: Integrity Lock, Public Verification & Vote Hash Chain

### Fitur yang Diimplementasikan

#### 1. Event State Machine & Integrity Lock
- Tambah status constants (`draft`, `published`, `active`, `closed`, `archived`) pada `Event` model
- Tambah helper methods: `areCandidatesLocked()`, `areVotersLocked()`, `areSettingsLocked()`, `isLocked()`, `isReadOnly()`, `canTransitionTo()`
- Tambah `transitionStatus()` dan `assertEditable()` di `EventService`
- Tambah `updateStatus()` action di `EventController` (AJAX POST)
- Lock guard di `CandidateController`, `VoterController`
- Lock validation di `StoreCandidateRequest`, `UpdateCandidateRequest`, `StoreVoterRequest`, `UpdateVoterRequest`

#### 2. Vote Hash Chain (SHA-256)
- Buat `VoteHashService` — generate & verify SHA-256 hash chain
- Tambah migration `add_hash_chain_to_votes_table` — kolom `previous_hash`, `current_hash`, `vote_sequence`
- Update `VoteService::castVote()` — hash chain dibangun atomik dalam DB transaction
- Anonimitas tetap terjaga: hash tidak mengandung voter_id atau email

#### 3. Public Verification Page
- Route `GET /event/{slug}/verification` (tanpa auth)
- `VerificationController` — hanya return aggregate stats
- View `public/verification.blade.php` — desain standalone dengan Musyawara branding

#### 4. Artisan Command
- `php artisan vote:verify` — verifikasi hash chain semua event
- `php artisan vote:verify --event={id|slug}` — verifikasi satu event

#### 5. Admin UI Updates
- Events index: badge warna per status + tombol transisi AJAX + shield icon (verifikasi publik)
- Candidates index: lock banner + disable tombol jika terkunci
- Voters index: lock banner + disable tombol jika terkunci

### Test Results
- 65 tests passed, 0 failed
- Migration berhasil dijalankan

### Files Modified
- `app/Models/Event.php`
- `app/Models/Vote.php`
- `app/Services/VoteHashService.php` [NEW]
- `app/Services/VoteService.php`
- `app/Services/EventService.php`
- `app/Http/Controllers/Admin/EventController.php`
- `app/Http/Controllers/Admin/CandidateController.php`
- `app/Http/Controllers/Admin/VoterController.php`
- `app/Http/Controllers/Public/VerificationController.php` [NEW]
- `app/Console/Commands/VerifyVoteHashChain.php` [NEW]
- `app/Http/Requests/Admin/StoreCandidateRequest.php`
- `app/Http/Requests/Admin/UpdateCandidateRequest.php`
- `app/Http/Requests/Admin/StoreVoterRequest.php`
- `app/Http/Requests/Admin/UpdateVoterRequest.php`
- `database/migrations/2026_06_10_000002_add_hash_chain_to_votes_table.php` [NEW]
- `routes/web.php`
- `resources/views/admin/events/index.blade.php`
- `resources/views/admin/candidates/index.blade.php`
- `resources/views/admin/voters/index.blade.php`
- `resources/views/public/verification.blade.php` [NEW]

---

## 2026-06-10: Frontend Design v2 — Musyawara Liquid Glass SaaS

### Perubahan

Menerapkan DESIGN.md v2 ke seluruh halaman frontend.

#### Layout & Global
- `frontend/layouts/app.blade.php` — Font Fustat (800/700) + Inter (400/500/600), primary `#0084FF`, Tailwind config baru, ambient background glow (blur radial gradient), utility classes: `glass-card`, `btn-primary/secondary/ghost`, `input-field`, `animate-fade-in-up`
- `frontend/layouts/header.blade.php` — Liquid Glass sticky navbar: `backdrop-filter:blur(50px)`, `rgba(255,255,255,0.3)`, `border-radius:16px`, `inset box-shadow`, CTA dengan arrow icon, mobile menu
- `frontend/layouts/footer.blade.php` — Dark `#0F172A`, Fustat heading, clean minimal style

#### Home Page
- Hero 2-kolom: headline besar (Fustat 72px), badge pill, rating ★★★★★, CTA primary+secondary
- Glassy Orb visual: `hue-rotate(-55deg) saturate(250%) brightness(1.2)`, floating cards verifikasi + anonimitas
- Statistics section: stat-number Fustat 42px
- Features 3x2 glass cards dengan hover lift
- Security section: integrity score visual + security flow timeline
- How It Works: 6 steps dengan step-circle #0084FF
- Active Events: glass event cards
- FAQ: accordion dengan glass background

#### OTP Pages
- `otp/request.blade.php` — glass card, Fustat heading, #0084FF icon, email input center
- `otp/verify.blade.php` — glass card, OTP input besar (Fustat, letter-spacing 0.6em), success green icon

#### Voting Pages
- `voting/ballot.blade.php` — glass candidate cards dengan hover lift, sticky ballot header dengan blur, glass profile modal & confirm modal
- `voting/success.blade.php` — premium glass success card, success icon glow, reference number display

### Test Results
- 65 tests passed, 0 failed (tidak ada breaking change)

Date: 2026-06-10
Type: REFACTOR | UI
Title: Adjusted event lock guards for editing and deletion
Status: DONE
Project Impact:
- Backend: Updated edit and destroy actions in EventController to restrict changes using areSettingsLocked() instead of isLocked(). This allows editing and deleting events that are in both draft and published status (before voting has started).
- Frontend: Adjusted the delete button conditional check in resources/views/admin/events/index.blade.php to be visible when the event is not settings locked (draft/published).
- Testing: Added 3 new test cases in EventCrudTest.php covering deletion of published events, and ensuring active events block deletion and edit requests. All 68 tests pass.

