feat: warm cream palette, new home page with line art and join card, 987x610 window

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
layue13andClaude Sonnet 5.5 committed 2026-11-08 13:58:07 +08:00
1 parent 323d09b104
commit dfdad64e93
14 files changed
+356 -242

No files matched your search

@@ -6,12 +6,6 @@ import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import org.glavo.monetfx.Brightness;
import org.glavo.monetfx.ColorRole;
import org.glavo.monetfx.ColorScheme;
import org.jackhuang.hmcl.theme.ResolvedTheme;
import org.jackhuang.hmcl.theme.ThemeColor;
import org.jackhuang.hmcl.theme.Themes;
import java.nio.charset.StandardCharsets;
@@ -100,55 +94,14 @@ public final class StyleSheets {
}
private static String getBrightnessStyleSheet() {
return Themes.getColorScheme().getBrightness() == Brightness.LIGHT
? "/assets/css/brightness-light.css"
: "/assets/css/brightness-dark.css";
}
private static void addColor(StringBuilder builder, String name, Color color) {
builder.append(" ").append(name)
.append(": ").append(ThemeColor.getColorDisplayName(color)).append(";\n");
}
private static void addColor(StringBuilder builder, String name, Color color, double opacity) {
builder.append(" ").append(name)
.append(": ").append(ThemeColor.getColorDisplayNameWithOpacity(color, opacity)).append(";\n");
}
private static void addColor(StringBuilder builder, ColorScheme scheme, ColorRole role, double opacity) {
builder.append(" ").append(role.getVariableName()).append("-transparent-%02d".formatted((int) (100 * opacity)))
.append(": ").append(ThemeColor.getColorDisplayNameWithOpacity(scheme.getColor(role), opacity))
.append(";\n");
return "/assets/css/brightness-light.css";
}
/// Returns the launcher color style sheet.
///
/// The launcher ships a single warm palette; user-selected themes are no longer applied.
private static String getThemeStyleSheet() {
final String blueCss = "/assets/css/blue.css";
if (ResolvedTheme.DEFAULT.equals(Themes.getTheme()))
return blueCss;
ColorScheme scheme = Themes.getColorScheme();
StringBuilder builder = new StringBuilder();
builder.append("* {\n");
for (ColorRole colorRole : ColorRole.ALL) {
addColor(builder, colorRole.getVariableName(), scheme.getColor(colorRole));
}
addColor(builder, "-monet-primary-seed", scheme.getPrimaryColorSeed());
addColor(builder, scheme, ColorRole.PRIMARY, 0.5);
addColor(builder, scheme, ColorRole.PRIMARY, 0.8);
addColor(builder, scheme, ColorRole.SECONDARY_CONTAINER, 0.5);
addColor(builder, scheme, ColorRole.SURFACE, 0.5);
addColor(builder, scheme, ColorRole.SURFACE, 0.8);
addColor(builder, scheme, ColorRole.ON_SURFACE_VARIANT, 0.38);
addColor(builder, scheme, ColorRole.SURFACE_CONTAINER_LOW, 0.8);
addColor(builder, scheme, ColorRole.SECONDARY_CONTAINER, 0.8);
addColor(builder, scheme, ColorRole.INVERSE_SURFACE, 0.8);
builder.append("}\n");
return toStyleSheetUri(builder.toString());
return "/assets/css/warm.css";
}
public static void init(Scene scene) {
@@ -1104,11 +1104,8 @@ public final class Themes {
/// The title text fill derived from the current color scheme.
private static final ObjectBinding<Color> titleFill = Bindings.createObjectBinding(
() -> titleBarTransparent.get()
? getColorScheme().getOnSurface()
: getColorScheme().getOnPrimaryContainer(),
colorSchemeProperty(),
titleBarTransparent
() -> WarmPalette.INK,
colorSchemeProperty()
);
/// Returns the title text fill property derived from the current color scheme.
@@ -0,0 +1,21 @@
// SPDX-FileCopyrightText: Copyright (C) 2026 The HMCL Authors
// SPDX-License-Identifier: GPL-3.0-or-later WITH AdditionRef-HMCL
package org.jackhuang.hmcl.theme;
import javafx.scene.paint.Color;
import org.jetbrains.annotations.NotNullByDefault;
/// The fixed warm cream palette used by window chrome that is painted from Java.
///
/// Values match `/assets/css/warm.css`, which supplies the same colors to style sheets.
@NotNullByDefault
public final class WarmPalette {
private WarmPalette() {
}
/// The window and title-bar background.
public static final Color WINDOW = Color.web("#F3EEE6");
/// The title-bar text and icon color.
public static final Color INK = Color.web("#2A2622");
}
@@ -81,10 +81,10 @@ import static org.jackhuang.hmcl.ui.FXUtils.onEscPressed;
@NotNullByDefault
public final class Decorator {
/// The minimum width, in pixels, of the visible window content.
private static final double MIN_CONTENT_WIDTH = 800.0;
private static final double MIN_CONTENT_WIDTH = 987.0;
/// The minimum height, in pixels, including the 450-pixel background and 40-pixel title bar.
private static final double MIN_CONTENT_HEIGHT = 450.0 + 40.0;
private static final double MIN_CONTENT_HEIGHT = 570.0 + 40.0;
/// The minimum visible overlap, in pixels, used to accept a persisted window position.
private static final double MIN_VISIBLE_WINDOW_AREA = 20.0;
@@ -27,6 +27,7 @@ import javafx.util.Duration;
import org.glavo.monetfx.ColorRole;
import org.glavo.monetfx.ColorScheme;
import org.jackhuang.hmcl.theme.Themes;
import org.jackhuang.hmcl.theme.WarmPalette;
import org.jackhuang.hmcl.ui.*;
import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
import org.jackhuang.hmcl.ui.animation.TransitionPane;
@@ -81,7 +82,7 @@ final class MainWindowPane extends StackPane {
() -> Themes.windowTransparentProperty().get()
? null
: new Background(new BackgroundFill(
Themes.getColorScheme().getColor(ColorRole.SURFACE_CONTAINER),
WarmPalette.WINDOW,
CornerRadii.EMPTY,
Insets.EMPTY)),
Themes.windowTransparentProperty(),
@@ -153,16 +154,7 @@ final class MainWindowPane extends StackPane {
Region backgroundNode = new Region();
backgroundNode.setMouseTransparent(true);
StackPane.setAlignment(backgroundNode, Pos.BOTTOM_CENTER);
holder.onWeakChangeAndOperate(Themes.backgroundProperty(), background -> {
double opacity = background.opacity();
if (opacity >= 0.001) {
backgroundNode.setBackground(background.background());
backgroundNode.setOpacity(opacity);
} else {
backgroundNode.setBackground(null);
backgroundNode.setOpacity(0);
}
});
// The launcher paints a flat cream window; wallpapers are no longer used.
return backgroundNode;
}
@@ -195,21 +187,10 @@ final class MainWindowPane extends StackPane {
/// Recomputes the title-bar background for the current theme and transparency preference.
private void updateTitleBarBackground() {
@Nullable ColorScheme colorScheme = Themes.getColorScheme();
if (colorScheme == null) {
titleBar.setBackground(null);
} else if (Themes.titleBarTransparentProperty().get()) {
Color surface = colorScheme.getSurface();
titleBar.setBackground(new Background(new BackgroundFill(
new Color(surface.getRed(), surface.getGreen(), surface.getBlue(), 0.5),
CornerRadii.EMPTY,
Insets.EMPTY)));
} else {
titleBar.setBackground(new Background(new BackgroundFill(
colorScheme.getPrimaryContainer(),
CornerRadii.EMPTY,
Insets.EMPTY)));
}
titleBar.setBackground(new Background(new BackgroundFill(
WarmPalette.WINDOW,
CornerRadii.EMPTY,
Insets.EMPTY)));
}
/// Rebuilds the navigation bar from the current page state.
@@ -0,0 +1,85 @@
// SPDX-FileCopyrightText: Copyright (C) 2026 The HMCL Authors
// SPDX-License-Identifier: GPL-3.0-or-later WITH AdditionRef-HMCL
package org.jackhuang.hmcl.ui.main;
import javafx.animation.Interpolator;
import javafx.animation.Timeline;
import javafx.animation.TranslateTransition;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Line;
import javafx.scene.shape.Polygon;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;
import javafx.util.Duration;
import org.jackhuang.hmcl.ui.animation.AnimationUtils;
import org.jetbrains.annotations.NotNullByDefault;
/// Builds the line illustration on the home page: a floating block island with a tree and a blocky figure.
///
/// All shapes are unfilled strokes whose colors come from the `.home-art` style classes, so the drawing
/// follows the launcher palette. The island drifts slowly up and down unless animations are disabled.
@NotNullByDefault
final class HomeArt {
private HomeArt() {
}
/// Creates the illustration, sized 290 by 250 pixels.
///
/// @return the illustration root node
static Node create() {
Group island = new Group(
// Stepped underside of the island, then the grass line along its top.
stroke(new Polygon(30, 150, 250, 150, 250, 166, 232, 166, 232, 184, 212, 184, 212, 204,
176, 204, 176, 222, 104, 222, 104, 204, 68, 204, 68, 184, 48, 184, 48, 166, 30, 166), "home-art-line"),
stroke(new Line(30, 158, 250, 158), "home-art-line"),
// Tree: trunk and three stacked leaf blocks.
stroke(rect(186, 96, 8, 54), "home-art-line"),
stroke(rect(162, 70, 56, 26), "home-art-line"),
stroke(rect(170, 50, 40, 20), "home-art-line"),
stroke(rect(178, 34, 24, 16), "home-art-line"),
// Generic blocky figure: legs, torso, arms and head.
stroke(rect(88, 126, 10, 24), "home-art-figure"),
stroke(rect(102, 126, 10, 24), "home-art-figure"),
stroke(rect(88, 92, 24, 34), "home-art-figure"),
stroke(rect(76, 92, 12, 34), "home-art-figure"),
stroke(rect(112, 92, 12, 34), "home-art-figure"),
stroke(rect(88, 68, 24, 24), "home-art-figure"));
Pane root = new Pane(
stroke(new Line(20, 30, 54, 30), "home-art-line"),
stroke(new Line(30, 38, 52, 38), "home-art-line"),
stroke(new Line(200, 14, 240, 14), "home-art-line"),
stroke(new Line(210, 22, 234, 22), "home-art-line"),
stroke(rect(22, 62, 14, 14), "home-art-line"),
stroke(rect(42, 100, 10, 10), "home-art-line"),
stroke(rect(238, 108, 10, 10), "home-art-line"),
island);
root.setPrefSize(290, 250);
root.setMaxSize(290, 250);
if (AnimationUtils.isAnimationEnabled()) {
TranslateTransition bob = new TranslateTransition(Duration.seconds(4), island);
bob.setFromY(0);
bob.setToY(-5);
bob.setAutoReverse(true);
bob.setCycleCount(Timeline.INDEFINITE);
bob.setInterpolator(Interpolator.EASE_BOTH);
bob.play();
}
return root;
}
/// Creates an unfilled rectangle.
private static Rectangle rect(double x, double y, double width, double height) {
return new Rectangle(x, y, width, height);
}
/// Makes a shape an unfilled outline styled by `styleClass`.
private static <T extends Shape> T stroke(T shape, String styleClass) {
shape.setFill(null);
shape.getStyleClass().addAll("home-art", styleClass);
return shape;
}
}
@@ -19,6 +19,8 @@ import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.util.Duration;
@@ -59,8 +61,6 @@ public final class MainPage extends StackPane implements DecoratorPage {
BindingMapping.of(GameDirectoryManager.selectedRepositoryProperty())
.flatMap(HMCLGameRepository::snapshotProperty);
private final JFXButton menuButton;
{
HBox titleNode = new HBox(8);
titleNode.setPadding(new Insets(0, 0, 0, 2));
@@ -79,111 +79,86 @@ public final class MainPage extends StackPane implements DecoratorPage {
state.setValue(new State(null, titleNode, false, false, true));
setPadding(new Insets(20));
setPadding(new Insets(34, 55, 34, 55));
HBox launchPane = new HBox();
launchPane.getStyleClass().add("launch-pane");
FXUtils.onChangeAndOperate(selectedRepositorySnapshot, ignored -> mutableInstances.setAll(GameDirectoryManager.getSelectedRepository().getDisplayInstances().toList()));
FXUtils.onScroll(launchPane, instances, list -> {
@Nullable HMCLGameInstance currentGame = getCurrentGame();
@Nullable GameInstanceID currentId = currentGame != null ? currentGame.getId() : null;
return Lang.indexWhere(list, instance -> instance.getId().equals(currentId));
}, instance -> instance.getRepository().setSelectedInstance(instance));
StackPane.setAlignment(launchPane, Pos.BOTTOM_RIGHT);
{
JFXButton launchButton = new JFXButton();
launchButton.getStyleClass().add("launch-button");
launchButton.setDefaultButton(true);
{
VBox graphic = new VBox();
graphic.setAlignment(Pos.CENTER);
Label launchLabel = new Label();
launchLabel.setStyle("-fx-font-size: 16px;");
Label currentLabel = new Label();
currentLabel.setStyle("-fx-font-size: 12px;");
// Left column: greeting, headline and a short description.
Label eyebrow = new Label(i18n("home.welcome"));
eyebrow.getStyleClass().add("home-eyebrow");
Label headline = new Label(i18n("home.title"));
headline.getStyleClass().add("home-title");
headline.setWrapText(true);
Label subtitle = new Label(i18n("home.subtitle"));
subtitle.getStyleClass().add("home-subtitle");
subtitle.setWrapText(true);
VBox hero = new VBox(8, eyebrow, headline, subtitle);
hero.setPrefWidth(330);
hero.setMaxWidth(330);
headline.setPrefWidth(330);
subtitle.setPrefWidth(330);
hero.setMaxHeight(Region.USE_PREF_SIZE);
StackPane.setAlignment(hero, Pos.TOP_LEFT);
hero.setPadding(new Insets(21, 0, 0, 0));
FXUtils.onChangeAndOperate(currentGameProperty(), new Consumer<>() {
private Tooltip tooltip;
// Line illustration on the right, behind the content.
Node art = HomeArt.create();
StackPane.setAlignment(art, Pos.TOP_RIGHT);
art.setMouseTransparent(true);
((Region) art).setMaxSize(290, 250);
@Override
public void accept(@Nullable HMCLGameInstance currentGame) {
if (currentGame == null) {
launchLabel.setText(i18n("instance.launch.empty"));
currentLabel.setText(null);
graphic.getChildren().setAll(launchLabel);
FXUtils.setOnActionWithCooldown(launchButton, MainPage.this::launchNoGame);
if (tooltip == null)
tooltip = new Tooltip(i18n("instance.launch.empty.tooltip"));
FXUtils.installFastTooltip(launchButton, tooltip);
} else {
launchLabel.setText(i18n("server.join"));
currentLabel.setText(currentGame.getId().toString());
graphic.getChildren().setAll(launchLabel, currentLabel);
FXUtils.setOnActionWithCooldown(launchButton, MainPage.this::launch);
if (tooltip != null)
Tooltip.uninstall(launchButton, tooltip);
}
}
});
// Bottom card: what will be launched, and the join button.
Label packLabel = factLabel(i18n("home.pack"));
Label packValue = new Label();
packValue.getStyleClass().add("home-fact-value");
Label routeLabel = factLabel(i18n("home.route"));
Label routeValue = new Label();
routeValue.getStyleClass().add("home-fact-value");
VBox packFact = new VBox(3, packLabel, packValue);
VBox routeFact = new VBox(3, routeLabel, routeValue);
HBox facts = new HBox(34, packFact, routeFact);
facts.setAlignment(Pos.CENTER_LEFT);
launchButton.setGraphic(graphic);
JFXButton joinButton = new JFXButton();
joinButton.getStyleClass().add("join-button");
joinButton.setDefaultButton(true);
Region spacer = new Region();
HBox.setHgrow(spacer, Priority.ALWAYS);
HBox card = new HBox(21, facts, spacer, joinButton);
card.getStyleClass().add("home-card");
card.setAlignment(Pos.CENTER_LEFT);
card.setMaxHeight(Region.USE_PREF_SIZE);
StackPane.setAlignment(card, Pos.BOTTOM_CENTER);
FXUtils.onChangeAndOperate(currentGameProperty(), currentGame -> {
if (currentGame == null) {
joinButton.setText(i18n("instance.launch.empty"));
FXUtils.setOnActionWithCooldown(joinButton, MainPage.this::launchNoGame);
packValue.setText(i18n("home.not_installed"));
routeFact.setVisible(false);
routeFact.setManaged(false);
} else {
joinButton.setText(i18n("server.join"));
FXUtils.setOnActionWithCooldown(joinButton, MainPage.this::launch);
packValue.setText(currentGame.getId().toString());
ServerEndpoint.@Nullable Route route = ServerEndpoint.selected(currentGame.getModpackConfigurationFile());
routeFact.setVisible(route != null);
routeFact.setManaged(route != null);
routeValue.setText(route != null ? route.name() : "");
}
});
menuButton = new JFXButton();
menuButton.getStyleClass().add("menu-button");
menuButton.setOnAction(e -> {
if (GameListPopupMenu.hideShowing(menuButton)) {
return;
}
JFXPopup popup = GameListPopupMenu.showAndGetPopup(
menuButton,
JFXPopup.PopupVPosition.BOTTOM,
JFXPopup.PopupHPosition.RIGHT,
0,
-menuButton.getHeight(),
instances
);
Node graphic = menuButton.getGraphic();
if (graphic != null) {
if (AnimationUtils.isAnimationEnabled()) {
Duration duration = Duration.millis(200);
RotateTransition rotateOpen = new RotateTransition(duration, graphic);
rotateOpen.setToAngle(-180);
FXUtils.playAnimation(graphic, "arrow-rotation", rotateOpen);
popup.setOnHidden(windowEvent -> {
RotateTransition rotateClose = new RotateTransition(duration, graphic);
rotateClose.setToAngle(0);
FXUtils.playAnimation(graphic, "arrow-rotation", rotateClose);
});
} else {
graphic.setRotate(-180);
popup.setOnHidden(windowEvent -> graphic.setRotate(0));
}
}
});
FXUtils.installFastTooltip(menuButton, i18n("instance.switch"));
menuButton.setGraphic(SVG.ARROW_DROP_UP.createIcon(30));
EventHandler<MouseEvent> secondaryClickHandle = event -> {
if (event.getButton() == MouseButton.SECONDARY && event.getClickCount() == 1) {
menuButton.fire();
event.consume();
}
};
launchButton.addEventHandler(MouseEvent.MOUSE_CLICKED, secondaryClickHandle);
menuButton.addEventHandler(MouseEvent.MOUSE_CLICKED, secondaryClickHandle);
launchPane.getChildren().setAll(launchButton, menuButton);
}
getChildren().addAll(launchPane);
getChildren().addAll(art, hero, card);
}
/// Creates the small caption above a fact value in the home card.
private static Label factLabel(String text) {
Label label = new Label(text);
label.getStyleClass().add("home-fact-label");
return label;
}
private void launch() {
@@ -1,61 +0,0 @@
* {
-monet-primary: #4352A5;
-monet-on-primary: #FFFFFF;
-monet-primary-container: #5C6BC0;
-monet-on-primary-container: #F8F6FF;
-monet-primary-fixed: #DEE0FF;
-monet-primary-fixed-dim: #BAC3FF;
-monet-on-primary-fixed: #00105B;
-monet-on-primary-fixed-variant: #2F3F92;
-monet-secondary: #575C7F;
-monet-on-secondary: #FFFFFF;
-monet-secondary-container: #D0D5FD;
-monet-on-secondary-container: #565B7D;
-monet-secondary-fixed: #DEE0FF;
-monet-secondary-fixed-dim: #BFC4EC;
-monet-on-secondary-fixed: #141938;
-monet-on-secondary-fixed-variant: #3F4566;
-monet-tertiary: #775200;
-monet-on-tertiary: #FFFFFF;
-monet-tertiary-container: #976900;
-monet-on-tertiary-container: #FFF6EE;
-monet-tertiary-fixed: #FFDEAC;
-monet-tertiary-fixed-dim: #F6BD58;
-monet-on-tertiary-fixed: #281900;
-monet-on-tertiary-fixed-variant: #5F4100;
-monet-error: #BA1A1A;
-monet-on-error: #FFFFFF;
-monet-error-container: #FFDAD6;
-monet-on-error-container: #93000A;
-monet-surface: #FBF8FF;
-monet-on-surface: #1B1B21;
-monet-surface-dim: #DBD9E1;
-monet-surface-bright: #FBF8FF;
-monet-surface-container-lowest: #FFFFFF;
-monet-surface-container-low: #F5F2FA;
-monet-surface-container: #EFEDF5;
-monet-surface-container-high: #E9E7EF;
-monet-surface-container-highest: #E3E1E9;
-monet-surface-variant: #E2E1EF;
-monet-on-surface-variant: #454651;
-monet-background: #FBF8FF;
-monet-on-background: #1B1B21;
-monet-outline: #767683;
-monet-outline-variant: #C6C5D3;
-monet-shadow: #000000;
-monet-scrim: #000000;
-monet-inverse-surface: #303036;
-monet-inverse-on-surface: #F2EFF7;
-monet-inverse-primary: #BAC3FF;
-monet-surface-tint: #4858AB;
-monet-primary-seed: #5C6BC0;
-monet-primary-transparent-50: #4352A580;
-monet-primary-transparent-80: #4352A5CC;
-monet-secondary-container-transparent-50: #D0D5FD80;
-monet-surface-transparent-50: #FBF8FF80;
-monet-surface-transparent-80: #FBF8FFCC;
-monet-on-surface-variant-transparent-38: #45465161;
-monet-surface-container-low-transparent-80: #F5F2FACC;
-monet-secondary-container-transparent-80: #D0D5FDCC;
-monet-inverse-surface-transparent-80: #303036CC;
}
@@ -2171,3 +2171,78 @@
.date-picker-popup .title {
-fx-text-fill: -monet-on-surface-variant;
}
/* ---- Home page ---- */
.home-eyebrow {
-fx-font-family: "Noto Sans SC";
-fx-font-size: 12px;
-fx-text-fill: -monet-on-surface-variant;
}
.home-title {
-fx-font-family: "Noto Sans SC";
-fx-font-weight: bold;
-fx-font-size: 39px;
-fx-text-fill: -monet-on-surface;
}
.home-subtitle {
-fx-font-size: 15px;
-fx-line-spacing: 4px;
-fx-text-fill: -monet-on-surface-variant;
}
.home-card {
-fx-background-color: -monet-surface-bright;
-fx-background-radius: 21px;
-fx-border-color: -monet-outline-variant;
-fx-border-radius: 21px;
-fx-padding: 21px 21px 21px 34px;
}
.home-fact-label {
-fx-font-family: "Noto Sans SC";
-fx-font-size: 12px;
-fx-text-fill: -monet-on-surface-variant;
}
.home-fact-value {
-fx-font-family: "Noto Sans SC";
-fx-font-size: 15px;
-fx-text-fill: -monet-on-surface;
}
.join-button {
-fx-font-family: "Noto Sans SC";
-fx-font-size: 16px;
-fx-background-color: -monet-primary;
-fx-background-radius: 13px;
-fx-text-fill: -monet-on-primary;
-fx-padding: 13px 34px;
-fx-min-width: 179px;
-fx-cursor: hand;
}
.join-button:hover {
-fx-background-color: derive(-monet-primary, 8%);
}
.join-button:pressed {
-fx-scale-x: 0.985;
-fx-scale-y: 0.985;
}
.join-button .label {
-fx-text-fill: -monet-on-primary;
}
.home-art-line {
-fx-stroke: -monet-outline-variant;
-fx-stroke-width: 1.5px;
}
.home-art-figure {
-fx-stroke: -monet-primary;
-fx-stroke-width: 1.5px;
}
@@ -0,0 +1,64 @@
/*
* Warm cream palette with a clay accent. Every launcher color is derived from these variables.
*/
* {
-monet-primary: #A9532F;
-monet-on-primary: #FFF8F1;
-monet-primary-container: #EFD9CC;
-monet-on-primary-container: #4A2312;
-monet-primary-fixed: #F6E3D8;
-monet-primary-fixed-dim: #E8B99F;
-monet-on-primary-fixed: #2E1307;
-monet-on-primary-fixed-variant: #7F3C1F;
-monet-secondary: #6E665B;
-monet-on-secondary: #FAF7F1;
-monet-secondary-container: #E9E1D3;
-monet-on-secondary-container: #4A433A;
-monet-secondary-fixed: #EDE6D9;
-monet-secondary-fixed-dim: #CFC6B5;
-monet-on-secondary-fixed: #231F19;
-monet-on-secondary-fixed-variant: #51493F;
-monet-tertiary: #5F7F54;
-monet-on-tertiary: #FFFFFF;
-monet-tertiary-container: #DCE5D2;
-monet-on-tertiary-container: #1F3018;
-monet-tertiary-fixed: #DCE5D2;
-monet-tertiary-fixed-dim: #B5C7A8;
-monet-on-tertiary-fixed: #121E0D;
-monet-on-tertiary-fixed-variant: #3E5A34;
-monet-error: #B3261E;
-monet-on-error: #FFFFFF;
-monet-error-container: #F9DEDC;
-monet-on-error-container: #410E0B;
-monet-surface: #F3EEE6;
-monet-on-surface: #2A2622;
-monet-surface-dim: #E2DBCF;
-monet-surface-bright: #FAF7F1;
-monet-surface-container-lowest: #FDFBF7;
-monet-surface-container-low: #F8F4EC;
-monet-surface-container: #EBE5DA;
-monet-surface-container-high: #E4DDCF;
-monet-surface-container-highest: #DDD5C7;
-monet-surface-variant: #E7E0D3;
-monet-on-surface-variant: #6E665B;
-monet-background: #F3EEE6;
-monet-on-background: #2A2622;
-monet-outline: #8C8377;
-monet-outline-variant: #DDD5C7;
-monet-shadow: #000000;
-monet-scrim: #000000;
-monet-inverse-surface: #2A2622;
-monet-inverse-on-surface: #F3EEE6;
-monet-inverse-primary: #E8A47F;
-monet-surface-tint: #A9532F;
-monet-primary-seed: #A9532F;
-monet-primary-transparent-50: #A9532F80;
-monet-primary-transparent-80: #A9532FCC;
-monet-secondary-container-transparent-50: #E9E1D380;
-monet-surface-transparent-50: #F3EEE680;
-monet-surface-transparent-80: #F3EEE6CC;
-monet-on-surface-variant-transparent-38: #6E665B61;
-monet-surface-container-low-transparent-80: #F8F4ECCC;
-monet-secondary-container-transparent-80: #E9E1D3CC;
-monet-inverse-surface-transparent-80: #2A2622CC;
}
@@ -791,6 +791,12 @@ instance.game.support_status.unsupported=Unsupported
instance.game.support_status.untested=Untested
instance.game.type=Type
instance.launch=Launch Game
home.welcome=Welcome back
home.title=Join our world
home.subtitle=One click syncs the modpack, prepares Java and connects you to the server.
home.pack=Modpack
home.route=Route
home.not_installed=Not installed
server.join=Join Server
instance.launch_and_enter_world=Play World
instance.launch.empty=Start Game
@@ -611,6 +611,12 @@ instance.game.snapshots=預版
# instance.game.support_status.untested=
instance.game.type=版類
instance.launch=戲
home.welcome=歸來
home.title=入吾世
home.subtitle=一點即同步、備器、入服。
home.pack=整合包
home.route=路
home.not_installed=未裝
server.join=入服
# instance.launch_and_enter_world=
instance.launch.empty=啟戲
@@ -614,6 +614,12 @@ instance.game.support_status.unsupported=不支持
instance.game.support_status.untested=未经测试
instance.game.type=版本类型
instance.launch=启动游戏
home.welcome=欢迎回来
home.title=进入我们的世界
home.subtitle=点一下就会同步整合包、准备好 Java,并直接连上服务器。
home.pack=整合包
home.route=线路
home.not_installed=尚未安装
server.join=进入服务器
instance.launch_and_enter_world=进入世界
instance.launch.empty=开始游戏
@@ -608,6 +608,12 @@ instance.game.support_status.unsupported=不支援
instance.game.support_status.untested=未經測試
instance.game.type=版本類型
instance.launch=啟動遊戲
home.welcome=歡迎回來
home.title=進入我們的世界
home.subtitle=點一下就會同步整合包、準備好 Java,並直接連上伺服器。
home.pack=整合包
home.route=線路
home.not_installed=尚未安裝
server.join=進入伺服器
instance.launch_and_enter_world=進入世界
instance.launch.empty=開始遊戲