Compare commits
9 Commits
e90dccd8bb
...
agent/code
| Author | SHA1 | Date | |
|---|---|---|---|
| 744749bc54 | |||
| c1e6b4b61f | |||
| 139c0d4fd2 | |||
| 8ce9314887 | |||
| 40100cccab | |||
| a079598f9c | |||
| 263bee12dd | |||
| de815cb9c1 | |||
| bf48924644 |
@@ -61,11 +61,6 @@ COPY --from=build /app/apps/worker apps/worker
|
||||
COPY --from=build /app/packages/shared packages/shared
|
||||
COPY --from=build /app/packages/game-engine packages/game-engine
|
||||
|
||||
# Nitro 2.10 resolves file-backed public assets from the directory containing
|
||||
# its split runtime chunk. Keep the generated output in its standard location
|
||||
# and expose it at that runtime path without storing a second copy.
|
||||
RUN ln -s ../../public apps/web/.output/server/chunks/public
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
# Coolify (and other hosts) override PORT at runtime; probe that port, not a
|
||||
|
||||
1
PLAN.md
1
PLAN.md
@@ -190,4 +190,3 @@ Desktop‑версия позднее создаётся через Tauri и и
|
||||
- MVP полностью текстовый.
|
||||
- Не входят: публичный каталог, marketplace, карты, изображения, TTS, видеогенерация, полноценный 5e combat, нативный desktop/mobile и пользовательские ruleset.
|
||||
- После альфы приоритет определяется метриками: удержание кампаний, завершённые раунды, стоимость AI‑хода, частота ручных исправлений и качество памяти.
|
||||
|
||||
|
||||
@@ -1 +1,24 @@
|
||||
:root{--acid:#d9f75f;--acid-dim:#596522;--ink:#eeeeE7;--muted:#888881;--line:#272725;--display:'Unbounded',sans-serif;--body:'Manrope',sans-serif;--mono:'DM Mono',monospace;color-scheme:dark}*{box-sizing:border-box}html{background:#0a0a0a;color:var(--ink);font-family:var(--body);scroll-behavior:smooth}body{margin:0;background:#0a0a0a}button,input,textarea{font:inherit}button,a{transition:filter .2s ease,opacity .2s ease}button:not(:disabled),a{cursor:pointer}button:hover:not(:disabled),a:hover{filter:brightness(1.12)}::selection{background:var(--acid);color:#070707}.noise{background-color:#0a0a0a;background-image:linear-gradient(rgba(255,255,255,.013) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.013) 1px,transparent 1px);background-size:34px 34px}textarea:focus,input:focus,button:focus-visible,a:focus-visible{outline:1px solid var(--acid);outline-offset:2px}@media(prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;animation-iteration-count:1!important;scroll-behavior:auto!important}}
|
||||
|
||||
/* Keep account pages usable even when a route-level component stylesheet is delayed or missed. */
|
||||
.auth-page{min-height:100vh;display:grid;place-content:center;justify-items:center;gap:28px;padding:42px 20px}
|
||||
.auth-page .auth-card{width:min(480px,calc(100vw - 40px));padding:clamp(28px,5vw,48px);border:1px solid var(--line);background:linear-gradient(145deg,#11110f,#090909);box-shadow:0 35px 100px rgba(0,0,0,.48)}
|
||||
.auth-page .auth-card header small{font:600 8px var(--mono);letter-spacing:.18em;color:var(--acid)}
|
||||
.auth-page .auth-card header h1{margin:14px 0 12px;font:600 clamp(32px,6vw,52px)/1 var(--display);letter-spacing:-.06em}
|
||||
.auth-page .auth-card header p{margin:0 0 30px;color:var(--muted);font-size:12px;line-height:1.7}
|
||||
.auth-page .auth-card footer{margin-top:25px;padding-top:22px;border-top:1px solid var(--line);text-align:center;color:var(--muted);font-size:11px}
|
||||
.auth-page .security-note{font:500 7px var(--mono);letter-spacing:.13em;color:var(--muted)}
|
||||
.auth-page .security-note i{display:inline-block;width:5px;height:5px;margin-right:8px;border-radius:50%;background:var(--acid)}
|
||||
.auth-page .auth-form{display:grid;gap:15px}
|
||||
.auth-page .auth-form label{display:grid;gap:8px;font:600 8px var(--mono);letter-spacing:.11em;color:#b5b5ae}
|
||||
.auth-page .auth-form input{box-sizing:border-box;width:100%;min-height:48px;padding:0 14px;border:1px solid #373732;background:#0a0a09;color:var(--ink);font:12px var(--body);outline:none}
|
||||
.auth-page .auth-form input:focus{border-color:var(--acid)}
|
||||
.auth-page .auth-form button{min-height:50px;border:0;background:var(--acid);color:#080808;font:700 9px var(--mono);letter-spacing:.12em}
|
||||
.auth-page .auth-form button:disabled{opacity:.45;cursor:wait}
|
||||
.auth-page .form-error,.auth-page .form-success{margin:0;padding:12px 14px;border:1px solid #6b372e;background:#221310;color:#ffab98;font:500 9px/1.55 var(--mono)}
|
||||
.auth-page .form-success{border-color:#526425;background:#151a0d;color:var(--acid)}
|
||||
.auth-page .form-link{color:var(--acid);text-decoration:none;font-weight:600}
|
||||
.auth-page .field-row{display:flex;align-items:center;justify-content:space-between}
|
||||
.auth-page .field-row a{color:var(--muted);font:500 8px var(--mono)}
|
||||
.auth-page .auth-form .consent{grid-template-columns:18px 1fr!important;align-items:start!important;font:400 10px/1.5 var(--body)!important;letter-spacing:0!important;color:var(--muted)!important}
|
||||
.auth-page .auth-form .consent input{width:16px!important;min-height:16px!important;margin:1px 0 0;padding:0!important;accent-color:var(--acid)}
|
||||
|
||||
@@ -3,6 +3,13 @@ export default defineNuxtConfig({
|
||||
devtools: { enabled: false },
|
||||
css: ['~/assets/css/main.css'],
|
||||
modules: [],
|
||||
nitro: {
|
||||
// Nitro 2.10 resolves file-backed assets relative to its split runtime
|
||||
// chunk, which makes every /_nuxt request fail outside the Docker-only
|
||||
// symlink workaround. Embedding them keeps every production launcher
|
||||
// (preview, Docker, and managed hosts) on the same reliable code path.
|
||||
serveStatic: 'inline',
|
||||
},
|
||||
runtimeConfig: {
|
||||
aiProvider: process.env.AI_PROVIDER ?? 'openrouter',
|
||||
openrouterApiKey: process.env.OPENROUTER_API_KEY,
|
||||
|
||||
@@ -94,5 +94,43 @@ onMounted(async () => {
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.draft-world .world-art{background:radial-gradient(circle at 50% 60%,#3f4720 0 2%,#1c2011 9%,#080808 58%)}.draft-world .world-art span{background:transparent;color:var(--acid);border:1px solid var(--acid-dim)}
|
||||
.dash-wrap{min-height:calc(100vh - 76px);padding:clamp(42px,6vw,86px) clamp(20px,6vw,88px)}
|
||||
.dash-head{display:flex;align-items:end;justify-content:space-between;gap:30px}
|
||||
.kicker{font:500 9px var(--mono);letter-spacing:.2em;color:var(--acid)}
|
||||
.dash-head h1{margin:14px 0 10px;font:600 clamp(44px,6vw,82px)/1 var(--display);letter-spacing:-.06em}
|
||||
.dash-head h1 span{color:var(--acid)}
|
||||
.dash-head p{color:var(--muted)}
|
||||
.create-button{display:flex;align-items:center;gap:18px;padding:18px 22px;background:var(--acid);color:#090909;text-decoration:none;font:600 10px var(--mono);letter-spacing:.12em}
|
||||
.create-button span{font-size:20px}
|
||||
.filter-row{display:flex;align-items:center;gap:10px;margin:58px 0 24px;border-bottom:1px solid var(--line)}
|
||||
.filter-row button{padding:0 4px 16px;margin-right:18px;background:none;border:0;color:var(--muted);font:500 9px var(--mono);text-transform:uppercase;letter-spacing:.14em}
|
||||
.filter-row button.active{color:var(--ink);border-bottom:2px solid var(--acid)}
|
||||
.filter-row>span{margin-left:auto;padding-bottom:16px;font:500 8px var(--mono);color:var(--muted)}
|
||||
.world-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px}
|
||||
.load-state{grid-column:1/-1;padding:34px;border:1px solid var(--line);font:500 9px var(--mono);color:var(--muted)}
|
||||
.load-state.error{color:#ff9d85}
|
||||
.load-state a{color:var(--acid)}
|
||||
.world-card{min-height:420px;border:1px solid var(--line);color:var(--ink);text-decoration:none;background:#0e0e0d;transition:border-color .25s ease,transform .25s ease}
|
||||
.world-card:hover{border-color:#65655e;transform:translateY(-3px)}
|
||||
.active-world{display:grid;grid-template-columns:.75fr 1.25fr}
|
||||
.world-art{position:relative;overflow:hidden;display:grid;place-items:center;background:radial-gradient(circle at 50% 60%,#7d8240 0 2%,#303018 4%,#0b0b0a 36%,#030303 72%)}
|
||||
.world-art::before{content:"";position:absolute;width:320px;height:320px;border:1px solid #38382d;border-radius:50%;box-shadow:0 0 0 34px #111,0 0 0 35px #26261d}
|
||||
.eclipse{position:absolute;width:126px;height:126px;border-radius:50%;background:#020202;box-shadow:0 0 50px var(--acid-dim)}
|
||||
.world-art span{position:absolute;left:20px;top:20px;padding:9px 11px;background:var(--acid);color:#0a0a0a;font:600 8px var(--mono);letter-spacing:.12em}
|
||||
.draft-world .world-art{background:radial-gradient(circle at 50% 60%,#3f4720 0 2%,#1c2011 9%,#080808 58%)}
|
||||
.draft-world .world-art span{background:transparent;color:var(--acid);border:1px solid var(--acid-dim)}
|
||||
.world-info{padding:42px;display:flex;flex-direction:column;min-width:0}
|
||||
.world-info small{font:500 8px var(--mono);letter-spacing:.14em;color:var(--acid);text-transform:uppercase}
|
||||
.world-info h2,.new-card h2{font:600 clamp(25px,3vw,42px)/1.05 var(--display);letter-spacing:-.05em;margin:22px 0;overflow-wrap:anywhere}
|
||||
.world-info p,.new-card p{color:var(--muted);font-size:13px;line-height:1.7;display:-webkit-box;-webkit-line-clamp:5;-webkit-box-orient:vertical;overflow:hidden}
|
||||
.world-info div{margin-top:auto;padding-top:26px;border-top:1px solid var(--line);display:flex;justify-content:space-between;gap:16px;font:500 8px var(--mono);color:var(--muted)}
|
||||
.world-info b{color:var(--acid)}
|
||||
.new-card{padding:48px;display:flex;flex-direction:column;justify-content:flex-end;background:linear-gradient(145deg,#121211,#090909)}
|
||||
.new-card .plus{margin-bottom:auto;font:300 42px var(--body);color:var(--acid)}
|
||||
.system-strip{margin-top:32px;padding:18px 0;border-top:1px solid var(--line);display:flex;justify-content:space-between;font:500 8px var(--mono);letter-spacing:.12em;color:var(--muted)}
|
||||
.system-strip i{display:inline-block;width:6px;height:6px;background:var(--acid);border-radius:50%;margin-right:8px}
|
||||
.system-strip b{color:var(--acid)}
|
||||
@media(max-width:1050px){.world-grid{grid-template-columns:1fr}}
|
||||
@media(max-width:850px){.dash-head{align-items:start;flex-direction:column}.active-world{grid-template-columns:1fr}.world-art{min-height:280px}.system-strip{gap:16px;flex-wrap:wrap}}
|
||||
@media(max-width:520px){.dash-head h1{font-size:clamp(34px,12vw,52px)}.create-button{width:100%;justify-content:center}.filter-row>span{display:none}.world-info,.new-card{padding:28px}.active-world{min-height:580px}.world-info div{align-items:flex-start;flex-direction:column}.system-strip{flex-direction:column}}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user