implement main screen

This commit is contained in:
2026-07-03 13:59:00 +02:00
parent d98d34ec3f
commit 2fc8a05617
35 changed files with 1637 additions and 89 deletions
+10
View File
@@ -0,0 +1,10 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<ui:VisualElement name="CollectionPanel" class="sub-panel hidden">
<ui:Label text="COLLECTION" class="screen-title" />
<ui:ScrollView name="CollectionScrollView" class="stub-scroll">
<!-- TODO: Render owned distros and cards here when collection data exists. -->
<ui:VisualElement name="CollectionContent" class="collection-content" />
</ui:ScrollView>
<ui:Button name="CollectionBackButton" text="Back" class="terminal-button back-button" />
</ui:VisualElement>
</ui:UXML>
+10
View File
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: b39165b71c3e4bef9656e93e236530c1
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
+9
View File
@@ -0,0 +1,9 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<ui:VisualElement name="GachaPanel" class="sub-panel hidden">
<ui:Label text="GACHA" class="screen-title" />
<ui:VisualElement name="GachaContent" class="stub-box">
<!-- TODO: Render summon options and results here when gacha logic exists. -->
</ui:VisualElement>
<ui:Button name="GachaBackButton" text="Back" class="terminal-button back-button" />
</ui:VisualElement>
</ui:UXML>
+10
View File
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: ec1119ad0fcf4b7282c4e65a3c7f186d
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
+356
View File
@@ -0,0 +1,356 @@
:root {
--kp-bg: #050807;
--kp-panel: #09100d;
--kp-primary: #5cff91;
--kp-primary-dim: #2f7a4d;
--kp-muted: #7f9b8a;
--kp-border: #1d3b2a;
--kp-hover: #102018;
--kp-amber: #ffbf5c;
}
.terminal-root {
flex-grow: 1;
background-color: var(--kp-bg);
color: var(--kp-primary);
font-size: 16px;
}
.background-log-layer {
position: absolute;
left: 24px;
right: 24px;
top: 0;
bottom: -120px;
opacity: 0.07;
}
.background-log {
color: var(--kp-primary);
white-space: normal;
font-size: 14px;
}
.boot-intro {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
padding: 48px;
background-color: var(--kp-bg);
justify-content: flex-end;
}
.boot-intro-log {
color: var(--kp-primary);
font-size: 15px;
white-space: normal;
}
.shell-root {
flex-grow: 1;
padding: 18px 24px 16px 24px;
opacity: 1;
transition-property: opacity;
transition-duration: 220ms;
}
.boot-hidden {
opacity: 0;
}
.boot-visible {
opacity: 1;
}
.reduced-motion {
transition-duration: 0ms;
}
.hidden {
display: none;
}
.status-bar,
.footer-bar {
min-height: 34px;
flex-direction: row;
align-items: center;
justify-content: space-between;
border-left-width: 0;
border-right-width: 0;
border-top-width: 0;
border-bottom-width: 1px;
border-bottom-color: var(--kp-border);
}
.footer-bar {
border-top-width: 1px;
border-top-color: var(--kp-border);
border-bottom-width: 0;
}
.status-right,
.prompt-row,
.title-row {
flex-direction: row;
align-items: center;
}
.status-right {
justify-content: flex-end;
}
.status-text,
.footer-muted,
.tagline,
.muted-text {
color: var(--kp-muted);
}
.currency-text {
color: var(--kp-amber);
margin-right: 18px;
}
.main-panel {
flex-grow: 1;
}
.content-row {
flex-grow: 1;
flex-direction: row;
padding-top: 52px;
padding-bottom: 42px;
}
.command-column {
flex-grow: 1;
min-width: 470px;
padding-right: 40px;
}
.terminal-title {
color: var(--kp-primary);
font-size: 54px;
-unity-font-style: bold;
}
.blink-cursor {
color: transparent;
margin-left: 4px;
}
.cursor-on {
color: var(--kp-primary);
}
.tagline {
margin-top: 4px;
margin-bottom: 34px;
font-size: 16px;
}
.command-list {
max-width: 720px;
}
.command-row {
min-height: 44px;
flex-direction: row;
align-items: center;
padding-left: 10px;
padding-right: 10px;
margin-top: 4px;
margin-bottom: 4px;
border-left-width: 2px;
border-left-color: transparent;
}
.command-row:hover,
.command-row.selected {
background-color: var(--kp-hover);
}
.command-row.selected {
border-left-color: var(--kp-primary);
}
.command-cursor {
width: 22px;
color: var(--kp-primary);
}
.command-text {
color: var(--kp-primary);
font-size: 19px;
flex-grow: 1;
}
.command-description {
color: var(--kp-muted);
-unity-text-align: middle-right;
width: 150px;
}
.featured-panel {
width: 430px;
min-height: 330px;
padding: 18px;
border-left-width: 1px;
border-right-width: 1px;
border-top-width: 1px;
border-bottom-width: 1px;
border-left-color: var(--kp-primary);
border-right-color: var(--kp-primary);
border-top-color: var(--kp-primary);
border-bottom-color: var(--kp-primary);
background-color: var(--kp-panel);
}
.featured-title,
.screen-title {
color: var(--kp-primary);
font-size: 24px;
-unity-font-style: bold;
margin-bottom: 20px;
}
.featured-empty {
flex-grow: 1;
justify-content: center;
align-items: center;
}
.empty-title {
color: var(--kp-primary);
font-size: 20px;
margin-bottom: 8px;
}
.featured-populated {
flex-direction: row;
}
.ascii-art {
width: 150px;
color: var(--kp-primary);
white-space: normal;
}
.unit-readout {
flex-grow: 1;
}
.kv-row {
flex-direction: row;
margin-bottom: 8px;
}
.kv-key {
width: 88px;
color: var(--kp-muted);
}
.kv-value {
flex-grow: 1;
color: var(--kp-primary);
}
.event-banner {
min-height: 34px;
justify-content: center;
padding-left: 12px;
padding-right: 12px;
border-left-width: 1px;
border-right-width: 1px;
border-top-width: 1px;
border-bottom-width: 1px;
border-left-color: var(--kp-amber);
border-right-color: var(--kp-amber);
border-top-color: var(--kp-amber);
border-bottom-color: var(--kp-amber);
}
.event-banner-text {
color: var(--kp-amber);
}
.sub-panel {
flex-grow: 1;
align-items: center;
justify-content: center;
padding: 48px;
}
.stub-scroll,
.stub-box {
width: 560px;
height: 300px;
border-left-width: 1px;
border-right-width: 1px;
border-top-width: 1px;
border-bottom-width: 1px;
border-left-color: var(--kp-border);
border-right-color: var(--kp-border);
border-top-color: var(--kp-border);
border-bottom-color: var(--kp-border);
background-color: var(--kp-panel);
}
.collection-content {
min-height: 280px;
}
.terminal-button {
height: 42px;
margin-top: 24px;
border-left-width: 1px;
border-right-width: 1px;
border-top-width: 1px;
border-bottom-width: 1px;
border-left-color: var(--kp-primary);
border-right-color: var(--kp-primary);
border-top-color: var(--kp-primary);
border-bottom-color: var(--kp-primary);
background-color: var(--kp-panel);
color: var(--kp-primary);
font-size: 16px;
}
.terminal-button:hover {
background-color: var(--kp-primary);
color: var(--kp-bg);
}
.back-button {
width: 220px;
}
.settings-row {
width: 420px;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 16px;
border-left-width: 1px;
border-right-width: 1px;
border-top-width: 1px;
border-bottom-width: 1px;
border-left-color: var(--kp-border);
border-right-color: var(--kp-border);
border-top-color: var(--kp-border);
border-bottom-color: var(--kp-border);
background-color: var(--kp-panel);
}
.disabled-row {
opacity: 0.55;
}
.settings-label,
.settings-toggle,
.prompt-text {
color: var(--kp-primary);
}
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: bce4c6ca6c1d455e99443cc2d7a2593b
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
disableValidation: 0
unsupportedSelectorAction: 0
+111
View File
@@ -0,0 +1,111 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<Style src="MainMenu.uss" />
<ui:Template name="CollectionScreen" src="CollectionScreen.uxml" />
<ui:Template name="GachaScreen" src="GachaScreen.uxml" />
<ui:Template name="SettingsScreen" src="SettingsScreen.uxml" />
<ui:VisualElement name="Root" class="terminal-root" focusable="true">
<ui:VisualElement name="BackgroundLogLayer" class="background-log-layer" pickingMode="Ignore">
<ui:Label name="BackgroundLogLabel" class="background-log" />
</ui:VisualElement>
<ui:VisualElement name="BootIntroPanel" class="boot-intro">
<ui:Label name="BootIntroLogLabel" class="boot-intro-log" />
</ui:VisualElement>
<ui:VisualElement name="ShellRoot" class="shell-root">
<ui:VisualElement class="status-bar">
<ui:Label name="AppIdLabel" class="status-text" />
<ui:VisualElement class="status-right">
<ui:Label name="EntropyLabel" class="currency-text" />
<ui:Label name="PullTokensLabel" class="currency-text" />
<ui:Label text="uid=1000(player)" class="status-text" />
</ui:VisualElement>
</ui:VisualElement>
<ui:VisualElement name="MainMenuPanel" class="main-panel">
<ui:VisualElement class="content-row">
<ui:VisualElement class="command-column">
<ui:VisualElement class="title-row">
<ui:Label text="KERNEL PANIC" class="terminal-title" />
<ui:Label name="TitleCursorLabel" text="█" class="blink-cursor" />
</ui:VisualElement>
<ui:Label text="roguelike kernel shell / unstable userspace" class="tagline" />
<ui:VisualElement class="command-list">
<ui:VisualElement name="CommandStartRun" class="command-row">
<ui:Label text="&gt;" class="command-cursor" />
<ui:Label text="./start_run" class="command-text" />
<ui:Label text="new run" class="command-description" />
</ui:VisualElement>
<ui:VisualElement name="CommandCollection" class="command-row">
<ui:Label text="&gt;" class="command-cursor" />
<ui:Label text="ls ~/collection" class="command-text" />
<ui:Label text="units + cards" class="command-description" />
</ui:VisualElement>
<ui:VisualElement name="CommandGacha" class="command-row">
<ui:Label text="&gt;" class="command-cursor" />
<ui:Label text="curl gacha.sh | sh" class="command-text" />
<ui:Label text="summon" class="command-description" />
</ui:VisualElement>
<ui:VisualElement name="CommandSettings" class="command-row">
<ui:Label text="&gt;" class="command-cursor" />
<ui:Label text="dpkg-reconfigure" class="command-text" />
<ui:Label text="settings" class="command-description" />
</ui:VisualElement>
<ui:VisualElement name="CommandQuit" class="command-row">
<ui:Label text="&gt;" class="command-cursor" />
<ui:Label text="shutdown -h now" class="command-text" />
<ui:Label text="quit" class="command-description" />
</ui:VisualElement>
</ui:VisualElement>
</ui:VisualElement>
<ui:VisualElement name="FeaturedUnitPanel" class="featured-panel">
<ui:Label name="FeaturedUnitTitle" text="neofetch" class="featured-title" />
<ui:VisualElement name="FeaturedUnitEmptyState" class="featured-empty">
<ui:Label name="FeaturedUnitEmptyTitle" text="no units installed" class="empty-title" />
<ui:Label name="FeaturedUnitEmptyHint" text="run: curl gacha.sh | sh" class="muted-text" />
</ui:VisualElement>
<ui:VisualElement name="FeaturedUnitPopulatedState" class="featured-populated hidden">
<ui:Label name="FeaturedUnitAscii" class="ascii-art" />
<ui:VisualElement class="unit-readout">
<ui:VisualElement class="kv-row">
<ui:Label text="unit" class="kv-key" />
<ui:Label name="FeaturedUnitName" class="kv-value" />
</ui:VisualElement>
<ui:VisualElement class="kv-row">
<ui:Label text="lang" class="kv-key" />
<ui:Label name="FeaturedUnitLanguages" class="kv-value" />
</ui:VisualElement>
<ui:VisualElement class="kv-row">
<ui:Label text="passive" class="kv-key" />
<ui:Label name="FeaturedUnitPassive" class="kv-value" />
</ui:VisualElement>
<ui:VisualElement class="kv-row">
<ui:Label text="best wave" class="kv-key" />
<ui:Label name="FeaturedUnitBestWave" class="kv-value" />
</ui:VisualElement>
</ui:VisualElement>
</ui:VisualElement>
</ui:VisualElement>
</ui:VisualElement>
</ui:VisualElement>
<ui:Instance template="CollectionScreen" />
<ui:Instance template="GachaScreen" />
<ui:Instance template="SettingsScreen" />
<ui:VisualElement name="EventBanner" class="event-banner hidden">
<ui:Label name="EventBannerLabel" class="event-banner-text" />
</ui:VisualElement>
<ui:VisualElement class="footer-bar">
<ui:VisualElement class="prompt-row">
<ui:Label text="player@mainframe:~$ " class="prompt-text" />
<ui:Label name="PromptCursorLabel" text="█" class="blink-cursor" />
</ui:VisualElement>
<ui:Label text="daily seed: --------" class="footer-muted" />
</ui:VisualElement>
</ui:VisualElement>
</ui:VisualElement>
</ui:UXML>
+10
View File
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: a720a33f8c2b4dfe9d8197772dc0ab21
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
+43
View File
@@ -0,0 +1,43 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 19101, guid: 0000000000000000e000000000000000, type: 0}
m_Name: MainMenuPanelSettings
m_EditorClassIdentifier:
themeUss: {fileID: -4733365628477956816, guid: 50d8f7f949f77429c91ec4d834d2afb2, type: 3}
m_TargetTexture: {fileID: 0}
m_RenderMode: 0
m_WorldSpaceLayer: 0
m_ScaleMode: 1
m_ReferenceSpritePixelsPerUnit: 100
m_PixelsPerUnit: 100
m_Scale: 1
m_ReferenceDpi: 96
m_FallbackDpi: 96
m_ReferenceResolution: {x: 1920, y: 1080}
m_ScreenMatchMode: 0
m_Match: 0
m_SortingOrder: 0
m_TargetDisplay: 0
m_BindingLogLevel: 0
m_ClearDepthStencil: 1
m_ClearColor: 0
m_ColorClearValue: {r: 0, g: 0, b: 0, a: 0}
m_VertexBudget: 0
m_DynamicAtlasSettings:
m_MinAtlasSize: 64
m_MaxAtlasSize: 4096
m_MaxSubTextureSize: 64
m_ActiveFilters: -1
m_AtlasBlitShader: {fileID: 9101, guid: 0000000000000000f000000000000000, type: 0}
m_RuntimeShader: {fileID: 9100, guid: 0000000000000000f000000000000000, type: 0}
m_RuntimeWorldShader: {fileID: 9102, guid: 0000000000000000f000000000000000, type: 0}
textSettings: {fileID: 0}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7d68bd7978394c8295debbd403a39d80
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
+10
View File
@@ -0,0 +1,10 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<ui:VisualElement name="SettingsPanel" class="sub-panel hidden">
<ui:Label text="SETTINGS" class="screen-title" />
<ui:VisualElement class="settings-row disabled-row">
<ui:Label text="Audio" class="settings-label" />
<ui:Toggle name="AudioToggle" text="TODO" enabled="false" class="settings-toggle" />
</ui:VisualElement>
<ui:Button name="SettingsBackButton" text="Back" class="terminal-button back-button" />
</ui:VisualElement>
</ui:UXML>
+10
View File
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: cb8ce38e52cb45179ea337b19fa99043
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
+2
View File
@@ -0,0 +1,2 @@
@import url("unity-theme://default");
VisualElement {}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 50d8f7f949f77429c91ec4d834d2afb2
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 12388, guid: 0000000000000000e000000000000000, type: 0}
disableValidation: 0