diff --git a/Assets/Resources/CombatScene.uss b/Assets/Resources/CombatScene.uss
index 9fd116f..e3a6a4b 100644
--- a/Assets/Resources/CombatScene.uss
+++ b/Assets/Resources/CombatScene.uss
@@ -18,12 +18,16 @@
--kp-beneficial: #57d8ff;
--kp-accent: #ff7a1a;
--kp-danger: #ff5f5f;
+ --kp-damage: #ffd166;
+ --kp-status-harmful: #ff4fa3;
+ --kp-kill: #ff3333;
+ --kp-empty-fill: #050a07;
--kp-overlay: rgba(0, 0, 0, 0.88);
--kp-lang-c: #8ea4a9;
--kp-lang-cpp: #6da6ff;
--kp-lang-rust: #d78b4a;
- --kp-lang-python: #f2ce61;
+ --kp-lang-python: #4fb8ff;
--kp-lang-javascript: #f7df1e;
--kp-lang-typescript: #5aa7ff;
--kp-lang-haskell: #b48cff;
@@ -326,16 +330,17 @@
.empty-state {
color: var(--kp-text-dim);
font-size: 12px;
- background-color: var(--kp-bg);
+ background-color: var(--kp-empty-fill);
padding-left: 8px;
padding-right: 8px;
padding-top: 5px;
padding-bottom: 5px;
- border-left-width: 1px;
+ border-left-width: 2px;
border-right-width: 1px;
border-top-width: 1px;
border-bottom-width: 1px;
border-color: var(--kp-border-empty);
+ border-left-color: var(--kp-text-dim);
}
.card-chip {
@@ -481,15 +486,36 @@
}
.hand-card-rare {
+ border-left-color: var(--kp-beneficial);
border-right-color: var(--kp-beneficial);
+ border-right-width: 4px;
}
.hand-card-epic {
+ border-left-color: var(--kp-lang-haskell);
border-right-color: var(--kp-lang-haskell);
+ border-right-width: 4px;
}
.hand-card-legendary {
+ border-left-color: var(--kp-warning);
border-right-color: var(--kp-warning);
+ border-right-width: 4px;
+}
+
+.rarity-rare {
+ color: var(--kp-beneficial);
+ border-color: var(--kp-beneficial);
+}
+
+.rarity-epic {
+ color: var(--kp-lang-haskell);
+ border-color: var(--kp-lang-haskell);
+}
+
+.rarity-legendary {
+ color: var(--kp-warning);
+ border-color: var(--kp-warning);
}
.card-top-row {
@@ -1000,7 +1026,7 @@
}
.float-damage {
- color: var(--kp-warning);
+ color: var(--kp-damage);
}
.float-heal {
@@ -1008,7 +1034,7 @@
}
.float-status {
- color: var(--kp-danger);
+ color: var(--kp-status-harmful);
}
.float-muted {
@@ -1016,7 +1042,7 @@
}
.float-kill {
- color: var(--kp-danger);
+ color: var(--kp-kill);
}
.float-large {
@@ -1038,7 +1064,7 @@
}
.feedback-card-strike {
- border-color: var(--kp-warning);
+ border-color: var(--kp-damage);
}
.feedback-card-discard {
@@ -1052,7 +1078,7 @@
.feedback-hit {
background-color: var(--kp-action-hover);
- border-color: var(--kp-warning);
+ border-color: var(--kp-damage);
scale: 1.025 0.98;
transition-property: scale, background-color, border-color;
transition-duration: 90ms;
@@ -1065,7 +1091,7 @@
}
.feedback-status {
- border-color: var(--kp-danger);
+ border-color: var(--kp-status-harmful);
}
.feedback-boost {
@@ -1075,7 +1101,7 @@
.feedback-killed {
opacity: 0.5;
scale: 0.95 0.95;
- border-color: var(--kp-danger);
+ border-color: var(--kp-kill);
transition-property: opacity, scale, border-color;
transition-duration: 180ms;
}
@@ -1086,7 +1112,7 @@
border-right-width: 1px;
border-top-width: 1px;
border-bottom-width: 1px;
- border-color: var(--kp-danger);
+ border-color: var(--kp-kill);
opacity: 0.72;
transition-property: opacity, scale;
transition-duration: 300ms;
diff --git a/Assets/Scripts/UI/CombatSceneController.cs b/Assets/Scripts/UI/CombatSceneController.cs
index c1de0b1..ec63e92 100644
--- a/Assets/Scripts/UI/CombatSceneController.cs
+++ b/Assets/Scripts/UI/CombatSceneController.cs
@@ -70,9 +70,19 @@ namespace KernelPanic.UI
saveService = new SaveService();
root = document.rootVisualElement;
LoadStyles();
+ ApplyTerminalFont();
BuildLayout();
}
+ private void ApplyTerminalFont()
+ {
+ var font = TerminalFontResolver.Resolve(null);
+ if (font != null)
+ {
+ root.style.unityFontDefinition = new StyleFontDefinition(font);
+ }
+ }
+
private void OnEnable()
{
root?.EnableInClassList("reduced-motion", UIPreferences.ReducedMotion);
@@ -1610,9 +1620,9 @@ namespace KernelPanic.UI
{
return rarity switch
{
- Rarity.Rare => "hand-card-rare",
- Rarity.Epic => "hand-card-epic",
- Rarity.Legendary => "hand-card-legendary",
+ Rarity.Rare => "rarity-rare",
+ Rarity.Epic => "rarity-epic",
+ Rarity.Legendary => "rarity-legendary",
_ => "track-tag"
};
}
diff --git a/Assets/Scripts/UI/MainMenuController.cs b/Assets/Scripts/UI/MainMenuController.cs
index 78c58b6..54f9e10 100644
--- a/Assets/Scripts/UI/MainMenuController.cs
+++ b/Assets/Scripts/UI/MainMenuController.cs
@@ -14,6 +14,52 @@ using UnityEditor;
namespace KernelPanic.UI
{
+ internal static class TerminalFontResolver
+ {
+ private static readonly string[] PreferredMonospaceFontFamilies =
+ {
+ "Consolas",
+ "Cascadia Mono",
+ "Menlo",
+ "Monaco",
+ "DejaVu Sans Mono",
+ "Liberation Mono",
+ "Ubuntu Mono",
+ "Courier New"
+ };
+
+ private static FontAsset runtimeMonospaceFont;
+ private static bool warnedMissingFont;
+
+ public static FontAsset Resolve(FontAsset configuredFont)
+ {
+ if (configuredFont != null)
+ {
+ return configuredFont;
+ }
+
+ if (runtimeMonospaceFont != null)
+ {
+ return runtimeMonospaceFont;
+ }
+
+ Font dynamicFont = Font.CreateDynamicFontFromOSFont(PreferredMonospaceFontFamilies, 16);
+ if (dynamicFont == null)
+ {
+ if (!warnedMissingFont)
+ {
+ Debug.LogWarning("No monospace OS font found; terminal UI will use Unity's default font.");
+ warnedMissingFont = true;
+ }
+
+ return null;
+ }
+
+ runtimeMonospaceFont = FontAsset.CreateFontAsset(dynamicFont);
+ return runtimeMonospaceFont;
+ }
+ }
+
///
/// Binds the main menu terminal UI document and routes command activation between panels.
///
@@ -36,7 +82,7 @@ namespace KernelPanic.UI
_bootIntroPlayed = false;
}
- [SerializeField] private FontAsset monospaceFont; // TODO: Assign a real monospace FontAsset when typography assets exist.
+ [SerializeField] private FontAsset monospaceFont;
[SerializeField] private string motdBody = "unstable userspace detected; keep a rollback shell open.";
[SerializeField] private DistroDatabase distroDatabase;
[SerializeField] private CardDatabase cardDatabase;
@@ -137,15 +183,16 @@ namespace KernelPanic.UI
LoadSharedStyles();
BindCommandEntries();
RegisterCommandEntryCallbacks();
- featuredUnitPanel.Bind(_root, monospaceFont);
- collectionScreen.Bind(_root, monospaceFont, languageDeckDatabase, cardDatabase, _playerCollection, GetMergesBalance, UpgradeCollectionUnit);
BindScreenFrames();
starterSelection.Bind(_root, distroDatabase, HandleStarterConfirmed);
- gachaScreen.Bind(_root, distroDatabase, monospaceFont, _gachaService, _playerCollection, _wallet, ResolvePulledDistros, HandleMetaStateChanged, OpenRootCreditExchange);
+ FontAsset resolvedFont = ResolveMonospaceFont();
+ featuredUnitPanel.Bind(_root, resolvedFont);
+ collectionScreen.Bind(_root, resolvedFont, languageDeckDatabase, cardDatabase, _playerCollection, GetMergesBalance, UpgradeCollectionUnit);
+ gachaScreen.Bind(_root, distroDatabase, resolvedFont, _gachaService, _playerCollection, _wallet, ResolvePulledDistros, HandleMetaStateChanged, OpenRootCreditExchange);
LoadMetaState();
_playerCollection.Changed += HandleMetaStateChanged;
_gachaService.Changed += HandleMetaStateChanged;
- ApplyOptionalFont();
+ ApplyOptionalFont(resolvedFont);
}
private void OnEnable()
@@ -250,14 +297,20 @@ namespace KernelPanic.UI
_commandEntries.Add(new CommandMenuEntry(_root.Q("CommandQuit"), HandleQuitClicked));
}
- private void ApplyOptionalFont()
+ private FontAsset ResolveMonospaceFont()
{
- if (monospaceFont == null)
+ monospaceFont = TerminalFontResolver.Resolve(monospaceFont);
+ return monospaceFont;
+ }
+
+ private void ApplyOptionalFont(FontAsset resolvedFont)
+ {
+ if (resolvedFont == null)
{
return;
}
- _root.style.unityFontDefinition = new StyleFontDefinition(monospaceFont);
+ _root.style.unityFontDefinition = new StyleFontDefinition(resolvedFont);
}
private void RegisterCallbacks()