Themes - Bonk.io

Recolors elements in Bonk.io to customizable colors, and allows toggling your theme with a hotkey

当前为 2021-11-23 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Themes - Bonk.io
  3. // @description Recolors elements in Bonk.io to customizable colors, and allows toggling your theme with a hotkey
  4. // @author Excigma
  5. // @namespace https://greasyfork.org/users/416480
  6. // @license GPL-3.0
  7. // @version 0.1.7
  8. // @match https://bonk.io/*
  9. // @grant GM_addStyle
  10. // @grant GM_registerMenuCommand
  11. // @grant unsafeWindow
  12. // @run-at document-start
  13. // ==/UserScript==
  14.  
  15. (() => {
  16. const configuration_metadata_map = {
  17. hotkey: {
  18. default_dark: "d",
  19. default_light: "d",
  20. description: "Hotkey used to toggle the theme on and off\n(Ctrl + Alt + <key>)",
  21. datatype: "char"
  22. },
  23. colored_text: {
  24. default_dark: "#40c99e",
  25. default_light: "#032a71",
  26. description: "Text color of custom games with friends online in the room, and 'Added by' in picks",
  27. datatype: "color"
  28. },
  29. primary_text: {
  30. default_dark: "#f8fafd",
  31. default_light: "#000000",
  32. description: "Primary text color",
  33. datatype: "color"
  34. },
  35. secondary_text: {
  36. default_dark: "#bebebe",
  37. default_light: "#505050",
  38. description: "Secondary text color\nNote: Some of the texts are lightened by 'brightness_lighter' above\nthis will have no affect on such texts (Eg: Chat usernames)",
  39. datatype: "color"
  40. },
  41. window_color: {
  42. default_dark: "#2b6351",
  43. default_light: "#009688",
  44. description: "Color of window titles\n(Eg: Custom games, Leave Game, Chat, Level Select, ...)",
  45. datatype: "color"
  46. },
  47. window_text: {
  48. default_dark: "#f8fafd",
  49. default_light: "#ffffff",
  50. description: "Color of text in window titles\n(Eg: Custom games, Leave Game, Chat, Level Select, ...)",
  51. datatype: "color"
  52. },
  53. page_background: {
  54. default_dark: "#111111",
  55. default_light: "#1a2733",
  56. description: "Used for the main page's background",
  57. datatype: "color"
  58. },
  59. primary_background: {
  60. default_dark: "#222222",
  61. default_light: "#e2e2e2",
  62. description: "Used as the main background color of windows\n(Eg: Chat background, Leave lobby background, Login page)",
  63. datatype: "color"
  64. },
  65. secondary_background: {
  66. default_dark: "#333333",
  67. default_light: "#f3f3f3",
  68. description: "Secondary background color for things inside windows\n(Eg: Auto login, Joining room status text, Map Editor inputs, ...)",
  69. datatype: "color"
  70. },
  71. behind_lobby_background: {
  72. default_dark: "#131313",
  73. default_light: "#1a2733",
  74. description: "Color for the Lobby's background\n(Eg: Behind the Lobby and Map Editor)",
  75. datatype: "color"
  76. },
  77. red_text: {
  78. default_dark: "#e14747",
  79. default_light: "#cc3333",
  80. description: "Used for player nerf indicator in the lobby",
  81. datatype: "color"
  82. },
  83. blue_text: {
  84. default_dark: "#179be8",
  85. default_light: "#0955c7",
  86. description: "Used for [Load] when a map is suggested, and Copy link is clicked",
  87. datatype: "color"
  88. },
  89. green_text: {
  90. default_dark: "#17e88b",
  91. default_light: "#155824",
  92. description: "Used for player buff and in chat friend requests",
  93. datatype: "color"
  94. },
  95. purple_text: {
  96. default_dark: "#8f68e8",
  97. default_light: "#6033cc",
  98. description: "Used for output of /curate",
  99. datatype: "color"
  100. },
  101. magenta_text: {
  102. default_dark: "#d23cfb",
  103. default_light: "#800d6e",
  104. description: "Used for when [Load] is clicked, or when you are now the host of the game",
  105. datatype: "color"
  106. },
  107. button_color: {
  108. default_dark: "#4f382f",
  109. default_light: "#795548",
  110. description: "Button/dropdown color",
  111. datatype: "color"
  112. },
  113. hover_button_color: {
  114. default_dark: "#3a2a24",
  115. default_light: "#7f5d51",
  116. description: "Button/dropdown hover color",
  117. datatype: "color"
  118. },
  119. active_button_color: {
  120. default_dark: "#362620",
  121. default_light: "#4b252b",
  122. description: "Button/dropdown click color",
  123. datatype: "color"
  124. },
  125. disabled_button_color: {
  126. default_dark: "#444444",
  127. default_light: "#777777",
  128. description: "Button/dropdown disabled color",
  129. datatype: "color"
  130. },
  131. button_text: {
  132. default_dark: "#f8fafd",
  133. default_light: "#ffffff",
  134. description: "Button/dropdown text color",
  135. datatype: "color"
  136. },
  137. xp_bar_fill: {
  138. default_dark: "#473aaf",
  139. default_light: "#473aaf",
  140. description: "XP bar fill color at the top of your screen whilst in-game",
  141. datatype: "color"
  142. },
  143. top_bar_opacity: {
  144. default_dark: "0.8",
  145. default_light: "0.8",
  146. description: "Opacity of the 'top bar' that contains your:\nSkin, Username, Level, Volume Settings, ...",
  147. datatype: "percentage"
  148. },
  149. top_bar_color: {
  150. default_dark: "#333333",
  151. default_light: "#273749",
  152. description: "Color of the 'top bar'\nMake sure this value is dark, the icon colors are white and can't really be easily changed",
  153. datatype: "color"
  154. },
  155. top_bar_hover_color: {
  156. default_dark: "#222222",
  157. default_light: "#2d435a",
  158. description: "Color of buttons in the 'top bar' then hovered",
  159. datatype: "color"
  160. },
  161. top_bar_text: {
  162. default_dark: "#bebebe",
  163. default_light: "#bebebe",
  164. description: "Color of text in the 'top bar'",
  165. datatype: "color"
  166. },
  167. football_background: {
  168. default_dark: "#161616",
  169. default_light: "#5a7f64",
  170. description: "Color for the Football gamemode's background\n(Note: Requires restarting the football to apply)\nWarning: Unstable, experimental",
  171. datatype: "color"
  172. },
  173. border_color: {
  174. default_dark: "#333333",
  175. default_light: "#a5acb0",
  176. description: "Color used for subtile borders\n(Eg. Settings border, line separating chat and messages in lobby)",
  177. datatype: "color"
  178. },
  179. mini_menu_color: {
  180. default_dark: "#191919",
  181. default_light: "#1e2833",
  182. description: "Used for Tooltips and 'Filter by' in Custom Games",
  183. datatype: "color"
  184. },
  185. mini_menu_text: {
  186. default_dark: "#bebebe",
  187. default_light: "#ffffff",
  188. description: "Used for Tooltips and 'Filter by' in Custom Games",
  189. datatype: "color"
  190. },
  191. scrollbar_background: {
  192. default_dark: "#191919",
  193. default_light: "#dddddd",
  194. description: "Used for the scrollbar's background (Chromium only)",
  195. datatype: "color"
  196. },
  197. scrollbar_thumb: {
  198. default_dark: "#555555",
  199. default_light: "#aaaaaa",
  200. description: "Used for the scrollbar's thumb - which is the thing you drag (Chromium only)",
  201. datatype: "color"
  202. },
  203. list_headers: {
  204. default_dark: "#2b3839",
  205. default_light: "#a8bcc0",
  206. description: "Used for the colors of lists\n(Eg: Friends list and the sections in the Map Editor, ...)",
  207. datatype: "color"
  208. },
  209. table_color: {
  210. default_dark: "#444444",
  211. default_light: "#c1cdd2",
  212. description: "Stripe color for use in tables\n(Eg: Custom games, Friends list, Map Editor, Skin Editor, ...)",
  213. datatype: "color"
  214. },
  215. table_alt_color: {
  216. default_dark: "#333333",
  217. default_light: "#d2dbde",
  218. description: "Alternative stripe color used in tables",
  219. datatype: "color"
  220. },
  221. table_hover_color: {
  222. default_dark: "#222222",
  223. default_light: "#aac5d7",
  224. description: "Color used when a row in a table is hovered",
  225. datatype: "color"
  226. },
  227. table_active_color: {
  228. default_dark: "#111111",
  229. default_light: "#9cc8d6",
  230. description: "Color used when a row in a table is selected",
  231. datatype: "color"
  232. },
  233. brightness_lighter: {
  234. default_dark: "2.5",
  235. default_light: "1",
  236. description: "Used to lighten text that have bad contrast with dark colors\nNote: Change to 1 if making a light theme\n(0.5 = 50%, 1.5 = 150% brightness)",
  237. datatype: "brightness"
  238. },
  239. brightness_darker: {
  240. default_dark: "0.5",
  241. default_light: "1",
  242. description: "Used to darken images that that are too bright\nNote: Change to 1 if making a light theme\n(0.5 = 50%, 1.5 = 150% brightness)",
  243. datatype: "brightness"
  244. },
  245. description_invert: {
  246. default_dark: "1",
  247. default_light: "0",
  248. description: "How much to invert description at the bottom of the page by\n(Value from 0 to 1, Don't use 0.5)",
  249. datatype: "percentage"
  250. },
  251. };
  252.  
  253. const datatype_metadata_map = {
  254. "color": {
  255. value: "value",
  256. attributes: {
  257. type: "color"
  258. }
  259. },
  260. "percentage": {
  261. value: "value",
  262. attributes: {
  263. type: "number",
  264. max: 1,
  265. min: 0,
  266. step: 0.01
  267. }
  268. },
  269. "brightness": {
  270. value: "value",
  271. attributes: {
  272. type: "number",
  273. max: 10,
  274. min: 0,
  275. step: 0.05
  276. }
  277. },
  278. "char": {
  279. value: "value",
  280. attributes: {
  281. type: "text" ,
  282. maxLength: 1
  283. }
  284. },
  285. };
  286.  
  287. const default_configuration = {};
  288. for (const [key, value] of Object.entries(configuration_metadata_map))
  289. default_configuration[key] = value.default_dark;
  290. // If running inside maingameframe, inject our injectors
  291. if (unsafeWindow.parent !== unsafeWindow) {
  292. unsafeWindow.bonk_theme = {
  293. on: true,
  294. get_football_background: () => parseInt(getComputedStyle(document.documentElement)
  295. .getPropertyValue("--bonk_theme_football_background").trim().slice(1), 16),
  296. get_hotkey: () => getComputedStyle(document.documentElement)
  297. .getPropertyValue("--bonk_theme_hotkey").trim() || default_configuration.hotkey
  298. };
  299.  
  300. // Injector for football mode, if it doesn't work, ...well football will be bright
  301. if (!unsafeWindow.bonkCodeInjectors) unsafeWindow.bonkCodeInjectors = [];
  302. unsafeWindow.bonkCodeInjectors.push(bonkCode => {
  303. try {
  304. // Default football background color, not used elsewhere (yet?)
  305. const FOOTBALL_BACKGROUND_COLOR = "0x5a7f64";
  306. let newBonkCode = bonkCode;
  307. newBonkCode = newBonkCode
  308. .replace(
  309. FOOTBALL_BACKGROUND_COLOR,
  310. `(window.bonk_theme.on ? window.bonk_theme.get_football_background() : ${FOOTBALL_BACKGROUND_COLOR})`
  311. );
  312. if (bonkCode === newBonkCode) throw "[Themes] Injection failed!";
  313.  
  314. console.log("Themes injector run");
  315. return newBonkCode;
  316. } catch (er) {
  317. // Silently ignore errors, only football's background will be affected
  318. console.log("[Themes] Failed to inject");
  319. console.error(er);
  320. return bonkCode;
  321. }
  322. });
  323. }
  324.  
  325. document.addEventListener("DOMContentLoaded", () => {
  326. document.body.classList.add("themed-colors");
  327. // Get the currently applied theme
  328. const get_stored_theme = () => {
  329. // Get the stored theme, if it doesn't exist, it will be null
  330. let stored_theme = localStorage.getItem("bonk_theme");
  331. try {
  332. stored_theme = JSON.parse(stored_theme);
  333. } catch (er) {
  334. // If the stored theme is somehow corrupted - use blank theme
  335. console.log("[Themes] Failed to load theme from localstorage");
  336. console.log(`[Themes] ${stored_theme}`);
  337. console.error(er);
  338. alert("Failed to load theme from localstorage");
  339. stored_theme = {};
  340. }
  341. // Merge the stored theme with the default (if null, it will overwrite)
  342. return {...default_configuration, ...stored_theme};
  343. };
  344.  
  345. // Get the stored theme when the page loads
  346. const configuration = get_stored_theme();
  347. // Check if the script is running inside maingameframe or not
  348. if (unsafeWindow.parent === unsafeWindow) {
  349. // Outer bonk.io website
  350. // Hotkey to turn the script on and off
  351. const maingameframe = document.getElementById("maingameframe");
  352. document.addEventListener("keydown", evt => {
  353. if (evt.key?.toLowerCase() === maingameframe.contentWindow.bonk_theme.get_hotkey() && evt.ctrlKey && evt.altKey) {
  354. document.body.classList.toggle("themed-colors");
  355. maingameframe.contentDocument.body.classList.toggle("themed-colors");
  356. maingameframe.contentWindow.bonk_theme.on = !maingameframe.contentWindow.bonk_theme.on;
  357. }
  358. });
  359.  
  360. // Flag to check whether the theme container already exists
  361. let theme_container_created = false;
  362. // Create the menu only when someone clicks on the thing in the menu
  363. // Show the theme container when you click the menu command thing
  364. // eslint-disable-next-line no-undef
  365. GM_registerMenuCommand("Edit theme", () => {
  366. // Creating a new theme_container, don't make new ones after this
  367. if (theme_container_created) return document.getElementById("theme_container").style.display = "block";
  368. theme_container_created = true;
  369.  
  370. // Create the theme menu. This is really ugly but there's like no other way idk.
  371. const theme_container = document.createElement("div");
  372. const theme_container_title = document.createElement("p");
  373. const configuration_container = document.createElement("div");
  374. const configuration_container_label = document.createElement("label");
  375. const configuration_list = document.createElement("div");
  376. const configuration_json = document.createElement("textarea");
  377. const configuration_json_label = document.createElement("label");
  378. const theme_cancel = document.createElement("div");
  379. const theme_save = document.createElement("div");
  380. const theme_reset_dark = document.createElement("div");
  381. const theme_reset_light = document.createElement("div");
  382. // Add the IDs so we can style them with CSS
  383. theme_container_title.id = "theme_container_title";
  384. theme_container.id = "theme_container";
  385. configuration_container_label.id = "configuration_container_label";
  386. configuration_list.id = "configuration_list";
  387. configuration_json.id = "configuration_json";
  388. theme_cancel.id = "theme_cancel";
  389. theme_save.id = "theme_save";
  390. theme_reset_dark.class = "theme_reset";
  391. theme_reset_light.class = "theme_reset";
  392.  
  393. // Add the classes
  394. theme_container_title.classList.add("classicTopBar");
  395. theme_cancel.classList.add("brownButton", "brownButton_classic", "buttonShadow");
  396. theme_save.classList.add("brownButton", "brownButton_classic", "buttonShadow");
  397. theme_reset_dark.classList.add("brownButton", "brownButton_classic", "buttonShadow");
  398. theme_reset_light.classList.add("brownButton", "brownButton_classic", "buttonShadow");
  399.  
  400. // Add text to buttons and titles
  401. theme_container_title.textContent = "Theme Editor";
  402. theme_cancel.textContent = "CANCEL";
  403. theme_save.textContent = "SAVE";
  404. theme_reset_dark.textContent = "RESET THEME TO DARK PRESET";
  405. theme_reset_light.textContent = "RESET THEME TO LIGHT PRESET";
  406. configuration_container_label.textContent = "Hover over settings for more info";
  407. configuration_json_label.textContent = "Share, Backup or Import theme data - Copy or paste themes from/into the textbox below";
  408. configuration_json_label.for = "configuration_json";
  409. configuration_json.value = JSON.stringify(configuration);
  410. theme_container.appendChild(theme_container_title);
  411.  
  412. configuration_list.appendChild(configuration_container_label);
  413. configuration_list.appendChild(document.createElement("br"));
  414.  
  415. // Populate the themes list with the theme that is currently loaded
  416. for (const [key, value] of Object.entries(configuration)) {
  417. // Check if the setting exists
  418. if (!configuration_metadata_map[key]) continue;
  419. const datatype_metadata = datatype_metadata_map[configuration_metadata_map[key].datatype];
  420. const configuration_container = document.createElement("div");
  421. const configuration_name = document.createElement("p");
  422. const configuration_value = document.createElement("input");
  423. configuration_container.classList.add("configuration_container");
  424. configuration_name.classList.add("configuration_name");
  425. configuration_value.classList.add("configuration_value");
  426.  
  427. configuration_container.dataset["configuration_name"] = key;
  428. configuration_container.title = configuration_metadata_map[key].description ?? "No description";
  429. configuration_name.textContent = key.replace(/_/g, " ");
  430.  
  431. for (const [key, value] of Object.entries(datatype_metadata.attributes))
  432. configuration_value[key] = value;
  433. configuration_value[datatype_metadata.value] = value;
  434. // Using "oninput" instead of addEventListener so we can call it somewhere else
  435. configuration_value.oninput = () => {
  436. if (!datatype_metadata.ignore_change) {
  437. // Update the CSS variable on both bonk.io and maingameframe
  438. document.documentElement.style
  439. .setProperty(`--bonk_theme_${key}`, configuration_value.value);
  440. maingameframe.contentDocument.documentElement.style
  441. .setProperty(`--bonk_theme_${key}`, configuration_value.value);
  442. // Store it in the current configuration (so it can be saved later)
  443. configuration[key] = configuration_value[datatype_metadata.value];
  444. }
  445.  
  446. // Update the data at the bottom
  447. configuration_json.value = JSON.stringify(configuration);
  448. };
  449.  
  450. // Add the current config to the list of settings
  451. configuration_container.appendChild(configuration_name);
  452. configuration_container.appendChild(configuration_value);
  453. configuration_list.appendChild(configuration_container);
  454. }
  455.  
  456. // Add the Save and Cancel buttons
  457. configuration_container.appendChild(theme_cancel);
  458. configuration_container.appendChild(theme_save);
  459.  
  460. configuration_list.appendChild(document.createElement("br")); // this
  461. configuration_list.appendChild(configuration_container);
  462. configuration_list.appendChild(document.createElement("br")); // is
  463. configuration_list.appendChild(configuration_json_label);
  464. configuration_list.appendChild(document.createElement("br")); // so
  465. configuration_list.appendChild(configuration_json);
  466. configuration_list.appendChild(document.createElement("br")); // so
  467. configuration_list.appendChild(theme_reset_dark);
  468. configuration_list.appendChild(document.createElement("br")); // bad
  469. configuration_list.appendChild(theme_reset_light);
  470. theme_container.appendChild(configuration_list);
  471.  
  472. // When save is clicked, try save theme to localstorage
  473. theme_save.addEventListener("click", () => {
  474. try {
  475. localStorage.setItem("bonk_theme", JSON.stringify(configuration));
  476. theme_container.style.display = "none";
  477. } catch (er) {
  478. console.log("[Themes] Failed to save theme to localstorage");
  479. console.log(`[Themes] ${JSON.stringify(configuration)}`);
  480. console.error(er);
  481. alert("Failed to save theme to localstorage");
  482. }
  483. });
  484.  
  485. // Reset the state of configuration from localstorage
  486. theme_cancel.addEventListener("click", () => {
  487. configuration_json.value = JSON.stringify(get_stored_theme());
  488. configuration_json.oninput();
  489. theme_container.style.display = "none";
  490. });
  491.  
  492. // Get the currently saved theme, and overwrite everything with it
  493. theme_reset_dark.addEventListener("click", () => {
  494. configuration_json.value = JSON.stringify(default_configuration);
  495. configuration_json.oninput();
  496. });
  497.  
  498. theme_reset_light.addEventListener("click", () => {
  499. // Light theme defaults are not calculated by default, so we need to calculate it here now
  500. const default_light_configuration = {};
  501. for (const [key, value] of Object.entries(configuration_metadata_map))
  502. default_light_configuration[key] = value.default_light;
  503.  
  504. configuration_json.value = JSON.stringify(default_light_configuration);
  505. configuration_json.oninput();
  506. });
  507.  
  508. configuration_json.oninput = () => {
  509. try {
  510. const new_theme = JSON.parse(configuration_json.value);
  511. // Update the configurations
  512. const configuration_list_children = Array.from(configuration_list.children);
  513. for (const configuration_container of configuration_list_children) {
  514. const key = configuration_container.dataset["configuration_name"];
  515. const value = new_theme[key];
  516. if (!value) continue;
  517.  
  518. const configuration_value = configuration_container.querySelector("input");
  519. const datatype_meta = datatype_metadata_map[configuration_metadata_map[key].datatype];
  520. configuration_value[datatype_meta.value] = value;
  521. configuration_value.oninput();
  522. }
  523.  
  524. // If success, remove the border
  525. configuration_json.style.setProperty("border", "none");
  526. } catch (er) {
  527. console.log("[Themes] Failed to load theme from <textarea>");
  528. console.log(`[Themes] ${configuration_json.value}`);
  529. console.error(er);
  530. // If there is an error, set a red border
  531. configuration_json.style.setProperty("border", "3px solid var(--bonk_theme_red)", "important");
  532. }
  533. };
  534.  
  535. // Add the theme dialog to body
  536. document.body.appendChild(theme_container);
  537. });
  538. } else {
  539. // This code is for inside maingameframe
  540. // Hotkey to turn the script on and off
  541. document.addEventListener("keydown", evt => {
  542. if (evt.key?.toLowerCase() === unsafeWindow.bonk_theme.get_hotkey() && evt.ctrlKey && evt.altKey) {
  543. unsafeWindow.bonk_theme.on = !unsafeWindow.bonk_theme.on;
  544. document.body.classList.toggle("themed-colors");
  545. unsafeWindow.parent.document.body.classList.toggle("themed-colors");
  546. }
  547. });
  548. }
  549.  
  550. // List of default CSS variables
  551. let root_vars = [];
  552. for (const [key, value] of Object.entries(configuration))
  553. root_vars.push(`--bonk_theme_${key}: ${value};`);
  554.  
  555. // eslint-disable-next-line no-undef
  556. GM_addStyle(`
  557. /* CSS Variables, so we can edit their values on the fly */
  558. :root {
  559. ${root_vars.join("\n ")}
  560. }
  561.  
  562. /* Page background color */
  563. .themed-colors #pagecontainer,
  564. body.themed-colors {
  565. background-color: var(--bonk_theme_page_background) !important;
  566. --kkleeMultiSelectColour: ${configuration.colored_text};
  567. --kkleeErrorColour: ${configuration.red_text};
  568. --kkleeCheckboxTfsTrue: ${configuration.green_text};
  569. --kkleeCheckboxTfsFalse: ${configuration.red_text};
  570. }
  571.  
  572. /* Dark scroll bar tracks on Firefox and Chromium-based browsers */
  573. .themed-colors {
  574. scrollbar-color: var(--bonk_theme_scrollbar_thumb) var(--bonk_theme_scrollbar_background) !important;
  575. }
  576.  
  577. .themed-colors ::-webkit-scrollbar-track {
  578. background-color: var(--bonk_theme_scrollbar_background) !important;
  579. }
  580.  
  581. .themed-colors ::-webkit-scrollbar-thumb {
  582. background-color: var(--bonk_theme_scrollbar_thumb) !important;
  583. }
  584.  
  585. /* Color tooltips */
  586. .themed-colors #friendsToolTip,
  587. .themed-colors #pretty_top_replay_report_tooltip,
  588. .themed-colors #pretty_top_replay_fav_tooltip,
  589. .themed-colors #newbonklobby_tooltip,
  590. .themed-colors #mapeditor_rightbox_shapeaddmenucontainer,
  591. .themed-colors #mapeditor_leftbox_createmenucontainerleft,
  592. .themed-colors #mapeditor_leftbox_createmenucontainerright,
  593. .themed-colors #mapeditor_leftbox_copywindow,
  594. .themed-colors #mapeditor_rightbox_newjointmenu,
  595. .themed-colors .newbonklobby_playerentry_menu,
  596. .themed-colors .newbonklobby_playerentry_menu_submenu {
  597. background-color: var(--bonk_theme_mini_menu_color) !important;
  598. color: var(--bonk_theme_mini_menu_text) !important;
  599. }
  600.  
  601. /* Color the lobby's background */
  602. .themed-colors #bonkiocontainer {
  603. background-color: var(--bonk_theme_behind_lobby_background) !important;
  604. }
  605. /* Dialogs - I can just do windowShadow, but it might break things if new things are added */
  606. /* It's better to have a new thing visibly light rather than broken */
  607. .themed-colors .bt-primary-background,
  608. .themed-colors #autoLoginContainer,
  609. .themed-colors #guestOrAccountContainer_accountBox,
  610. .themed-colors #guestOrAccountContainer_guestBox,
  611. .themed-colors #guestContainer,
  612. .themed-colors .accountContainer,
  613. .themed-colors #registerwindow_remember_label,
  614. .themed-colors #loginwindow_remember_label,
  615. .themed-colors #loginwindow,
  616. .themed-colors #registerwindow,
  617. .themed-colors #settingsContainer,
  618. .themed-colors .settingsHeading,
  619. .themed-colors .redefineControls_selectionCell:hover,
  620. .themed-colors #newswindow,
  621. .themed-colors #skinmanager,
  622. .themed-colors .skineditor_shapewindow,
  623. .themed-colors .skineditor_shapewindow_imagecontainer,
  624. .themed-colors #skineditor_propertiesbox,
  625. .themed-colors #skineditor_propertiesbox_table,
  626. .themed-colors #skineditor_previewbox,
  627. .themed-colors #skineditor_layerbox,
  628. .themed-colors #skineditor_layerbox_baselabel,
  629. .themed-colors #quickPlayWindow,
  630. .themed-colors #roomlistcreatewindow,
  631. .themed-colors .roomlistcreatewindowlabel,
  632. .themed-colors #roomlistjoinpasswordwindow,
  633. .themed-colors #sm_connectingWindow,
  634. .themed-colors #newbonklobby_specbox,
  635. .themed-colors #newbonklobby_playerbox,
  636. .themed-colors #newbonklobby_chatbox,
  637. .themed-colors #newbonklobby_settingsbox,
  638. .themed-colors #newbonklobby_votewindow,
  639. .themed-colors #newbonklobby_votewindow_maptitle,
  640. .themed-colors #newbonklobby_votewindow_mapauthor,
  641. .themed-colors #leaveconfirmwindow,
  642. .themed-colors #leaveconfirmwindow_text2,
  643. .themed-colors #hostleaveconfirmwindow,
  644. .themed-colors #hostleaveconfirmwindow_text2,
  645. .themed-colors #maploadwindow,
  646. .themed-colors #maploadwindowgreybar,
  647. .themed-colors #maploadwindowstatustext,
  648. .themed-colors #mapeditor_leftbox,
  649. .themed-colors #mapeditor_midbox,
  650. .themed-colors #mapeditor_rightbox,
  651. .themed-colors #mapeditor_save_window,
  652. .themed-colors #kkleeRoot,
  653. .themed-colors #skineditor_colorpicker,
  654. .themed-colors #mapeditor_colorpicker,
  655. .themed-colors #friendsSendWindow,
  656. .themed-colors #roomlistfilterwindow,
  657. .themed-colors #ingamecountdown,
  658. .themed-colors #mapeditor_save_overwrite_window,
  659. #theme_container {
  660. background-color: var(--bonk_theme_primary_background) !important;
  661. color: var(--bonk_theme_primary_text) !important;
  662. }
  663. /* Lighter backgrounds for some menus and stuff */
  664. .themed-colors .bt-secondary-background,
  665. .themed-colors #bonkioheader,
  666. .themed-colors .windowTopBar_classic,
  667. .themed-colors #autoLogin_text,
  668. .themed-colors .guestOrAccountContainerLabelBox,
  669. .themed-colors #guest_nametext,
  670. .themed-colors #loginwindow_username,
  671. .themed-colors #loginwindow_password,
  672. .themed-colors #registerwindow_username,
  673. .themed-colors #registerwindow_password,
  674. .themed-colors #guest_skinbox,
  675. .themed-colors #skineditor_propertiesbox_blocker,
  676. .themed-colors #newswindow_white,
  677. .themed-colors .quickPlayWindowModeDiv,
  678. .themed-colors .quickPlayWindowText1,
  679. .themed-colors .quickPlayWindowText2,
  680. .themed-colors .quickPlayWindowText3,
  681. .themed-colors #roomlist,
  682. .themed-colors #roomlisttableheadercontainer,
  683. .themed-colors .roomlistcreatewindowinput,
  684. .themed-colors .whiteInputField,
  685. .themed-colors #sm_connectingWindow_text,
  686. .themed-colors #friendsContainer,
  687. .themed-colors .friends_table,
  688. .themed-colors .skinmanager_icon,
  689. .themed-colors #maploadwindowsearchinput,
  690. .themed-colors .maploadwindowmapdiv,
  691. .themed-colors #mapeditor_midbox_explain,
  692. .themed-colors #mapeditor_rightbox_namefield,
  693. .configuration_value,
  694. #configuration_json {
  695. border-color: transparent !important;
  696. background-color: var(--bonk_theme_secondary_background) !important;
  697. color: var(--bonk_theme_primary_text) !important;
  698. }
  699. .themed-colors .mapeditor_field,
  700. .themed-colors .skineditor_field,
  701. .themed-colors .mapeditor_rightbox_table_shape_headerfield {
  702. border-color: transparent;
  703. background-color: var(--bonk_theme_secondary_background);
  704. color: var(--bonk_theme_primary_text);
  705. }
  706.  
  707. .themed-colors .newbonklobby_playerentry_name,
  708. .themed-colors #newbonklobby_modetext,
  709. .themed-colors #newbonklobby_roundslabel,
  710. .themed-colors .maploadwindowtext,
  711. .themed-colors #roomliststatustext,
  712. .themed-colors #roomlisttable,
  713. .themed-colors .mapeditor_rightbox_table_leftcell,
  714. .themed-colors .mapeditor_rightbox_table_rightcell,
  715. .themed-colors #ingamecountdown_text,
  716. .themed-colors #bonkiobugemail {
  717. color: var(--bonk_theme_primary_text) !important;
  718. }
  719.  
  720. .themed-colors .newbonklobby_mapsuggest_high,
  721. .themed-colors .maploadwindowtext_picks,
  722. .themed-colors .newbonklobby_chat_msg_name,
  723. .themed-colors .newbonklobby_playerentry_balancetext {
  724. color: var(--bonk_theme_primary_text);
  725. }
  726.  
  727. .themed-colors .newbonklobby_playerentry_level,
  728. .themed-colors .newbonklobby_playerentry_pingtext,
  729. .themed-colors #newbonklobby_chat_lowerinstruction,
  730. .themed-colors #newbonklobby_chat_lowerline,
  731. .themed-colors .newbonklobby_chat_msg_txt,
  732. .themed-colors #newbonklobby_chat_input,
  733. .themed-colors #newbonklobby_maptext,
  734. .themed-colors #newbonklobby_roundsinput,
  735. .themed-colors #newbonklobby_mapauthortext,
  736. .themed-colors #newbonklobby_votewindow_maptitle_by,
  737. .themed-colors #hostleaveconfirmwindow_text1,
  738. .themed-colors #leaveconfirmwindow_text1,
  739. .themed-colors .maploadwindowtextmode_picks,
  740. .themed-colors .maploadwindowtextmode,
  741. .themed-colors .maploadwindowtextauthor,
  742. .themed-colors .maploadwindowtextauthor_picks,
  743. .themed-colors .roomlisttablejoined {
  744. color: var(--bonk_theme_secondary_text) !important;
  745. }
  746.  
  747. /* Lobby chat */
  748. .themed-colors .newbonklobby_mapsuggest_low {
  749. color: var(--bonk_theme_secondary_text);
  750. }
  751.  
  752. /* Copy link */
  753. .themed-colors #newbonklobby_chat_content span[style="color: rgb(9, 85, 199);"],
  754. .themed-colors .newbonklobby_chat_link {
  755. color: var(--bonk_theme_blue_text) !important;
  756. }
  757.  
  758. /* /help, player join */
  759. .themed-colors .newbonklobby_playerentry_balance_nerf,
  760. .themed-colors #newbonklobby_chat_content span[style="color: rgb(204, 68, 68);"],
  761. .themed-colors #newbonklobby_chat_content span[style="color: rgb(204, 51, 51);"],
  762. .themed-colors #newbonklobby_chat_content span[style="color: rgb(255, 0, 0);"] {
  763. color: var(--bonk_theme_red_text) !important;
  764. }
  765.  
  766. /* Friend requests */
  767. .themed-colors .newbonklobby_playerentry_balance_buff,
  768. .themed-colors #newbonklobby_chat_content span[style="color: rgb(0, 103, 93);"] {
  769. color: var(--bonk_theme_green_text) !important;
  770. }
  771.  
  772. /* /curate */
  773. .themed-colors #newbonklobby_chat_content span[style="color: rgb(96, 51, 204);"] {
  774. color: var(--bonk_theme_purple_text) !important;
  775. }
  776.  
  777. /* "You are now host" */
  778. .themed-colors #newbonklobby_chat_content span[style="color: rgb(122, 25, 154);"],
  779. .themed-colors #newbonklobby_chat_content span[style="color: rgb(128, 13, 110);"] {
  780. color: var(--bonk_theme_magenta_text) !important;
  781. }
  782.  
  783. .themed-colors .newbonklobby_chat_status:not([style]) {
  784. filter: brightness(var(--bonk_theme_brightness_lighter)) !important;
  785. }
  786.  
  787. .themed-colors #descriptioncontainer,
  788. .themed-colors #gamethumbbox,
  789. .themed-colors #bgreplay {
  790. filter: brightness(var(--bonk_theme_brightness_darker)) !important;
  791. }
  792.  
  793. /* Style sliders and buttons */
  794. .themed-colors .compactSlider {
  795. background-color: transparent !important;
  796. color: var(--bonk_theme_button_text) !important;
  797. }
  798.  
  799. .themed-colors .brownButton_classic,
  800. .themed-colors .dropdown_classic,
  801. .themed-colors .skineditor_field_button,
  802. .themed-colors .mapeditor_field_button,
  803. #theme_save, #theme_cancel, .theme_reset {
  804. border-color: transparent !important;
  805. background-color: var(--bonk_theme_button_color) !important;
  806. color: var(--bonk_theme_button_text) !important;
  807. }
  808.  
  809. .themed-colors .brownButtonDisabled,
  810. .themed-colors .brownButton_disabled_classic,
  811. .themed-colors .dropdown-option-disabled {
  812. background-color: var(--bonk_theme_disabled_button_color) !important;
  813. color: var(--bonk_theme_button_text) !important;
  814. }
  815.  
  816. .themed-colors .brownButton_classic:hover,
  817. .themed-colors .dropdown_classic:hover,
  818. #theme_save:hover, #theme_cancel:hover, .theme_reset:hover {
  819. background-color: var(--bonk_theme_hover_button_color) !important;
  820. color: var(--bonk_theme_button_text) !important;
  821. }
  822.  
  823. .themed-colors .brownButton_classic:active,
  824. .themed-colors .dropdown_classic:active,
  825. .themed-colors .newbonklobby_teamlockbutton_warn,
  826. #theme_save:active, #theme_cancel:active, .theme_reset:active {
  827. background-color: var(--bonk_theme_active_button_color) !important;
  828. color: var(--bonk_theme_button_text) !important;
  829. }
  830.  
  831. /* Tables in the game - Skin editor, Map Editor and Custom game list */
  832. .themed-colors #roomlisttable tr:nth-child(odd),
  833. .themed-colors .friends_table>tbody:nth-child(odd),
  834. .themed-colors #skineditor_layerbox_layertable tr:nth-child(odd),
  835. .themed-colors #mapeditor_leftbox_platformtable tr:nth-child(odd),
  836. .themed-colors #mapeditor_leftbox_spawntable tr:nth-child(odd),
  837. .themed-colors #redefineControls_table tr:nth-child(odd),
  838. .themed-colors .roomlistfilterwindow_a,
  839. .themed-colors #redefineControls_table th {
  840. background-color: var(--bonk_theme_table_color) !important;
  841. color: var(--bonk_theme_primary_text) !important;
  842. }
  843.  
  844. .themed-colors #roomlisttable tr:nth-child(even),
  845. .themed-colors .friends_table tr:nth-child(even),
  846. .themed-colors #skineditor_layerbox_layertable tr:nth-child(even),
  847. .themed-colors #mapeditor_leftbox_platformtable tr:nth-child(even),
  848. .themed-colors #mapeditor_leftbox_spawntable tr:nth-child(even),
  849. .themed-colors #redefineControls_table tr:nth-child(even),
  850. .themed-colors #roomlisttableheadercontainer,
  851. .themed-colors .roomlistfilterwindow_b {
  852. background-color: var(--bonk_theme_table_alt_color) !important;
  853. color: var(--bonk_theme_primary_text) !important;
  854. }
  855.  
  856. .themed-colors #roomlisttable tr.FRIENDSPRESENT,
  857. .themed-colors .maploadwindowtextaddedby_picks {
  858. color: var(--bonk_theme_colored_text) !important;
  859. }
  860.  
  861. .themed-colors tr.HOVERUNSELECTED:hover td {
  862. background-color: var(--bonk_theme_table_hover_color) !important;
  863. }
  864.  
  865. .themed-colors tr.HOVERSELECTED td,
  866. .themed-colors tr.SELECTED td {
  867. background-color: var(--bonk_theme_table_active_color) !important;
  868. }
  869.  
  870. /* "popup" color, custom room list top bar */
  871. .themed-colors .bt-titlebar,
  872. .themed-colors .windowTopBar_classic,
  873. .themed-colors .classicTopBar,
  874. .themed-colors .newbonklobby_boxtop,
  875. .themed-colors .newbonklobby_boxtop_classic,
  876. .themed-colors .friends_topbar,
  877. .themed-colors #newbonklobby_votewindow_top,
  878. .themed-colors #hostleaveconfirmwindow_top,
  879. .themed-colors #leaveconfirmwindow_top,
  880. .themed-colors #ingamecountdown_top,
  881. .themed-colors #roomlisthidepasswordedcheckboxlabel,
  882. #theme_container_title {
  883. background-color: var(--bonk_theme_window_color) !important;
  884. color: var(--bonk_theme_window_text) !important;
  885. }
  886.  
  887. /* Style the top bar */
  888. .themed-colors #pretty_top_bar {
  889. background-color: var(--bonk_theme_top_bar_color) !important;
  890. opacity: var(--bonk_theme_top_bar_opacity) !important;
  891. color: var(--bonk_theme_top_bar_text) !important;
  892. }
  893.  
  894. .themed-colors .pretty_top_button,
  895. .themed-colors #pretty_top_name,
  896. .themed-colors #pretty_top_name,
  897. .themed-colors #pretty_top_level,
  898. .themed-colors #pretty_top_playercount {
  899. background-color: var(--bonk_theme_top_bar_color) !important;
  900. color: var(--bonk_theme_top_bar_text) !important;
  901. }
  902.  
  903. .themed-colors .pretty_top_button:hover {
  904. background-color: var(--bonk_theme_top_bar_hover_color) !important;
  905. }
  906.  
  907. /* Invert the Bonk.io description at the bottom of the page */
  908. .themed-colors #descriptioninner,
  909. .themed-colors #descriptioninner .descriptionthumbr,
  910. .themed-colors #descriptioninner .descriptionthumbl {
  911. filter: invert(var(--bonk_theme_description_invert)) !important;
  912. }
  913.  
  914. /* Change color of borders in settings */
  915. .themed-colors #redefineControls_table td,
  916. .themed-colors #redefineControls_table th,
  917. .themed-colors #redefineControls_table {
  918. border: 1px solid var(--bonk_theme_border_color) !important;
  919. }
  920.  
  921. /* Players in lobby */
  922. .themed-colors .newbonklobby_playerentry {
  923. border-left: 4px solid var(--bonk_theme_primary_background) !important;
  924. border-top: 4px solid var(--bonk_theme_primary_background) !important;
  925. border-right: 4px solid var(--bonk_theme_primary_background) !important;
  926. background-color: var(--bonk_theme_primary_background) !important;
  927. color: var(--bonk_theme_primary_text) !important;
  928. }
  929.  
  930. .themed-colors .newbonklobby_playerentry:hover {
  931. border-left: 4px solid var(--bonk_theme_secondary_background) !important;
  932. border-top: 4px solid var(--bonk_theme_secondary_background) !important;
  933. border-right: 4px solid var(--bonk_theme_secondary_background) !important;
  934. background-color: var(--bonk_theme_secondary_background) !important;
  935. }
  936.  
  937. .themed-colors #newbonklobby_chat_lowerline {
  938. border-top: 1px solid var(--bonk_theme_border_color) !important;
  939. }
  940.  
  941. .themed-colors #newbonklobby_playerbox_middleline {
  942. border-left: 1px solid var(--bonk_theme_border_color) !important;
  943. }
  944.  
  945. /* Headings in the Map Editor and stuff */
  946. .themed-colors .friends_titles,
  947. .themed-colors .mapeditor_table_heading_div {
  948. background-color: var(--bonk_theme_list_headers) !important;
  949. }
  950.  
  951. /* Change the XP bar to use the colors we want */
  952. .themed-colors #xpbarfill {
  953. background-color: var(--bonk_theme_xp_bar_fill) !important;
  954. }
  955.  
  956. /* Below is CSS for our theme editor thing */
  957. #theme_container {
  958. border-radius: 3px 0px 3px 3px;
  959. z-index: 999;
  960. font-family: "futurept_b1";
  961. padding: 0px;
  962. right: 0px;
  963. top: 0px;
  964. position: fixed;
  965. overflow-y: scroll;
  966. max-height: 100vh;
  967. width: 20em;
  968. }
  969.  
  970. #configuration_list {
  971. padding: 1.5em;
  972. display: flex;
  973. flex-direction: column;
  974. }
  975.  
  976. #theme_container_title {
  977. text-align: center;
  978. margin: 0px;
  979. font-size: 20px;
  980. line-height: 32px;
  981. font-family: "futurept_b1"
  982. }
  983.  
  984. .configuration_container {
  985. white-space: pre-line;
  986. display: flex;
  987. justify-content: space-between;
  988. align-items: center;
  989. height: 2.25em;
  990. }
  991.  
  992. .configuration_name {
  993. text-transform: capitalize;
  994. float: left;
  995. width: 70%;
  996. }
  997.  
  998. .configuration_value {
  999. float: right;
  1000. width: 25%;
  1001. }
  1002.  
  1003. #theme_cancel {
  1004. float: left;
  1005. width: 45%;
  1006. }
  1007.  
  1008. #theme_save {
  1009. float: right;
  1010. width: 45%;
  1011. }
  1012.  
  1013. #configuration_json {
  1014. align-self: center;
  1015. resize: none;
  1016. width: 100%;
  1017. height: 15em;
  1018. }
  1019. `);
  1020. });
  1021. })();