The Sims Online 2D — full game: CAS, build mode, needs, AI Mode (whim-driven autonomy), careers+chance cards, neighborhood AI sims, death/ghosts, meal tiers+sickness, paintings/novels, house parties, memories, weather; 38 headless tests green

This commit is contained in:
2026-08-23 07:02:13 +00:00
commit 90bcecbf4b
14 changed files with 6626 additions and 0 deletions
+235
View File
@@ -0,0 +1,235 @@
/* ============ The Sims Online 2D — styles ============ */
* { margin:0; padding:0; box-sizing:border-box; user-select:none; }
html,body { width:100%; height:100%; overflow:hidden; background:#0b1020;
font-family:'Segoe UI', 'Trebuchet MS', Verdana, sans-serif; }
#app { position:relative; width:100%; height:100%; }
#game { position:absolute; inset:0; width:100%; height:100%; display:block; cursor:default; }
.hidden { display:none !important; }
button { font-family:inherit; cursor:pointer; }
/* ---------- HUD chips ---------- */
#topbar { position:absolute; top:10px; left:10px; right:10px; display:flex;
gap:8px; align-items:center; z-index:20; pointer-events:none; }
.hud-chip { pointer-events:auto; background:linear-gradient(#3a6fd8,#274b9f);
border:2px solid #16255c; color:#fff; border-radius:12px;
padding:6px 12px; font-size:14px; font-weight:600;
box-shadow:0 3px 8px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.35); }
#fundsBox { font-size:18px; min-width:110px; text-align:center; color:#ffe97a; }
#clockBox { display:flex; gap:6px; align-items:center; }
#speedBox { display:flex; gap:4px; padding:5px 8px; }
.speed-btn { background:#1d3c85; color:#cfe0ff; border:1px solid #14224f;
border-radius:8px; padding:3px 9px; font-size:13px; }
.speed-btn.active { background:#ffd23e; color:#3a2800; border-color:#b98a00; }
#optionsBox { margin-left:auto; display:flex; gap:6px; padding:5px 8px; }
.opt-btn { background:#1d3c85; color:#dfe9ff; border:1px solid #14224f; border-radius:8px;
padding:4px 10px; font-size:12px; font-weight:600; }
.opt-btn:hover { background:#2a51ab; }
.opt-btn.active { background:#37b34a; color:#fff; }
/* ---------- toasts ---------- */
#toasts { position:absolute; top:56px; left:50%; transform:translateX(-50%);
z-index:60; display:flex; flex-direction:column; gap:6px; align-items:center; pointer-events:none; }
.toast { background:rgba(16,24,52,.92); color:#fff; border:2px solid #4a72d6;
padding:8px 18px; border-radius:14px; font-size:14px; max-width:520px;
box-shadow:0 4px 14px rgba(0,0,0,.5); animation:toastIn .25s ease-out; }
.toast.bad { border-color:#e05252; }
.toast.good { border-color:#43c15a; }
.toast .envelope { cursor:pointer; pointer-events:auto; display:inline-block;
background:#ffd23e; color:#4a3200; border-radius:8px; padding:2px 10px; margin-left:8px;
font-weight:700; }
@keyframes toastIn { from { opacity:0; transform:translateY(-12px);} to { opacity:1; } }
/* ---------- bottom bar ---------- */
#bottombar { position:absolute; bottom:10px; left:50%; transform:translateX(-50%);
z-index:20; display:flex; flex-direction:column; gap:8px; align-items:center; }
#modeBtns { display:flex; gap:8px; }
.mode-btn { background:linear-gradient(#4472e0,#22449c); border:2px solid #131f4d;
color:#fff; width:86px; height:64px; border-radius:14px; display:flex;
flex-direction:column; align-items:center; justify-content:center; gap:2px;
box-shadow:0 4px 10px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.35); }
.mode-btn span { font-size:22px; }
.mode-btn label { font-size:11px; font-weight:700; letter-spacing:.08em; cursor:pointer; }
.mode-btn.active { background:linear-gradient(#ffd94e,#e89a00); color:#3a2500;
border-color:#7a5500; transform:translateY(3px); }
#portraitRow { display:flex; gap:8px; }
.portrait { width:74px; height:88px; background:linear-gradient(#20356f,#101b40);
border:2px solid #0c1533; border-radius:12px; position:relative; cursor:pointer;
overflow:hidden; transition:transform .12s; }
.portrait:hover { transform:translateY(-3px); }
.portrait canvas { width:70px; height:62px; display:block; margin-top:2px; }
.portrait .pname { position:absolute; bottom:2px; left:0; right:0; text-align:center;
color:#fff; font-size:11px; font-weight:700; text-shadow:0 1px 2px #000; }
.portrait.selected { border-color:#ffd23e; box-shadow:0 0 12px #ffd23e88; }
.portrait .plumbob { position:absolute; top:3px; right:5px; font-size:13px; }
.moodbar { position:absolute; bottom:16px; left:6px; right:6px; height:5px;
border-radius:3px; background:#222c; overflow:hidden; }
.moodbar > div { height:100%; border-radius:3px; }
/* ---------- sim panel ---------- */
#simPanel { position:absolute; top:60px; right:10px; bottom:96px; width:308px;
background:linear-gradient(#28407f,#182a5c); border:2px solid #0e1838;
border-radius:16px; z-index:30; display:flex; flex-direction:column;
box-shadow:0 8px 24px rgba(0,0,0,.55); color:#fff; }
#simPanelClose { position:absolute; top:8px; right:8px; background:#12204d;
color:#9fb4ea; border:none; border-radius:8px; width:26px; height:26px; font-weight:700; }
#simPanelHead { display:flex; gap:10px; padding:12px 12px 6px; align-items:center; }
#simPortrait { background:#0d1737; border-radius:10px; border:2px solid #0a1230; }
#simPanelName { font-size:17px; font-weight:800; }
#simPanelMood { font-size:12px; color:#bcd0ff; }
#simPanelTabs { display:flex; gap:4px; padding:4px 10px; flex-wrap:wrap; }
#simPanelTabs button { flex:1; background:#152450; color:#a9bdf0; border:1px solid #0c1738;
border-radius:8px; padding:5px 2px; font-size:11px; font-weight:700; }
#simPanelTabs button.active { background:#ffd23e; color:#3a2800; }
#simPanelBody { flex:1; overflow-y:auto; padding:8px 12px 12px; font-size:13px; }
.needRow { margin-bottom:8px; }
.needRow .nlabel { display:flex; justify-content:space-between; font-size:12px; margin-bottom:2px; }
.nbar { height:10px; background:#0c1636; border-radius:5px; overflow:hidden;
border:1px solid #0a1230; }
.nbar > div { height:100%; transition:width .4s; }
.skillRow { display:flex; justify-content:space-between; align-items:center; margin-bottom:6px; }
.pips { letter-spacing:2px; font-size:11px; }
.relCard { background:#152450; border:1px solid #0c1738; border-radius:10px;
padding:8px; margin-bottom:8px; }
.relCard .rname { font-weight:700; margin-bottom:4px; display:flex; justify-content:space-between;}
.relBar { height:8px; border-radius:4px; background:#0c1636; margin-bottom:3px; overflow:hidden; }
.relBar > div { height:100%; }
.careerLine { margin-bottom:8px; line-height:1.45; }
.bioLine { margin-bottom:6px; }
#simPanelBody::-webkit-scrollbar { width:8px; }
#simPanelBody::-webkit-scrollbar-thumb { background:#3a5aa8; border-radius:4px; }
/* ---------- buy drawer ---------- */
#buyDrawer { position:absolute; bottom:96px; left:10px; right:10px; height:218px;
background:linear-gradient(#28407f,#141f47); border:2px solid #0e1838; border-radius:16px;
z-index:25; display:flex; flex-direction:column; color:#fff;
box-shadow:0 -6px 20px rgba(0,0,0,.5); }
#buyTabs { display:flex; gap:4px; padding:8px 10px 4px; flex-wrap:wrap; }
#buyTabs button { background:#152450; color:#a9bdf0; border:1px solid #0c1738;
border-radius:8px 8px 0 0; padding:5px 12px; font-size:12px; font-weight:700; }
#buyTabs button.active { background:#ffd23e; color:#3a2800; }
#buyGrid { flex:1; overflow-y:auto; display:flex; gap:8px; padding:8px 12px; flex-wrap:wrap;
align-content:flex-start; }
.buyItem { width:104px; background:#152450; border:2px solid #0c1738; border-radius:10px;
padding:6px; text-align:center; cursor:pointer; }
.buyItem:hover { border-color:#ffd23e; }
.buyItem.sel { border-color:#43c15a; box-shadow:0 0 10px #43c15a88; }
.buyItem canvas { width:84px; height:64px; }
.buyItem .bn { font-size:11px; font-weight:700; white-space:nowrap; overflow:hidden;
text-overflow:ellipsis; }
.buyItem .bp { color:#ffe97a; font-size:12px; font-weight:800; }
#buyHint, #buildHint { padding:4px 12px 8px; font-size:11px; color:#9fb4ea; }
#buildHint b { color:#ffd23e; }
/* ---------- build bar ---------- */
#buildBar { position:absolute; bottom:96px; left:50%; transform:translateX(-50%);
background:linear-gradient(#28407f,#141f47); border:2px solid #0e1838; border-radius:14px;
z-index:25; display:flex; gap:6px; align-items:center; padding:8px 12px; color:#fff;
flex-wrap:wrap; max-width:92vw; }
#buildBar button { background:#152450; color:#dfe9ff; border:1px solid #0c1738;
border-radius:9px; padding:7px 12px; font-size:13px; font-weight:600; }
#buildBar button.active { background:#ffd23e; color:#3a2800; }
#floorSwatches { display:flex; gap:4px; margin-left:4px; }
.swatch { width:22px; height:22px; border-radius:5px; border:2px solid #0c1738; cursor:pointer; }
.swatch.sel { border-color:#fff; }
/* ---------- pie menu ---------- */
#pieMenu { position:absolute; z-index:50; background:rgba(13,20,46,.96);
border:2px solid #4a72d6; border-radius:12px; padding:6px; min-width:170px;
box-shadow:0 6px 18px rgba(0,0,0,.6); }
#pieMenu .pi { display:flex; gap:8px; align-items:center; padding:7px 12px; color:#fff;
border-radius:8px; cursor:pointer; font-size:13px; }
#pieMenu .pi:hover { background:#2a51ab; }
#pieMenu .pi.dis { opacity:.4; pointer-events:none; }
#pieMenu .pi .price { margin-left:auto; color:#ffe97a; font-weight:700; }
#pieMenu hr { border:none; border-top:1px solid #2a3f80; margin:4px 6px; }
/* ---------- CAS screen ---------- */
#casScreen { position:absolute; inset:0; z-index:80; background:
radial-gradient(1200px 700px at 50% 20%, #2b3f86 0%, #131c44 55%, #0a0f26 100%);
display:flex; flex-direction:column; align-items:center; color:#fff; overflow-y:auto; padding:14px; }
.cas-title { font-size:34px; letter-spacing:.06em; text-shadow:0 3px 0 #0a1030; margin-bottom:6px; }
#casMain { display:flex; gap:18px; align-items:flex-start; }
#casLeft { display:flex; flex-direction:column; align-items:center; gap:8px; }
#casPreview { background:linear-gradient(#1a2a5e,#0d1533); border:2px solid #0a1230; border-radius:16px; }
#casRight { width:400px; display:flex; flex-direction:column; gap:9px; }
.cas-row { display:flex; align-items:center; gap:8px; flex-wrap:wrap;
background:rgba(21,36,80,.75); border:1px solid #0c1738; border-radius:12px; padding:8px 10px; }
.cas-row .clabel { width:92px; font-size:12px; font-weight:700; color:#bcd0ff; }
.swatchBig { width:26px; height:26px; border-radius:7px; border:2px solid #0c1738; cursor:pointer; }
.swatchBig.sel { border-color:#fff; box-shadow:0 0 8px #fff8; }
.chip { background:#152450; border:2px solid #0c1738; color:#dfe9ff; border-radius:9px;
padding:5px 11px; font-size:12px; font-weight:700; cursor:pointer; }
.chip.sel { background:#ffd23e; color:#3a2800; border-color:#7a5500; }
input[type=text] { background:#0d1737; border:1px solid #2a3f80; color:#fff;
border-radius:8px; padding:7px 10px; font-size:15px; font-family:inherit; width:200px; }
input[type=range] { flex:1; accent-color:#ffd23e; }
.pval { width:22px; text-align:center; font-weight:800; color:#ffe97a; }
#casFamilyRow { display:flex; gap:8px; margin-top:10px; flex-wrap:wrap; justify-content:center; }
.famSlot { width:64px; height:78px; border-radius:10px; background:rgba(21,36,80,.75);
border:2px dashed #2a3f80; display:flex; flex-direction:column; align-items:center;
justify-content:center; cursor:pointer; font-size:10px; color:#8fa6dd; position:relative; }
.famSlot.sel { border-style:solid; border-color:#ffd23e; color:#fff; }
.famSlot canvas { width:58px; height:48px; }
.famSlot .del { position:absolute; top:-7px; right:-7px; background:#e05252; color:#fff;
border:none; width:20px; height:20px; border-radius:50%; font-size:11px; display:none; }
.famSlot:hover .del { display:block; }
#casActions { display:flex; gap:10px; margin-top:10px; }
.cas-btn { background:#152450; color:#dfe9ff; border:2px solid #0c1738; border-radius:11px;
padding:9px 18px; font-size:14px; font-weight:700; }
.cas-btn:hover { background:#1e3272; }
.cas-btn.primary { background:linear-gradient(#ffd94e,#e89a00); color:#3a2500; border-color:#7a5500; }
/* ---------- title ---------- */
#titleScreen { position:absolute; inset:0; z-index:90; display:flex; align-items:center;
justify-content:center; background:
radial-gradient(1400px 900px at 50% 30%, #2e4390 0%, #16204d 50%, #090e22 100%); }
#titleInner { text-align:center; color:#fff; }
#titleInner h1 { font-size:76px; letter-spacing:.04em; text-shadow:0 5px 0 #0a1030, 0 0 40px #4a72d688; }
#titleInner h1 .tm { font-size:22px; vertical-align:top; }
#titleInner h2 { font-size:22px; letter-spacing:.42em; color:#ffd23e; margin:2px 0 10px; }
.tagline { color:#aebfec; margin-bottom:26px; font-style:italic; }
.title-btn { display:block; width:260px; margin:10px auto; background:linear-gradient(#4472e0,#22449c);
border:2px solid #131f4d; color:#fff; font-size:19px; font-weight:800; padding:13px;
border-radius:14px; box-shadow:0 5px 14px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.35); }
.title-btn:hover { filter:brightness(1.15); transform:translateY(-2px); }
.credits { margin-top:24px; color:#67799f; font-size:12px; }
/* ---------- help ---------- */
#helpOverlay { position:absolute; inset:0; z-index:95; background:rgba(5,8,20,.72);
display:flex; align-items:center; justify-content:center; }
#helpCard { background:linear-gradient(#28407f,#141f47); border:2px solid #4a72d6;
border-radius:18px; padding:22px 26px; max-width:560px; color:#e7eeff; }
#helpCard h2 { margin-bottom:10px; color:#ffd23e; }
#helpCard ul { list-style:none; }
#helpCard li { margin-bottom:8px; line-height:1.45; font-size:13.5px; }
#helpCard b { color:#ffd23e; }
#helpClose { margin-top:8px; float:right; }
@media (max-width: 900px) {
#simPanel { width:260px; }
#casRight { width:min(400px, 92vw); }
}
/* ===== career chance card modal ===== */
#chanceCard {
position: fixed; inset: 0; z-index: 90;
display: flex; align-items: center; justify-content: center;
background: rgba(10, 14, 24, .55); backdrop-filter: blur(2px);
}
#chanceCard.hidden { display: none; }
.cc-box {
width: min(430px, 92vw); background: linear-gradient(#fdf8ec, #f1e7d0);
border: 3px solid #b98a2e; border-radius: 16px; padding: 18px 20px;
box-shadow: 0 12px 40px rgba(0,0,0,.5); font-family: inherit;
}
.cc-head { font-weight: bold; color: #7a4d12; margin-bottom: 8px; letter-spacing: .3px; }
.cc-q { font-size: 15px; color: #2e2a22; min-height: 42px; }
.cc-btns { display: flex; gap: 10px; margin-top: 14px; flex-wrap: wrap; }
.cc-btns button {
flex: 1; padding: 9px 10px; border: none; border-radius: 10px; cursor: pointer;
background: #2f6f3e; color: #fff; font-weight: bold; font-size: 13px;
}
.cc-btns button:last-child { background: #8a4040; }
.cc-btns button:hover { filter: brightness(1.12); }
.cc-sub { margin-top: 10px; font-size: 11px; color: #94856a; text-align: center; }