feat(patterns,api): pattern OTA, graceful shutdown, driver delivery updates

- Pattern controller/UI and presets patterns tab for OTA to Wi-Fi drivers
- Device controller extensions; driver_delivery chunk handling
- main: SIGINT/SIGTERM shutdown, TCP/UDP server close coordination
- Submodule led-driver: Wi-Fi default transport, lazy espnow import, dynamic patterns

Made-with: Cursor
This commit is contained in:
pi
2026-04-11 15:10:23 +12:00
parent 7179b6531e
commit e67de6215a
9 changed files with 1031 additions and 67 deletions

View File

@@ -458,22 +458,28 @@ body.preset-ui-run .edit-mode-only {
.n-param-group {
display: flex;
align-items: center;
gap: 0.5rem;
gap: 0.75rem;
justify-content: space-between;
}
.n-param-group label {
min-width: 40px;
flex: 1;
min-width: 0;
font-weight: 500;
}
.n-input {
flex: 1;
flex: 0 0 var(--n-input-width, 5ch);
width: var(--n-input-width, 5ch);
max-width: 100%;
box-sizing: border-box;
padding: 0.5rem;
background-color: #3a3a3a;
color: white;
border: 1px solid #4a4a4a;
border-radius: 4px;
font-size: 1rem;
text-align: right;
}
.n-input:focus {
@@ -1251,6 +1257,48 @@ body.preset-ui-run .edit-mode-only {
flex: 1;
display: flex;
flex-direction: column;
align-items: flex-end;
}
.preset-editor-field label {
align-self: stretch;
}
.preset-editor-field input[type="number"] {
width: var(--n-input-width, 5ch);
max-width: 100%;
box-sizing: border-box;
text-align: right;
}
/* Pattern editor: numeric metadata row */
#pattern-editor-modal input[type="number"] {
width: var(--n-input-width, 5ch);
max-width: 100%;
box-sizing: border-box;
text-align: right;
}
/* Pattern editor: human-readable n labels (text), full width */
#pattern-editor-modal .n-params-grid {
grid-template-columns: 1fr;
}
#pattern-editor-modal .n-param-group:has(.pattern-n-readable-input) {
justify-content: stretch;
}
#pattern-editor-modal .pattern-n-readable-input {
flex: 1 1 auto;
width: 100%;
min-width: 0;
text-align: left;
}
@supports not selector(:has(*)) {
#pattern-editor-modal #pattern-create-n-section .n-param-group {
justify-content: stretch;
}
}
/* Settings modal */