Add resource icons and registry images
Some checks failed
publish-images / build (push) Failing after 3s
ci / tests (push) Successful in 21s

This commit is contained in:
dan
2025-12-25 10:09:02 +03:00
parent e9d87473aa
commit 1c0603022a
10 changed files with 1469 additions and 350 deletions

View File

@@ -12,9 +12,7 @@ services:
- catan-db:/var/lib/postgresql/data - catan-db:/var/lib/postgresql/data
api: api:
build: image: cr.danosito.com/dan/catan-api:latest
context: .
dockerfile: docker/api.Dockerfile
restart: unless-stopped restart: unless-stopped
env_file: .env env_file: .env
depends_on: depends_on:
@@ -27,9 +25,7 @@ services:
- caddy-network - caddy-network
game: game:
build: image: cr.danosito.com/dan/catan-game:latest
context: .
dockerfile: docker/game.Dockerfile
restart: unless-stopped restart: unless-stopped
env_file: .env env_file: .env
depends_on: depends_on:
@@ -40,9 +36,7 @@ services:
- ./models:/models - ./models:/models
ai: ai:
build: image: cr.danosito.com/dan/catan-ai:latest
context: .
dockerfile: docker/ai.Dockerfile
restart: unless-stopped restart: unless-stopped
env_file: .env env_file: .env
depends_on: depends_on:
@@ -53,9 +47,7 @@ services:
- ./models:/models - ./models:/models
analytics: analytics:
build: image: cr.danosito.com/dan/catan-analytics:latest
context: .
dockerfile: docker/analytics.Dockerfile
restart: unless-stopped restart: unless-stopped
env_file: .env env_file: .env
depends_on: depends_on:
@@ -64,9 +56,7 @@ services:
- default - default
web: web:
build: image: cr.danosito.com/dan/catan-web:latest
context: .
dockerfile: docker/web.Dockerfile
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- api - api

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Brick">
<rect x="6" y="18" width="52" height="28" rx="4" fill="none" stroke="#fdf7e3" stroke-width="4" stroke-linejoin="round" />
<path d="M6 30h52M20 18v12M44 30v16" fill="none" stroke="#fdf7e3" stroke-width="3" stroke-linecap="round" />
</svg>

After

Width:  |  Height:  |  Size: 333 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Card Back">
<rect x="14" y="8" width="36" height="48" rx="6" fill="#1a365d" stroke="#fdf7e3" stroke-width="3" />
<path d="M20 18h24M20 26h24M20 34h24M20 42h24" fill="none" stroke="#fdf7e3" stroke-width="2" stroke-linecap="round" />
</svg>

After

Width:  |  Height:  |  Size: 326 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Development Card">
<rect x="12" y="10" width="40" height="48" rx="6" fill="none" stroke="#fdf7e3" stroke-width="4" />
<path d="M32 20l4 8 9 1-6 6 2 9-9-4-9 4 2-9-6-6 9-1z" fill="none" stroke="#fdf7e3" stroke-width="3" stroke-linejoin="round" />
</svg>

After

Width:  |  Height:  |  Size: 339 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Grain">
<path d="M32 12v40" fill="none" stroke="#fdf7e3" stroke-width="3" stroke-linecap="round" />
<path d="M32 18c-6 0-10 5-10 10 6 0 10-5 10-10z" fill="none" stroke="#fdf7e3" stroke-width="3" />
<path d="M32 28c6 0 10 5 10 10-6 0-10-5-10-10z" fill="none" stroke="#fdf7e3" stroke-width="3" />
<path d="M32 38c-6 0-10 5-10 10 6 0 10-5 10-10z" fill="none" stroke="#fdf7e3" stroke-width="3" />
</svg>

After

Width:  |  Height:  |  Size: 491 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Lumber">
<rect x="8" y="22" width="48" height="20" rx="10" fill="none" stroke="#fdf7e3" stroke-width="4" />
<circle cx="18" cy="32" r="4" fill="none" stroke="#fdf7e3" stroke-width="3" />
<circle cx="46" cy="32" r="4" fill="none" stroke="#fdf7e3" stroke-width="3" />
</svg>

After

Width:  |  Height:  |  Size: 362 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Ore">
<path d="M14 42l8-18 12-8 16 10 4 16-10 10H20z" fill="none" stroke="#fdf7e3" stroke-width="4" stroke-linejoin="round" />
<path d="M28 36l6-8 10 6" fill="none" stroke="#fdf7e3" stroke-width="3" stroke-linecap="round" />
</svg>

