2026-06-01 18:27:25 +09:00
<!doctype html>
< html lang = "en" >
< head >
< meta charset = "utf-8" / >
< meta name = "viewport" content = "width=device-width, initial-scale=1" / >
< title > Pixel Island Summoner - Local Prototype< / title >
< link rel = "stylesheet" href = "./styles.css" / >
< / head >
< body >
< div class = "app" >
< canvas id = "worldCanvas" aria-label = "Island map" > < / canvas >
< button id = "openEditor" class = "edgeAdd" title = "Open Pixel Studio" > +< / button >
< header class = "hud topHud" >
< div >
< div class = "logo" > Pixel Island< / div >
< div class = "subline" > Local prototype / Draw pixels, summon them to islands.< / div >
< / div >
< label class = "authorCard" >
< span > Your Name< / span >
< input id = "authorName" type = "text" maxlength = "24" value = "Local Artist" / >
< / label >
< div class = "clockCard" aria-label = "world clock" >
< div id = "phaseLabel" class = "phaseLabel" > Day< / div >
< div class = "phaseBar" > < span id = "phaseBar" > < / span > < / div >
< div class = "clockHint" > 10 min = 1 day< / div >
< / div >
< / header >
< aside class = "hud toolHud" >
< button id = "modeInspect" class = "iconButton active" title = "Pan / Inspect" > Pan< / button >
< button id = "modePlace" class = "iconButton" title = "Summon selected asset" > Place< / button >
< button id = "modeErase" class = "iconButton danger" title = "Remove asset" > Erase< / button >
< div class = "divider" > < / div >
2026-06-01 21:17:09 +09:00
< button id = "zoomOut" class = "iconButton" title = "Zoom out" > − < / button >
2026-06-01 18:27:25 +09:00
< button id = "zoomIn" class = "iconButton" title = "Zoom in" > +< / button >
< button id = "resetView" class = "iconButton" title = "Reset view" > Reset< / button >
< / aside >
< section id = "studioDrawer" class = "studioDrawer" aria-label = "Pixel Studio" >
< div class = "drawerHead" >
< div >
< h1 > Pixel Studio< / h1 >
< p > Make static scenery or moving island life.< / p >
< / div >
2026-06-01 21:17:09 +09:00
< button id = "closeEditor" class = "ghostButton" title = "Close" > × < / button >
2026-06-01 18:27:25 +09:00
< / div >
< nav class = "tabs" aria-label = "Studio tabs" >
< button class = "tab active" data-tab = "draw" > Draw< / button >
< button class = "tab" data-tab = "library" > Library< / button >
< button class = "tab" data-tab = "data" > Data< / button >
< / nav >
< div class = "drawerBody" >
< section id = "tab-draw" class = "tabPanel active" >
< div class = "card editorCard heroEditor" >
< div class = "quickSetupBar twoCols" >
< label class = "field" > Canvas size
< select id = "assetSize" >
2026-06-01 21:17:09 +09:00
< option value = "8" selected > 8× 8< / option >
< option value = "16" > 16× 16< / option >
< option value = "32" > 32× 32< / option >
< option value = "64" > 64× 64< / option >
2026-06-01 18:27:25 +09:00
< / select >
< / label >
< label class = "field" > Role
< select id = "assetCategory" >
< option value = "human" > Human< / option >
< option value = "animal" > Animal< / option >
< option value = "nature" selected > Nature< / option >
< option value = "building" > Building< / option >
2026-06-02 00:05:03 +09:00
< option value = "ship" > Ship< / option >
2026-06-01 18:27:25 +09:00
< option value = "other" > Other< / option >
< / select >
< / label >
< / div >
< label class = "field compactNameField" > Name
< input id = "assetName" type = "text" maxlength = "32" placeholder = "Tiny bakery, round tree, island pup..." / >
< / label >
< div class = "editorTop compactEditorTop" >
< div id = "sideSwitcher" class = "sideSwitcher" hidden aria-label = "Sprite direction" >
2026-06-01 21:17:09 +09:00
< button id = "editLeft" title = "Left-facing sprite" > ◀ Left< / button >
< button id = "editRight" class = "active" title = "Right-facing sprite is the main/front direction" > ▶ Right< / button >
2026-06-01 18:27:25 +09:00
< / div >
< / div >
< div class = "paintLayout" >
< canvas id = "paintCanvas" width = "512" height = "512" aria-label = "Pixel editor" > < / canvas >
< div class = "palettePanel" >
< div id = "paletteGrid" class = "paletteGrid" aria-label = "Color palette" > < / div >
< / div >
< / div >
2026-06-01 22:48:15 +09:00
< div class = "toolRow editorToolRow" >
< button id = "toolBrush" class = "tool active" title = "B" > Draw< / button >
< button id = "toolErase" class = "tool" title = "E" > Erase< / button >
< button id = "toolFill" class = "tool" title = "F" > Fill< / button >
< button id = "toolPick" class = "tool" title = "I" > Pick< / button >
< button id = "toolLine" class = "tool" title = "L" > Line< / button >
< button id = "toolRect" class = "tool" title = "R" > Rect< / button >
< button id = "toolSelect" class = "tool" title = "S" > Select< / button >
2026-06-01 18:27:25 +09:00
< button id = "toolDoor" class = "tool buildingOnly" > Door< / button >
< button id = "clearPaint" class = "tool danger" > Clear< / button >
< / div >
2026-06-01 22:48:15 +09:00
< div class = "toolRow editorHistoryRow" >
< button id = "undoPaint" class = "tool" type = "button" disabled > Undo< / button >
< button id = "redoPaint" class = "tool" type = "button" disabled > Redo< / button >
< button id = "outlinePaint" class = "tool" type = "button" > Outline< / button >
< button id = "flipHorizontal" class = "tool" type = "button" > Flip H< / button >
< button id = "flipVertical" class = "tool" type = "button" > Flip V< / button >
< / div >
< div class = "toolRow editorMoveRow" >
< button id = "nudgeLeft" class = "tool" type = "button" > ←< / button >
< button id = "nudgeUp" class = "tool" type = "button" > ↑< / button >
< button id = "nudgeDown" class = "tool" type = "button" > ↓< / button >
< button id = "nudgeRight" class = "tool" type = "button" > →< / button >
< button id = "clearSelection" class = "tool" type = "button" disabled > Clear Sel< / button >
< / div >
< div class = "toolRow editorFileRow" >
< button id = "exportPng" class = "tool" type = "button" > Export PNG< / button >
< button id = "importPng" class = "tool" type = "button" > Import PNG< / button >
< input id = "pngImportInput" type = "file" accept = "image/png,image/*" hidden / >
< / div >
2026-06-01 21:17:09 +09:00
< div class = "advancedRow" >
< button id = "toggleAdvanced" class = "tool" type = "button" > Advanced Draw< / button >
< button id = "toolLight" class = "tool advancedOnly" hidden > Light< / button >
< button id = "toolDepth" class = "tool advancedOnly" hidden > Depth< / button >
2026-06-01 22:48:15 +09:00
< button id = "depthHigh" class = "tool advancedOnly" type = "button" hidden > High< / button >
< button id = "depthLow" class = "tool advancedOnly" type = "button" hidden > Low< / button >
< button id = "depthClear" class = "tool advancedOnly" type = "button" hidden > Clear< / button >
< span id = "advancedHint" class = "hint" hidden > Light/Depth tools are here. Depth supports High/Low/Clear. Left-drag paints the selected depth value; Shift clears.< / span >
2026-06-01 18:27:25 +09:00
< / div >
< input id = "paintColor" type = "color" value = "#6bd06b" hidden / >
2026-06-01 22:48:15 +09:00
< div id = "editHint" class = "hint" > Palette color is used for pixels, lights, and depth marks. Shortcuts: B/E/F/I/L/R/S, Ctrl/Cmd+Z, arrows move a selection.< / div >
2026-06-01 18:27:25 +09:00
< / div >
< div class = "card stack summonCard" >
< div class = "cardTitle" > Finish< / div >
< div class = "actionRow finishActions" >
< button id = "saveAndPlace" class = "primary bigPrimary" > Save + Summon on Map< / button >
< button id = "saveAsset" class = "secondary" > Save only< / button >
< button id = "newAsset" class = "secondary" > New< / button >
< / div >
< / div >
< div id = "lineageNote" class = "lineageNote" > < / div >
< / section >
< section id = "tab-library" class = "tabPanel" >
< div class = "card stack" >
2026-06-01 21:17:09 +09:00
< div class = "libraryHead" >
< div class = "cardTitle" > Library< / div >
< button id = "showHiddenAssets" class = "tool" type = "button" > Hidden< / button >
< / div >
2026-06-01 18:27:25 +09:00
< p class = "hint" > Click an asset to select it and jump to it on the map. Copy Edit creates a new derivative.< / p >
2026-06-01 21:17:09 +09:00
< div id = "hiddenAssetPanel" class = "hiddenAssetPanel" hidden >
2026-06-02 00:05:03 +09:00
< div class = "cardTitle" > Hidden< / div >
2026-06-01 21:17:09 +09:00
< div id = "hiddenAssetList" class = "assetList compactAssetList" > < / div >
< / div >
2026-06-01 18:27:25 +09:00
< div id = "assetList" class = "assetList" > < / div >
< / div >
< / section >
< section id = "tab-data" class = "tabPanel" >
< div class = "card stack" >
< div class = "cardTitle" > Local save< / div >
< p class = "hint" > Saved to this browser only. Export JSON if you want to move or share a local world.< / p >
< div class = "actionRow wrap" >
2026-06-01 22:48:15 +09:00
< button id = "exportData" > Export full JSON< / button >
< button id = "exportCompact" > Export compact< / button >
< button id = "exportSnapshot" > Export snapshot< / button >
< button id = "exportAssetBundle" > Export asset bundle< / button >
2026-06-01 18:27:25 +09:00
< button id = "importData" > Import JSON< / button >
< button id = "resetAll" class = "danger" > Reset all< / button >
< / div >
2026-06-01 22:48:15 +09:00
< div id = "syncStats" class = "syncStats" > < / div >
2026-06-01 18:27:25 +09:00
< textarea id = "dataBox" rows = "10" placeholder = "Exported JSON appears here." > < / textarea >
< / div >
2026-06-02 00:05:03 +09:00
< div class = "card stack" >
< div class = "cardTitle" > Visual settings< / div >
< p class = "hint" > Turn major visual systems on or off.< / p >
< div class = "toggleList" >
< label class = "checkRow" > < input id = "settingLights" type = "checkbox" checked / > < span > Lights & glow< / span > < / label >
< label class = "checkRow" > < input id = "settingParticles" type = "checkbox" checked / > < span > Particles & ambient FX< / span > < / label >
< label class = "checkRow" > < input id = "settingDayNight" type = "checkbox" checked / > < span > Day / night cycle< / span > < / label >
< / div >
< / div >
< div class = "card stack" >
< div class = "cardTitle" > Phase 5 guardrails< / div >
< p class = "hint" > Local pre-server checks for object volume, orphaned placements, terrain compatibility, hidden objects, and report logs.< / p >
< div id = "guardrailStats" class = "syncStats" > < / div >
< div class = "actionRow wrap" >
< button id = "validateWorld" type = "button" > Validate world< / button >
< button id = "exportModerationReport" type = "button" > Export moderation report< / button >
< button id = "clearReports" class = "danger" type = "button" > Clear reports< / button >
< / div >
< / div >
2026-06-01 18:27:25 +09:00
< / section >
< / div >
< / section >
< div id = "selectionBubble" class = "selectionBubble" hidden >
< div id = "bubbleName" class = "bubbleName" > Name< / div >
< div id = "bubbleAuthor" class = "bubbleAuthor" > by Author< / div >
< div id = "bubbleRemixFrom" class = "bubbleRemixFrom" hidden > < / div >
< div id = "bubbleRemixCount" class = "bubbleRemixCount" > Remixed: 0< / div >
< div class = "bubbleVotes" >
2026-06-01 21:17:09 +09:00
< button id = "voteUp" type = "button" > ▲< / button >
2026-06-01 18:27:25 +09:00
< span id = "voteScore" > 0< / span >
2026-06-01 21:17:09 +09:00
< button id = "voteDown" type = "button" > ▼< / button >
2026-06-01 18:27:25 +09:00
< / div >
< div class = "bubbleActions" >
< button id = "bubbleRemix" type = "button" > Remix< / button >
2026-06-02 00:05:03 +09:00
< button id = "bubbleReport" type = "button" > Report< / button >
2026-06-01 18:27:25 +09:00
< button id = "bubbleHide" type = "button" hidden > Hide< / button >
< / div >
< / div >
< div id = "toast" class = "toast" hidden > < / div >
2026-06-02 00:05:03 +09:00
< div id = "reportDialog" class = "reportDialog" hidden >
< div class = "reportCard" role = "dialog" aria-modal = "true" aria-labelledby = "reportTitle" >
< div id = "reportTitle" class = "cardTitle" > Report object< / div >
< p class = "hint" > Select a reason for reporting < strong id = "reportObjectName" > this object< / strong > .< / p >
< label class = "field" > Reason
< select id = "reportReason" >
< option value = "inappropriate" > Inappropriate / sexual< / option >
< option value = "harassment" > Harassment / hate< / option >
< option value = "spam" > Spam / flooding< / option >
< option value = "copyright" > Copyright / stolen work< / option >
< option value = "other" > Other< / option >
< / select >
< / label >
< div class = "actionRow wrap reportActions" >
< button id = "reportSubmit" class = "danger" type = "button" > Report + Hide< / button >
< button id = "reportCancel" type = "button" > Cancel< / button >
< / div >
< / div >
< / div >
2026-06-01 18:27:25 +09:00
< / div >
2026-06-01 22:48:15 +09:00
< script src = "./js/editor-actions.js" > < / script >
< script src = "./js/phase2-sync.js" > < / script >
2026-06-01 18:27:25 +09:00
< script src = "./app.js" > < / script >
< / body >
< / html >