diff --git a/tools/editor/common/dtf.js b/tools/editor/common/dtf.js index 04c87574..ecd1144a 100644 --- a/tools/editor/common/dtf.js +++ b/tools/editor/common/dtf.js @@ -144,10 +144,12 @@ const DTF = (() => { for (let i = 0; i < width * height; i++) { const o = i * 4; switch (format) { - case FORMAT_ALPHA: - out[o] = out[o + 1] = out[o + 2] = redAsAlpha ? src[o] : src[o + 3]; - out[o + 3] = 255; + case FORMAT_ALPHA: { + const v = redAsAlpha ? src[o] : src[o + 3]; + out[o] = out[o + 1] = out[o + 2] = v; + out[o + 3] = v; // use value as canvas alpha so background shows through transparent areas break; + } case FORMAT_RGB: out[o] = src[o]; out[o + 1] = src[o + 1]; diff --git a/tools/editor/styles/components/swatches.css b/tools/editor/styles/components/bg-swatches.css similarity index 100% rename from tools/editor/styles/components/swatches.css rename to tools/editor/styles/components/bg-swatches.css diff --git a/tools/editor/styles/components/buttons.css b/tools/editor/styles/components/btn.css similarity index 95% rename from tools/editor/styles/components/buttons.css rename to tools/editor/styles/components/btn.css index b3ce4bfe..a6f72bcd 100644 --- a/tools/editor/styles/components/buttons.css +++ b/tools/editor/styles/components/btn.css @@ -1,4 +1,4 @@ -/* Component – Buttons */ +/* Component – Button */ .btn { display: block; diff --git a/tools/editor/styles/components/control-row.css b/tools/editor/styles/components/control-row.css new file mode 100644 index 00000000..8ffa92f7 --- /dev/null +++ b/tools/editor/styles/components/control-row.css @@ -0,0 +1,13 @@ +/* Component – Control row */ + +.control-row { + display: flex; + align-items: center; + gap: 0.5rem; + font-size: 0.875rem; +} + +.control-row label { + color: var(--text-muted); + min-width: 44px; +} diff --git a/tools/editor/styles/components/empty-state.css b/tools/editor/styles/components/empty-state.css new file mode 100644 index 00000000..5dd12cab --- /dev/null +++ b/tools/editor/styles/components/empty-state.css @@ -0,0 +1,13 @@ +/* Component – Empty state */ + +.empty-state { + border-style: dashed; + padding: 3rem; + text-align: center; + color: var(--text-muted); +} + +.empty-state p { + margin-top: 0.5rem; + font-size: 0.875rem; +} diff --git a/tools/editor/styles/components/file-info.css b/tools/editor/styles/components/file-info.css deleted file mode 100644 index d9d14399..00000000 --- a/tools/editor/styles/components/file-info.css +++ /dev/null @@ -1,43 +0,0 @@ -/* Component – File info and load area */ - -.file-name { - font-size: 0.775rem; - color: var(--text-muted); - word-break: break-all; - line-height: 1.4; -} - -.info-table { - width: 100%; - border-collapse: collapse; - font-size: 0.8rem; -} - -.info-table td { - padding: 0.15rem 0; - vertical-align: top; -} - -.info-table td:first-child { - color: var(--text-muted); - width: 50px; - font-size: 0.75rem; - padding-right: 0.75rem; -} - -.load-area { - border: 1px dashed var(--border); - border-radius: var(--radius); - padding: 0.6rem; - text-align: center; - cursor: pointer; - font-size: 0.825rem; - color: var(--text-muted); - transition: border-color var(--speed), color var(--speed); - line-height: 1.5; -} - -.load-area:hover, -.load-area.drag-over { - color: var(--text); -} diff --git a/tools/editor/styles/components/file-name.css b/tools/editor/styles/components/file-name.css new file mode 100644 index 00000000..3f45daf7 --- /dev/null +++ b/tools/editor/styles/components/file-name.css @@ -0,0 +1,8 @@ +/* Component – File name */ + +.file-name { + font-size: 0.775rem; + color: var(--text-muted); + word-break: break-all; + line-height: 1.4; +} diff --git a/tools/editor/styles/components/info-table.css b/tools/editor/styles/components/info-table.css new file mode 100644 index 00000000..59545517 --- /dev/null +++ b/tools/editor/styles/components/info-table.css @@ -0,0 +1,19 @@ +/* Component – Info table */ + +.info-table { + width: 100%; + border-collapse: collapse; + font-size: 0.8rem; +} + +.info-table td { + padding: 0.15rem 0; + vertical-align: top; +} + +.info-table td:first-child { + color: var(--text-muted); + width: 50px; + font-size: 0.75rem; + padding-right: 0.75rem; +} diff --git a/tools/editor/styles/components/load-area.css b/tools/editor/styles/components/load-area.css new file mode 100644 index 00000000..b5e0dff1 --- /dev/null +++ b/tools/editor/styles/components/load-area.css @@ -0,0 +1,18 @@ +/* Component – Load area */ + +.load-area { + border: 1px dashed var(--border); + border-radius: var(--radius); + padding: 0.6rem; + text-align: center; + cursor: pointer; + font-size: 0.825rem; + color: var(--text-muted); + transition: border-color var(--speed), color var(--speed); + line-height: 1.5; +} + +.load-area:hover, +.load-area.drag-over { + color: var(--text); +} diff --git a/tools/editor/styles/components/panel.css b/tools/editor/styles/components/panel-inputs.css similarity index 64% rename from tools/editor/styles/components/panel.css rename to tools/editor/styles/components/panel-inputs.css index 06180413..64d5f802 100644 --- a/tools/editor/styles/components/panel.css +++ b/tools/editor/styles/components/panel-inputs.css @@ -1,36 +1,4 @@ -/* Component – Tool panel (sidebar) */ - -.tool-panel { - width: 210px; - flex-shrink: 0; - overflow: hidden; - display: flex; - flex-direction: column; -} - -.panel-section { - padding: 0.875rem; - display: flex; - flex-direction: column; - gap: 0.5rem; - border-bottom: 1px solid var(--border); -} - -.panel-section:last-child { - border-bottom: none; -} - -.control-row { - display: flex; - align-items: center; - gap: 0.5rem; - font-size: 0.875rem; -} - -.control-row label { - color: var(--text-muted); - min-width: 44px; -} +/* Component – Panel form inputs */ .tool-panel select { width: 100%; diff --git a/tools/editor/styles/components/panel-section.css b/tools/editor/styles/components/panel-section.css new file mode 100644 index 00000000..d39ccd24 --- /dev/null +++ b/tools/editor/styles/components/panel-section.css @@ -0,0 +1,13 @@ +/* Component – Panel section */ + +.panel-section { + padding: 0.875rem; + display: flex; + flex-direction: column; + gap: 0.5rem; + border-bottom: 1px solid var(--border); +} + +.panel-section:last-child { + border-bottom: none; +} diff --git a/tools/editor/styles/components/preview-empty.css b/tools/editor/styles/components/preview-empty.css new file mode 100644 index 00000000..ba5ae4f7 --- /dev/null +++ b/tools/editor/styles/components/preview-empty.css @@ -0,0 +1,14 @@ +/* Component – Preview empty state */ + +.preview-empty { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + color: var(--text-muted); + font-size: 0.875rem; + text-align: center; + white-space: nowrap; + user-select: none; + pointer-events: none; +} diff --git a/tools/editor/styles/components/preview-scroll.css b/tools/editor/styles/components/preview-scroll.css new file mode 100644 index 00000000..f9539b12 --- /dev/null +++ b/tools/editor/styles/components/preview-scroll.css @@ -0,0 +1,16 @@ +/* Component – Preview scroll */ + +.preview-scroll { + width: 100%; + display: flex; + align-items: center; + justify-content: center; + padding: 1.5rem; +} + +.preview-scroll canvas { + image-rendering: pixelated; + image-rendering: crisp-edges; + display: block; + max-width: none; +} diff --git a/tools/editor/styles/components/preview.css b/tools/editor/styles/components/preview.css deleted file mode 100644 index c5b7a8de..00000000 --- a/tools/editor/styles/components/preview.css +++ /dev/null @@ -1,36 +0,0 @@ -/* Component – Preview area */ - -.tool-preview { - flex: 1; - position: relative; - min-height: 300px; - transition: border-color var(--speed); -} - -.preview-scroll { - width: 100%; - display: flex; - align-items: center; - justify-content: center; - padding: 1.5rem; -} - -.preview-scroll canvas { - image-rendering: pixelated; - image-rendering: crisp-edges; - display: block; - max-width: none; -} - -.preview-empty { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - color: var(--text-muted); - font-size: 0.875rem; - text-align: center; - white-space: nowrap; - user-select: none; - pointer-events: none; -} diff --git a/tools/editor/styles/components/header.css b/tools/editor/styles/components/site-header.css similarity index 100% rename from tools/editor/styles/components/header.css rename to tools/editor/styles/components/site-header.css diff --git a/tools/editor/styles/components/cards.css b/tools/editor/styles/components/tool-card.css similarity index 63% rename from tools/editor/styles/components/cards.css rename to tools/editor/styles/components/tool-card.css index 1f5e6efe..c7d1fc17 100644 --- a/tools/editor/styles/components/cards.css +++ b/tools/editor/styles/components/tool-card.css @@ -1,4 +1,4 @@ -/* Component – Tool cards and empty state */ +/* Component – Tool card */ .tool-card { padding: 1.25rem; @@ -24,15 +24,3 @@ font-size: 0.85rem; line-height: 1.5; } - -.empty-state { - border-style: dashed; - padding: 3rem; - text-align: center; - color: var(--text-muted); -} - -.empty-state p { - margin-top: 0.5rem; - font-size: 0.875rem; -} diff --git a/tools/editor/styles/components/tool-panel.css b/tools/editor/styles/components/tool-panel.css new file mode 100644 index 00000000..87b324b4 --- /dev/null +++ b/tools/editor/styles/components/tool-panel.css @@ -0,0 +1,9 @@ +/* Component – Tool panel */ + +.tool-panel { + width: 210px; + flex-shrink: 0; + overflow: hidden; + display: flex; + flex-direction: column; +} diff --git a/tools/editor/styles/components/tool-preview.css b/tools/editor/styles/components/tool-preview.css new file mode 100644 index 00000000..51d74d24 --- /dev/null +++ b/tools/editor/styles/components/tool-preview.css @@ -0,0 +1,8 @@ +/* Component – Tool preview */ + +.tool-preview { + flex: 1; + position: relative; + min-height: 300px; + transition: border-color var(--speed); +} diff --git a/tools/editor/styles/components/warnings.css b/tools/editor/styles/components/warning-list.css similarity index 80% rename from tools/editor/styles/components/warnings.css rename to tools/editor/styles/components/warning-list.css index 59e5fc88..a175f192 100644 --- a/tools/editor/styles/components/warnings.css +++ b/tools/editor/styles/components/warning-list.css @@ -1,8 +1,4 @@ -/* Component – Warnings panel */ - -.warnings-section { - border-color: #6b4a00; -} +/* Component – Warning list */ .warning-list { list-style: none; diff --git a/tools/editor/styles/components/warnings-section.css b/tools/editor/styles/components/warnings-section.css new file mode 100644 index 00000000..0ffe30e1 --- /dev/null +++ b/tools/editor/styles/components/warnings-section.css @@ -0,0 +1,5 @@ +/* Component – Warnings section */ + +.warnings-section { + border-color: #6b4a00; +} diff --git a/tools/editor/styles/generic.css b/tools/editor/styles/generic.css index 4d67dbe3..b9b6fce0 100644 --- a/tools/editor/styles/generic.css +++ b/tools/editor/styles/generic.css @@ -5,3 +5,5 @@ margin: 0; padding: 0; } + +[hidden] { display: none !important; } diff --git a/tools/editor/styles/main.css b/tools/editor/styles/main.css index 0b52c034..064fb492 100644 --- a/tools/editor/styles/main.css +++ b/tools/editor/styles/main.css @@ -3,13 +3,31 @@ @import "settings.css"; @import "generic.css"; @import "elements.css"; -@import "objects.css"; -@import "components/header.css"; + +/* Objects */ +@import "objects/surface.css"; +@import "objects/section-label.css"; +@import "objects/page.css"; +@import "objects/section.css"; +@import "objects/tool-grid.css"; +@import "objects/tool-workspace.css"; + +/* Components */ +@import "components/site-header.css"; @import "components/hero.css"; -@import "components/cards.css"; -@import "components/panel.css"; -@import "components/buttons.css"; -@import "components/swatches.css"; -@import "components/preview.css"; -@import "components/file-info.css"; -@import "components/warnings.css"; +@import "components/tool-card.css"; +@import "components/empty-state.css"; +@import "components/tool-panel.css"; +@import "components/panel-section.css"; +@import "components/control-row.css"; +@import "components/panel-inputs.css"; +@import "components/btn.css"; +@import "components/bg-swatches.css"; +@import "components/tool-preview.css"; +@import "components/preview-scroll.css"; +@import "components/preview-empty.css"; +@import "components/load-area.css"; +@import "components/file-name.css"; +@import "components/info-table.css"; +@import "components/warnings-section.css"; +@import "components/warning-list.css"; diff --git a/tools/editor/styles/objects.css b/tools/editor/styles/objects.css deleted file mode 100644 index 9c5c8752..00000000 --- a/tools/editor/styles/objects.css +++ /dev/null @@ -1,59 +0,0 @@ -/* Objects – Layout patterns and shared abstractions */ - -/* Surface base – background, border, and radius shared across raised UI */ -.tool-card, -.tool-panel, -.tool-preview, -.empty-state { - background: var(--bg-surface); - border: 1px solid var(--border); - border-radius: var(--radius); -} - -/* Hover accent border – interactive surfaces that highlight on focus/drag */ -.tool-card:hover, -.btn:hover:not(:disabled), -.load-area:hover, -.load-area.drag-over, -.tool-preview.drag-over { - border-color: var(--accent-dim); -} - -/* Section label – small uppercase heading shared across page and panel contexts */ -.section-label { - font-size: 0.7rem; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.08em; - color: var(--text-muted); -} - -/* Page container */ -.page { - max-width: 1400px; - margin: 0 auto; - padding: var(--gap); -} - -/* Top-level sections share uniform vertical spacing */ -.section, -.tool-workspace { - margin-top: var(--gap); -} - -.section > .section-label { - margin-bottom: 1rem; -} - -/* Tool grid */ -.tool-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); - gap: 1rem; -} - -/* Tool workspace */ -.tool-workspace { - display: flex; - gap: 1rem; -} diff --git a/tools/editor/styles/objects/page.css b/tools/editor/styles/objects/page.css new file mode 100644 index 00000000..cfd1726b --- /dev/null +++ b/tools/editor/styles/objects/page.css @@ -0,0 +1,7 @@ +/* Object – Page container */ + +.page { + max-width: 1400px; + margin: 0 auto; + padding: var(--gap); +} diff --git a/tools/editor/styles/objects/section-label.css b/tools/editor/styles/objects/section-label.css new file mode 100644 index 00000000..1708deff --- /dev/null +++ b/tools/editor/styles/objects/section-label.css @@ -0,0 +1,13 @@ +/* Object – Section label */ + +.section-label { + font-size: 0.7rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.08em; + color: var(--text-muted); +} + +.section > .section-label { + margin-bottom: 1rem; +} diff --git a/tools/editor/styles/objects/section.css b/tools/editor/styles/objects/section.css new file mode 100644 index 00000000..0c559b33 --- /dev/null +++ b/tools/editor/styles/objects/section.css @@ -0,0 +1,5 @@ +/* Object – Page section */ + +.section { + margin-top: var(--gap); +} diff --git a/tools/editor/styles/objects/surface.css b/tools/editor/styles/objects/surface.css new file mode 100644 index 00000000..34d9bd42 --- /dev/null +++ b/tools/editor/styles/objects/surface.css @@ -0,0 +1,19 @@ +/* Object – Shared surface base (background, border, radius) */ + +.tool-card, +.tool-panel, +.tool-preview, +.empty-state { + background: var(--bg-surface); + border: 1px solid var(--border); + border-radius: var(--radius); +} + +/* Hover accent border – interactive surfaces that highlight on focus/drag */ +.tool-card:hover, +.btn:hover:not(:disabled), +.load-area:hover, +.load-area.drag-over, +.tool-preview.drag-over { + border-color: var(--accent-dim); +} diff --git a/tools/editor/styles/objects/tool-grid.css b/tools/editor/styles/objects/tool-grid.css new file mode 100644 index 00000000..974f866e --- /dev/null +++ b/tools/editor/styles/objects/tool-grid.css @@ -0,0 +1,7 @@ +/* Object – Tool grid */ + +.tool-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); + gap: 1rem; +} diff --git a/tools/editor/styles/objects/tool-workspace.css b/tools/editor/styles/objects/tool-workspace.css new file mode 100644 index 00000000..0363a3bd --- /dev/null +++ b/tools/editor/styles/objects/tool-workspace.css @@ -0,0 +1,7 @@ +/* Object – Tool workspace */ + +.tool-workspace { + margin-top: var(--gap); + display: flex; + gap: 1rem; +} diff --git a/tools/editor/texture/texture.js b/tools/editor/texture/texture.js index 93011fde..34dc7ee2 100644 --- a/tools/editor/texture/texture.js +++ b/tools/editor/texture/texture.js @@ -164,8 +164,9 @@ function applyImageData(width, height, data, filename, formatLabel, format) { // Sync format selector when loading an existing DTF if (format !== undefined) { - state.format = format; - formatSelect.value = format; + state.format = format; + formatSelect.value = format; + redAsAlphaRow.hidden = format !== DTF.FORMAT_ALPHA; } // Sidebar info