After

Width:  |  Height:  |  Size: 319 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Wool">
<path d="M18 42h28c6 0 10-4 10-9 0-4-3-8-7-9-1-6-6-10-12-8-3-4-9-5-13-1-4-1-8 2-8 7 0 6 4 10 10 10z" fill="none" stroke="#fdf7e3" stroke-width="4" stroke-linejoin="round" />
</svg>

After

Width:  |  Height:  |  Size: 273 B

View File

@@ -855,24 +855,113 @@ textarea {
background: #d95f00; background: #d95f00;
} }
.game-layout { .game-shell {
display: grid;
grid-template-columns: 260px 1fr 260px;
gap: 16px;
width: 100%;
height: 100%;
overflow: hidden;
}
.game-panel {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 16px; gap: 12px;
overflow: auto; width: 100%;
height: 100%;
min-height: 0;
} }
.game-board { .game-topbar {
display: flex;
flex-wrap: wrap;
gap: 12px;
padding: 12px;
border-radius: 12px; border-radius: 12px;
background: rgba(0, 0, 0, 0.2);
}
.player-chip {
display: flex;
gap: 10px;
align-items: center;
padding: 8px 12px;
border-radius: 12px;
background: rgba(0, 0, 0, 0.25);
min-width: 180px;
}
.player-chip-body {
display: flex;
flex-direction: column;
gap: 2px;
flex: 1;
}
.player-chip--active {
border: 2px solid #48ff00;
}
.player-color {
width: 12px;
height: 12px;
border-radius: 999px;
}
.player-name {
font-weight: bold;
}
.player-meta {
font-size: 0.85rem;
color: rgba(255, 255, 255, 0.7);
}
.player-hand {
display: flex;
align-items: center;
gap: 8px;
}
.card-stack {
position: relative;
width: 44px;
height: 34px;
display: flex;
align-items: center;
justify-content: center;
}
.card-back {
width: 30px;
height: 30px;
}
.card-back--offset {
position: absolute;
left: 6px;
top: 4px;
opacity: 0.85;
}
.card-stack--dev {
width: 34px;
}
.card-count {
position: absolute;
bottom: -6px;
right: -6px;
background: rgba(0, 0, 0, 0.65);
color: #fff;
border-radius: 999px;
font-size: 0.7rem;
padding: 2px 6px;
border: 1px solid rgba(255, 255, 255, 0.3);
}
.game-main {
display: grid;
grid-template-columns: 1fr 300px;
gap: 12px;
flex: 1;
min-height: 0;
}
.game-board-area {
border-radius: 16px;
background: rgba(0, 0, 0, 0.15); background: rgba(0, 0, 0, 0.15);
display: flex; display: flex;
align-items: center; align-items: center;
@@ -881,21 +970,122 @@ textarea {
overflow: hidden; overflow: hidden;
} }
.board-svg { .game-side {
width: 100%; display: flex;
height: 100%; flex-direction: column;
gap: 12px;
overflow: auto;
} }
.player-row { .game-bottom {
display: flex;
flex-direction: column;
gap: 10px;
}
.resource-bar {
display: flex;
flex-wrap: wrap;
gap: 10px;
justify-content: center;
padding: 10px;
border-radius: 12px;
background: rgba(0, 0, 0, 0.2);
}
.resource-card {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 4px;
min-width: 90px;
padding: 8px 10px;
border-radius: 12px;
color: #1b1b1b;
font-weight: bold;
}
.resource-icon {
width: 30px;
height: 30px;
}
.resource-card-label {
font-size: 0.8rem;
}
.resource-card-count {
font-size: 1.1rem;
}
.resource-card--dev {
background: rgba(0, 0, 0, 0.3);
color: #fff;
}
.action-bar {
display: flex;
flex-wrap: wrap;
gap: 8px;
justify-content: center;
}
.action-button {
border: 0;
border-radius: 8px;
background: rgba(0, 0, 0, 0.25);
color: #fff;
font-weight: bold;
padding: 10px 14px;
cursor: pointer;
transition: all 0.15s ease;
}
.action-button:hover {
background: rgba(0, 0, 0, 0.4);
}
.action-button--primary {
background: #f06800;
}
.action-button--primary:hover {
background: #bd5200;
}
.action-button--active {
border: 2px solid #48ff00;
}
.action-button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.action-banner {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 10px 14px;
border-radius: 12px;
background: rgba(0, 0, 0, 0.2);
}
.robber-panel {
display: flex; display: flex;
gap: 10px; gap: 10px;
align-items: center; align-items: center;
justify-content: center;
padding: 8px 12px;
border-radius: 12px;
background: rgba(0, 0, 0, 0.2);
} }
.player-dot { .board-svg {
width: 12px; width: 100%;
height: 12px; height: 100%;
border-radius: 999px;
} }
.trade-card { .trade-card {
@@ -919,6 +1109,260 @@ textarea {
overflow: auto; overflow: auto;
} }
.trade-panel {
display: flex;
flex-direction: column;
gap: 12px;
}
.trade-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
}
.trade-offer-list {
display: flex;
flex-direction: column;
gap: 10px;
}
.trade-offer {
border-radius: 12px;
padding: 10px;
background: rgba(0, 0, 0, 0.25);
}
.trade-offer-meta {
font-size: 0.85rem;
color: rgba(255, 255, 255, 0.7);
margin-bottom: 6px;
}
.trade-offer-row {
display: flex;
gap: 8px;
align-items: center;
margin-bottom: 6px;
}
.trade-offer-label {
font-weight: bold;
min-width: 60px;
}
.trade-chip-row {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.trade-chip {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 8px;
border-radius: 999px;
background: rgba(0, 0, 0, 0.3);
font-size: 0.75rem;
}
.trade-chip-icon {
width: 16px;
height: 16px;
}
.trade-chip--brick {
background: #c46a44;
}
.trade-chip--lumber {
background: #4a6d4a;
}
.trade-chip--wool {
background: #8cc071;
}
.trade-chip--grain {
background: #e2c065;
}
.trade-chip--ore {
background: #7a7c83;
}
.modal-backdrop {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.65);
display: flex;
align-items: center;
justify-content: center;
z-index: 100;
}
.trade-modal {
width: min(640px, 90vw);
max-height: 90vh;
overflow: auto;
padding: 20px;
border-radius: 16px;
background: #1062b0;
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.4);
display: flex;
flex-direction: column;
gap: 16px;
}
.trade-tabs {
display: flex;
gap: 8px;
}
.trade-tab {
flex: 1;
padding: 8px 12px;
border-radius: 10px;
border: 0;
background: rgba(0, 0, 0, 0.2);
color: #fff;
font-weight: bold;
cursor: pointer;
}
.trade-tab.active {
background: #1e90ff;
}
.trade-tab:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.trade-content {
display: flex;
flex-direction: column;
gap: 14px;
}
.trade-row {
display: flex;
flex-direction: column;
gap: 6px;
}
.trade-section h4 {
margin-bottom: 8px;
}
.trade-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: 10px;
}
.trade-resource {
padding: 8px;
border-radius: 10px;
background: rgba(0, 0, 0, 0.2);
}
.trade-resource-name {
display: flex;
align-items: center;
gap: 6px;
font-size: 0.85rem;
margin-bottom: 6px;
}
.trade-resource-icon {
width: 18px;
height: 18px;
}
.trade-stepper {
display: flex;
align-items: center;
justify-content: space-between;
gap: 6px;
}
.stepper-btn {
border: 0;
border-radius: 8px;
width: 28px;
height: 28px;
background: rgba(0, 0, 0, 0.3);
color: #fff;
font-weight: bold;
cursor: pointer;
}
.stepper-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.stepper-value {
min-width: 24px;
text-align: center;
}
.trade-actions-row {
display: flex;
gap: 10px;
justify-content: flex-end;
}
.hex {
transition: all 0.15s ease;
pointer-events: all;
}
.hex--highlight {
stroke: #48ff00;
stroke-width: 3;
cursor: pointer;
}
.hex--selected {
stroke: #f4ff00;
stroke-width: 4;
}
.edge-hit {
stroke: transparent;
cursor: default;
pointer-events: stroke;
}
.edge-hit--active {
stroke: rgba(255, 255, 255, 0.2);
cursor: pointer;
}
.edge-hit--selected {
stroke: rgba(244, 255, 0, 0.6);
}
.corner-hit {
fill: transparent;
stroke: transparent;
cursor: default;
pointer-events: all;
}
.corner-hit--active {
stroke: rgba(255, 255, 255, 0.5);
cursor: pointer;
}
.corner-hit--selected {
stroke: rgba(244, 255, 0, 0.8);
}
.replay-table { .replay-table {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -1071,7 +1515,7 @@ textarea {
display: none; display: none;
} }
.game-layout { .game-main {
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }
} }