);
diff --git a/pwa/src/components/game/Workbench.css b/pwa/src/components/game/Workbench.css
index 1ba51b0..0bbe863 100644
--- a/pwa/src/components/game/Workbench.css
+++ b/pwa/src/components/game/Workbench.css
@@ -13,19 +13,39 @@
backdrop-filter: blur(4px);
}
-.workbench-menu {
+/* Specific Override for GameModal container when used as Workbench */
+.game-modal-container.workbench-modal {
width: 95vw;
max-width: 1400px;
- height: 85vh;
+ height: 90%;
+ max-height: 90%;
background: var(--game-bg-modal);
border: 1px solid var(--game-border-color);
- display: flex;
- flex-direction: column;
box-shadow: var(--game-shadow-modal);
- overflow: hidden;
color: var(--game-text-primary);
font-family: var(--game-font-main);
- clip-path: var(--game-clip-path);
+}
+
+.game-modal-container.workbench-modal .game-modal-content {
+ padding: 0;
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+}
+
+.workbench-menu {
+ /* Legacy class support or internal structure if needed, but GameModal is the container */
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ overflow: hidden;
+}
+
+.workbench-menu-content {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ overflow: hidden;
}
.workbench-header {
@@ -46,6 +66,15 @@
gap: 0.5rem;
}
+.workbench-header-tabs {
+ display: flex;
+ gap: 0.5rem;
+ padding: 1rem;
+ background: var(--game-bg-panel);
+ border-bottom: 1px solid var(--game-border-color);
+ flex-shrink: 0;
+}
+
.workbench-tabs {
display: flex;
gap: 0.5rem;
diff --git a/pwa/src/components/game/Workbench.tsx b/pwa/src/components/game/Workbench.tsx
index 9209e72..c613571 100644
--- a/pwa/src/components/game/Workbench.tsx
+++ b/pwa/src/components/game/Workbench.tsx
@@ -1,8 +1,9 @@
-import { useState, useEffect, type MouseEvent, type ChangeEvent } from 'react'
+import { useState, useEffect, type ChangeEvent } from 'react'
import { useTranslation } from 'react-i18next'
import type { Profile, WorkbenchTab } from './types'
import { getAssetPath } from '../../utils/assetPath'
import { getTranslatedText } from '../../utils/i18nUtils'
+import { GameModal } from './GameModal'
import { GameButton } from '../common/GameButton'
import './Workbench.css'
@@ -476,33 +477,31 @@ function Workbench({
]
return (
-
) => {
- if (e.target === e.currentTarget) onCloseCrafting()
- }}>
-
-
-
{t('game.workbench')}
-
-
-
-
-
-
+
+
+
+
+
+
@@ -678,7 +677,7 @@ function Workbench({
-
+
)
}
diff --git a/pwa/src/components/game/hooks/useGameEngine.ts b/pwa/src/components/game/hooks/useGameEngine.ts
index bd24669..e2c3474 100644
--- a/pwa/src/components/game/hooks/useGameEngine.ts
+++ b/pwa/src/components/game/hooks/useGameEngine.ts
@@ -234,7 +234,7 @@ export function useGameEngine(
const addLocationMessage = useCallback((msg: string) => {
const now = new Date()
const timeStr = now.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' })
- const locationName = location?.name ? (typeof location.name === 'string' ? location.name : location.name.en || Object.values(location.name)[0]) : ''
+ const locationName = location?.name || ''
setLocationMessages((prev: LocationMessage[]) => {
const newMessages = [...prev, { time: timeStr, message: msg, location_name: locationName }]
diff --git a/pwa/src/components/game/types.ts b/pwa/src/components/game/types.ts
index d22cd1c..711d90e 100644
--- a/pwa/src/components/game/types.ts
+++ b/pwa/src/components/game/types.ts
@@ -77,7 +77,7 @@ export interface CombatLogEntry {
export interface LocationMessage {
time: string
message: string
- location_name?: string
+ location_name?: string | { [key: string]: string }
}
export interface Equipment {
diff --git a/pwa/src/i18n/locales/en.json b/pwa/src/i18n/locales/en.json
index 3d4101c..f643e4b 100644
--- a/pwa/src/i18n/locales/en.json
+++ b/pwa/src/i18n/locales/en.json
@@ -11,6 +11,10 @@
"game": "Game",
"leaderboards": "Leaderboards",
"account": "Account",
+ "accountSettings": "Account Settings",
+ "general": "General",
+ "audio": "Audio",
+ "security": "Security",
"info": "Info",
"talk": "Talk",
"loot": "Loot",
@@ -23,7 +27,10 @@
"enemy": "Enemy",
"you": "You",
"quests": "Quests",
- "all": "All"
+ "all": "All",
+ "prev": "Prev",
+ "next": "Next",
+ "back": "Back"
},
"auth": {
"login": "Login",
@@ -40,25 +47,88 @@
"loginTitle": "Welcome Back",
"registerTitle": "Create Account",
"loginSubtitle": "Sign in to continue your journey",
- "registerSubtitle": "Join the survivors"
+ "registerSubtitle": "Join the survivors",
+ "confirmPassword": "Confirm Password",
+ "emailPlaceholder": "your.email@example.com",
+ "passwordPlaceholder": "At least 6 characters",
+ "passwordPlaceholderLogin": "Your password",
+ "confirmPasswordPlaceholder": "Re-enter your password",
+ "submit": "Create Account",
+ "submitting": "Creating Account...",
+ "loggingIn": "Logging in...",
+ "loginLink": "Already have an account? Login",
+ "registerLink": "Don't have an account? Register",
+ "errors": {
+ "invalidEmail": "Please enter a valid email address",
+ "passwordLength": "Password must be at least 6 characters",
+ "passwordMatch": "Passwords do not match",
+ "registrationFailed": "Registration failed",
+ "loginFailed": "Login failed"
+ },
+ "strength": {
+ "weak": "Weak",
+ "medium": "Medium",
+ "strong": "Strong"
+ },
+ "accountInfo": "Account Information",
+ "accountType": "Account Type",
+ "premiumStatus": "Premium Status",
+ "premiumActive": "✓ Premium Active",
+ "freeAccount": "Free Account",
+ "created": "Created",
+ "lastLogin": "Last Login",
+ "gameActions": "Game Actions",
+ "switchCharacter": "Switch Character",
+ "audioSettings": "Audio Settings",
+ "volumeControls": "Volume Controls",
+ "muteAll": "Mute All",
+ "masterVolume": "Master Volume",
+ "musicVolume": "Music Volume",
+ "sfxVolume": "SFX Volume",
+ "securitySettings": "Security Settings",
+ "changeEmail": "Change Email",
+ "changePassword": "Change Password",
+ "currentPassword": "Current Password",
+ "newPassword": "New Password",
+ "confirmNewPassword": "Confirm New Password",
+ "verifyIdentity": "Verify your identity",
+ "updateEmail": "Update Email",
+ "updatePassword": "Update Password",
+ "updating": "Updating...",
+ "change": "Change",
+ "cancel": "Cancel"
},
"characters": {
"title": "Select Character",
"createNew": "Create New Character",
"play": "Play",
"delete": "Delete",
+ "deleteModal": {
+ "title": "Delete Character",
+ "confirm": "Are you sure you want to delete this character? This action cannot be undone."
+ },
"noCharacters": "No characters yet",
"createFirst": "Create your first character to begin",
"name": "Character Name",
"class": "Class",
- "level": "Level"
+ "level": "Level",
+ "lastActive": "Last active",
+ "create": {
+ "title": "Create New",
+ "slots": "slots used"
+ },
+ "premium": {
+ "title": "Character Limit Reached",
+ "description": "Upgrade to Premium to create up to 10 characters!",
+ "upgrade": "Upgrade to Premium - $4.99"
+ }
},
"game": {
"travel": "🧭 Travel",
"surroundings": "🌿 Surroundings",
"character": "👤 Character",
"equipment": "⚔️ Equipment",
- "inventory": "🎒 Open Inventory",
+ "inventory": "🎒 Inventory",
"workbench": "🔧 Workbench",
"craft": "🔨 Craft",
"repair": "🛠️ Repair",
@@ -69,6 +139,7 @@
"equip": "Equip",
"unequip": "Unequip",
"attack": "⚔️ Attack",
+ "kill": "Kill",
"flee": "🏃 Flee",
"rest": "Rest",
"onlineCount": "{{count}} Online",
@@ -92,7 +163,33 @@
"poisoned": "Poisoned"
},
"effectAlreadyActive": "Effect already active",
- "found": "Found"
+ "found": "Found",
+ "value": "Value",
+ "dialog": {
+ "back": "Back",
+ "goodbye": "Goodbye",
+ "trade": "Trade",
+ "acceptQuest": "Accept Quest",
+ "completeQuest": "Complete Quest",
+ "handInItems": "Hand In Items",
+ "questInProgress": "(Quest in progress...)",
+ "questAccepted": "Quest accepted! Good luck.",
+ "progressUpdated": "Progress updated.",
+ "rewards": "Rewards"
+ }
+ },
+ "trade": {
+ "title": "Trade",
+ "buying": "Buying",
+ "selling": "Selling",
+ "merchantStock": "Merchant Stock",
+ "inventory": "Inventory",
+ "invalidOffer": "INVALID OFFER",
+ "confirmTrade": "CONFIRM TRADE",
+ "balance": "Balance",
+ "empty": "Empty",
+ "clickToRemove": "Click to remove",
+ "howMany": "How many {{item}}?"
},
"location": {
"recentActivity": "📜 Recent Activity",
@@ -315,7 +412,11 @@
"staminaRegenerated": "Stamina regenerated",
"combatTimeout": "⏱️ Turn skipped due to timeout!",
"interactableReady": "{{action}} is ready on {{name}}",
- "waitBeforeMovingSimple": "Wait {{seconds}}s before moving"
+ "waitBeforeMovingSimple": "Wait {{seconds}}s before moving",
+ "questAccepted": "Quest Accepted!",
+ "questCompleted": "Quest Completed!",
+ "questProgressUpdated": "Quest Progress Updated",
+ "failedToAcceptQuest": "Failed to accept quest"
},
"directions": {
"north": "North",
@@ -337,6 +438,114 @@
"heroTitle": "Echoes of the Ash",
"heroSubtitle": "A post-apocalyptic survival RPG",
"playNow": "Play Now",
- "features": "Features"
+ "login": "Login",
+ "features": "Game Features",
+ "about": {
+ "title": "About the World",
+ "description": "In a world ravaged by nuclear fire, survival is the only law. Scavenge for resources, craft distinct weapons, and fight for your life against mutants and other survivors. Will you rebuild civilization or rule over the ashes?"
+ },
+ "featureCards": {
+ "survival": {
+ "title": "Hardcore Survival",
+ "description": "Survive in a harsh environment filled with radiation and deadly enemies. Manage your inventory and resources wisely."
+ },
+ "combat": {
+ "title": "Tactical Combat",
+ "description": "Engage in turn-based battles where every decision counts. Use skills, items, and strategy."
+ },
+ "crafting": {
+ "title": "Deep Crafting",
+ "description": "Scavenge materials to create weapons, armor, and tools essential for your survival."
+ }
+ },
+ "footer": {
+ "copyright": "© {{year}} Echoes of the Ash. All rights reserved.",
+ "links": {
+ "privacy": "Privacy Policy",
+ "terms": "Terms of Service",
+ "discord": "Join Discord"
+ }
+ }
+ },
+ "journal": {
+ "title": "Quest Journal",
+ "activeQuests": "Active Quests",
+ "history": "History",
+ "searchPlaceholder": "Search quests...",
+ "noQuests": "No quests found.",
+ "objectives": "Objectives",
+ "completionMessage": "Completion Message",
+ "rewards": "Rewards",
+ "accepted": "Accepted",
+ "completed": "Completed",
+ "type": "Type",
+ "status": "Status",
+ "ready": "READY",
+ "giver": "Giver",
+ "location": "Location",
+ "inProgress": "In Progress",
+ "story": "Story",
+ "side": "Side",
+ "daily": "Daily",
+ "global": "Global",
+ "selectQuest": "Select a quest to view details",
+ "communityProgress": "Global progress",
+ "yourContribution": "Your contribution"
+ },
+ "legal": {
+ "privacy": {
+ "title": "Privacy Policy",
+ "lastUpdated": "Last updated: February 16, 2026",
+ "sections": {
+ "1": {
+ "title": "1. Information We Collect",
+ "content": "We collect your email address and game-related data (character progress, inventory, etc.) to provide the service."
+ },
+ "2": {
+ "title": "2. How We Use Information",
+ "content": "We use your information to manage your account, save your game progress, and improve the game experience. We do not sell your data to third parties."
+ },
+ "3": {
+ "title": "3. Data Security",
+ "content": "We implement security measures to maintain the safety of your personal information. However, no method of transmission over the Internet is 100% secure."
+ },
+ "4": {
+ "title": "4. Cookies",
+ "content": "We use local storage to maintain your login session and game settings."
+ },
+ "5": {
+ "title": "5. Contact",
+ "content": "If you have questions about this privacy policy, please contact us via our Discord community."
+ }
+ },
+ "back": "Return to Home"
+ },
+ "terms": {
+ "title": "Terms of Service",
+ "lastUpdated": "Last updated: February 16, 2026",
+ "sections": {
+ "1": {
+ "title": "1. Acceptance of Terms",
+ "content": "By accessing and using Echoes of the Ash, you accept and agree to be bound by the terms and provision of this agreement."
+ },
+ "2": {
+ "title": "2. Game Rules",
+ "content": "Users agree not to exploit bugs, use automation software (bots), or engage in harassment of other players. We reserve the right to ban accounts that violate these rules."
+ },
+ "3": {
+ "title": "3. User Accounts",
+ "content": "You are responsible for maintaining the confidentiality of your account and password. You agree to accept responsibility for all activities that occur under your account."
+ },
+ "4": {
+ "title": "4. Virtual Items",
+ "content": "Virtual items and currency in Echoes of the Ash have no real-world value and cannot be exchanged for real currency."
+ },
+ "5": {
+ "title": "5. Disclaimer",
+ "content": "The game is provided \"as is\" without warranties of any kind. We are not responsible for any data loss or service interruptions."
+ }
+ },
+ "back": "Return to Home"
+ }
}
}
\ No newline at end of file
diff --git a/pwa/src/i18n/locales/es.json b/pwa/src/i18n/locales/es.json
index ec59456..46a0bdf 100644
--- a/pwa/src/i18n/locales/es.json
+++ b/pwa/src/i18n/locales/es.json
@@ -11,6 +11,10 @@
"game": "Juego",
"leaderboards": "Clasificación",
"account": "Cuenta",
+ "accountSettings": "Ajustes de Cuenta",
+ "general": "General",
+ "audio": "Audio",
+ "security": "Seguridad",
"info": "Info",
"talk": "Hablar",
"loot": "Saquear",
@@ -21,7 +25,10 @@
"pickUpAll": "Recoger Todo",
"qty": "Cant",
"quests": "Misiones",
- "all": "Todo"
+ "all": "Todo",
+ "prev": "Ant",
+ "next": "Sig",
+ "back": "Volver"
},
"auth": {
"login": "Iniciar sesión",
@@ -38,25 +45,88 @@
"loginTitle": "Bienvenido de nuevo",
"registerTitle": "Crear cuenta",
"loginSubtitle": "Inicia sesión para continuar tu viaje",
- "registerSubtitle": "Únete a los supervivientes"
+ "registerSubtitle": "Únete a los supervivientes",
+ "confirmPassword": "Confirmar Contraseña",
+ "emailPlaceholder": "tu.email@ejemplo.com",
+ "passwordPlaceholder": "Al menos 6 caracteres",
+ "passwordPlaceholderLogin": "Tu contraseña",
+ "confirmPasswordPlaceholder": "Reingresa tu contraseña",
+ "submit": "Crear Cuenta",
+ "submitting": "Creando Cuenta...",
+ "loggingIn": "Iniciando sesión...",
+ "loginLink": "¿Ya tienes una cuenta? Inicia sesión",
+ "registerLink": "¿No tienes una cuenta? Regístrate",
+ "errors": {
+ "invalidEmail": "Por favor ingresa un correo electrónico válido",
+ "passwordLength": "La contraseña debe tener al menos 6 caracteres",
+ "passwordMatch": "Las contraseñas no coinciden",
+ "registrationFailed": "Error en el registro",
+ "loginFailed": "Error al iniciar sesión"
+ },
+ "strength": {
+ "weak": "Débil",
+ "medium": "Media",
+ "strong": "Fuerte"
+ },
+ "accountInfo": "Información de la Cuenta",
+ "accountType": "Tipo de Cuenta",
+ "premiumStatus": "Estado Premium",
+ "premiumActive": "✓ Premium Activo",
+ "freeAccount": "Cuenta Gratuita",
+ "created": "Creado",
+ "lastLogin": "Último Acceso",
+ "gameActions": "Acciones de Juego",
+ "switchCharacter": "Cambiar Personaje",
+ "audioSettings": "Ajustes de Audio",
+ "volumeControls": "Controles de Volumen",
+ "muteAll": "Silenciar Todo",
+ "masterVolume": "Volumen Principal",
+ "musicVolume": "Música",
+ "sfxVolume": "Efectos",
+ "securitySettings": "Ajustes de Seguridad",
+ "changeEmail": "Cambiar Correo",
+ "changePassword": "Cambiar Contraseña",
+ "currentPassword": "Contraseña Actual",
+ "newPassword": "Nueva Contraseña",
+ "confirmNewPassword": "Confirmar Nueva Contraseña",
+ "verifyIdentity": "Verifica tu identidad",
+ "updateEmail": "Actualizar Correo",
+ "updatePassword": "Actualizar Contraseña",
+ "updating": "Actualizando...",
+ "change": "Cambiar",
+ "cancel": "Cancelar"
},
"characters": {
"title": "Seleccionar Personaje",
"createNew": "Crear Nuevo Personaje",
"play": "Jugar",
"delete": "Eliminar",
+ "deleteModal": {
+ "title": "Eliminar Personaje",
+ "confirm": "¿Estás seguro de que quieres eliminar este personaje? Esta acción no se puede deshacer."
+ },
"noCharacters": "Aún no hay personajes",
"createFirst": "Crea tu primer personaje para comenzar",
"name": "Nombre del Personaje",
"class": "Clase",
- "level": "Nivel"
+ "level": "Nivel",
+ "lastActive": "Última actividad",
+ "create": {
+ "title": "Crear Nuevo",
+ "slots": "ranuras usadas"
+ },
+ "premium": {
+ "title": "Límite de Personajes",
+ "description": "¡Mejora a Premium para crear hasta 10 personajes!",
+ "upgrade": "Mejorar a Premium - $4.99"
+ }
},
"game": {
"travel": "🧭 Viajar",
"surroundings": "🌿 Alrededores",
"character": "👤 Personaje",
"equipment": "⚔️ Equipamiento",
- "inventory": "🎒 Abrir Inventario",
+ "inventory": "🎒 Inventario",
"workbench": "🔧 Banco de Trabajo",
"craft": "🔨 Fabricar",
"repair": "🛠️ Reparar",
@@ -67,6 +137,7 @@
"equip": "Equipar",
"unequip": "Desequipar",
"attack": "⚔️ Atacar",
+ "kill": "Mata",
"flee": "🏃 Huir",
"rest": "Descansar",
"onlineCount": "{{count}} En línea",
@@ -90,7 +161,33 @@
"poisoned": "Envenenamiento"
},
"effectAlreadyActive": "Efecto ya activo",
- "found": "Encontrado"
+ "found": "Encontrado",
+ "value": "Valor",
+ "dialog": {
+ "back": "Atrás",
+ "goodbye": "Adiós",
+ "trade": "Comerciar",
+ "acceptQuest": "Aceptar Misión",
+ "completeQuest": "Completar Misión",
+ "handInItems": "Entregar Objetos",
+ "questInProgress": "(Misión en progreso...)",
+ "questAccepted": "¡Misión aceptada! Buena suerte.",
+ "progressUpdated": "Progreso actualizado.",
+ "rewards": "Recompensas"
+ }
+ },
+ "trade": {
+ "title": "Comercio",
+ "buying": "Comprando",
+ "selling": "Vendiendo",
+ "merchantStock": "Inventario del Mercader",
+ "inventory": "Inventario",
+ "invalidOffer": "OFERTA INVÁLIDA",
+ "confirmTrade": "CONFIRMAR COMERCIO",
+ "balance": "Balance",
+ "empty": "Vacío",
+ "clickToRemove": "Haz clic para remover",
+ "howMany": "¿Cuántos {{item}}?"
},
"location": {
"recentActivity": "📜 Actividad Reciente",
@@ -313,7 +410,11 @@
"staminaRegenerated": "Estamina regenerada",
"combatTimeout": "⏱️ ¡Turno saltado por tiempo agotado!",
"interactableReady": "{{action}} está listo en {{name}}",
- "waitBeforeMovingSimple": "Espera {{seconds}}s antes de moverte"
+ "waitBeforeMovingSimple": "Espera {{seconds}}s antes de moverte",
+ "questAccepted": "¡Misión Aceptada!",
+ "questCompleted": "¡Misión Completada!",
+ "questProgressUpdated": "Progreso de Misión Actualizado",
+ "failedToAcceptQuest": "Error al aceptar la misión"
},
"directions": {
"north": "Norte",
@@ -332,9 +433,117 @@
"exit": "Salir"
},
"landing": {
- "heroTitle": "Ecos de las Cenizas",
+ "heroTitle": "Echoes of the Ash",
"heroSubtitle": "Un RPG de supervivencia post-apocalíptico",
"playNow": "Jugar Ahora",
- "features": "Características"
+ "login": "Iniciar Sesión",
+ "features": "Características del Juego",
+ "about": {
+ "title": "Sobre el Mundo",
+ "description": "En un mundo devastado por el fuego nuclear, la supervivencia es la única ley. Busca recursos, fabrica armas distintas y lucha por tu vida contra mutantes y otros supervivientes. ¿Reconstruirás la civilización o reinarás sobre las cenizas?"
+ },
+ "featureCards": {
+ "survival": {
+ "title": "Supervivencia Extrema",
+ "description": "Sobrevive en un entorno hostil lleno de radiación y enemigos mortales. Gestiona tu inventario y recursos sabiamente."
+ },
+ "combat": {
+ "title": "Combate Táctico",
+ "description": "Participa en batallas por turnos donde cada decisión cuenta. Usa habilidades, objetos y estrategia."
+ },
+ "crafting": {
+ "title": "Fabricación Profunda",
+ "description": "Busca materiales para crear armas, armaduras y herramientas esenciales para tu supervivencia."
+ }
+ },
+ "footer": {
+ "copyright": "© {{year}} Echoes of the Ash. Todos los derechos reservados.",
+ "links": {
+ "privacy": "Política de Privacidad",
+ "terms": "Términos de Servicio",
+ "discord": "Unirse a Discord"
+ }
+ }
+ },
+ "journal": {
+ "title": "Diario de Misiones",
+ "activeQuests": "Misiones Activas",
+ "history": "Historial",
+ "searchPlaceholder": "Buscar misiones...",
+ "noQuests": "No se encontraron misiones.",
+ "objectives": "Objetivos",
+ "completionMessage": "Mensaje de Completado",
+ "rewards": "Recompensas",
+ "accepted": "Aceptado",
+ "completed": "Completado",
+ "type": "Tipo",
+ "status": "Estado",
+ "ready": "LISTO",
+ "giver": "Dador",
+ "location": "Ubicación",
+ "inProgress": "En Progreso",
+ "story": "Historia",
+ "side": "Secundaria",
+ "daily": "Diaria",
+ "global": "Global",
+ "selectQuest": "Selecciona una misión para ver detalles",
+ "communityProgress": "Progreso global",
+ "yourContribution": "Tu contribución"
+ },
+ "legal": {
+ "privacy": {
+ "title": "Política de Privacidad",
+ "lastUpdated": "Última actualización: 16 de Febrero de 2026",
+ "sections": {
+ "1": {
+ "title": "1. Información que Recopilamos",
+ "content": "Recopilamos tu dirección de correo electrónico y datos relacionados con el juego (progreso del personaje, inventario, etc.) para proporcionar el servicio."
+ },
+ "2": {
+ "title": "2. Cómo Usamos la Información",
+ "content": "Usamos tu información para administrar tu cuenta, guardar tu progreso y mejorar la experiencia de juego. No vendemos tus datos a terceros."
+ },
+ "3": {
+ "title": "3. Seguridad de Datos",
+ "content": "Implementamos medidas de seguridad para mantener a salvo tu información personal. Sin embargo, ningún método de transmisión por Internet es 100% seguro."
+ },
+ "4": {
+ "title": "4. Cookies",
+ "content": "Usamos almacenamiento local para mantener tu sesión de inicio y configuraciones del juego."
+ },
+ "5": {
+ "title": "5. Contacto",
+ "content": "Si tienes preguntas sobre esta política de privacidad, contáctanos a través de nuestra comunidad de Discord."
+ }
+ },
+ "back": "Volver al Inicio"
+ },
+ "terms": {
+ "title": "Términos de Servicio",
+ "lastUpdated": "Última actualización: 16 de Febrero de 2026",
+ "sections": {
+ "1": {
+ "title": "1. Aceptación de Términos",
+ "content": "Al acceder y usar Echoes of the Ash, aceptas y acuerdas estar sujeto a los términos y disposiciones de este acuerdo."
+ },
+ "2": {
+ "title": "2. Reglas del Juego",
+ "content": "Los usuarios acuerdan no explotar errores, usar software de automatización (bots) o participar en el acoso de otros jugadores. Nos reservamos el derecho de prohibir cuentas que violen estas reglas."
+ },
+ "3": {
+ "title": "3. Cuentas de Usuario",
+ "content": "Eres responsable de mantener la confidencialidad de tu cuenta y contraseña. Aceptas la responsabilidad de todas las actividades que ocurran bajo tu cuenta."
+ },
+ "4": {
+ "title": "4. Objetos Virtuales",
+ "content": "Los objetos virtuales y la moneda en Echoes of the Ash no tienen valor en el mundo real y no pueden intercambiarse por moneda real."
+ },
+ "5": {
+ "title": "5. Descargo de Responsabilidad",
+ "content": "El juego se proporciona \"tal cual\" sin garantías de ningún tipo. No somos responsables de ninguna pérdida de datos o interrupciones del servicio."
+ }
+ },
+ "back": "Volver al Inicio"
+ }
}
}
\ No newline at end of file
diff --git a/pwa/src/index.css b/pwa/src/index.css
index 213a05f..cc09a98 100644
--- a/pwa/src/index.css
+++ b/pwa/src/index.css
@@ -87,20 +87,6 @@
/* Default (1080p and below) */
}
-@media (min-width: 2200px) {
- :root {
- --location-content-width: 1000px;
- /* 1440p */
- }
-}
-
-@media (min-width: 3400px) {
- :root {
- --location-content-width: 1400px;
- /* 4K */
- }
-}
-
/* --- Reusable Game Classes --- */
/* Panels */
diff --git a/pwa/src/services/api.ts b/pwa/src/services/api.ts
index 2c83243..8133649 100644
--- a/pwa/src/services/api.ts
+++ b/pwa/src/services/api.ts
@@ -56,6 +56,10 @@ export interface Character {
is_dead: boolean
created_at: string
last_played_at: string
+ weight: number
+ max_weight: number
+ volume: number
+ max_volume: number
}
export interface LoginResponse {
diff --git a/pwa/vite.config.ts b/pwa/vite.config.ts
index 0e1017a..c8d2662 100644
--- a/pwa/vite.config.ts
+++ b/pwa/vite.config.ts
@@ -18,7 +18,7 @@ export default defineConfig({
theme_color: '#1a1a1a',
background_color: '#1a1a1a',
display: 'standalone',
- orientation: 'portrait',
+ orientation: 'landscape',
scope: '/',
start_url: '/',
icons: [