layout tweaks

This commit is contained in:
javl
2026-08-18 09:26:39 +02:00
parent 1845f4ea81
commit d21cc62c34
3 changed files with 99 additions and 81 deletions
+53 -38
View File
@@ -39,6 +39,7 @@
/* Fonts */ /* Fonts */
--font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif; --font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
--font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
--font-size: 14px;
} }
* { * {
@@ -49,7 +50,7 @@
body { body {
font-family: var(--font-body); font-family: var(--font-body);
font-size: 16px; font-size: var(--font-size);
line-height: 24px; line-height: 24px;
color: var(--on-background); color: var(--on-background);
background-color: var(--background); background-color: var(--background);
@@ -67,7 +68,7 @@ body {
} }
.topnav-inner { .topnav-inner {
max-width: 1400px; max-width: 1200px;
margin: auto; margin: auto;
height: 64px; height: 64px;
padding: 0 var(--space-6); padding: 0 var(--space-6);
@@ -96,7 +97,7 @@ body {
.topnav-links a { .topnav-links a {
color: var(--secondary); color: var(--secondary);
font-weight: 500; font-weight: 500;
font-size: 14px; font-size: var(--font-size);
text-decoration: underline; text-decoration: underline;
} }
@@ -142,7 +143,7 @@ body {
.layout { .layout {
display: flex; display: flex;
gap: var(--space-7); gap: var(--space-7);
max-width: 1400px; max-width: 1200px;
margin: auto; margin: auto;
padding: var(--space-7) var(--space-6) var(--space-9); padding: var(--space-7) var(--space-6) var(--space-9);
align-items: flex-start; align-items: flex-start;
@@ -353,6 +354,7 @@ code {
.table-row { .table-row {
display: table-row; display: table-row;
width: 100%; width: 100%;
border-bottom: 1px solid var(--border-subtle);
} }
.table-cell { .table-cell {
@@ -370,66 +372,71 @@ code {
width: 70%; width: 70%;
} }
.table-cell:first-child label { .table-cell:first-child > label {
font-family: var(--font-mono); font-family: var(--font-mono);
font-size: 13px; font-size: 13px;
font-weight: 500; /* font-weight: 500; */
color: var(--primary); color: var(--primary);
} }
.table-cell:last-child label { .table-cell:last-child > label {
margin-right: var(--space-2); margin-right: var(--space-2);
color: var(--on-surface-variant); color: var(--on-surface-variant);
font-size: 14px; font-size: var(--font-size);
} }
.nested-table { .nested-table {
margin: 0; margin: 0;
} }
/* ---- Settings grid (step 2) ---- /* ---- Settings rows (step 2) ----
2-column min-width forces a predictable 2-up (or 1-up) grid instead of Single-column label-left / value-right rows, hairline-divided. Denser
auto-fitting 3 columns, which paired short/tall fields at random and than the old 2-up grid, and keeps each setting's note attached under
left ragged whitespace between rows. */ its label instead of floating below the control in the value column. */
.settings-grid { .settings-grid {
display: grid; display: block;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: var(--space-6) var(--space-7);
}
.settings-grid.table {
margin: var(--space-2) 0 0; margin: var(--space-2) 0 0;
} }
.settings-grid .table-row { .settings-grid .table-row {
display: flex; display: flex;
flex-direction: column; align-items: flex-start;
gap: var(--space-2); gap: var(--space-6);
padding: var(--space-1) 0;
border-top: 1px solid var(--border-subtle);
} }
.settings-grid .table-row.full-row { .settings-grid .table-row:first-child {
grid-column: 1 / -1; border-top: none;
padding-top: 0;
} }
.settings-grid .table-cell { .settings-grid .table-cell {
display: block;
padding: 0; padding: 0;
} }
.settings-grid .table-cell:first-child { .settings-grid .table-cell:first-child {
width: auto; width: 34%;
padding-right: 0; flex-shrink: 0;
} }
.settings-grid .table-cell:last-child { .settings-grid .table-cell:last-child {
width: auto; width: auto;
flex: 1;
min-width: 0;
}
.settings-grid .table-cell:first-child .note {
font-size: 13px;
line-height: 1.45em;
margin: var(--space-1) 0 0;
} }
.nested-table .table-cell { .nested-table .table-cell {
color: var(--text-muted); color: var(--text-muted);
font-size: 0.9em; font-size: 0.9em;
width: 200px; /* width: 200px; */
} }
#format-caption-container { #format-caption-container {
@@ -442,14 +449,14 @@ code {
/* Reserve space for the tallest combination (Adafruit GFX shows both its /* Reserve space for the tallest combination (Adafruit GFX shows both its
own fields and the Arduino identifier fields) so the Generate/Copy/ own fields and the Arduino identifier fields) so the Generate/Copy/
Download buttons don't jump around when switching output format. */ Download buttons don't jump around when switching output format. */
min-height: 278px; /* min-height: 278px; */
transition: min-height 0.15s ease; transition: min-height 0.15s ease;
} }
#format-caption-container div { #format-caption-container div {
color: var(--text-muted); color: var(--text-muted);
display: none; display: none;
font-size: 14px; font-size: var(--font-size);
line-height: 1.5em; line-height: 1.5em;
padding: var(--space-2) 0 var(--space-4); padding: var(--space-2) 0 var(--space-4);
width: 100%; width: 100%;
@@ -459,7 +466,7 @@ code {
.note { .note {
color: var(--text-muted); color: var(--text-muted);
font-size: 14px; font-size: var(--font-size);
line-height: 1.5em; line-height: 1.5em;
margin: var(--space-1) 0; margin: var(--space-1) 0;
} }
@@ -468,9 +475,9 @@ code {
display: none; display: none;
} }
.upload-note { /* .upload-note {
max-width: 320px; max-width: 320px;
} } */
#continue-note { #continue-note {
display: none; display: none;
@@ -494,7 +501,7 @@ input[type="number"],
textarea, textarea,
select { select {
font-family: var(--font-body); font-family: var(--font-body);
font-size: 14px; font-size: var(--font-size);
color: var(--on-surface-variant); color: var(--on-surface-variant);
background: var(--surface-container); background: var(--surface-container);
border: 1px solid transparent; border: 1px solid transparent;
@@ -530,13 +537,13 @@ input[type="radio"] {
min-width: 360px; min-width: 360px;
width: 100%; width: 100%;
font-family: var(--font-mono); font-family: var(--font-mono);
font-size: 14px; font-size: var(--font-size);
line-height: 22px; line-height: 22px;
resize: vertical; resize: vertical;
} }
#text-input-error { #text-input-error {
color: var(--error); color: var(--error);
font-size: 14px; font-size: var(--font-size);
margin-top: var(--space-2); margin-top: var(--space-2);
display: none; display: none;
} }
@@ -558,7 +565,7 @@ input[type="radio"] {
.text-input-size { .text-input-size {
margin: var(--space-2) 0; margin: var(--space-2) 0;
color: var(--on-surface-variant); color: var(--on-surface-variant);
font-size: 14px; font-size: var(--font-size);
} }
.size-input { .size-input {
@@ -577,7 +584,10 @@ input[type="radio"] {
} }
.sub-field-label { .sub-field-label {
min-width: 160px; min-width: 200px;
font-family: var(--font-mono);
font-size: 13px;
color: var(--primary);
} }
.glyph-input { .glyph-input {
@@ -618,7 +628,7 @@ input[type="file"] {
color: var(--on-surface-variant); color: var(--on-surface-variant);
/* border: 2px dashed var(--outline-variant); */ /* border: 2px dashed var(--outline-variant); */
border-radius: var(--radius-lg); border-radius: var(--radius-lg);
font-size: 14px; font-size: var(--font-size);
padding: 16px 20px; padding: 16px 20px;
margin: var(--space-2) 0 0; margin: var(--space-2) 0 0;
cursor: pointer; cursor: pointer;
@@ -778,7 +788,7 @@ input[type="file"]::file-selector-button {
border: 1px solid var(--on-surface-variant); border: 1px solid var(--on-surface-variant);
border-radius: var(--radius-xl); border-radius: var(--radius-xl);
font-family: var(--font-mono); font-family: var(--font-mono);
font-size: 14px; font-size: var(--font-size);
line-height: 22px; line-height: 22px;
padding: 20px; padding: 20px;
resize: vertical; resize: vertical;
@@ -870,6 +880,11 @@ input[type="file"]::file-selector-button {
.table-cell:first-child { .table-cell:first-child {
padding-bottom: 0; padding-bottom: 0;
} }
.settings-grid .table-row {
flex-direction: column;
gap: var(--space-1);
}
} }
/* ---- Dark theme ---- */ /* ---- Dark theme ---- */
+45 -42
View File
@@ -85,7 +85,7 @@
<section class="sub-section"> <section class="sub-section">
<div class="table settings-grid"> <div class="table settings-grid">
<div class="table-row full-row"> <div class="table-row">
<div class="table-cell"><label>Canvas size(s): </label></div> <div class="table-cell"><label>Canvas size(s): </label></div>
<div class="table-cell"> <div class="table-cell">
<ul id="image-size-settings"></ul> <ul id="image-size-settings"></ul>
@@ -99,7 +99,10 @@
</div> </div>
<div class="table-row"> <div class="table-row">
<div class="table-cell"><label>Canvas background color:</label></div> <div class="table-cell">
<label>Canvas background color:</label>
<div class="note">Used for parts of the canvas that are not covered by your image.</div>
</div>
<div class="table-cell"> <div class="table-cell">
<input id="backgroundColorWhite" type="radio" name="backgroundColor" value="white" checked="checked" onchange="updateRadio('backgroundColor')"/> <input id="backgroundColorWhite" type="radio" name="backgroundColor" value="white" checked="checked" onchange="updateRadio('backgroundColor')"/>
<label for="backgroundColorWhite" class="smallLabel">White</label> <label for="backgroundColorWhite" class="smallLabel">White</label>
@@ -107,43 +110,11 @@
<label for="backgroundColorBlack" class="smallLabel">Black</label> <label for="backgroundColorBlack" class="smallLabel">Black</label>
<input id="backgroundColorTransparent" type="radio" name="backgroundColor" value="transparent" onchange="updateRadio('backgroundColor')"/> <input id="backgroundColorTransparent" type="radio" name="backgroundColor" value="transparent" onchange="updateRadio('backgroundColor')"/>
<label for="backgroundColorTransparent" class="smallLabel">Transparent</label> <label for="backgroundColorTransparent" class="smallLabel">Transparent</label>
<div class="note">
<i>Used for parts of the canvas that are not covered by your image.</i>
</div>
</div>
</div>
<div class="table-row">
<div class="table-cell"><label for="invertColors">Invert image colors</label></div>
<div class="table-cell">
<input id="invertColors" type="checkbox" onchange="updateBoolean('invertColors')" />
</div> </div>
</div> </div>
<div class="table-row"> <div class="table-row">
<div class="table-cell"><label for="ditheringMode">Dithering: </label></div> <div class="table-cell"><label for="scale">Image Scaling:</label></div>
<div class="table-cell">
<select id="ditheringMode" onchange="updateInteger('ditheringMode')">
<option value="2">Floyd-Steinberg</option>
<option value="0">Binary</option>
<option value="1">Bayer</option>
<option value="3">Atkinson</option>
</select>
</div>
</div>
<div class="table-row">
<div class="table-cell"><label for="ditheringThreshold">Brightness / alpha threshold: </label></div>
<div class="table-cell">
<input id="ditheringThreshold" class="size-input" type="number" min="0" max="255" name="ditheringThreshold" oninput="updateInteger('ditheringThreshold')" value="128"/>
<div class="note">
<i>0 - 255; if the brightness of a pixel is above the given level the pixel becomes white, otherwise they become black. When using alpha, opaque and transparent are used instead. Default is 128.</i>
</div>
</div>
</div>
<div class="table-row">
<div class="table-cell"><label for="scale">Scaling:</label></div>
<div class="table-cell"> <div class="table-cell">
<select id="scale" name="scale" onchange="updateInteger('scale')"> <select id="scale" name="scale" onchange="updateInteger('scale')">
<option value="1">original size</option> <option value="1">original size</option>
@@ -156,15 +127,46 @@
</div> </div>
<div class="table-row"> <div class="table-row">
<div class="table-cell"><label>Center image:</label></div> <div class="table-cell"><label for="invertColors">Invert image colors</label></div>
<div class="table-cell">
<input id="invertColors" type="checkbox" onchange="updateBoolean('invertColors')" /> <label for="invertColors">Invert</label>
</div>
</div>
<div class="table-row">
<div class="table-cell"><label for="ditheringMode">Dithering: </label>
<div class="note">Different dithering algorithms produce different results.</div>
</div>
<div class="table-cell">
<select id="ditheringMode" onchange="updateInteger('ditheringMode')">
<option value="0">Binary</option>
<option value="1">Bayer</option>
<option value="2">Floyd-Steinberg</option>
<option value="3">Atkinson</option>
</select>
</div>
</div>
<div class="table-row">
<div class="table-cell">
<label for="ditheringThreshold">Brightness / alpha threshold: </label>
<div class="note">0 - 255; if the brightness of a pixel is above the given level the pixel becomes white, otherwise they become black. When using alpha, opaque and transparent are used instead. Default is 128.</div>
</div>
<div class="table-cell">
<input id="ditheringThreshold" class="size-input" type="number" min="0" max="255" name="ditheringThreshold" oninput="updateInteger('ditheringThreshold')" value="128"/>
</div>
</div>
<div class="table-row">
<div class="table-cell">
<label>Center image:</label>
<div class="note">Centering the image only works when using a canvas larger than the original image.</div>
</div>
<div class="table-cell"> <div class="table-cell">
<input id="centerHorizontally" type="checkbox" onchange="updateBoolean('centerHorizontally')" /> <input id="centerHorizontally" type="checkbox" onchange="updateBoolean('centerHorizontally')" />
<label for="centerHorizontally">horizontally</label> <label for="centerHorizontally">horizontally</label>
<input id="centerVertically" type="checkbox" onchange="updateBoolean('centerVertically')" /> <input id="centerVertically" type="checkbox" onchange="updateBoolean('centerVertically')" />
<label for="centerVertically">vertically</label> <label for="centerVertically">vertically</label>
<div class="note">
<i>Centering the image only works when using a canvas larger than the original image.</i>
</div>
</div> </div>
</div> </div>
@@ -288,7 +290,7 @@
<div class="table-cell"><label for="esp32Format">ESP32 formatting:</label></div> <div class="table-cell"><label for="esp32Format">ESP32 formatting:</label></div>
<div class="table-cell"> <div class="table-cell">
<input id="esp32Format" type="checkbox" onchange="updateBoolean('esp32Format')" /> <input id="esp32Format" type="checkbox" onchange="updateBoolean('esp32Format')" />
<i class="note">Uses <code>uint8_t</code> instead of <code>unsigned char</code> and drops <code>PROGMEM</code>, which is a no-op on ESP32.</i> <i class="note">Use <code>uint8_t</code> instead of <code>unsigned char</code> and drops <code>PROGMEM</code>, which is a no-op on ESP32.</i>
</div> </div>
</div> </div>
</div> </div>
@@ -323,10 +325,11 @@
<i class="note">Set to 0 to wrap using the image's width instead, e.g. an 8px wide image adds a newline every 8th byte.</i> <i class="note">Set to 0 to wrap using the image's width instead, e.g. an 8px wide image adds a newline every 8th byte.</i>
</div> </div>
<div class="sub-field"> <div class="sub-field">
<label for="showAsciiPreview" class="sub-field-label">Ascii preview:</label>
<input id="showAsciiPreview" type="checkbox" onchange="updateBoolean('showAsciiPreview')"> <input id="showAsciiPreview" type="checkbox" onchange="updateBoolean('showAsciiPreview')">
<label for="showAsciiPreview">Show ascii preview behind output</label> <i class="note">Add an ascii-art comment after each row of bytes. Forces one image row per output line, regardless of "Bytes per row".</i>
<i class="note">Adds a dot/hash ascii-art comment after each row of bytes. Forces one image row per output line, regardless of "Bytes per row".</i>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
+1 -1
View File
@@ -16,7 +16,7 @@ const settings = {
drawMode: 'horizontal', drawMode: 'horizontal',
prefix: '0x', prefix: '0x',
ditheringThreshold: 128, ditheringThreshold: 128,
ditheringMode: 2, ditheringMode: 0,
outputFormat: 'plain', outputFormat: 'plain',
separator: ', ', separator: ', ',
outputComments: true, outputComments: true,