<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tile Sheet Editor</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1400px;
margin: 0 auto;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border-radius: 20px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 30px;
text-align: center;
}
.header h1 {
font-size: 2.5rem;
margin-bottom: 10px;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}
.header p {
font-size: 1.1rem;
opacity: 0.9;
}
@media (max-width: 768px) {
.header {
padding: 20px;
}
.header h1 {
font-size: 1.8rem;
}
.header p {
font-size: 1rem;
}
}
.main-content {
display: flex;
min-height: 600px;
}
.sidebar {
width: 300px;
background: #f8f9fa;
border-right: 1px solid #e9ecef;
padding: 20px;
overflow-y: auto;
}
@media (max-width: 768px) {
.main-content {
flex-direction: column;
}
.sidebar {
width: 100%;
border-right: none;
border-bottom: 1px solid #e9ecef;
padding: 15px;
max-height: 300px;
}
}
.image-list {
display: flex;
flex-direction: column;
gap: 10px;
}
.image-item {
display: flex;
align-items: center;
padding: 10px;
background: white;
border-radius: 10px;
cursor: pointer;
transition: all 0.3s ease;
border: 2px solid transparent;
}
.image-item:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
border-color: #667eea;
}
.image-item.active {
border-color: #667eea;
background: #f0f4ff;
}
.image-item img {
width: 60px;
height: 60px;
object-fit: contain;
border-radius: 5px;
margin-right: 10px;
background: #f8f9fa;
border: 1px solid #e9ecef;
}
.image-name {
font-weight: 500;
color: #333;
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 13px;
}
.image-preview {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
display: none;
justify-content: center;
align-items: center;
z-index: 1000;
backdrop-filter: blur(5px);
}
.preview-content {
position: relative;
max-width: 90vw;
max-height: 90vh;
background: white;
border-radius: 15px;
padding: 20px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
}
.preview-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid #e9ecef;
}
.preview-title {
font-size: 1.2rem;
font-weight: 600;
color: #333;
}
.preview-close {
background: #dc3545;
color: white;
border: none;
border-radius: 50%;
width: 30px;
height: 30px;
cursor: pointer;
font-size: 16px;
display: flex;
align-items: center;
justify-content: center;
}
.preview-close:hover {
background: #c82333;
}
.preview-canvas-container {
position: relative;
display: flex;
justify-content: center;
align-items: center;
max-height: 70vh;
overflow: auto;
border-radius: 8px;
background: #f8f9fa;
}
.preview-canvas {
border: 2px solid #ddd;
border-radius: 5px;
background: white;
image-rendering: pixelated;
image-rendering: crisp-edges;
}
.preview-info {
margin-top: 10px;
padding: 10px;
background: #f8f9fa;
border-radius: 8px;
font-size: 12px;
color: #666;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
gap: 10px;
}
.editor-area {
flex: 1;
padding: 20px;
display: flex;
flex-direction: column;
}
@media (max-width: 768px) {
.editor-area {
padding: 15px;
}
}
.editor-header {
margin-bottom: 20px;
padding-bottom: 20px;
border-bottom: 1px solid #e9ecef;
}
@media (max-width: 768px) {
.editor-header {
margin-bottom: 15px;
padding-bottom: 15px;
}
}
.editor-title {
font-size: 1.5rem;
color: #333;
margin-bottom: 10px;
}
@media (max-width: 768px) {
.editor-title {
font-size: 1.2rem;
margin-bottom: 8px;
}
}
.controls {
display: flex;
gap: 15px;
align-items: center;
flex-wrap: wrap;
margin-bottom: 15px;
}
.control-group {
display: flex;
align-items: center;
gap: 8px;
min-width: 120px;
}
.control-group label {
font-weight: 500;
color: #555;
min-width: 80px;
font-size: 14px;
}
@media (max-width: 768px) {
.controls {
gap: 10px;
}
.control-group {
min-width: 100%;
justify-content: space-between;
margin-bottom: 8px;
}
.control-group label {
min-width: auto;
flex: 1;
font-size: 13px;
}
}
input[type="number"] {
width: 80px;
padding: 8px;
border: 2px solid #ddd;
border-radius: 5px;
font-size: 14px;
transition: border-color 0.3s ease;
}
input[type="number"]:focus {
outline: none;
border-color: #667eea;
}
@media (max-width: 768px) {
input[type="number"] {
width: 70px;
padding: 6px;
font-size: 13px;
}
}
.btn {
padding: 10px 20px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
font-weight: 500;
transition: all 0.3s ease;
margin-right: 10px;
margin-bottom: 8px;
font-size: 14px;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
}
@media (max-width: 768px) {
.btn {
padding: 8px 16px;
font-size: 13px;
margin-right: 8px;
margin-bottom: 8px;
flex: 1;
min-width: calc(50% - 4px);
}
.btn:last-child {
margin-right: 0;
}
}
@media (max-width: 480px) {
.btn {
min-width: 100%;
margin-right: 0;
}
}
.btn.success {
background: linear-gradient(135deg, #28a745 0%, #20c997 100%);
}
.btn.warning {
background: linear-gradient(135deg, #ffc107 0%, #fd7e14 100%);
color: #333;
}
.selected-tiles-section {
margin-bottom: 15px;
}
.selected-tiles-list {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-bottom: 10px;
min-height: 30px;
padding: 10px;
background: #f8f9fa;
border-radius: 8px;
border: 2px dashed #ddd;
}
@media (max-width: 768px) {
.selected-tiles-list {
gap: 6px;
padding: 8px;
min-height: 40px;
}
}
.tile-tag {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
display: flex;
align-items: center;
gap: 5px;
}
.tile-tag .remove {
cursor: pointer;
font-weight: bold;
opacity: 0.7;
}
.tile-tag .remove:hover {
opacity: 1;
}
.canvas-container {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
background: #f8f9fa;
border-radius: 10px;
padding: 20px;
position: relative;
overflow: auto;
}
@media (max-width: 768px) {
.canvas-container {
padding: 10px;
min-height: 400px;
}
}
.tile-grid-container {
position: relative;
display: inline-block;
border: 2px solid #ddd;
border-radius: 8px;
background: white;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
image-rendering: pixelated;
image-rendering: crisp-edges;
transform-origin: top left;
}
.tile-image {
display: block;
image-rendering: pixelated;
image-rendering: crisp-edges;
}
.tile-overlay {
position: absolute;
top: 0;
left: 0;
display: grid;
cursor: crosshair;
}
.tile-cell {
position: relative;
border-right: 1px solid rgba(0, 255, 0, 0.5);
border-bottom: 1px solid rgba(0, 255, 0, 0.5);
box-sizing: border-box;
}
.tile-cell:nth-child(-n + var(--grid-cols)) {
border-top: 1px solid rgba(0, 255, 0, 0.5);
}
.tile-cell:nth-child(var(--grid-cols) + 1) ~ .tile-cell {
border-top: 1px solid rgba(0, 255, 0, 0.5);
}
.tile-cell:nth-child(n + var(--grid-cols) * (var(--grid-rows) - 1) + 1) {
border-bottom: none;
}
.tile-cell:nth-child(var(--grid-cols)) {
border-right: none;
}
.tile-cell.selected {