:root { color: #f5f7f0; background: #0e1813; font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; font-synthesis: none; text-rendering: optimizeLegibility; } * { box-sizing: border-box; } html, body, #root { width: 100%; height: 100%; margin: 0; overflow: hidden; } button { font: inherit; } .shell { position: relative; width: 100vw; height: 100svh; overflow: hidden; } .worldCanvas { position: absolute !important; inset: 0; z-index: 0; width: 100% !important; height: 100% !important; } /* ---------------------------------------------------------------- panels */ .scoreboard, .eventFeed, .controls, .agentPanel, .errorToast, .busyToast { border: 1px solid rgb(255 255 255 / 18%); background: rgb(18 28 23 / 80%); box-shadow: 0 18px 60px rgb(0 0 0 / 22%); backdrop-filter: blur(14px); } /* ------------------------------------------------------------ scoreboard */ .scoreboard { position: absolute; top: 14px; left: 50%; z-index: 60; width: min(460px, calc(100vw - 28px)); display: grid; gap: 8px; padding: 10px 14px 12px; border-radius: 10px; transform: translateX(-50%); } .scoreDuel { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 10px; } .scoreSide { display: flex; align-items: baseline; gap: 10px; } .scoreName { font-size: 13px; font-weight: 800; letter-spacing: 0.06em; } .scoreValue { font-size: 24px; font-weight: 800; line-height: 1; } .scoreVs { color: rgb(245 247 240 / 55%); font-size: 12px; font-weight: 700; text-transform: uppercase; } .scoreMeta { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 10px; color: rgb(245 247 240 / 78%); font-size: 12px; } .scoreActivity { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #c7e6bd; } .famineBadge { padding: 2px 8px; border: 1px solid rgb(240 195 78 / 50%); border-radius: 5px; background: rgb(240 195 78 / 14%); color: #ffeebc; font-size: 11px; font-weight: 800; letter-spacing: 0.04em; animation: faminePulse 1.6s ease-in-out infinite; } .countryGrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; } .countryCard { display: grid; gap: 5px; min-width: 0; padding: 8px 9px; border: 1px solid rgb(255 255 255 / 22%); border-radius: 8px; background: rgb(255 255 255 / 7%); } .countryCardEmpty { grid-column: 1 / -1; color: rgb(245 247 240 / 60%); font-size: 12px; } .countryHead { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 6px; font-size: 11px; } .countryHead strong { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .countryHead span:last-child { color: rgb(245 247 240 / 58%); font-size: 10px; } .countryBadge, .npcCountryBadge { display: inline-grid; place-items: center; width: 18px; height: 18px; border-radius: 5px; color: #101813; font-size: 11px; font-weight: 900; line-height: 1; } .countryPolicy { margin: 0; min-height: 2.5em; color: rgb(245 247 240 / 82%); font-size: 11px; line-height: 1.25; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; } .countryFacts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 3px 8px; color: rgb(245 247 240 / 62%); font-size: 10px; } .countryFacts span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } @keyframes faminePulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } } .winProgress { display: grid; gap: 5px; } .winRow { display: grid; grid-template-columns: 158px 1fr; align-items: center; gap: 8px; } .winLabel { font-size: 11px; color: rgb(245 247 240 / 82%); white-space: nowrap; } .winBar { height: 8px; border-radius: 5px; background: rgb(255 255 255 / 12%); overflow: hidden; } .winFill { display: block; height: 100%; border-radius: 5px; transition: width 320ms ease; } .winFillPopulation { background: linear-gradient(90deg, #6fd96a, #b8f08a); } .winFillSurvival { background: linear-gradient(90deg, #5b96f0, #9fd1ff); } .modelPills { display: flex; gap: 6px; justify-content: center; } .modelPill { padding: 4px 8px; border-radius: 5px; background: rgb(255 255 255 / 9%); font-size: 10px; } .modelStatusReady { color: #d9f4cf; } .modelStatusWarmup, .modelStatusUnknown { color: #fff3a1; } .modelStatusError { color: #ffd3c8; } .scoreboard .tooltipAnchor[data-tooltip]::before { top: calc(100% + 2px); bottom: auto; border-top-color: transparent; border-bottom-color: rgb(10 17 14 / 96%); } .scoreboard .tooltipAnchor[data-tooltip]::after { top: calc(100% + 14px); bottom: auto; } /* ------------------------------------------------------------ side panels */ .sidePanelHeader { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 11px 12px 9px; border-bottom: 1px solid rgb(255 255 255 / 14%); } .sidePanelTitle { font-size: 13px; font-weight: 800; color: #fffce9; } .sidePanelHint { font-size: 11px; color: rgb(245 247 240 / 55%); } .eventEmpty { margin: 0; padding: 12px; color: rgb(245 247 240 / 55%); font-size: 12px; } /* ------------------------------------------------------------- event feed */ .eventFeed { position: absolute; top: 14px; right: 14px; bottom: 84px; z-index: 30; width: min(316px, calc(100vw - 28px)); display: flex; flex-direction: column; border-radius: 10px; overflow: hidden; } .eventList { flex: 1; min-height: 0; overflow-y: auto; padding: 6px 8px 10px; display: grid; gap: 2px; align-content: start; scrollbar-width: thin; } .eventLine { display: grid; grid-template-columns: 34px 20px 1fr; gap: 6px; align-items: baseline; padding: 4px 6px; border-left: 3px solid transparent; border-radius: 4px; font-size: 12px; line-height: 1.3; } .eventTick { color: rgb(245 247 240 / 45%); font-size: 10px; font-variant-numeric: tabular-nums; text-align: right; } .eventIcon { text-align: center; } .eventText { color: rgb(245 247 240 / 88%); overflow-wrap: anywhere; } .severityGood { border-left-color: #6fd96a; background: rgb(111 217 106 / 8%); } .severityGood .eventText { color: #d6f5cf; } .severityWarning { border-left-color: #f0c34e; background: rgb(240 195 78 / 8%); } .severityWarning .eventText { color: #ffeebc; } .severityDanger { border-left-color: #f06a4e; background: rgb(240 106 78 / 10%); } .severityDanger .eventText { color: #ffd3c8; } .severityNeutral { border-left-color: rgb(255 255 255 / 18%); } .directiveTarget { flex-shrink: 0; color: #9fd1ff; font-weight: 700; font-family: ui-monospace, monospace; font-size: 10px; } .directiveText { color: rgb(245 247 240 / 82%); } .directiveBadge { flex-shrink: 0; padding: 1px 5px; border-radius: 4px; background: rgb(240 195 78 / 18%); color: #ffeebc; font-size: 9px; font-weight: 700; } /* --------------------------------------------------------------- controls */ .controls { position: absolute; right: 14px; bottom: 18px; z-index: 30; display: flex; gap: 8px; padding: 8px; border-radius: 8px; } .controls button { width: 42px; height: 42px; display: grid; place-items: center; border: 0; border-radius: 7px; color: #f7f5dd; background: rgb(255 255 255 / 12%); cursor: pointer; } .controls button:disabled { cursor: wait; opacity: 0.88; } .controls button:hover { background: rgb(255 255 255 / 20%); } .controls button.isActive { color: #142018; background: #f8df6b; } .controls button.isActive:hover { background: #ffe983; } .controls button:focus-visible, .npcLabel button:focus-visible { outline: 2px solid #f8df6b; outline-offset: 2px; } /* -------------------------------------------------------------- agent panel */ .agentPanel { position: absolute; left: 14px; bottom: 18px; z-index: 30; width: min(316px, calc(100vw - 108px)); border-radius: 8px; overflow: visible; } .panelHeader { display: flex; justify-content: space-between; gap: 12px; padding: 13px 14px 10px; border-bottom: 1px solid rgb(255 255 255 / 14%); } .panelTitle { min-width: 0; color: #fffce9; font-size: 15px; font-weight: 750; } .panelRole { color: #c7e6bd; font-size: 12px; text-transform: uppercase; } .agentReadout { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1px; background: rgb(255 255 255 / 10%); } .readoutCell { min-width: 0; padding: 11px 8px; background: rgb(18 28 23 / 68%); color: rgb(245 247 240 / 82%); font-size: 12px; text-align: center; } .healthCell { color: #fff3a1; font-weight: 750; } .modelControl { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 8px; padding: 8px 10px; border-top: 1px solid rgb(255 255 255 / 10%); background: rgb(255 255 255 / 5%); } .modelControl span { color: #c7e6bd; font-size: 10px; font-weight: 750; letter-spacing: 0.07em; text-transform: uppercase; } .modelControl select { min-width: 0; height: 30px; border: 1px solid rgb(255 255 255 / 18%); border-radius: 6px; background: rgb(18 28 23 / 88%); color: #fffce9; font-size: 11px; } .modelControl select:disabled { opacity: 0.65; } .directiveBanner { display: grid; gap: 4px; padding: 10px 12px; border-top: 1px solid rgb(255 255 255 / 10%); background: rgb(248 223 107 / 9%); } .directiveBanner span { color: #fff3a1; font-size: 11px; font-weight: 750; line-height: 1.1; text-transform: uppercase; } .directiveBanner p { margin: 0; color: rgb(245 247 240 / 86%); font-size: 12px; line-height: 1.35; } .relationshipStrip { display: flex; flex-wrap: wrap; gap: 6px; padding: 9px 10px 0; } .relationshipPill { max-width: 96px; padding: 6px 8px; border-radius: 6px; background: rgb(255 255 255 / 9%); color: rgb(245 247 240 / 82%); font-size: 11px; line-height: 1; } .houseResidents { display: grid; gap: 2px; padding: 9px 0 0; } .houseResidents:last-child { padding-bottom: 10px; } .houseResidentsLabel { padding: 0 10px; color: #c7e6bd; font-size: 10px; font-weight: 750; letter-spacing: 0.07em; text-transform: uppercase; } .houseResidentStrip { padding-top: 4px; } button.houseResidentPill { border: none; font: inherit; font-size: 11px; cursor: pointer; } button.houseResidentPill:hover { background: rgb(255 255 255 / 18%); color: #fffce9; } .memoryList { max-height: 148px; overflow-y: auto; padding: 9px 10px 10px; } .memorySummary, .memoryItem { display: grid; gap: 4px; padding: 9px 0; border-bottom: 1px solid rgb(255 255 255 / 10%); } .memorySummary { padding-top: 0; } .memoryItem:last-child { border-bottom: 0; } .memoryTick { color: #c7e6bd; font-size: 11px; line-height: 1.1; } .memorySummary p, .memoryItem p { position: relative; margin: 0; color: rgb(245 247 240 / 84%); font-size: 12px; line-height: 1.35; } .memorySummary p { color: rgb(245 247 240 / 72%); } .thinkingBlock { display: grid; gap: 4px; margin: 8px 10px 0; padding: 9px 10px; max-height: 140px; overflow-y: auto; border: 1px solid rgb(160 180 255 / 22%); border-radius: 8px; background: rgb(120 140 255 / 8%); } .thinkingLabel { color: #b9c4ff; font-size: 11px; line-height: 1.1; letter-spacing: 0.02em; } .thinkingText { margin: 0; color: rgb(232 236 255 / 86%); font-size: 12px; font-style: italic; line-height: 1.4; white-space: pre-wrap; } /* ----------------------------------------------------------------- tooltips */ .tooltipAnchor { position: relative; min-width: 0; overflow: visible; } .tooltipAnchor:focus-visible { outline: 2px solid #f8df6b; outline-offset: 2px; } .truncateText { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .tooltipMeasure { position: absolute; width: max-content; height: 0; overflow: hidden; pointer-events: none; visibility: hidden; white-space: nowrap; } .tooltipAnchor[data-tooltip]::before, .tooltipAnchor[data-tooltip]::after, .memoryItem p[data-tooltip]::before, .memoryItem p[data-tooltip]::after { position: absolute; left: 50%; z-index: 80; opacity: 0; pointer-events: none; transition: opacity 120ms ease, transform 120ms ease, visibility 120ms ease; visibility: hidden; } .tooltipAnchor[data-tooltip]::before, .memoryItem p[data-tooltip]::before { content: ""; border: 6px solid transparent; } .tooltipAnchor[data-tooltip]::after, .memoryItem p[data-tooltip]::after { content: attr(data-tooltip); width: max-content; max-width: min(320px, calc(100vw - 28px)); padding: 8px 10px; border: 1px solid rgb(255 255 255 / 18%); border-radius: 6px; background: rgb(10 17 14 / 96%); box-shadow: 0 14px 42px rgb(0 0 0 / 28%); color: #fffce9; font-size: 12px; font-weight: 600; line-height: 1.3; overflow-wrap: anywhere; text-align: left; text-transform: none; white-space: normal; } .tooltipAnchor[data-tooltip]:hover::before, .tooltipAnchor[data-tooltip]:hover::after, .tooltipAnchor[data-tooltip]:focus-visible::before, .tooltipAnchor[data-tooltip]:focus-visible::after, .memoryItem p[data-tooltip]:hover::before, .memoryItem p[data-tooltip]:hover::after { opacity: 1; visibility: visible; } .tooltipAnchor[data-tooltip]::before, .memoryItem p[data-tooltip]::before { bottom: calc(100% + 2px); border-top-color: rgb(10 17 14 / 96%); transform: translate(-50%, 4px); } .tooltipAnchor[data-tooltip]::after, .memoryItem p[data-tooltip]::after { bottom: calc(100% + 14px); transform: translate(-50%, 4px); } .tooltipAnchor[data-tooltip]:hover::before, .tooltipAnchor[data-tooltip]:hover::after, .tooltipAnchor[data-tooltip]:focus-visible::before, .tooltipAnchor[data-tooltip]:focus-visible::after, .memoryItem p[data-tooltip]:hover::before, .memoryItem p[data-tooltip]:hover::after { transform: translate(-50%, 0); } /* ------------------------------------------------------------------ toasts */ .errorToast { position: absolute; top: 142px; left: 50%; z-index: 70; max-width: min(560px, calc(100vw - 28px)); padding: 11px 14px; border-color: rgb(255 120 94 / 54%); border-radius: 8px; color: #ffd3c8; font-size: 13px; transform: translateX(-50%); } .busyToast { position: absolute; top: 142px; left: 50%; z-index: 65; display: inline-flex; align-items: center; gap: 8px; max-width: min(560px, calc(100vw - 28px)); padding: 11px 14px; border-radius: 8px; color: #fffce9; font-size: 13px; transform: translateX(-50%); } .spinIcon { animation: spin 0.9s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } /* ------------------------------------------------------------ scene labels */ .npcLabel { pointer-events: auto; } /* Lift the character/beast badges up off the actor's head. */ .npcLabel > button { transform: translateY(-16px); } .npcCard { min-width: 96px; max-width: 136px; display: grid; gap: 3px; padding: 6px 8px 7px; border: 1.5px solid rgb(255 255 255 / 22%); border-radius: 8px; color: #fffce9; background: rgb(15 24 20 / 82%); box-shadow: 0 10px 28px rgb(0 0 0 / 24%); cursor: pointer; text-align: left; } .npcCard:hover { background: rgb(18 30 24 / 92%); box-shadow: 0 12px 30px rgb(0 0 0 / 28%); } .npcCardDead { opacity: 0.62; filter: grayscale(0.7); } .npcCardName { display: flex; align-items: center; gap: 5px; min-width: 0; } .npcCardName strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; line-height: 1.1; } .npcCardIcon { font-size: 11px; line-height: 1; } .npcCountryBadge { width: 16px; height: 16px; background: #f7d96c; font-size: 10px; } .npcCardRole { font-size: 9px; font-weight: 700; letter-spacing: 0.07em; line-height: 1; text-transform: uppercase; } .npcBar { display: block; width: 100%; height: 5px; border-radius: 3px; background: rgb(255 255 255 / 14%); overflow: hidden; } .npcBarFill { display: block; height: 100%; border-radius: 3px; transition: width 280ms ease; } .npcAgeBar { height: 3px; } .npcAgeFill { background: #d9b35a; } .houseTag, .beastTag, .resourceTag { pointer-events: none; display: grid; gap: 3px; padding: 5px 8px; border: 1px solid rgb(255 255 255 / 20%); border-radius: 7px; background: rgb(15 24 20 / 80%); color: #fffce9; white-space: nowrap; } .houseTag { min-width: 88px; } /* The house tag is a button so the home can be selected from the label. */ button.houseTag { pointer-events: auto; font: inherit; text-align: left; cursor: pointer; } button.houseTag:hover { background: rgb(18 30 24 / 92%); box-shadow: 0 10px 26px rgb(0 0 0 / 26%); } .houseTagBuilding { border-color: rgb(255 208 122 / 50%); } .houseTagDestroyed { border-color: rgb(240 106 78 / 55%); opacity: 0.85; } .houseTagSelected { border-color: rgb(159 216 255 / 85%); box-shadow: 0 0 0 1px rgb(159 216 255 / 45%); } .houseTagTitle, .beastTagTitle { font-size: 11px; font-weight: 700; line-height: 1.1; } .houseHpBar, .beastHpBar { height: 4px; } .beastTag { min-width: 80px; border-color: rgb(240 106 78 / 50%); } .beastTagTitle { color: #ffd3c8; } .resourceTag { padding: 3px 7px; font-size: 11px; font-weight: 700; } .treasuryTag, .cannonTag { border-color: rgb(244 211 106 / 45%); background: rgb(15 24 20 / 88%); text-align: center; } /* -------------------------------------------------------- game over overlay */ .gameOverOverlay { position: absolute; inset: 0; z-index: 100; display: grid; place-items: center; padding: 20px; background: rgb(8 13 10 / 78%); backdrop-filter: blur(6px); animation: overlayIn 400ms ease; } @keyframes overlayIn { from { opacity: 0; } to { opacity: 1; } } .gameOverCard { width: min(620px, calc(100vw - 40px)); max-height: calc(100svh - 60px); overflow-y: auto; display: grid; gap: 14px; padding: 26px 28px; border: 1px solid rgb(255 255 255 / 22%); border-radius: 14px; background: rgb(18 28 23 / 96%); box-shadow: 0 30px 90px rgb(0 0 0 / 50%); text-align: center; } .gameOver-win .gameOverCard { border-color: rgb(111 217 106 / 45%); } .gameOver-lose .gameOverCard { border-color: rgb(240 106 78 / 45%); } .gameOverCard h1 { margin: 0; font-size: 26px; letter-spacing: 0.04em; } .gameOver-win .gameOverCard h1 { color: #d6f5cf; } .gameOver-lose .gameOverCard h1 { color: #ffd3c8; } .gameOverSubtitle { margin: 0; color: rgb(245 247 240 / 78%); font-size: 14px; } .gameOverScore { display: flex; justify-content: center; gap: 12px; font-size: 17px; font-weight: 800; } .scoreDivider { color: rgb(245 247 240 / 40%); } .gameOverStats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; } .gameOverStat { display: grid; gap: 3px; padding: 10px 6px; border-radius: 8px; background: rgb(255 255 255 / 7%); } .gameOverStatValue { font-size: 17px; font-weight: 800; } .gameOverStatLabel { color: rgb(245 247 240 / 62%); font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; } .gameOverCauses { margin: 0; color: rgb(245 247 240 / 68%); font-size: 12px; } .gameOverStory { display: grid; gap: 7px; text-align: left; } .gameOverStory h2 { margin: 0; font-size: 13px; color: rgb(245 247 240 / 80%); text-transform: uppercase; letter-spacing: 0.06em; } .gameOverStoryList { display: grid; gap: 2px; max-height: 220px; overflow-y: auto; padding: 6px; border-radius: 8px; background: rgb(0 0 0 / 22%); scrollbar-width: thin; } .gameOverDismiss { justify-self: center; padding: 10px 22px; border: 1px solid rgb(255 255 255 / 26%); border-radius: 8px; background: rgb(255 255 255 / 10%); color: #fffce9; font-size: 13px; font-weight: 700; cursor: pointer; } .gameOverDismiss:hover { background: rgb(255 255 255 / 18%); } /* ---------------------------------------------------------------- responsive */ @media (max-width: 1180px) { .eventFeed { width: min(262px, calc(100vw - 28px)); } } @media (max-width: 860px) { .scoreboard { top: 8px; width: min(400px, calc(100vw - 16px)); } .eventFeed { top: auto; bottom: 200px; max-height: 32svh; } .agentPanel { display: none; } .controls { right: 8px; bottom: 200px; } }