v0.12.0 - A working Settings page. It shows the current engine settings and lets BLACK and up start or pause the engine, manage competition placeholders, and export or import the competition's configuration. WHITE can view it but not change anything. Import and Reset only show for ADMIN - Export to a ZIP. Staff pick any of checks, graders, injects, IR, users and settings, and `POST /api/settings/export` returns `hermes-settings.zip` with one TOML file per section. Inject and IR exports include their PDFs. Submissions are never exported. Requires BLACK - Import from that ZIP. `POST /api/settings/bulk-import` now reads `graders.toml`, `inject.toml` and `ir.toml` along with checks, users and settings, and picks up the inject and IR PDFs from their `document_path` entries. Each section has its own destructive flag (`destructiveChecks`, `destructiveGraders`, `destructiveInjects`, `destructiveIR`, `destructiveUsers`, `destructiveSettings`) that replaces existing data instead of adding to it. Replacing graders fails with a 409 while reviews or submissions still reference them. Replacing injects deletes their submissions and reviews. Replacing IR deletes all IR reports and reviews so a rubric that has already been graded against can change - The users export carries each account's bcrypt hash, and import restores it as is. An import rejects a user with a missing or invalid `hashed_password` - Engine reset. `POST /api/settings/reset` deletes score adjustments, current team scores, team variable overrides, inject submissions, rounds, the round ledger and round scores, then sets the engine to PAUSED. It asks for confirmation on the page. Requires ADMIN - List variables. A check variable can now hold a list of values instead of one. Each round it hands the check one item, walking the list in order, or a random item when `randomize` is set. Teams can override a list with their own items from the blue team check page. When a list variable is secret, every item in it is scrubbed from round output - `variable_type`, `default_items` and `randomize` on the check variable endpoints, and `items` on a team's own variable writes. `POST /api/checks` takes a `variables` JSON array, so a check and its variables are created in one request and no round can run the check before its variables exist - Multiple accepted outputs. HTTP, FTP, SMB, SSH and WinRM checks gain two match types, "equals one of" (`exactListMatch`) and "contains one of" (`substringListMatch`), which pass when the output matches any entry in the new `accepted_outputs` list. Telnet gains only "contains one of". SSH, Telnet and WinRM checks get a `match_type` field for this, defaulting to the comparison they used before - A reusable list editor in the frontend for entering list items one at a time - Bruno requests for settings export, list variables, randomized list variables, a team's list overrides, and a chain check - Icons on several admin buttons - Almost every frontend API hook now goes through `apiFetch`, replacing each hook's own fetch and error handling - The checks export and import round-trip variables, including their type, list items and `randomize`. A `checks.toml` from before this release imports its variables as strings - The round number comes from the latest round in the database instead of a counter the scheduler keeps in memory, so an engine reset starts back at round 1. An ABORTED round is retried under its own number - Importing checks no longer fails with "conn busy", and chain checks import correctly - A bulk import without a zip file returns a 400 instead of panicking on the missing upload - The scoreboard fits every team on screen. Rows and columns share the available space down to a minimum size, and the panel scrolls past that, in the default, template and irsec-2026 themes