Palette calibration: precise hex/RGB inputs instead of a color picker
Build and push server image / build-and-push (push) Successful in 41s

A native <input type="color"> swatch can't be typed into precisely --
no way to enter an exact measured value. Replaced with a small table:
a read-only preview swatch, a hex text field, and three 0-255 number
fields (R/G/B) per ink color, kept in sync live in both directions
(editing hex updates R/G/B and the swatch; editing any of R/G/B updates
hex and the swatch). Hex stays the field actually read at save time --
the server-side validation (#rrggbb via hex_to_rgb) is unchanged, this
is a client-side-only swap of the input widget.
This commit is contained in:
2026-07-22 01:26:03 -04:00
parent 5b11f2accb
commit e802882fc1
3 changed files with 104 additions and 34 deletions
+24 -8
View File
@@ -120,14 +120,30 @@
aren't published. Tune them by comparing a rendered photo against
the physical panel; different panel units can vary enough to be
worth calibrating per frame.</p>
<div class="palette-grid">
{% set current_hex = palette_to_hex(frame.palette_rgb or default_palette_rgb) %}
{% for label in palette_labels %}
<label class="palette-swatch">
<input type="color" id="palette_{{ loop.index0 }}" value="{{ current_hex[loop.index0] }}">
{{ label }}
</label>
{% endfor %}
<div class="palette-table-wrap">
<table class="palette-table">
<thead><tr><th></th><th>Color</th><th>Hex</th><th>R</th><th>G</th><th>B</th></tr></thead>
<tbody>
{% set current_palette = frame.palette_rgb or default_palette_rgb %}
{% set current_hex = palette_to_hex(current_palette) %}
{% for label in palette_labels %}
<tr>
<td><span class="palette-swatch-preview" data-index="{{ loop.index0 }}"
style="background: {{ current_hex[loop.index0] }};"></span></td>
<td>{{ label }}</td>
<td><input type="text" class="palette-hex" id="palette_{{ loop.index0 }}" data-index="{{ loop.index0 }}"
value="{{ current_hex[loop.index0] }}" maxlength="7" pattern="#[0-9a-fA-F]{6}"
spellcheck="false" autocomplete="off"></td>
<td><input type="number" class="palette-rgb palette-r" data-index="{{ loop.index0 }}"
min="0" max="255" value="{{ current_palette[loop.index0][0] }}"></td>
<td><input type="number" class="palette-rgb palette-g" data-index="{{ loop.index0 }}"
min="0" max="255" value="{{ current_palette[loop.index0][1] }}"></td>
<td><input type="number" class="palette-rgb palette-b" data-index="{{ loop.index0 }}"
min="0" max="255" value="{{ current_palette[loop.index0][2] }}"></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<button type="button" class="secondary" id="palette-save">Save</button>
<button type="button" class="secondary" id="palette-reset">Reset to defaults</button>