commit 4a2f02930f8447a91aa0c9539c8d7949e6335454 Author: Leilukin Date: Sat Apr 19 23:05:34 2025 +0800 Update repository information diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..dfe07704 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..a0eb4e35 --- /dev/null +++ b/.gitignore @@ -0,0 +1,182 @@ +# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore + +# Working files for my website + +__Source/ + +# Eleventy site output folder + +_site/ + +# Logs + +_.log +npm-debug.log_ +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Caches + +.cache + +# Diagnostic reports (https://nodejs.org/api/report.html) + +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# Runtime data + +pids +_.pid +_.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover + +lib-cov + +# Coverage directory used by tools like istanbul + +coverage +*.lcov + +# nyc test coverage + +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) + +.grunt + +# Bower dependency directory (https://bower.io/) + +bower_components + +# node-waf configuration + +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) + +build/Release + +# Dependency directories + +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) + +web_modules/ + +# TypeScript cache + +*.tsbuildinfo + +# Optional npm cache directory + +.npm + +# Optional eslint cache + +.eslintcache + +# Optional stylelint cache + +.stylelintcache + +# Microbundle cache + +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history + +.node_repl_history + +# Output of 'npm pack' + +*.tgz + +# Yarn Integrity file + +.yarn-integrity + +# dotenv environment variable files + +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) + +.parcel-cache + +# Next.js build output + +.next +out + +# Nuxt.js build / generate output + +.nuxt +dist + +# Gatsby files + +# Comment in the public line in if your project uses Gatsby and not Next.js + +# https://nextjs.org/blog/next-9-1#public-directory-support + +# public + +# vuepress build output + +.vuepress/dist + +# vuepress v2.x temp and cache directory + +.temp + +# Docusaurus cache and generated files + +.docusaurus + +# Serverless directories + +.serverless/ + +# FuseBox cache + +.fusebox/ + +# DynamoDB Local files + +.dynamodb/ + +# TernJS port file + +.tern-port + +# Stores VSCode versions used for testing VSCode extensions + +.vscode-test + +# yarn v2 + +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config +.DS_Store diff --git a/README.md b/README.md new file mode 100644 index 00000000..6fdca4d9 --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +# Leilukin's Hub + +Source code of my hobby website, [Leilukin's Hub](https://leilukin.com/). Built with [Eleventy](https://www.11ty.dev/) and hosted on [Hostinger](https://www.hostinger.my/). + +More technical information can be found on my site's [colophon page](https://leilukin.com/colophon). + +## Run Locally +Recommended JavaScript runtime: [Bun](https://bun.sh). + +1. Clone this repository locally + ``` + git clone https://git.32bit.cafe/Leilukin/leilukin-site.git + ``` +1. Install dependencies + ``` + bun install + ``` +1. Run the project + ``` + bun run start + ``` +1. Open http://localhost:8080/ in your browser diff --git a/bun.lockb b/bun.lockb new file mode 100644 index 00000000..c2b028e5 Binary files /dev/null and b/bun.lockb differ diff --git a/eleventy.config.js b/eleventy.config.js new file mode 100644 index 00000000..092656af --- /dev/null +++ b/eleventy.config.js @@ -0,0 +1,50 @@ +// Plugins +import { InputPathToUrlTransformPlugin } from "@11ty/eleventy"; +import pluginRss from "@11ty/eleventy-plugin-rss"; +import pluginEleventyNavigation from "@11ty/eleventy-navigation"; +import pluginSyntaxHighlight from "@11ty/eleventy-plugin-syntaxhighlight"; +import pluginEmbedEverything from "eleventy-plugin-embed-everything"; +import pluginWordcount from "eleventy-plugin-wordcount-extended"; +import pluginTOC from "@uncenter/eleventy-plugin-toc"; + +// Custom Configurations +import markdownItConfig from "./src/_config/markdown-it.js"; +import filesConfig from "./src/_config/files.js"; +import collectionsConfig from "./src/_config/collections.js"; +import filtersConfig from "./src/_config/filters.js"; +import shortCodesConfig from "./src/_config/shortcodes.js"; + +export default function(eleventyConfig) { + // Plugins + eleventyConfig.addPlugin(InputPathToUrlTransformPlugin); + eleventyConfig.addPlugin(pluginRss); + eleventyConfig.addPlugin(pluginEleventyNavigation); + eleventyConfig.addPlugin(pluginSyntaxHighlight, { preAttributes: { tabindex: 0 } }); + eleventyConfig.addPlugin(pluginEmbedEverything, { add: ['soundcloud'] }); + eleventyConfig.addPlugin(pluginWordcount); + eleventyConfig.addPlugin(pluginTOC, { + tags: ['h2', 'h3', 'h4', 'h5', 'h6'], + wrapper: function (toc) { + return ``; + }, + }); + + // Custom Configurations + eleventyConfig.addPlugin(markdownItConfig); + eleventyConfig.addPlugin(filesConfig); + eleventyConfig.addPlugin(collectionsConfig); + eleventyConfig.addPlugin(filtersConfig); + eleventyConfig.addPlugin(shortCodesConfig); + + // Eleventy bundle plugin + eleventyConfig.addBundle("css"); + eleventyConfig.addBundle("js", { toFileDirectory: "assets/js" }); + + return { + markdownTemplateEngine: "njk", + htmlTemplateEngine: "njk", + dir: { + input: "src" + } + }; +}; \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 00000000..f050fbb6 --- /dev/null +++ b/package.json @@ -0,0 +1,36 @@ +{ + "name": "leilukin-site", + "description": "Leilukin's personal and hobby website.", + "author": "Leilukin", + "repository": { + "type": "git", + "url": "https://git.32bit.cafe/Leilukin/leilukin-site" + }, + "scripts": { + "start": "bunx @11ty/eleventy --serve --quiet", + "build": "bunx @11ty/eleventy" + }, + "type": "module", + "devDependencies": { + "@types/bun": "^1.2.5" + }, + "dependencies": { + "@11ty/eleventy": "^3.0.0", + "@11ty/eleventy-fetch": "^5.0.2", + "@11ty/eleventy-navigation": "^1.0.1", + "@11ty/eleventy-plugin-rss": "^2.0.3", + "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0", + "@uncenter/eleventy-plugin-toc": "^1.0.3", + "@zachleat/details-utils": "^2.0.2", + "eleventy-plugin-embed-everything": "^1.20.0", + "eleventy-plugin-wordcount-extended": "^0.2.1", + "install": "^0.13.0", + "markdown-it-anchor": "^9.2.0", + "markdown-it-attribution": "^0.1.4", + "markdown-it-attrs": "^4.3.1", + "markdown-it-bracketed-spans": "^1.0.1", + "markdown-it-deflist": "^3.0.0", + "markdown-it-footnote": "^4.0.0", + "slugify": "^1.6.6" + } +} diff --git a/src/.htaccess.njk b/src/.htaccess.njk new file mode 100644 index 00000000..03e71cc0 --- /dev/null +++ b/src/.htaccess.njk @@ -0,0 +1,22 @@ +--- +permalink: "{{ page.filePathStem }}" +eleventyExcludeFromCollections: true +eleventyAllowMissingExtension: true +--- +ErrorDocument 404 /404.html + + +Header set Cache-Control "max-age=31536000, public" + + +Header set Cache-Control "no-cache, public" + + +RewriteEngine on + +# Redirect obfuscated email links to mailto link +RewriteRule ^.*{{ sitemeta.siteAuthor.emailDecoyUrl }}.*$ "mailto:{{ sitemeta.siteAuthor.email }}" [R=301,L] + +# Block bad bots +RewriteCond %{HTTP_USER_AGENT} ({{ robots.htaccess }}) [NC] +RewriteRule .* https://nocommercialuse.org/ [L] \ No newline at end of file diff --git a/src/404.njk b/src/404.njk new file mode 100644 index 00000000..156dc432 --- /dev/null +++ b/src/404.njk @@ -0,0 +1,4 @@ +--- +layout: misc/404 +permalink: "{{ page.filePathStem }}.html" +--- diff --git a/src/_bundle/css/comments.css b/src/_bundle/css/comments.css new file mode 100644 index 00000000..d4468983 --- /dev/null +++ b/src/_bundle/css/comments.css @@ -0,0 +1,139 @@ +/** +* Author: Vera Konigin +* Site: https://groundedwren.neocities.org +* Contact: vera@groundedwren.com +* +* File Description: Styles for the guestbook control +* CSS variables come from https://groundedwren.neocities.org/styles/gwBoilerPlatePersonalization.css +*/ +:root { --icon-color: var(--clr-body-txt); } + +.comment-form { + display: grid; + border: 0.1rem solid var(--clr-body-txt); + padding: 1em; + margin: 2em 0; +} + +.comment-form, +.input-horizontal-wrapper { gap: 1em; } + +.comment-form-title { + text-align: center; + margin-bottom: 0 !important; +} + +.comment-form input, +.comment-form textarea { + color: var(--clr-body-txt); + background-color: var(--clr-quote-bg); +} + +.input-horizontal-wrapper { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(min(100%/1, max(16rem, 100%/3)), 1fr)); +} + +.input-vertical, +.comment-box-container { + display: grid; + gap: 0.3em; +} + +.input-vertical input:focus, +.comment-box-container textarea:focus { outline: 0.15em solid var(--clr-link); } + +.comment-box-container textarea { resize: vertical; } + +.inline-banner { + padding: 0.5em; + word-break: break-word; + display: flex; + align-items: center; + justify-content: center; + gap: 0.5em; + background-color: var(--clr-quote-bg); +} + +.inline-banner.warning { background-color: #9e0f00; } + +.inline-banner.warning a { color: unset; } + +.form-footer, +.comment-footer { + display: flex; + gap: 0.5em; +} + +.form-footer { justify-content: flex-end; } + +.form-footer input, +.comment-footer button, +.show-comment { + border: none; + background: var(--clr-link-btn-bg); + color: var(--clr-link-btn-txt); + padding: 0.3em 0.6em; + border-radius: 0.2em; +} + +.comment-footer button, +.show-comment { font-size: initial; } + +gw-comment-card:not(.collapsed) .show-comment { display: none; } +gw-comment-card.collapsed .comment-article > *:not(.comment-header) { display: none !important; } +gw-comment-card.collapsed .show-comment { display: block; } +gw-comment-card.collapsed .comment-header-right time { display: none; } + +.comments-container { + display: flex; + flex-direction: column; + align-items: stretch; + max-width: 100%; + gap: 1.5em; +} + +.comment-article { + padding: 0.3em 0; + display: flex; + flex-direction: column; +} + +.comment-article blockquote { + max-width: unset !important; + overflow-wrap: break-word; + margin: 0.5em 0; +} + +.comment-article > button { max-width: fit-content; } + +.comment-header { + display: grid; + grid-template-columns: 0fr auto 1fr; + gap: 0.4em; + align-items: baseline; +} + +.comment-article .comment-article { + margin-left: 2em; + margin-top: 0.5em; + padding-right: 0; +} + +.comment-id, .comment-header-right > time { + font-size: 0.85em; + font-style: italic; + word-break: keep-all; +} + +.comment-header-right { + display: flex; + flex-direction: row; + justify-content: flex-end; +} + +.commenter-name { + font-size: 1.1em; + font-weight: 700; + overflow-wrap: break-word; +} diff --git a/src/_bundle/js/comments.js b/src/_bundle/js/comments.js new file mode 100644 index 00000000..d6d28593 --- /dev/null +++ b/src/_bundle/js/comments.js @@ -0,0 +1,528 @@ +/** + * @file Comments control + * @author Vera Konigin vera@groundedwren.com + * https://groundedwren.neocities.org + */ + +window.GW = window.GW || {}; +(function Controls(ns) { + ns.CommentForm = class CommentForm extends HTMLElement { + //#region staticProperties + static instanceCount = 0; + static instanceMap = {}; + //#endregion + + //#region instance properties + instanceId; + isInitialized; + titleText; + discordURL; + encodedPath; + fallbackEmail; + + //#region element properties + formEl; + titleEl; + bannerEl; + + dispNameInpt; + emailInpt; + websiteInpt; + respToInpt; + commentInpt; + + resetBtn; + submitBtn; + //#endregion + //#endregion + + constructor() { + super(); + this.instanceId = CommentForm.instanceCount++; + CommentForm.instanceMap[this.instanceId] = this; + } + + get idKey() { + return `gw-comment-form-${this.instanceId}`; + } + + connectedCallback() { + if (this.isInitialized) { return; } + + this.titleText = this.getAttribute("titleText") || "Add a Comment"; + this.discordURL = this.getAttribute("discordURL"); + this.encodedPath = this.getAttribute("encodedPath"); + this.fallbackEmail = this.getAttribute("fallbackEmail"); + + this.renderContent(); + this.registerHandlers(); + + this.isInitialized = true; + } + + renderContent() { + //Markup + this.innerHTML = ` +
+

${this.titleText}

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + +
+
+
+ + Comments are manually approved +
+ +
+ `; + + //element properties + this.formEl = document.getElementById(`${this.idKey}-form`); + this.titleEl = document.getElementById(`${this.idKey}-title`); + this.bannerEl = document.getElementById(`${this.idKey}-banner`); + + this.dispNameInpt = document.getElementById(`${this.idKey}-dispName`); + this.emailInpt = document.getElementById(`${this.idKey}-email`); + this.websiteInpt = document.getElementById(`${this.idKey}-website`); + this.respToInpt = document.getElementById(`${this.idKey}-respTo`); + this.commentInpt = document.getElementById(`${this.idKey}-comment`); + + this.resetBtn = document.getElementById(`${this.idKey}-reset`); + this.submitBtn = document.getElementById(`${this.idKey}-submit`); + + //default values + this.dispNameInpt.value = localStorage.getItem("comment-name") || ""; + this.emailInpt.value = localStorage.getItem("comment-email") || ""; + this.websiteInpt.value = localStorage.getItem("comment-website") || ""; + } + + //#region Handlers + registerHandlers() { + this.formEl.onsubmit = this.onSubmit; + } + + onSubmit = (event) => { + event.preventDefault(); + + const contentObj = { + name: this.dispNameInpt.value, + email: this.emailInpt.value, + website: this.websiteInpt.value, + responseTo: this.respToInpt.value, + comment: ( + this.commentInpt.value || "" + ).replaceAll("\n", "
").replaceAll("(", "\\("), + timestamp: new Date().toUTCString(), + }; + const contentAry = []; + for (let contentKey in contentObj) { + contentAry.push(`${contentKey}=${contentObj[contentKey]}`); + } + + const request = new XMLHttpRequest(); + request.open( + "POST", + this.discordURL || atob("aHR0cHM6Ly9kaXNjb3JkLmNvbS9hcGkvd2ViaG9va3Mv" + this.encodedPath), + true + ); + request.setRequestHeader("Content-Type", "application/json"); + + request.onreadystatechange = () => { + if (request.readyState !== XMLHttpRequest.DONE) { return; } + if (Math.floor(request.status / 100) !== 2) { + console.log(request.responseText); + this.bannerEl.classList.add("warning"); + this.bannerEl.innerHTML = + ` + + + That didn't work. + ${this.fallbackEmail + ? `Click here to send as an email instead.` + : "" + } + + `; + } + else { + alert("Your comment has been submitted!"); + } + }; + + request.send(JSON.stringify({ + embeds: [{ + fields: Object.keys(contentObj).map(key => { return { name: key, value: contentObj[key] }}) + }] + })); + + localStorage.setItem("comment-name", contentObj.name); + localStorage.setItem("comment-email", contentObj.email); + localStorage.setItem("comment-website", contentObj.website); + + this.formEl.reset(); + this.dispNameInpt.value = contentObj.name; + this.emailInpt.value = contentObj.email; + this.websiteInpt.value = contentObj.website; + }; + //#endregion + }; + customElements.define("gw-comment-form", ns.CommentForm); + + ns.CommentList = class CommentList extends HTMLElement { + //#region staticProperties + static instanceCount = 0; + static instanceMap = {}; + static Data = []; + //#endregion + + //#region instance properties + instanceId; + isInitialized; + gSpreadsheetId; + gSheetId; + isNewestFirst; + gwCommentFormId; + + //#region element properties + //#endregion + //#endregion + + constructor() { + super(); + this.instanceId = CommentList.instanceCount++; + CommentList.instanceMap[this.instanceId] = this; + CommentList.Data[this.instanceId] = {}; + } + + get idKey() { + return `gw-comment-list-${this.instanceId}`; + } + + connectedCallback() { + if (this.isInitialized) { return; } + + this.gSpreadsheetId = this.getAttribute("gSpreadsheetId"); + this.gSheetId = this.getAttribute("gSheetId"); + this.isNewestFirst = this.getAttribute("isNewestFirst"); + this.gwCommentFormId = this.getAttribute("gwCommentFormId"); + + this.loadAndRender(); + + this.isInitialized = true; + } + + async loadAndRender() { + this.innerHTML = ` +
+ + Comments loading.... +
+ ` + + const sheetReader = new GW.Gizmos.GoogleSheetsReader(this.gSpreadsheetId, this.gSheetId); + await sheetReader.loadData(); + this.innerHTML = ""; + + const allComments = sheetReader.rowData; + if (this.isNewestFirst) { + allComments.reverse(); + } + + this.renderContent(); + this.registerHandlers(); + + const allCommentsIndex = {}; + const topLevelCommentIdxs = []; + const childCommentIdxs = []; + for (let i = 0; i < allComments.length; i++) { + const comment = allComments[i]; + allCommentsIndex[comment.ID] = i; + if (!comment.ResponseTo) { + topLevelCommentIdxs.push(i); + } + else { + childCommentIdxs.push(i); + } + } + childCommentIdxs.forEach(childIdx => { + const replyId = allComments[childIdx].ResponseTo; + const respondeeComment = allComments[allCommentsIndex[replyId]]; + + respondeeComment.ChildIdxs = respondeeComment.ChildIdxs || []; + respondeeComment.ChildIdxs.push(childIdx); + }); + + let commentsToBuild = []; + topLevelCommentIdxs.forEach( + topCommentIdx => commentsToBuild.push({ + parent: this.containerEl, + comment: allComments[topCommentIdx] + }) + ); + + while (commentsToBuild.length > 0) { + let { parent, comment } = commentsToBuild.shift(); + if (!comment.Timestamp) { + continue; + } + + CommentList.Data[this.instanceId][comment.ID] = comment; + + parent.insertAdjacentHTML("beforeend", ` + + `); + + const commentEl = document.getElementById(`${this.idKey}-cmt-${comment.ID}`); + (comment.ChildIdxs || []).forEach( + childIdx => commentsToBuild.push({ + parent: commentEl.articleEl, + comment: allComments[childIdx] + }) + ); + } + } + + renderContent() { + //Markup + this.innerHTML = ` +
+
+ `; + + //element properties + this.containerEl = document.getElementById(`${this.idKey}-container`); + } + + //#region Handlers + registerHandlers() { + } + //#endregion + }; + customElements.define("gw-comment-list", ns.CommentList); + + ns.CommentCard = class CommentCard extends HTMLElement { + //#region staticProperties + static instanceCount = 0; + static instanceMap = {}; + //#endregion + + //#region instance properties + instanceId; + isInitialized; + + commentId; + gwCommentFormId; + + replyToId; + numChildren; + commenterName; + datetime; + websiteURL; + commentText; + + //#region element properties + articleEl; + replyBtn; + //#endregion + //#endregion + + constructor() { + super(); + this.instanceId = CommentCard.instanceCount++; + CommentCard.instanceMap[this.instanceId] = this; + } + + get idKey() { + return `gw-comment-card-${this.instanceId}`; + } + + //#region HTMLElement implementation + connectedCallback() { + if (this.isInitialized) { return; } + + this.commentId = this.getAttribute("commentId"); + this.gwCommentFormId = this.getAttribute("gwCommentFormId"); + + const commentData = ns.CommentList.Data[this.getAttribute("listInstance")][this.commentId]; + + this.replyToId = commentData.ResponseTo; + this.numChildren = (commentData.ChildIdxs || []).length; + this.commenterName = commentData["Display Name"]; + this.datetime = commentData.Timestamp; + this.websiteURL = commentData.Website; + this.commentText = this.parseCommentText(commentData.Comment); + + this.renderContent(); + this.registerHandlers(); + + this.isInitialized = true; + } + //#endregion + + renderContent() { + let headerText = this.replyToId + ? `Comment #${this.commentId} replying to #${this.replyToId}` + : `Top level comment #${this.commentId}`; + headerText += ` with ${this.numChildren} direct ${this.numChildren == 1 ? "reply" : "replies"}`; + + const displayTimestamp = this.datetime.toLocaleString( + undefined, + { dateStyle: "short", timeStyle: "short" } + ); + + const commenterNameEl = this.websiteURL + ? `${this.commenterName}` + : `${this.commenterName}`; + + //Markup + this.innerHTML = ` +
+
+ + ${commenterNameEl} +
+ + +
+
+
${this.commentText}
+ +
+ `; + + //element properties + this.articleEl = document.getElementById(`${this.idKey}-article`); + this.timestamp = document.getElementById(`${this.idKey}-timestamp`); + this.replyBtn = document.getElementById(`${this.idKey}-reply`); + this.hideBtn = document.getElementById(`${this.idKey}-hide`); + this.showBtn = document.getElementById(`${this.idKey}-show`); + } + + //#region Handlers + registerHandlers() { + this.replyBtn.onclick = this.onReply; + this.hideBtn.onclick = this.onHide; + this.showBtn.onclick = this.onShow; + } + + onReply = () => { + const gwCommentForm = document.getElementById(this.gwCommentFormId); + const respToInpt = gwCommentForm.respToInpt; + if (!respToInpt) { + alert("Comment form not found"); + return; + } + + respToInpt.value = this.commentId; + respToInpt.focus(); + }; + + onHide = () => { + this.classList.add("collapsed"); + this.showBtn.focus(); + }; + + onShow = () => { + this.classList.remove("collapsed"); + this.timestamp.focus(); + }; + //#endregion + + parseCommentText(commentString) { + let commentText = ""; + let linkObj = {}; + + for(let i = 0; i < commentString.length; i++){ + let char = commentString.charAt(i); + switch (char) { + case '[': + linkObj = {tStart: i}; + break; + case ']': + if(linkObj.tStart !== undefined && linkObj.tStart !== i-1) { + linkObj.tEnd = i; + } + else { linkObj = {}; } + break; + case '(': + if(linkObj.tEnd !== undefined && linkObj.tEnd === i-1) { + linkObj.lStart = i; + } + else { linkObj = {}; } + break; + case ')': + if(linkObj.lStart !== undefined && linkObj.lStart !== i-1) { + linkObj.lEnd = i; + } + else { linkObj = {}; } + break; + } + if(linkObj.lEnd !== undefined) { + const linkText = commentString.substring(linkObj.tStart + 1, linkObj.tEnd); + const linkURL = commentString.substring(linkObj.lStart + 1, linkObj.lEnd); + commentText = commentText.substring(0, commentText.length - (i - linkObj.tStart)); + commentText += `${linkText}`; + linkObj = {}; + } + else { + commentText += char; + } + } + return commentText; + } + }; + customElements.define("gw-comment-card", ns.CommentCard); +}) (window.GW.Controls = window.GW.Controls || {}); \ No newline at end of file diff --git a/src/_bundle/js/googleSheetsReaderGizmo.js b/src/_bundle/js/googleSheetsReaderGizmo.js new file mode 100644 index 00000000..769f0a1a --- /dev/null +++ b/src/_bundle/js/googleSheetsReaderGizmo.js @@ -0,0 +1,179 @@ +/** + * Author: Vera Konigin + * Site: https://groundedwren.neocities.org + * Contact: vera@groundedwren.com + * + * File Description: Gizmo for reading from Google Sheets. + * Neocities editor users will see a lot of linter errors in this file, but none of them are real errors. The linter just doesn't understand some modern JS. +*/ + +/** + * By default, any JavaScript code written is defined in the global namespace, which means it's accessible directly under the "window" element. + * If you have a lot of scripts, this can lead to clutter and naming collisions (what if two different scripts use a variable called "i"? They can inadvertently mess each other up). + * To get around this, we define the registerNamespace function in the global namespace, which just confines all the code in the function passed to it to a property under window. + * That property is represented as the "path" parameter. It is passed to the function for ease of access. +*/ +function registerNamespace(path, nsFunc) +{ + var ancestors = path.split("."); + + var ns = window; + for(var i = 0; i < ancestors.length; i++) + { + ns[ancestors[i]] = ns[ancestors[i]] || {}; + ns = ns[ancestors[i]]; + } + nsFunc(ns); +} + +registerNamespace("GW.Gizmos", function(ns) { + /** + * A class to read from one page in a google sheet document + */ + ns.GoogleSheetsReader = class GoogleSheetsReader + { + //setResponse is intended for React - it's how google responds to our GET. Fortunately valid JSON is inside this call, so we can just parse it out. + static #RESPONSE_PREFIX = "setResponse("; + static #RESPONSE_SUFFIX = ");"; + + //Here we can define any custom types based on column label. "Timestamp" is intended for ISO 8601 format date/time strings. + static #CUSTOM_LABEL_TYPES = { + "Timestamp": "timestamp" + }; + + spreadsheetId; //The ID of the spreadsheet. This is the part just after /d/ in the docs.google.com URL + sheetName; //The name of the particular sheet we're after + + #sheetURL; //Composed request URL + + loadPromise = null; //A promise created when loading begins and which resolves when data has finished loading. + tableJSON = null; //Raw JS Object version of the returned JSON. + rowData = null; //Parsed row data + colData = null; //A shortcut to the the column data in tableJSON + colIndex = null; //An index from column label to its metadata, plus array position + + /** + * Constructs a GoogleSheetsReader object + * spreadsheetId is the part of the docs.google.com URL just after /d/ + * sheetName is the name of the particular page + */ + constructor(spreadsheetId, sheetName) + { + this.spreadsheetId = spreadsheetId; + this.sheetName = sheetName; + this.#sheetURL = `https://docs.google.com/spreadsheets/d/${spreadsheetId}/gviz/tq?sheet=${sheetName}`; + } + + /** + * Loads and parses sheet data via HTTP GET + * Returns null on success, and an error string on failure. + */ + async loadData() + { + this.loadPromise = this.#loadData(); + return this.loadPromise; + } + + async #loadData() + { + this.tableJSON = null; + this.rowData = null; + this.colData = null; + this.colIndex = null; + + const response = await fetch(this.#sheetURL); + if (response.ok) + { + return response.text().then((unparsedData) => + { + //This is parsing out the valid JSON from the React method they gave us + const targetData = unparsedData.split( + GoogleSheetsReader.#RESPONSE_PREFIX + )[1].split( + GoogleSheetsReader.#RESPONSE_SUFFIX + )[0]; + + this.tableJSON = GoogleSheetsReader.#applyCustomLabelTypes(JSON.parse(targetData).table); + this.rowData = GoogleSheetsReader.#parseAllRows(this.tableJSON); + this.colIndex = GoogleSheetsReader.#indexColumns(this.tableJSON); + this.colData = this.tableJSON.cols; + + return null; + }); + } + else + { + return response.statusText || response.status; + } + } + + /** + * Overrides any google-returned column data types with custom ones based on label + */ + static #applyCustomLabelTypes(tableJSON) + { + tableJSON.cols.forEach(col => { + if(this.#CUSTOM_LABEL_TYPES[col.label]) + { + col.type = this.#CUSTOM_LABEL_TYPES[col.label] + }; + }); + return tableJSON; + } + + static #parseAllRows(tableJSON) + { + const rowDataArray = []; + for(let i = 0; i < tableJSON.rows.length; i++) + { + rowDataArray.push(this.#parseRow(i, tableJSON)); + } + return rowDataArray; + } + + static #parseRow(rowIdx, tableJSON) + { + const rowData = {}; + const cells = tableJSON.rows[rowIdx].c; + + for(let i = 0; i < cells.length; i++) + { + rowData[tableJSON.cols[i].label] = this.#parseCellType(cells[i], tableJSON.cols[i].type); + } + return rowData; + } + + /** + * Parses a cell based on its type. Further custom types will need their own parsing added here. + */ + static #parseCellType(cellData, cellType) + { + switch (cellType) + { + case "string": + return cellData ? cellData.v : cellData; + case "number": + return cellData ? cellData.v : cellData; + case "datetime": + case "date": + return (cellData && cellData.v) ? eval("new " + cellData.v) : null; + case "timestamp": + const cellTimestamp = new Date(cellData ? cellData.v : ""); + return isNaN(cellTimestamp) ? null : cellTimestamp; + default: + return cellData; + } + } + + static #indexColumns(tableJSON) + { + const colIndex = {}; + for(let i = 0; i < tableJSON.cols.length; i++) + { + const colData = tableJSON.cols[i]; + colIndex[colData.label] = {...colData, index: i}; + } + return colIndex; + } + }; +}); \ No newline at end of file diff --git a/src/_bundle/js/svgIconControl.js b/src/_bundle/js/svgIconControl.js new file mode 100644 index 00000000..69d513fa --- /dev/null +++ b/src/_bundle/js/svgIconControl.js @@ -0,0 +1,453 @@ +/** + * Author: Vera Konigin + * Site: https://groundedwren.neocities.org + * Contact: vera@groundedwren.com + * + * File Description: A web component to site SVG icons easily +*/ + +/** + * By default, any JavaScript code written is defined in the global namespace, which means it's accessible directly under the "window" element. + * If you have a lot of scripts, this can lead to clutter and naming collisions (what if two different scripts use a variable called "i"? They can inadvertently mess each other up). + * To get around this, we define the registerNamespace function in the global namespace, which just confines all the code in the function passed to it to a property under window. + * That property is represented as the "path" parameter. It is passed to the function for ease of access. +*/ +function registerNamespace(path, nsFunc) +{ + var ancestors = path.split("."); + + var ns = window; + for(var i = 0; i < ancestors.length; i++) + { + ns[ancestors[i]] = ns[ancestors[i]] || {}; + ns = ns[ancestors[i]]; + } + nsFunc(ns); +} + +registerNamespace("GW.Controls.SVGLib", function(ns) { + const XML_NAMESPACE = "http://www.w3.org/2000/svg"; + + /** + * https://www.w3.org/TR/SVG/eltindex.html + */ + ns.ElementTypes = { + svg: "svg", //viewBox, preserveAspectRatio, zoomAndPan, transform - https://www.w3.org/TR/SVG/struct.html#SVGElement + circle: "circle", //cx, cy, r - https://www.w3.org/TR/SVG/shapes.html#CircleElement + linearGradient: "linearGradient", //x1, y1, x2, y2, gradientUnits, gradientTransform, spreadMethod, href - https://www.w3.org/TR/SVG/pservers.html#LinearGradientElement + stop: "stop", //offset, stop-color https://www.w3.org/TR/SVG/pservers.html#StopElement + defs: "defs", //https://www.w3.org/TR/SVG/struct.html#DefsElement + rect: "rect", //x, y, width, height, rx, ry - https://www.w3.org/TR/SVG/shapes.html#RectElement + text: "text", //x, y, dominant-baseline, text-anchor, fill - https://www.w3.org/TR/SVG/text.html#TextElement + a: "a", //href, target - https://developer.mozilla.org/en-US/docs/Web/SVG/Element/a + path: "path", //d, pathLength - https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path + title: "title", // - https://developer.mozilla.org/en-US/docs/Web/SVG/Element/title + desc: "desc", // - https://developer.mozilla.org/en-US/docs/Web/SVG/Element/desc + foreignObject: "foreignObject", // - https://developer.mozilla.org/en-US/docs/Web/SVG/Element/foreignObject + }; + + /** + * Shortcut to create an SVG element and append it to a parent + * @param parent the parent element + * ... see ns.createElement + */ + function createChildElement(parent, elementType, attributes, innerHTML) + { + var childEl = createElement(elementType, attributes, innerHTML); + parent.appendChild(childEl); + return childEl; + } + ns.createChildElement = createChildElement; + + /** + * Creates an SVG element to spec + * @param elementType type of SVG element (see ns.ElementTypes) + * @param attributes object of attributes and values + * @param innerHTML inner HTML + */ + function createElement(elementType, attributes, innerHTML) + { + var el = document.createElementNS(XML_NAMESPACE, elementType); + Object.keys(attributes || {}).forEach((attr) => el.setAttributeNS(null, attr, attributes[attr])); + el.innerHTML = innerHTML || null; + return el; + } + ns.createElement = createElement; + + //#region Icons + const ICON_CITATION = ""; + const ICON_CLASS = "icon"; + + /** + * Icon SVG path definitions + */ + ns.Icons = { + "circle-info": { + title: "info", + viewBox: "0 0 512 512", + d: "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM216 336h24V272H216c-13.3 0-24-10.7-24-24s10.7-24 24-24h48c13.3 0 24 10.7 24 24v88h8c13.3 0 24 10.7 24 24s-10.7 24-24 24H216c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-208a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" + }, + "play": { + title: "play", + viewBox: "0 0 384 512", + d: "M73 39c-14.8-9.1-33.4-9.4-48.5-.9S0 62.6 0 80V432c0 17.4 9.4 33.4 24.5 41.9s33.7 8.1 48.5-.9L361 297c14.3-8.7 23-24.2 23-41s-8.7-32.2-23-41L73 39z" + }, + "backward-step": { + title: "backward step", + viewBox: "0 0 320 512", + d: "M267.5 440.6c9.5 7.9 22.8 9.7 34.1 4.4s18.4-16.6 18.4-29V96c0-12.4-7.2-23.7-18.4-29s-24.5-3.6-34.1 4.4l-192 160L64 241V96c0-17.7-14.3-32-32-32S0 78.3 0 96V416c0 17.7 14.3 32 32 32s32-14.3 32-32V271l11.5 9.6 192 160z" + }, + "forward-step": { + title: "forward step", + viewBox: "0 0 320 512", + d: "M52.5 440.6c-9.5 7.9-22.8 9.7-34.1 4.4S0 428.4 0 416V96C0 83.6 7.2 72.3 18.4 67s24.5-3.6 34.1 4.4l192 160L256 241V96c0-17.7 14.3-32 32-32s32 14.3 32 32V416c0 17.7-14.3 32-32 32s-32-14.3-32-32V271l-11.5 9.6-192 160z" + }, + "pause": { + title: "pause", + viewBox: "0 0 320 512", + d: "M48 64C21.5 64 0 85.5 0 112V400c0 26.5 21.5 48 48 48H80c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48H48zm192 0c-26.5 0-48 21.5-48 48V400c0 26.5 21.5 48 48 48h32c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48H240z" + }, + "triangle-exclamation": { + title: "warning", + viewBox: "0 0 512 512", + d: "M256 32c14.2 0 27.3 7.5 34.5 19.8l216 368c7.3 12.4 7.3 27.7 .2 40.1S486.3 480 472 480H40c-14.3 0-27.6-7.7-34.7-20.1s-7-27.8 .2-40.1l216-368C228.7 39.5 241.8 32 256 32zm0 128c-13.3 0-24 10.7-24 24V296c0 13.3 10.7 24 24 24s24-10.7 24-24V184c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z" + }, + "laptop-code": { + title: "coding", + viewBox: "0 0 640 512", + d: "M64 96c0-35.3 28.7-64 64-64H512c35.3 0 64 28.7 64 64V352H512V96H128V352H64V96zM0 403.2C0 392.6 8.6 384 19.2 384H620.8c10.6 0 19.2 8.6 19.2 19.2c0 42.4-34.4 76.8-76.8 76.8H76.8C34.4 480 0 445.6 0 403.2zM281 209l-31 31 31 31c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-48-48c-9.4-9.4-9.4-24.6 0-33.9l48-48c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9zM393 175l48 48c9.4 9.4 9.4 24.6 0 33.9l-48 48c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l31-31-31-31c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0z" + }, + "guitar": { + title: "guitar", + viewBox: "0 0 512 512", + d: "M465 7c-9.4-9.4-24.6-9.4-33.9 0L383 55c-2.4 2.4-4.3 5.3-5.5 8.5l-15.4 41-77.5 77.6c-45.1-29.4-99.3-30.2-131 1.6c-11 11-18 24.6-21.4 39.6c-3.7 16.6-19.1 30.7-36.1 31.6c-25.6 1.3-49.3 10.7-67.3 28.6C-16 328.4-7.6 409.4 47.5 464.5s136.1 63.5 180.9 18.7c17.9-17.9 27.4-41.7 28.6-67.3c.9-17 15-32.3 31.6-36.1c15-3.4 28.6-10.5 39.6-21.4c31.8-31.8 31-85.9 1.6-131l77.6-77.6 41-15.4c3.2-1.2 6.1-3.1 8.5-5.5l48-48c9.4-9.4 9.4-24.6 0-33.9L465 7zM208 256a48 48 0 1 1 0 96 48 48 0 1 1 0-96z" + }, + "pen-fancy": { + title: "pen", + viewBox: "0 0 512 512", + d: "M373.5 27.1C388.5 9.9 410.2 0 433 0c43.6 0 79 35.4 79 79c0 22.8-9.9 44.6-27.1 59.6L277.7 319l-10.3-10.3-64-64L193 234.3 373.5 27.1zM170.3 256.9l10.4 10.4 64 64 10.4 10.4-19.2 83.4c-3.9 17.1-16.9 30.7-33.8 35.4L24.4 510.3l95.4-95.4c2.6 .7 5.4 1.1 8.3 1.1c17.7 0 32-14.3 32-32s-14.3-32-32-32s-32 14.3-32 32c0 2.9 .4 5.6 1.1 8.3L1.7 487.6 51.5 310c4.7-16.9 18.3-29.9 35.4-33.8l83.4-19.2z" + }, + "glasses": { + title: "glasses", + viewBox: "0 0 576 512", + d: "M118.6 80c-11.5 0-21.4 7.9-24 19.1L57 260.3c20.5-6.2 48.3-12.3 78.7-12.3c32.3 0 61.8 6.9 82.8 13.5c10.6 3.3 19.3 6.7 25.4 9.2c3.1 1.3 5.5 2.4 7.3 3.2c.9 .4 1.6 .7 2.1 1l.6 .3 .2 .1 .1 0 0 0 0 0s0 0-6.3 12.7h0l6.3-12.7c5.8 2.9 10.4 7.3 13.5 12.7h40.6c3.1-5.3 7.7-9.8 13.5-12.7l6.3 12.7h0c-6.3-12.7-6.3-12.7-6.3-12.7l0 0 0 0 .1 0 .2-.1 .6-.3c.5-.2 1.2-.6 2.1-1c1.8-.8 4.2-1.9 7.3-3.2c6.1-2.6 14.8-5.9 25.4-9.2c21-6.6 50.4-13.5 82.8-13.5c30.4 0 58.2 6.1 78.7 12.3L481.4 99.1c-2.6-11.2-12.6-19.1-24-19.1c-3.1 0-6.2 .6-9.2 1.8L416.9 94.3c-12.3 4.9-26.3-1.1-31.2-13.4s1.1-26.3 13.4-31.2l31.3-12.5c8.6-3.4 17.7-5.2 27-5.2c33.8 0 63.1 23.3 70.8 56.2l43.9 188c1.7 7.3 2.9 14.7 3.5 22.1c.3 1.9 .5 3.8 .5 5.7v6.7V352v16c0 61.9-50.1 112-112 112H419.7c-59.4 0-108.5-46.4-111.8-105.8L306.6 352H269.4l-1.2 22.2C264.9 433.6 215.8 480 156.3 480H112C50.1 480 0 429.9 0 368V352 310.7 304c0-1.9 .2-3.8 .5-5.7c.6-7.4 1.8-14.8 3.5-22.1l43.9-188C55.5 55.3 84.8 32 118.6 32c9.2 0 18.4 1.8 27 5.2l31.3 12.5c12.3 4.9 18.3 18.9 13.4 31.2s-18.9 18.3-31.2 13.4L127.8 81.8c-2.9-1.2-6-1.8-9.2-1.8zM64 325.4V368c0 26.5 21.5 48 48 48h44.3c25.5 0 46.5-19.9 47.9-45.3l2.5-45.6c-2.3-.8-4.9-1.7-7.5-2.5c-17.2-5.4-39.9-10.5-63.6-10.5c-23.7 0-46.2 5.1-63.2 10.5c-3.1 1-5.9 1.9-8.5 2.9zM512 368V325.4c-2.6-.9-5.5-1.9-8.5-2.9c-17-5.4-39.5-10.5-63.2-10.5c-23.7 0-46.4 5.1-63.6 10.5c-2.7 .8-5.2 1.7-7.5 2.5l2.5 45.6c1.4 25.4 22.5 45.3 47.9 45.3H464c26.5 0 48-21.5 48-48z" + }, + "clock": { + title: "glasses", + viewBox: "0 0 512 512", + d: "M256 0a256 256 0 1 1 0 512A256 256 0 1 1 256 0zM232 120V256c0 8 4 15.5 10.7 20l96 64c11 7.4 25.9 4.4 33.3-6.7s4.4-25.9-6.7-33.3L280 243.2V120c0-13.3-10.7-24-24-24s-24 10.7-24 24z" + }, + "envelope": { + title: "envelope", + viewBox: "0 0 512 512", + d: "M48 64C21.5 64 0 85.5 0 112c0 15.1 7.1 29.3 19.2 38.4L236.8 313.6c11.4 8.5 27 8.5 38.4 0L492.8 150.4c12.1-9.1 19.2-23.3 19.2-38.4c0-26.5-21.5-48-48-48H48zM0 176V384c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V176L294.4 339.2c-22.8 17.1-54 17.1-76.8 0L0 176z" + }, + "discord": { + title: "discord", + viewBox: "0 0 640 512", + d: "M524.531,69.836a1.5,1.5,0,0,0-.764-.7A485.065,485.065,0,0,0,404.081,32.03a1.816,1.816,0,0,0-1.923.91,337.461,337.461,0,0,0-14.9,30.6,447.848,447.848,0,0,0-134.426,0,309.541,309.541,0,0,0-15.135-30.6,1.89,1.89,0,0,0-1.924-.91A483.689,483.689,0,0,0,116.085,69.137a1.712,1.712,0,0,0-.788.676C39.068,183.651,18.186,294.69,28.43,404.354a2.016,2.016,0,0,0,.765,1.375A487.666,487.666,0,0,0,176.02,479.918a1.9,1.9,0,0,0,2.063-.676A348.2,348.2,0,0,0,208.12,430.4a1.86,1.86,0,0,0-1.019-2.588,321.173,321.173,0,0,1-45.868-21.853,1.885,1.885,0,0,1-.185-3.126c3.082-2.309,6.166-4.711,9.109-7.137a1.819,1.819,0,0,1,1.9-.256c96.229,43.917,200.41,43.917,295.5,0a1.812,1.812,0,0,1,1.924.233c2.944,2.426,6.027,4.851,9.132,7.16a1.884,1.884,0,0,1-.162,3.126,301.407,301.407,0,0,1-45.89,21.83,1.875,1.875,0,0,0-1,2.611,391.055,391.055,0,0,0,30.014,48.815,1.864,1.864,0,0,0,2.063.7A486.048,486.048,0,0,0,610.7,405.729a1.882,1.882,0,0,0,.765-1.352C623.729,277.594,590.933,167.465,524.531,69.836ZM222.491,337.58c-28.972,0-52.844-26.587-52.844-59.239S193.056,219.1,222.491,219.1c29.665,0,53.306,26.82,52.843,59.239C275.334,310.993,251.924,337.58,222.491,337.58Zm195.38,0c-28.971,0-52.843-26.587-52.843-59.239S388.437,219.1,417.871,219.1c29.667,0,53.307,26.82,52.844,59.239C470.715,310.993,447.538,337.58,417.871,337.58Z" + }, + "plus": { + title: "plus", + viewBox: "0 0 448 512", + d: "M256 80c0-17.7-14.3-32-32-32s-32 14.3-32 32V224H48c-17.7 0-32 14.3-32 32s14.3 32 32 32H192V432c0 17.7 14.3 32 32 32s32-14.3 32-32V288H400c17.7 0 32-14.3 32-32s-14.3-32-32-32H256V80z" + }, + "circle-check": { + title: "done", + viewBox: "0 0 512 512", + d: "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM369 209L241 337c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L335 175c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z" + }, + "delete-left": { + title: "delete", + viewBox: "0 0 576 512", + d: "M576 128c0-35.3-28.7-64-64-64H205.3c-17 0-33.3 6.7-45.3 18.7L9.4 233.4c-6 6-9.4 14.1-9.4 22.6s3.4 16.6 9.4 22.6L160 429.3c12 12 28.3 18.7 45.3 18.7H512c35.3 0 64-28.7 64-64V128zM271 175c9.4-9.4 24.6-9.4 33.9 0l47 47 47-47c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-47 47 47 47c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-47-47-47 47c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l47-47-47-47c-9.4-9.4-9.4-24.6 0-33.9z" + }, + "link": { + title: "link", + viewBox: "0 0 640 512", + d: "M579.8 267.7c56.5-56.5 56.5-148 0-204.5c-50-50-128.8-56.5-186.3-15.4l-1.6 1.1c-14.4 10.3-17.7 30.3-7.4 44.6s30.3 17.7 44.6 7.4l1.6-1.1c32.1-22.9 76-19.3 103.8 8.6c31.5 31.5 31.5 82.5 0 114L422.3 334.8c-31.5 31.5-82.5 31.5-114 0c-27.9-27.9-31.5-71.8-8.6-103.8l1.1-1.6c10.3-14.4 6.9-34.4-7.4-44.6s-34.4-6.9-44.6 7.4l-1.1 1.6C206.5 251.2 213 330 263 380c56.5 56.5 148 56.5 204.5 0L579.8 267.7zM60.2 244.3c-56.5 56.5-56.5 148 0 204.5c50 50 128.8 56.5 186.3 15.4l1.6-1.1c14.4-10.3 17.7-30.3 7.4-44.6s-30.3-17.7-44.6-7.4l-1.6 1.1c-32.1 22.9-76 19.3-103.8-8.6C74 372 74 321 105.5 289.5L217.7 177.2c31.5-31.5 82.5-31.5 114 0c27.9 27.9 31.5 71.8 8.6 103.9l-1.1 1.6c-10.3 14.4-6.9 34.4 7.4 44.6s34.4 6.9 44.6-7.4l1.1-1.6C433.5 260.8 427 182 377 132c-56.5-56.5-148-56.5-204.5 0L60.2 244.3z" + }, + "xmark": { + title: "close", + viewBox: "0 0 384 512", + d: "M342.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 210.7 86.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L146.7 256 41.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 301.3 297.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.3 256 342.6 150.6z" + }, + "trash": { + title: "trash", + viewBox: "0 0 448 512", + d: "M135.2 17.7L128 32H32C14.3 32 0 46.3 0 64S14.3 96 32 96H416c17.7 0 32-14.3 32-32s-14.3-32-32-32H320l-7.2-14.3C307.4 6.8 296.3 0 284.2 0H163.8c-12.1 0-23.2 6.8-28.6 17.7zM416 128H32L53.2 467c1.6 25.3 22.6 45 47.9 45H346.9c25.3 0 46.3-19.7 47.9-45L416 128z" + }, + "thumbtack": { + title: "trash", + viewBox: "0 0 384 512", + d: "M32 32C32 14.3 46.3 0 64 0H320c17.7 0 32 14.3 32 32s-14.3 32-32 32H290.5l11.4 148.2c36.7 19.9 65.7 53.2 79.5 94.7l1 3c3.3 9.8 1.6 20.5-4.4 28.8s-15.7 13.3-26 13.3H32c-10.3 0-19.9-4.9-26-13.3s-7.7-19.1-4.4-28.8l1-3c13.8-41.5 42.8-74.8 79.5-94.7L93.5 64H64C46.3 64 32 49.7 32 32zM160 384h64v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V384z" + }, + "pen-to-square": { + title: "edit", + viewBox: "0 0 512 512", + d: "M471.6 21.7c-21.9-21.9-57.3-21.9-79.2 0L362.3 51.7l97.9 97.9 30.1-30.1c21.9-21.9 21.9-57.3 0-79.2L471.6 21.7zm-299.2 220c-6.1 6.1-10.8 13.6-13.5 21.9l-29.6 88.8c-2.9 8.6-.6 18.1 5.8 24.6s15.9 8.7 24.6 5.8l88.8-29.6c8.2-2.7 15.7-7.4 21.9-13.5L437.7 172.3 339.7 74.3 172.4 241.7zM96 64C43 64 0 107 0 160V416c0 53 43 96 96 96H352c53 0 96-43 96-96V320c0-17.7-14.3-32-32-32s-32 14.3-32 32v96c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32h96c17.7 0 32-14.3 32-32s-14.3-32-32-32H96z" + }, + "book": { + title: "book", + viewBox: "0 0 448 512", + d: "M96 0C43 0 0 43 0 96V416c0 53 43 96 96 96H384h32c17.7 0 32-14.3 32-32s-14.3-32-32-32V384c17.7 0 32-14.3 32-32V32c0-17.7-14.3-32-32-32H384 96zm0 384H352v64H96c-17.7 0-32-14.3-32-32s14.3-32 32-32zm32-240c0-8.8 7.2-16 16-16H336c8.8 0 16 7.2 16 16s-7.2 16-16 16H144c-8.8 0-16-7.2-16-16zm16 48H336c8.8 0 16 7.2 16 16s-7.2 16-16 16H144c-8.8 0-16-7.2-16-16s7.2-16 16-16z" + }, + "gamepad": { + title: "game", + viewBox: "0 0 640 512", + d: "M192 64C86 64 0 150 0 256S86 448 192 448H448c106 0 192-86 192-192s-86-192-192-192H192zM496 168a40 40 0 1 1 0 80 40 40 0 1 1 0-80zM392 304a40 40 0 1 1 80 0 40 40 0 1 1 -80 0zM168 200c0-13.3 10.7-24 24-24s24 10.7 24 24v32h32c13.3 0 24 10.7 24 24s-10.7 24-24 24H216v32c0 13.3-10.7 24-24 24s-24-10.7-24-24V280H136c-13.3 0-24-10.7-24-24s10.7-24 24-24h32V200z" + }, + "hammer": { + title: "game", + viewBox: "0 0 576 512", + d: "M413.5 237.5c-28.2 4.8-58.2-3.6-80-25.4l-38.1-38.1C280.4 159 272 138.8 272 117.6V105.5L192.3 62c-5.3-2.9-8.6-8.6-8.3-14.7s3.9-11.5 9.5-14l47.2-21C259.1 4.2 279 0 299.2 0h18.1c36.7 0 72 14 98.7 39.1l44.6 42c24.2 22.8 33.2 55.7 26.6 86L503 183l8-8c9.4-9.4 24.6-9.4 33.9 0l24 24c9.4 9.4 9.4 24.6 0 33.9l-88 88c-9.4 9.4-24.6 9.4-33.9 0l-24-24c-9.4-9.4-9.4-24.6 0-33.9l8-8-17.5-17.5zM27.4 377.1L260.9 182.6c3.5 4.9 7.5 9.6 11.8 14l38.1 38.1c6 6 12.4 11.2 19.2 15.7L134.9 484.6c-14.5 17.4-36 27.4-58.6 27.4C34.1 512 0 477.8 0 435.7c0-22.6 10.1-44.1 27.4-58.6z" + }, + "location-dot": { + title: "location", + viewBox: "0 0 384 512", + d: "M215.7 499.2C267 435 384 279.4 384 192C384 86 298 0 192 0S0 86 0 192c0 87.4 117 243 168.3 307.2c12.3 15.3 35.1 15.3 47.4 0zM192 128a64 64 0 1 1 0 128 64 64 0 1 1 0-128z" + }, + "box-open": { + title: "box", + viewBox: "0 0 640 512", + d: "M58.9 42.1c3-6.1 9.6-9.6 16.3-8.7L320 64 564.8 33.4c6.7-.8 13.3 2.7 16.3 8.7l41.7 83.4c9 17.9-.6 39.6-19.8 45.1L439.6 217.3c-13.9 4-28.8-1.9-36.2-14.3L320 64 236.6 203c-7.4 12.4-22.3 18.3-36.2 14.3L37.1 170.6c-19.3-5.5-28.8-27.2-19.8-45.1L58.9 42.1zM321.1 128l54.9 91.4c14.9 24.8 44.6 36.6 72.5 28.6L576 211.6v167c0 22-15 41.2-36.4 46.6l-204.1 51c-10.2 2.6-20.9 2.6-31 0l-204.1-51C79 419.7 64 400.5 64 378.5v-167L191.6 248c27.8 8 57.6-3.8 72.5-28.6L318.9 128h2.2z" + }, + "calendar": { + title: "box", + viewBox: "0 0 448 512", + d: "M128 0c17.7 0 32 14.3 32 32V64H288V32c0-17.7 14.3-32 32-32s32 14.3 32 32V64h48c26.5 0 48 21.5 48 48v48H0V112C0 85.5 21.5 64 48 64H96V32c0-17.7 14.3-32 32-32zM0 192H448V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V192zm64 80v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V272c0-8.8-7.2-16-16-16H80c-8.8 0-16 7.2-16 16zm128 0v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V272c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16zm144-16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V272c0-8.8-7.2-16-16-16H336zM64 400v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V400c0-8.8-7.2-16-16-16H80c-8.8 0-16 7.2-16 16zm144-16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V400c0-8.8-7.2-16-16-16H208zm112 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V400c0-8.8-7.2-16-16-16H336c-8.8 0-16 7.2-16 16z" + }, + "people-group": { + title: "people", + viewBox: "0 0 640 512", + d: "M72 88a56 56 0 1 1 112 0A56 56 0 1 1 72 88zM64 245.7C54 256.9 48 271.8 48 288s6 31.1 16 42.3V245.7zm144.4-49.3C178.7 222.7 160 261.2 160 304c0 34.3 12 65.8 32 90.5V416c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V389.2C26.2 371.2 0 332.7 0 288c0-61.9 50.1-112 112-112h32c24 0 46.2 7.5 64.4 20.3zM448 416V394.5c20-24.7 32-56.2 32-90.5c0-42.8-18.7-81.3-48.4-107.7C449.8 183.5 472 176 496 176h32c61.9 0 112 50.1 112 112c0 44.7-26.2 83.2-64 101.2V416c0 17.7-14.3 32-32 32H480c-17.7 0-32-14.3-32-32zm8-328a56 56 0 1 1 112 0A56 56 0 1 1 456 88zM576 245.7v84.7c10-11.3 16-26.1 16-42.3s-6-31.1-16-42.3zM320 32a64 64 0 1 1 0 128 64 64 0 1 1 0-128zM240 304c0 16.2 6 31 16 42.3V261.7c-10 11.3-16 26.1-16 42.3zm144-42.3v84.7c10-11.3 16-26.1 16-42.3s-6-31.1-16-42.3zM448 304c0 44.7-26.2 83.2-64 101.2V448c0 17.7-14.3 32-32 32H288c-17.7 0-32-14.3-32-32V405.2c-37.8-18-64-56.5-64-101.2c0-61.9 50.1-112 112-112h32c61.9 0 112 50.1 112 112z" + }, + "comments": { + title: "comments", + viewBox: "0 0 640 512", + d: "M208 352c114.9 0 208-78.8 208-176S322.9 0 208 0S0 78.8 0 176c0 38.6 14.7 74.3 39.6 103.4c-3.5 9.4-8.7 17.7-14.2 24.7c-4.8 6.2-9.7 11-13.3 14.3c-1.8 1.6-3.3 2.9-4.3 3.7c-.5 .4-.9 .7-1.1 .8l-.2 .2 0 0 0 0C1 327.2-1.4 334.4 .8 340.9S9.1 352 16 352c21.8 0 43.8-5.6 62.1-12.5c9.2-3.5 17.8-7.4 25.3-11.4C134.1 343.3 169.8 352 208 352zM448 176c0 112.3-99.1 196.9-216.5 207C255.8 457.4 336.4 512 432 512c38.2 0 73.9-8.7 104.7-23.9c7.5 4 16 7.9 25.2 11.4c18.3 6.9 40.3 12.5 62.1 12.5c6.9 0 13.1-4.5 15.2-11.1c2.1-6.6-.2-13.8-5.8-17.9l0 0 0 0-.2-.2c-.2-.2-.6-.4-1.1-.8c-1-.8-2.5-2-4.3-3.7c-3.6-3.3-8.5-8.1-13.3-14.3c-5.5-7-10.7-15.4-14.2-24.7c24.9-29 39.6-64.7 39.6-103.4c0-92.8-84.9-168.9-192.6-175.5c.4 5.1 .6 10.3 .6 15.5z" + }, + "clipboard-check": { + title: "clipboard", + viewBox: "0 0 384 512", + d: "M192 0c-41.8 0-77.4 26.7-90.5 64H64C28.7 64 0 92.7 0 128V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V128c0-35.3-28.7-64-64-64H282.5C269.4 26.7 233.8 0 192 0zm0 64a32 32 0 1 1 0 64 32 32 0 1 1 0-64zM305 273L177 401c-9.4 9.4-24.6 9.4-33.9 0L79 337c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L271 239c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z" + }, + "user": { + title: "clipboard", + viewBox: "0 0 448 512", + d: "M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512H418.3c16.4 0 29.7-13.3 29.7-29.7C448 383.8 368.2 304 269.7 304H178.3z" + }, + "door-open": { + title: "open door", + viewBox: "0 0 576 512", + d: "M320 32c0-9.9-4.5-19.2-12.3-25.2S289.8-1.4 280.2 1l-179.9 45C79 51.3 64 70.5 64 92.5V448H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H96 288h32V480 32zM256 256c0 17.7-10.7 32-24 32s-24-14.3-24-32s10.7-32 24-32s24 14.3 24 32zm96-128h96V480c0 17.7 14.3 32 32 32h64c17.7 0 32-14.3 32-32s-14.3-32-32-32H512V128c0-35.3-28.7-64-64-64H352v64z" + }, + "scroll": { + title: "scroll", + viewBox: "0 0 576 512", + d: "M0 80v48c0 17.7 14.3 32 32 32H48 96V80c0-26.5-21.5-48-48-48S0 53.5 0 80zM112 32c10 13.4 16 30 16 48V384c0 35.3 28.7 64 64 64s64-28.7 64-64v-5.3c0-32.4 26.3-58.7 58.7-58.7H480V128c0-53-43-96-96-96H112zM464 480c61.9 0 112-50.1 112-112c0-8.8-7.2-16-16-16H314.7c-14.7 0-26.7 11.9-26.7 26.7V384c0 53-43 96-96 96H368h96z" + }, + "star": { + title: "star", + viewBox: "0 0 576 512", + d: "M316.9 18C311.6 7 300.4 0 288.1 0s-23.4 7-28.8 18L195 150.3 51.4 171.5c-12 1.8-22 10.2-25.7 21.7s-.7 24.2 7.9 32.7L137.8 329 113.2 474.7c-2 12 3 24.2 12.9 31.3s23 8 33.8 2.3l128.3-68.5 128.3 68.5c10.8 5.7 23.9 4.9 33.8-2.3s14.9-19.3 12.9-31.3L438.5 329 542.7 225.9c8.6-8.5 11.7-21.2 7.9-32.7s-13.7-19.9-25.7-21.7L381.2 150.3 316.9 18z" + }, + "boxes-stacked": { + title: "stacked boxes", + viewBox: "0 0 576 512", + d: "M248 0H208c-26.5 0-48 21.5-48 48V160c0 35.3 28.7 64 64 64H352c35.3 0 64-28.7 64-64V48c0-26.5-21.5-48-48-48H328V80c0 8.8-7.2 16-16 16H264c-8.8 0-16-7.2-16-16V0zM64 256c-35.3 0-64 28.7-64 64V448c0 35.3 28.7 64 64 64H224c35.3 0 64-28.7 64-64V320c0-35.3-28.7-64-64-64H184v80c0 8.8-7.2 16-16 16H120c-8.8 0-16-7.2-16-16V256H64zM352 512H512c35.3 0 64-28.7 64-64V320c0-35.3-28.7-64-64-64H472v80c0 8.8-7.2 16-16 16H408c-8.8 0-16-7.2-16-16V256H352c-15 0-28.8 5.1-39.7 13.8c4.9 10.4 7.7 22 7.7 34.2V464c0 12.2-2.8 23.8-7.7 34.2C323.2 506.9 337 512 352 512z" + }, + "person-running": { + title: "person running", + viewBox: "0 0 448 512", + d: "M320 48a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM125.7 175.5c9.9-9.9 23.4-15.5 37.5-15.5c1.9 0 3.8 .1 5.6 .3L137.6 254c-9.3 28 1.7 58.8 26.8 74.5l86.2 53.9-25.4 88.8c-4.9 17 5 34.7 22 39.6s34.7-5 39.6-22l28.7-100.4c5.9-20.6-2.6-42.6-20.7-53.9L238 299l30.9-82.4 5.1 12.3C289 264.7 323.9 288 362.7 288H384c17.7 0 32-14.3 32-32s-14.3-32-32-32H362.7c-12.9 0-24.6-7.8-29.5-19.7l-6.3-15c-14.6-35.1-44.1-61.9-80.5-73.1l-48.7-15c-11.1-3.4-22.7-5.2-34.4-5.2c-31 0-60.8 12.3-82.7 34.3L57.4 153.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l23.1-23.1zM91.2 352H32c-17.7 0-32 14.3-32 32s14.3 32 32 32h69.6c19 0 36.2-11.2 43.9-28.5L157 361.6l-9.5-6c-17.5-10.9-30.5-26.8-37.9-44.9L91.2 352z" + }, + "handshake": { + title: "handshake", + viewBox: "0 0 640 512", + d: "M323.4 85.2l-96.8 78.4c-16.1 13-19.2 36.4-7 53.1c12.9 17.8 38 21.3 55.3 7.8l99.3-77.2c7-5.4 17-4.2 22.5 2.8s4.2 17-2.8 22.5l-20.9 16.2L550.2 352H592c26.5 0 48-21.5 48-48V176c0-26.5-21.5-48-48-48H516h-4-.7l-3.9-2.5L434.8 79c-15.3-9.8-33.2-15-51.4-15c-21.8 0-43 7.5-60 21.2zm22.8 124.4l-51.7 40.2C263 274.4 217.3 268 193.7 235.6c-22.2-30.5-16.6-73.1 12.7-96.8l83.2-67.3c-11.6-4.9-24.1-7.4-36.8-7.4C234 64 215.7 69.6 200 80l-72 48H48c-26.5 0-48 21.5-48 48V304c0 26.5 21.5 48 48 48H156.2l91.4 83.4c19.6 17.9 49.9 16.5 67.8-3.1c5.5-6.1 9.2-13.2 11.1-20.6l17 15.6c19.5 17.9 49.9 16.6 67.8-2.9c4.5-4.9 7.8-10.6 9.9-16.5c19.4 13 45.8 10.3 62.1-7.5c17.9-19.5 16.6-49.9-2.9-67.8l-134.2-123z" + }, + "reply": { + title: "reply", + viewBox: "0 0 512 512", + d: "M205 34.8c11.5 5.1 19 16.6 19 29.2v64H336c97.2 0 176 78.8 176 176c0 113.3-81.5 163.9-100.2 174.1c-2.5 1.4-5.3 1.9-8.1 1.9c-10.9 0-19.7-8.9-19.7-19.7c0-7.5 4.3-14.4 9.8-19.5c9.4-8.8 22.2-26.4 22.2-56.7c0-53-43-96-96-96H224v64c0 12.6-7.4 24.1-19 29.2s-25 3-34.4-5.4l-160-144C3.9 225.7 0 217.1 0 208s3.9-17.7 10.6-23.8l160-144c9.4-8.5 22.9-10.6 34.4-5.4z" + }, + "d20": { + title: "d20", + viewBox: "0 0 512 512", + d: "M48.7 125.8l53.2 31.9c7.8 4.7 17.8 2 22.2-5.9L201.6 12.1c3-5.4-.9-12.1-7.1-12.1c-1.6 0-3.2 .5-4.6 1.4L47.9 98.8c-9.6 6.6-9.2 20.9 .8 26.9zM16 171.7V295.3c0 8 10.4 11 14.7 4.4l60-92c5-7.6 2.6-17.8-5.2-22.5L40.2 158C29.6 151.6 16 159.3 16 171.7zM310.4 12.1l77.6 139.6c4.4 7.9 14.5 10.6 22.2 5.9l53.2-31.9c10-6 10.4-20.3 .8-26.9L322.1 1.4c-1.4-.9-3-1.4-4.6-1.4c-6.2 0-10.1 6.7-7.1 12.1zM496 171.7c0-12.4-13.6-20.1-24.2-13.7l-45.3 27.2c-7.8 4.7-10.1 14.9-5.2 22.5l60 92c4.3 6.7 14.7 3.6 14.7-4.4V171.7zm-49.3 246L286.1 436.6c-8.1 .9-14.1 7.8-14.1 15.9v52.8c0 3.7 3 6.8 6.8 6.8c.8 0 1.6-.1 2.4-.4l172.7-64c6.1-2.2 10.1-8 10.1-14.5c0-9.3-8.1-16.5-17.3-15.4zM233.2 512c3.7 0 6.8-3 6.8-6.8V452.6c0-8.1-6.1-14.9-14.1-15.9l-160.6-19c-9.2-1.1-17.3 6.1-17.3 15.4c0 6.5 4 12.3 10.1 14.5l172.7 64c.8 .3 1.6 .4 2.4 .4zM41.7 382.9l170.9 20.2c7.8 .9 13.4-7.5 9.5-14.3l-85.7-150c-5.9-10.4-20.7-10.8-27.3-.8L30.2 358.2c-6.5 9.9-.3 23.3 11.5 24.7zm439.6-24.8L402.9 238.1c-6.5-10-21.4-9.6-27.3 .8L290.2 388.5c-3.9 6.8 1.6 15.2 9.5 14.3l170.1-20c11.8-1.4 18-14.7 11.5-24.6zm-216.9 11l78.4-137.2c6.1-10.7-1.6-23.9-13.9-23.9H183.1c-12.3 0-20 13.3-13.9 23.9l78.4 137.2c3.7 6.4 13 6.4 16.7 0zM174.4 176H337.6c12.2 0 19.9-13.1 14-23.8l-80-144c-2.8-5.1-8.2-8.2-14-8.2h-3.2c-5.8 0-11.2 3.2-14 8.2l-80 144c-5.9 10.7 1.8 23.8 14 23.8z" + }, + "screwdriver-wrench": { + title: "settings", + viewBox: "0 0 512 512", + d: "M78.6 5C69.1-2.4 55.6-1.5 47 7L7 47c-8.5 8.5-9.4 22-2.1 31.6l80 104c4.5 5.9 11.6 9.4 19 9.4h54.1l109 109c-14.7 29-10 65.4 14.3 89.6l112 112c12.5 12.5 32.8 12.5 45.3 0l64-64c12.5-12.5 12.5-32.8 0-45.3l-112-112c-24.2-24.2-60.6-29-89.6-14.3l-109-109V104c0-7.5-3.5-14.5-9.4-19L78.6 5zM19.9 396.1C7.2 408.8 0 426.1 0 444.1C0 481.6 30.4 512 67.9 512c18 0 35.3-7.2 48-19.9L233.7 374.3c-7.8-20.9-9-43.6-3.6-65.1l-61.7-61.7L19.9 396.1zM512 144c0-10.5-1.1-20.7-3.2-30.5c-2.4-11.2-16.1-14.1-24.2-6l-63.9 63.9c-3 3-7.1 4.7-11.3 4.7H352c-8.8 0-16-7.2-16-16V102.6c0-4.2 1.7-8.3 4.7-11.3l63.9-63.9c8.1-8.1 5.2-21.8-6-24.2C388.7 1.1 378.5 0 368 0C288.5 0 224 64.5 224 144l0 .8 85.3 85.3c36-9.1 75.8 .5 104 28.7L429 274.5c49-23 83-72.8 83-130.5zM56 432a24 24 0 1 1 48 0 24 24 0 1 1 -48 0z" + }, + "dumbbell": { + title: "dumbbell", + viewBox: "0 0 640 512", + d: "M96 64c0-17.7 14.3-32 32-32h32c17.7 0 32 14.3 32 32V224v64V448c0 17.7-14.3 32-32 32H128c-17.7 0-32-14.3-32-32V384H64c-17.7 0-32-14.3-32-32V288c-17.7 0-32-14.3-32-32s14.3-32 32-32V160c0-17.7 14.3-32 32-32H96V64zm448 0v64h32c17.7 0 32 14.3 32 32v64c17.7 0 32 14.3 32 32s-14.3 32-32 32v64c0 17.7-14.3 32-32 32H544v64c0 17.7-14.3 32-32 32H480c-17.7 0-32-14.3-32-32V288 224 64c0-17.7 14.3-32 32-32h32c17.7 0 32 14.3 32 32zM416 224v64H224V224H416z" + }, + "chevron-down": { + title: "chevron down", + viewBox: "0 0 512 512", + d: "M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z" + }, + "chevron-up": { + title: "chevron up", + viewBox: "0 0 512 512", + d: "M233.4 105.4c12.5-12.5 32.8-12.5 45.3 0l192 192c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L256 173.3 86.6 342.6c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3l192-192z" + }, + "chevron-left": { + title: "chevron left", + viewBox: "0 0 320 512", + d: "M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l192 192c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256 246.6 86.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-192 192z" + }, + "chevron-right": { + title: "chevron right", + viewBox: "0 0 320 512", + d: "M310.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L242.7 256 73.4 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z" + }, + }; + + ns.createIcon = function createIcon(iconDef, title, desc, classes, style) + { + var iconEl = createElement( + ns.ElementTypes.svg, + { + "viewBox": iconDef.viewBox, + "class": `${ICON_CLASS} ${classes}`, + "role": "img", + "style": style || "" + }, + ICON_CITATION + ); + + iconEl.insertAdjacentHTML("afterbegin", + `` + ); + + createChildElement( + iconEl, + ns.ElementTypes.title, + {}, + title || iconDef.title + ); + if (desc) + { + createChildElement( + iconEl, + ns.ElementTypes.desc, + {}, + desc + ); + } + + createChildElement( + iconEl, + ns.ElementTypes.path, + { + "d": iconDef.d + } + ); + + return iconEl; + }; + //#endregion +}); + +registerNamespace("GW.Controls", function(ns) { + ns.IconEl = class IconEl extends HTMLElement + { + //#region staticProperties + static observedAttributes = []; + static instanceCount = 0; + static instanceMap = {}; + //#endregion + + //#region instance properties + instanceId; + iconObj; + titleText; + isInitialized; + + //#region element properties + //#endregion + //#endregion + + constructor() + { + super(); + this.instanceId = IconEl.instanceCount++; + IconEl.instanceMap[this.instanceId] = this; + } + + get idKey() + { + return `gw-icon-${this.instanceId}`; + } + + //#region HTMLElement implementation + connectedCallback() + { + if (this.isInitialized) { return; } + + this.iconObj = ns.SVGLib.Icons[this.getAttribute("iconKey")]; + + this.titleText = this.getAttribute("title"); + if (this.hasAttribute("titleId")) + { + const titleEl = document.getElementById(this.getAttribute("titleId")); + this.titleText = titleEl.innerText; + titleEl.remove(); + } + + this.iconDescription = this.getAttribute("description"); + this.iconClasses = this.getAttribute("iconClasses"); + this.iconStyle = this.getAttribute("iconStyle"); + + this.renderContent(); + this.isInitialized = true; + } + //#endregion + + renderContent() + { + if (!this.iconObj) + { + debugger; + return; + } + + //Markup + this.insertAdjacentHTML("beforebegin", + `` + ); + this.appendChild( + ns.SVGLib.createIcon( + this.iconObj, + this.titleText, + this.iconDescription, + this.iconClasses, + this.iconStyle, + ) + ); + + //element properties + } + }; + customElements.define("gw-icon", ns.IconEl); +}); \ No newline at end of file diff --git a/src/_config/collections.js b/src/_config/collections.js new file mode 100644 index 00000000..502fbf5a --- /dev/null +++ b/src/_config/collections.js @@ -0,0 +1,12 @@ +export default function(eleventyConfig) { + // Add content categories to a collection + eleventyConfig.addCollection("categories", function(collectionApi) { + let categories = new Set(); + let contents = collectionApi.getFilteredByTag('contents'); + contents.forEach(p => { + let cats = p.data.categories; + cats.forEach(c => categories.add(c)); + }); + return Array.from(categories).sort(); + }); +} \ No newline at end of file diff --git a/src/_config/files.js b/src/_config/files.js new file mode 100644 index 00000000..d452a9bf --- /dev/null +++ b/src/_config/files.js @@ -0,0 +1,11 @@ +// Passthrough File Copy +export default function(eleventyConfig) { + eleventyConfig.addPassthroughCopy("./src/assets/"); + eleventyConfig.addWatchTarget("./src/assets/"); + eleventyConfig.addWatchTarget("./src/_bundle/"); + eleventyConfig.addPassthroughCopy({ + "./src/assets/favicon/favicon.ico": "/favicon.ico", + "./src/assets/favicon/apple-touch-icon.png": "/apple-touch-icon.png", + "node_modules/@zachleat/details-utils/details-utils.js": "assets/js/details-utils.js", + }); +} diff --git a/src/_config/filters.js b/src/_config/filters.js new file mode 100644 index 00000000..d39765bf --- /dev/null +++ b/src/_config/filters.js @@ -0,0 +1,32 @@ +import { DateTime } from "luxon"; + +export default function(eleventyConfig) { + // Filter: Filter contents by category + eleventyConfig.addFilter("filterByCategory", function(contents, cat) { + cat = cat.toLowerCase(); + let result = contents.filter(item => { + let cats = item.data.categories.map(c => c.toLowerCase()); + return cats.includes(cat); + }); + return result; + }); + + // Filter: Format dates + eleventyConfig.addFilter("formatDate", (date) => { + const dateFormat = "d LLLL yyyy"; + if (typeof date === "object") { + return DateTime.fromJSDate(date).toFormat(dateFormat); + } + return DateTime.fromISO(date, { setZone: true }).toFormat(dateFormat); + }); + + // Filter: Limit number of items displayed + eleventyConfig.addFilter("itemLimit", function(array, maximum) { + return array.slice(0, maximum); + }); + + // Filter: Thousands separator + eleventyConfig.addFilter("thousands", function(num) { + return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); + }); +} \ No newline at end of file diff --git a/src/_config/markdown-it.js b/src/_config/markdown-it.js new file mode 100644 index 00000000..61a78b0a --- /dev/null +++ b/src/_config/markdown-it.js @@ -0,0 +1,106 @@ +// markdown-it plugins +import markdownIt from "markdown-it"; +import markdownItAnchor from "markdown-it-anchor"; +import markdownItAttribution from "markdown-it-attribution"; +import markdownItAttrs from "markdown-it-attrs"; +import markdownItBracketedSpans from 'markdown-it-bracketed-spans'; +import markdownItDefList from "markdown-it-deflist"; +import markdownItFootnote from "markdown-it-footnote"; + +// Configure slug filter +import slugify from "slugify"; + +// Enable exporting markdown-it library to another module +export let markdownLibrary; + +export default function(eleventyConfig) { + // Configure markdown-it-anchor plugins + eleventyConfig.setLibrary('md', markdownIt().use(markdownItAnchor)) + const linkAfterHeader = markdownItAnchor.permalink.linkAfterHeader({ + class: "heading-anchor", + symbol: "", + style: "aria-labelledby", + }); + const markdownItAnchorOptions = { + level: [2, 3, 4, 5], + slugify: (str) => + slugify(str, { + lower: true, + strict: true, + remove: /["]/g, + }), + tabIndex: false, + permalink(slug, opts, state, idx) { + state.tokens.splice(idx, 0, + Object.assign(new state.Token("div_open", "div", 1), { + // Add class "header-wrapper [h1 or h2 or h3]" + attrs: [["class", `heading-wrapper ${state.tokens[idx].tag}`]], + block: true, + }) + ); + + state.tokens.splice(idx + 4, 0, + Object.assign(new state.Token("div_close", "div", -1), { + block: true, + }) + ); + + linkAfterHeader(slug, opts, state, idx + 1); + }, + }; + + /* Markdown Overrides */ + markdownLibrary = markdownIt({ + html: true, + linkify: true, + }) + .use(markdownItAnchor, markdownItAnchorOptions) + .use(markdownItAttribution) + .use(markdownItAttrs) + .use(markdownItBracketedSpans) + .use(markdownItDefList) + .use(markdownItFootnote); + + // Configure linkify + markdownLibrary.linkify.set({ fuzzyLink: false }); + + // Configure markdown-it-footnote + markdownLibrary.renderer.rules.footnote_block_open = () => ( + '
\n' + + '
\n' + + `
+

Footnotes

+ +
\n` + + '
    \n' + ); + + markdownLibrary.renderer.rules.footnote_anchor = (tokens, idx, options, env, slf) => { + let id = slf.rules.footnote_anchor_name(tokens, idx, options, env, slf); + + if (tokens[idx].meta.subId > 0) id += `:${tokens[idx].meta.subId}`; + + /* ↩ with escape code to prevent display as Apple Emoji on iOS */ + return ` +

    + + + Back to reference ${id} + +

    + `; + }; + + const renderRules = { + footnote_caption: ['[', '[Note '] + }; + Object.keys(renderRules).map(rule => { + let defaultRender = markdownLibrary.renderer.rules[rule]; + markdownLibrary.renderer.rules[rule] = (tokens, idx, options, env, self) => { + return defaultRender(tokens, idx, options, env, self).replace(...renderRules[rule]); + } + }); + + /* This is the part that tells 11ty to swap to our custom config */ + eleventyConfig.setLibrary("md", markdownLibrary); +} \ No newline at end of file diff --git a/src/_config/shortcodes.js b/src/_config/shortcodes.js new file mode 100644 index 00000000..7e94141d --- /dev/null +++ b/src/_config/shortcodes.js @@ -0,0 +1,54 @@ +import slugify from "slugify"; +import { markdownLibrary } from "./markdown-it.js"; + +export default function(eleventyConfig) { + // Shortcode: tag + eleventyConfig.addShortcode('cite', (str) => `${str}`); + + // Shortcode: Manual heading anchor + eleventyConfig.addPairedShortcode('headingAnchor', (title, hLevel, id=slugify(title)) => { + return `
    + ${title} + +
    `; + }); + + // Shortcode: Custom container + eleventyConfig.addPairedShortcode('container', (children, el, className) => { + const classMarkup = className ? ` class="${className}"` : ""; + const content = markdownLibrary.render(children); + return `<${el}${classMarkup}>${content}`; + }); + + // Shortcode: Image figure and figcaption + eleventyConfig.addPairedShortcode('imgFigure', ( + caption, img, alt=caption, className, enableLazyLoading=true + ) => { + const classMarkup = className ? ` class="${className}"` : ""; + const figcaption = markdownLibrary.renderInline(caption); + return ` + ${alt} +
    ${figcaption}
    + `; + }); + + // Shortcode: Content disclosure + eleventyConfig.addPairedShortcode('disclosure', (content, summary) => { + const summaryMarkup = markdownLibrary.renderInline(summary); + const contentMarkup = markdownLibrary.render(content); + return `
    + ${summaryMarkup} +
    ${contentMarkup}
    +
    `; + }); + + // Shortcode: Content warning disclosure + eleventyConfig.addPairedShortcode('contentWarning', (content, warning) => { + const warningMarkup = markdownLibrary.renderInline(warning); + const contentMarkup = markdownLibrary.render(content); + return `
    + Content Warning: ${warningMarkup} +
    ${contentMarkup}
    +
    `; + }); +} \ No newline at end of file diff --git a/src/_data/robots.js b/src/_data/robots.js new file mode 100644 index 00000000..da695e77 --- /dev/null +++ b/src/_data/robots.js @@ -0,0 +1,32 @@ +/* + Modified from Robb Knight's script: + https://rknight.me/blog/blocking-bots-with-nginx/ +*/ + +import EleventyFetch from "@11ty/eleventy-fetch"; + +export default async function () { + const url = "https://raw.githubusercontent.com/ai-robots-txt/ai.robots.txt/main/robots.txt"; + let txt = await EleventyFetch(url, { + duration: "1w", + type: "text", + }); + + const botExceptions = ["Applebot", "CCBot"]; + const botExceptionsFullStr = botExceptions.map(bot => "User-agent: " + bot) + + txt = txt + .split("\n") + .filter((line) => !botExceptionsFullStr.includes(line)) + .join("\n"); + + const bots = txt + .split("\n") + .filter((line) => line.startsWith("User-agent:")) + .map((line) => line.split(":")[1].trim().replace(/\s/gi, ".*")); + + return { + txt: txt, + htaccess: bots.join('|'), + }; +} \ No newline at end of file diff --git a/src/_data/sitemeta.js b/src/_data/sitemeta.js new file mode 100644 index 00000000..1c4c5d6e --- /dev/null +++ b/src/_data/sitemeta.js @@ -0,0 +1,28 @@ +export const siteName = "Leilukin's Hub"; +export const siteDomain = "leilukin.com"; +export const siteUrl = "https://" + siteDomain || "http://localhost:8080"; +export const siteAuthor = { + name: "Leilukin", + email: "contact@leilukin.com", + emailEncoded: '', + emailDecoyUrl: "emailme/", + url: siteUrl + "/about" +}; +export const siteLanguage = "en"; +export const siteLocale = "en_MY"; +export const siteDescription = siteAuthor.name + "'s personal website."; +export const fediverseHandle = "@Leilukin@dragonscave.space"; +export const feedPath = "/feed.xml"; +export const feedUrl = siteUrl + feedPath; +export const subsites = [ + { + siteName: "Tumbleblog", + subDomain: `tumbleblog.${siteDomain}`, + siteUrl() { return "https://" + this.subDomain; } + }, + { + siteName: `Beehive - ${siteAuthor.name}'s Fanlisitng Collective`, + subDomain: `fan.${siteDomain}`, + siteUrl() { return "https://" + this.subDomain; } + }, +]; \ No newline at end of file diff --git a/src/_includes/asummersend/base.njk b/src/_includes/asummersend/base.njk new file mode 100644 index 00000000..34b35bf6 --- /dev/null +++ b/src/_includes/asummersend/base.njk @@ -0,0 +1,19 @@ +{%- css %}{% include "src/assets/css/asummersend.css" %}{%- endcss %} + +{% extends "global/baselayout.njk" %} + +{% block metaTitle %} + +{% endblock %} + +{% block pageTitle %} +{{ title + " | " if title }}A Summer’s End — Hong Kong 1986 Shrine | {{ sitemeta.siteName | safe }} +{% endblock %} + +{% block favicon %} + +{% endblock %} + +{% block hero %}{% include "asummersend/hero.njk" %}{% endblock %} +{% block navbar %}{% include "asummersend/navbar.njk" %}{% endblock %} +{% block footer %}{% include "asummersend/footer.njk" %}{% endblock %} diff --git a/src/_includes/asummersend/content.njk b/src/_includes/asummersend/content.njk new file mode 100644 index 00000000..f77c6358 --- /dev/null +++ b/src/_includes/asummersend/content.njk @@ -0,0 +1,7 @@ +--- +layout: asummersend/base +--- + +{% extends "global/content.njk" %} + +{% block shrineInfo %}{% include "asummersend/shrineinfo.njk" %}{% endblock %} \ No newline at end of file diff --git a/src/_includes/asummersend/footer.njk b/src/_includes/asummersend/footer.njk new file mode 100644 index 00000000..b7c2c785 --- /dev/null +++ b/src/_includes/asummersend/footer.njk @@ -0,0 +1,6 @@ +{% extends "global/footer.njk" %} + +{% block footerContent %} +

    Made with ♥ by {{ sitemeta.siteAuthor.name }} • Shrine Launched: 16 February 2023

    +{% endblock %} + diff --git a/src/_includes/asummersend/hero.njk b/src/_includes/asummersend/hero.njk new file mode 100644 index 00000000..e8c9af7b --- /dev/null +++ b/src/_includes/asummersend/hero.njk @@ -0,0 +1,46 @@ +{% extends "global/hero.njk" %} + +{% block heroImg %} + + + Banner of A Summer’s End — Hong Kong 1986 Shrine + +{% endblock %} + +{% block eventScript %} +const todayEvent = getTodayEvent(); + +if (todayEvent) { + heroTopBarEl.classList.remove('hidden'); + heroTopBarEl.innerHTML = todayEvent; +} + +function getTodayEvent() { + const date = new Date(); + const month = date.getMonth() + 1; + const day = date.getDate(); + const year = date.getFullYear(); + + const aseReleaseDate = new Date("2020-04-23").getFullYear(); + const aseAnniversary = year - aseReleaseDate; + + if (month === 2 && day === 16) + return ` + Today is Michelle Cheung's birthday. Happy Birthday Michelle! + `; + else if (month === 4 && day === 23) + return ` + Today is the ${aseAnniversary}-year anniversary of the release of {% cite "A Summer’s End — Hong Kong 1986" %}! + `; + else if (month === 8 && day === 9) + return ` + Today is Cecelia Cortes' birthday. Happy Birthday Cecelia! + `; + else if (month === 12 && day === 28) + return ` + Today is Sam Wong's birthday. Happy Birthday Sam! + `; + else + return null; +} +{% endblock %} diff --git a/src/_includes/asummersend/myplaylist.njk b/src/_includes/asummersend/myplaylist.njk new file mode 100644 index 00000000..a7e1f06c --- /dev/null +++ b/src/_includes/asummersend/myplaylist.njk @@ -0,0 +1,31 @@ +{% macro myASEPlaylist(intro) %} +{% imgFigure "/assets/projects/playlists/My-Dear-Summer-Lover-cover.avif", "Cover image of A Summer’s End fanmix 'My Dear Summer Lover: A Sam x Michelle Fanmix'" %} +[Image description: Sam and Michelle from A Summer’s End almost kisses, with a play symbol and text on the top left corner, and the text "My Dear Summer Lover: A Sam x Michelle Fanmix" in a digital style font in front.] +{% endimgFigure %} + +{{ intro }} [{% cite "A Summer’s End — Hong Kong 1986" %}](https://www.asummersend.com/home), dedicated to Sam and Michelle’s love story. + +This mix contains mostly Cantonese and English songs, with one Mandarin song. Majority of these songs were performed by Hong Kong artists and released in the 80s, because A Summer’s End took place in Hong Kong and in the 80s. + +I have carefully selected and arranged these tracks, so the lyrics would reflect Sam and Michelle’s relationship development throughout {% cite "A Summer’s End" %}. Therefore, the content of this mix could be considered spoilers if you have not played the visual novel. + +Since Oracle and Bone has cited Anita Mui as a major inspiration for them and this visual novel, I have also included multiple songs performed by Anita Mui in this mix. Because A Summer’s End is a lesbian story, when I was choosing which songs to include in this mix, I also prioritize songs that were performed by women artists. + +Tracklist: +1. [輕輕嘆]{lang="zh"} (Sigh Softly) — Deanie Ip +2. [愛我便說愛我吧]{lang="zh"} (Just Say You Love Me) — Anita Mui +3. [夏日戀人]{lang="zh"} (Summer Lover) — Anita Mui +4. [星空下的戀人]{lang="zh"} (Lovers Under the Stars) — Shirley Kwan +5. I Want Your Love — CHIC +6. [激情]{lang="zh"} (Passion) — Sandy Lam +7. When Will I See You Again — Teresa Carpio +8. [愛你、想你]{lang="zh"} (Love You, Miss You) — Anita Mui +9. Within You’ll Remain — Julia Hsu +10. I Want to Know What Love Is — Tina Arena +11. Touch — Anita Mui +12. [親密愛人]{lang="zh"} (Intimate Lover) — Anita Mui + +[Listen on Spotify](https://open.spotify.com/playlist/3SIV7VjSKhspYwugVIQjug){.link-btn} + + +{% endmacro %} \ No newline at end of file diff --git a/src/_includes/asummersend/navbar.njk b/src/_includes/asummersend/navbar.njk new file mode 100644 index 00000000..8c547b66 --- /dev/null +++ b/src/_includes/asummersend/navbar.njk @@ -0,0 +1,11 @@ +{% extends "global/navbar.njk" %} +{% set shrineHomeUrl = "/shrines/asummersend/" %} + +{% block navbarLinks %} +{% set navPages = collections.all | eleventyNavigation("A Summer’s End Shrine") %} +{%- for entry in navPages %} +
  1. + {{ entry.title }} +
  2. +{%- endfor %} +{% endblock %} diff --git a/src/_includes/asummersend/shrineinfo.njk b/src/_includes/asummersend/shrineinfo.njk new file mode 100644 index 00000000..0bea6ca6 --- /dev/null +++ b/src/_includes/asummersend/shrineinfo.njk @@ -0,0 +1,12 @@ +{% extends "global/shrineinfo.njk" %} + +{% block shrineAbout %} +

    Welcome to {{ sitemeta.siteAuthor.name }}'s shrine for {% cite "A Summer’s End — Hong Kong 1986" %}, an indie visual novel developed by Oracle and Bone. Set in 1980s Hong Kong, it tells of a love story between two women.

    +{% endblock %} + +{% block shrineLinks %} +
  3. Official Website +
  4. +
  5. Steam
  6. +
  7. itch.io
  8. +{% endblock %} diff --git a/src/_includes/cassettebeasts/base.njk b/src/_includes/cassettebeasts/base.njk new file mode 100644 index 00000000..a81a2649 --- /dev/null +++ b/src/_includes/cassettebeasts/base.njk @@ -0,0 +1,19 @@ +{%- css %}{% include "src/assets/css/cassettebeasts.css" %}{%- endcss %} + +{% extends "global/baselayout.njk" %} + +{% block metaTitle %} + +{% endblock %} + +{% block pageTitle %} +{{ title + " | " if title }}Cassette Beasts Shrine | {{ sitemeta.siteName | safe }} +{% endblock %} + +{% block favicon %} + +{% endblock %} + +{% block hero %}{% include "cassettebeasts/hero.njk" %}{% endblock %} +{% block navbar %}{% include "cassettebeasts/navbar.njk" %}{% endblock %} +{% block footer %}{% include "cassettebeasts/footer.njk" %}{% endblock %} diff --git a/src/_includes/cassettebeasts/content.njk b/src/_includes/cassettebeasts/content.njk new file mode 100644 index 00000000..e7674e69 --- /dev/null +++ b/src/_includes/cassettebeasts/content.njk @@ -0,0 +1,7 @@ +--- +layout: cassettebeasts/base +--- + +{% extends "global/content.njk" %} + +{% block shrineInfo %}{% include "cassettebeasts/shrineinfo.njk" %}{% endblock %} \ No newline at end of file diff --git a/src/_includes/cassettebeasts/footer.njk b/src/_includes/cassettebeasts/footer.njk new file mode 100644 index 00000000..2bfc9183 --- /dev/null +++ b/src/_includes/cassettebeasts/footer.njk @@ -0,0 +1,6 @@ +{% extends "global/footer.njk" %} + +{% block footerContent %} +

    Made with ♥ by {{ sitemeta.siteAuthor.name }} • Shrine Launched: 3 August 2023

    +{% endblock %} + diff --git a/src/_includes/cassettebeasts/hero.njk b/src/_includes/cassettebeasts/hero.njk new file mode 100644 index 00000000..9068ea7e --- /dev/null +++ b/src/_includes/cassettebeasts/hero.njk @@ -0,0 +1,40 @@ +{% extends "global/hero.njk" %} + +{% block heroImg %} + + + Banner of Cassette Beasts Shrine + +{% endblock %} + +{% block eventScript %} +const todayEvent = getTodayEvent(); + +if (todayEvent) { + heroTopBarEl.classList.remove('hidden'); + heroTopBarEl.innerHTML = todayEvent; +} + +function getTodayEvent() { + const date = new Date(); + const month = date.getMonth() + 1; + const day = date.getDate(); + const year = date.getFullYear(); + + const cbReleaseDate = new Date("2023-04-26").getFullYear(); + const pierReleaseDate = new Date("2023-10-04").getFullYear(); + const cbAnniversary = year - cbReleaseDate; + const pierAnniversary = year - pierReleaseDate; + + if (month === 4 && day === 26) + return ` + Today is the ${cbAnniversary}-year anniversary of the release of {% cite "Cassette Beasts" %}! + `; + else if (month === 10 && day === 4) + return ` + Today is the ${pierAnniversary}-year anniversary of the release of Pier of the Unknown, the first DLC expansion of {% cite "Cassette Beasts" %}! + `; + else + return null; +} +{% endblock %} diff --git a/src/_includes/cassettebeasts/navbar.njk b/src/_includes/cassettebeasts/navbar.njk new file mode 100644 index 00000000..bd36dcc4 --- /dev/null +++ b/src/_includes/cassettebeasts/navbar.njk @@ -0,0 +1,11 @@ +{% extends "global/navbar.njk" %} +{% set shrineHomeUrl = "/shrines/cassettebeasts/" %} + +{% block navbarLinks %} +{% set navPages = collections.all | eleventyNavigation("Cassette Beasts Shrine") %} +{%- for entry in navPages %} +
  9. + {{ entry.title }} +
  10. +{%- endfor %} +{% endblock %} diff --git a/src/_includes/cassettebeasts/shrineinfo.njk b/src/_includes/cassettebeasts/shrineinfo.njk new file mode 100644 index 00000000..1c755f8b --- /dev/null +++ b/src/_includes/cassettebeasts/shrineinfo.njk @@ -0,0 +1,14 @@ +{% extends "global/shrineinfo.njk" %} + +{% block shrineAbout %} +

    Welcome to {{ sitemeta.siteAuthor.name }}'s shrine for {% cite "Cassette Beasts" %}, an indie monster collecting turn-based open-world role-playing video game developed by Bytten Studio and published by Raw Fury.

    +{% endblock %} + +{% block shrineLinks %} +
  11. Official Website +
  12. +
  13. Official Wiki
  14. +
  15. Steam
  16. +
  17. Bytten Studio
  18. +
  19. Cassette Beasts fanlisting
  20. +{% endblock %} diff --git a/src/_includes/global/baselayout.njk b/src/_includes/global/baselayout.njk new file mode 100644 index 00000000..cfc704e6 --- /dev/null +++ b/src/_includes/global/baselayout.njk @@ -0,0 +1,53 @@ + + + + + + + {# Open Graph Meta #} + {% block metaTitle %} + + {% endblock %} + {% include "global/meta.njk" %} + {# Feeds #} + {% include "global/feeds.njk" %} + {# Fonts #} + {% include "global/fonts.njk" %} + {# CSS #} + {% include "global/css-bundle.njk" %} + {% if hasTooltips %} + + {% endif %} + + {# Favicon #} + {% block favicon %}{% endblock %} + {# Verifications #} + + + + {# JavaScript #} + + {% if toc %} + + {% endif %} + {% if hasCodeBlock %} + + {% endif %} + {% if hasTooltips %} + + {% endif %} + + + {% block pageTitle %}{{ title + " | " if title }}{{ sitemeta.siteName | safe }}{% endblock %} + + + + + {% block hero %}{% include "global/hero.njk" %}{% endblock %} + {% block navbar %}{% include "global/navbar.njk" %}{% endblock %} +
    + {{ content | safe }} +
    + {% block footer %}{% include "global/footer.njk" %}{% endblock %} + + diff --git a/src/_includes/global/content.njk b/src/_includes/global/content.njk new file mode 100644 index 00000000..01e25c04 --- /dev/null +++ b/src/_includes/global/content.njk @@ -0,0 +1,115 @@ +
    + {% if isArticle or hasBreadcrumbs %} + + {% endif %} + +

    {{ articleTitle or pageTitle or title }}

    + + {% if isArticle %} + + {% else %} + {% if desc %} +

    {{ desc }}

    + {% endif %} + {% endif %} +
    + + + {% if toc %} + {% include "global/toc.njk" %} + {% endif %} + + {% set contentEl = "article" if isArticle or articleElement else "div" %} + + <{{contentEl}} class="content{{' content--divided' if isContentDivided }}"> + {{ content | safe }} + + {% if tags and tags.includes("posts") %} + {%- if collections.posts.length > 1 %} + + {%- endif %} + {% endif %} + + + {% if + tags and tags.includes("articles") + or tags and tags.includes("posts") + or page.url === "/articles/" + or tags and tags.includes("blog pages") + %} + {% include "main/content-nav.njk" %} + {% endif %} + + {% block shrineInfo %}{% endblock %} + + +{%- css %} +.breadcrumbs { + margin-bottom: 0.7em; + display: flex; + gap: 0.5em; + flex-wrap: wrap; + justify-content: center; +} + +.blog__post--pagination { + padding-top: 1em; + margin-block-start: 2.5em; + border-top: 0.1em solid var(--clr-title-border); +} + +.blog__post--nextprev { + list-style-type: ""; + padding: 0; + margin: 0; + display: grid; + gap: 0.7em; + grid-template-columns: repeat(2, 1fr); + grid-template-areas: 'prev next'; +} + +.blog__post--prev { grid-area: prev; } +.blog__post--next { grid-area: next; } +{% endcss %} diff --git a/src/_includes/global/css-bundle.njk b/src/_includes/global/css-bundle.njk new file mode 100644 index 00000000..b5cd78ac --- /dev/null +++ b/src/_includes/global/css-bundle.njk @@ -0,0 +1,14 @@ +{% set cssFiles = [ + "global", + "a11y-syntax-highlighting-dark", + "general", + "content", + "plugins", + "components", + "pridesymbols", + "utility" +] %} + +{%- for file in cssFiles -%} + +{%- endfor -%} \ No newline at end of file diff --git a/src/_includes/global/feeds.njk b/src/_includes/global/feeds.njk new file mode 100644 index 00000000..66a1aa98 --- /dev/null +++ b/src/_includes/global/feeds.njk @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/_includes/global/fonts.njk b/src/_includes/global/fonts.njk new file mode 100644 index 00000000..b6b0d138 --- /dev/null +++ b/src/_includes/global/fonts.njk @@ -0,0 +1,19 @@ + + + + diff --git a/src/_includes/global/footer.njk b/src/_includes/global/footer.njk new file mode 100644 index 00000000..a150eeb1 --- /dev/null +++ b/src/_includes/global/footer.njk @@ -0,0 +1,53 @@ + + +{%- css %} +:root { --footer-gap: 0.5em; } + +.footer { + margin-top: auto; + width: 100%; + background: var(--clr-main-footer-bg); + padding: 1.5rem 1rem clamp(1.5rem, calc(100% - 1.5rem), 3.5rem); + text-align: center; + display: grid; + gap: var(--footer-gap); +} + +.footer__links, +.footer__shrines { + display: flex; + flex-wrap: wrap; + justify-content: center; + column-gap: var(--footer-gap); +} + +.footer__links { justify-self: center; } +.footer__shrines { align-self: center; } +{% endcss %} diff --git a/src/_includes/global/h-card.njk b/src/_includes/global/h-card.njk new file mode 100644 index 00000000..4544b3ed --- /dev/null +++ b/src/_includes/global/h-card.njk @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/src/_includes/global/hero.njk b/src/_includes/global/hero.njk new file mode 100644 index 00000000..7971887e --- /dev/null +++ b/src/_includes/global/hero.njk @@ -0,0 +1,46 @@ +
    + +
    + {% block heroImg %} + {{ heroImg }} + {% endblock %} +
    +
    + +{%- css %} +.hero { + width: 100%; + background-color: var(--clr-hero-bg); + display: flex; + flex-direction: column; + justify-content: center; + text-align: center; +} + +.hero__top-bar { + background: var(--clr-navbar-bg); + width: 100%; + padding: 0.5em 0.7em; +} + +.hero__img { + display: grid; + place-content: center; +} + +.hero img { + object-fit: contain; + overflow: hidden; + max-height: 16rem; +} +{% endcss %} + +{%- js %} +const hero = document.querySelector(".hero"); +const heroTopBarEl = document.querySelector(".hero__top-bar"); +const headerImgEl = document.querySelector(".hero__img"); + +{% block eventScript %} +{{ eventScript }} +{% endblock %} +{% endjs %} diff --git a/src/_includes/global/macros.njk b/src/_includes/global/macros.njk new file mode 100644 index 00000000..c8c26fd6 --- /dev/null +++ b/src/_includes/global/macros.njk @@ -0,0 +1,26 @@ +{%- macro articleList(tag) -%} + +{%- endmacro -%} + +{%- macro modEntry(params) -%} +{% headingAnchor 3 %}{{ params.title }}{% endheadingAnchor %} +
    + Banner of {{ params.title }} mod +

    {{ params.desc | safe }}

    +

    Download the mod:

    +
    + {%- for download in params.downloads -%} + {{ download.site }} + {%- endfor -%} +
    +
    +{%- endmacro -%} diff --git a/src/_includes/global/meta.njk b/src/_includes/global/meta.njk new file mode 100644 index 00000000..939ee95d --- /dev/null +++ b/src/_includes/global/meta.njk @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/_includes/global/navbar.njk b/src/_includes/global/navbar.njk new file mode 100644 index 00000000..817fbd6d --- /dev/null +++ b/src/_includes/global/navbar.njk @@ -0,0 +1,105 @@ +{% set navLinksEl %} + {%- if tags and tags.includes("shrine pages") %} +
  21. + Shrine Home +
  22. + {%- endif -%} + {% block navbarLinks %}{% endblock %} + {%- if tags and tags.includes("shrine pages") %} +
  23. Shrine Directory
  24. +
  25. Main Site
  26. + {%- endif -%} +{% endset %} + + + + +{%- css %} +.navbar { + background: var(--clr-navbar-bg); + width: 100%; + z-index: 998; + position: sticky; + top: 0; + padding: 0.6em; +} + +.navbar__menu { + list-style-type: ""; + margin: 0; + padding: 0; + display: flex; + gap: 1em; + flex-wrap: wrap; + text-align: center; +} + +.navbar__menu a { + color: var(--clr-navbar-link); + text-decoration: none; + font-weight: 700; + display: inline-block; +} + +.navbar__menu a:hover { color: var(--clr-link-hover); } +.navbar__menu a:focus { outline-offset: 0.2em; } + +.navbar__links { + display: flex; + flex-wrap: wrap; + justify-content: space-evenly; + gap: 0.5em; +} + +.navbar__toggle { + background-color: inherit; + color: var(--clr-navbar-link); + border: none; + padding: 0; + font-size: 1.25rem; + font-weight: 700; + display: none; + align-items: center; + gap: 0.3em; +} + +.navbar__toggle svg { fill: currentColor; } + +.navbar__toggle:focus, +.navbar__menu a:focus { outline-offset: 0.1em; } +.navbar__toggle:focus, +.navbar__menu a:focus { outline: 0.15em solid var(--clr-navbar-link); } + +.navbar__popover { + background: var(--clr-navbar-bg); + border: 0.15em solid var(--clr-navbar-link); + padding: 1.5em; + max-width: 85%; +} + +.navbar__popover::backdrop { + background-color: black; + opacity: 0.5; +} + +@supports selector([popover]) { + .navbar__toggle { display: flex; } + .navbar__links { display: none; } +} + +/* Tablet screen size */ +@media only screen and (min-width: 43.75rem) { + .navbar { padding: 1em 0.6em; } + .navbar__toggle, .navbar__popover { display: none; } + .navbar__links { display: flex; } +} +{% endcss %} diff --git a/src/_includes/global/pagination-oldnew.njk b/src/_includes/global/pagination-oldnew.njk new file mode 100644 index 00000000..14a6cfdd --- /dev/null +++ b/src/_includes/global/pagination-oldnew.njk @@ -0,0 +1,98 @@ +{% set firstLabel %} + +Newest{% endset %} + +{% set prevLabel %} + +Newer{% endset %} + +{% set nextLabel %}Older + +{% endset %} + +{% set lastLabel %}Oldest + +{% endset %} + + + +{%- css %} +.pagination__wrapper { + display: grid; + place-content: center; + margin-top: 3em; +} + +.pagination { + list-style-type: ""; + padding: 0; + margin: 0; + display: flex; + gap: 0.5em; + flex-wrap: wrap; + justify-content: center; +} + +.pagination li { + text-align: center; + padding: 0.3em 0.7em; + color: var(--clr-title-border); + background-color: var(--clr-code-bg); +} + +.pagination li:has(a) { background-color: var(--clr-title-border); } +.pagination li:has(a):hover { background-color: var(--clr-link-hover); } + +.pagination li:has(a):focus-within { + outline: 0.2em solid var(--clr-title-border); + outline-offset: 0.15em; +} + +.pagination li a { + color: var(--clr-link-btn-hover); + text-decoration: none; +} + +.pagination li a:focus { outline: none; } +{% endcss %} diff --git a/src/_includes/global/shrineinfo.njk b/src/_includes/global/shrineinfo.njk new file mode 100644 index 00000000..c6fc0c93 --- /dev/null +++ b/src/_includes/global/shrineinfo.njk @@ -0,0 +1,39 @@ + + +{%- css %} +.right-sidebar { + background-color: var(--clr-content-bg); + font-size: clamp(0.9rem, 0.9rem + 3vw, 1rem); +} + +.shrine__info { + padding: 1rem; + max-height: var(--ht-sticky-sidebar); + overflow-x: auto; +} + +.shrine__info h2 { + font-size: clamp(1.5rem, 1rem + 3vw, 1.7rem); + margin-bottom: 0.2em; +} + +.shrine__info h3 { + font-size: clamp(1.3rem, 1rem + 3vw, 1.5rem); + margin-top: 1em; +} + +.shrine__info ul { margin-top: 0.5em; } +{% endcss %} diff --git a/src/_includes/global/toc.njk b/src/_includes/global/toc.njk new file mode 100644 index 00000000..1e53d10a --- /dev/null +++ b/src/_includes/global/toc.njk @@ -0,0 +1,57 @@ + + +{%- css %} +.toc__wrapper { + max-height: var(--ht-sticky-sidebar); + overflow-x: auto; + background-color: var(--clr-content-bg); + padding: 1rem 1.3rem; +} + +.toc__heading { + font-size: 1.3rem; + font-weight: 700; + color: var(--clr-sub-heading); +} + +.toc__wrapper[open] > .toc__heading { + margin-bottom: 0.5em; +} + +.toc ol, .toc ol ol { + display: grid; + gap: 0.3em; +} + +.toc ol { + border-top: 0.1em solid var(--clr-title-border); + padding-left: 1.3em; + padding-top: 1em; +} + +.toc ol ol { + border-top: none; + list-style-type: disc; + padding-left: 1em; + padding-top: 0.3em; +} + +.toc ol a { + font-size: 1.1rem; + padding-left: 0.3em; +} + +.toc ol ol a { + padding: 0; + font-size: 1rem; +} +{% endcss %} diff --git a/src/_includes/global/top-btn.njk b/src/_includes/global/top-btn.njk new file mode 100644 index 00000000..6a50d2b2 --- /dev/null +++ b/src/_includes/global/top-btn.njk @@ -0,0 +1,43 @@ + + + Back to Top + + +{%- css %} +.top-btn, +.top-btn:hover { + color: var(--clr-top-btn-txt); + text-decoration: none; + font-weight: 700; +} + +.top-btn { + position: fixed; + bottom: 0.5rem; + right: 0.5rem; + z-index: 999; + + background-color: var(--clr-top-btn-bg); + display: flex; + align-items: center; + border-radius: 50em; + padding: 0.3em 0.5em; + gap: 0.2em; +} + +.top-btn:focus { + outline: 0.25em solid var(--clr-top-btn-bg); + outline-offset: 0.15em; +} + +.top-btn__arrow { + display: inline-block; + width: 1em; + aspect-ratio: 1 / 1; + stroke-width: 0; + stroke: currentColor; + fill: currentColor; +} +{% endcss %} diff --git a/src/_includes/main/archive.njk b/src/_includes/main/archive.njk new file mode 100644 index 00000000..1c07d8bd --- /dev/null +++ b/src/_includes/main/archive.njk @@ -0,0 +1,16 @@ + \ No newline at end of file diff --git a/src/_includes/main/base.njk b/src/_includes/main/base.njk new file mode 100644 index 00000000..0a6100f9 --- /dev/null +++ b/src/_includes/main/base.njk @@ -0,0 +1,5 @@ +{% extends "global/baselayout.njk" %} + +{% block hero %}{% include "main/hero.njk" %}{% endblock %} +{% block navbar %}{% include "main/navbar.njk" %}{% endblock %} +{% block footer %}{% include "main/footer.njk" %}{% endblock %} \ No newline at end of file diff --git a/src/_includes/main/changelogs-list.njk b/src/_includes/main/changelogs-list.njk new file mode 100644 index 00000000..e10d7277 --- /dev/null +++ b/src/_includes/main/changelogs-list.njk @@ -0,0 +1,7 @@ +{% for log in changelogList | reverse %} +{% headingAnchor 2, log.fileSlug %} +{{ log.date | formatDate }} +{% endheadingAnchor %} + +{{ log.content | safe }} +{%- endfor %} diff --git a/src/_includes/main/changelogs.njk b/src/_includes/main/changelogs.njk new file mode 100644 index 00000000..3e4da0f7 --- /dev/null +++ b/src/_includes/main/changelogs.njk @@ -0,0 +1,62 @@ +--- +layout: main/content +articleElement: true +--- + +{% set currentUrl %}{{ page.url }}{% endset %} + + + +

    To get notified of the updates on this website, you can subscribe to its RSS feed, which contains new articles, blog posts and website changelogs.

    + +{{ content | safe }} + +{%- css %} +.changelog__nav, +.changelog__nav--links { + display: flex; + align-items: center; + justify-content: center; + flex-wrap: wrap; +} + +.changelog__nav { + flex-direction: column; + gap: 0.2em; + align-self: center; + font-weight: 700; + gap: 0.5em; +} + +.changelog__nav--links li { + text-align: center; + align-self: center; +} + +.changelog__nav--links [aria-current="page"] { + text-decoration: none; + color: var(--clr-bold-txt); +} + +@media (min-width: 640px) { + .changelog__nav { + flex-direction: row; + gap: 1em; + } +} +{% endcss %} diff --git a/src/_includes/main/content-nav.njk b/src/_includes/main/content-nav.njk new file mode 100644 index 00000000..2823d4ed --- /dev/null +++ b/src/_includes/main/content-nav.njk @@ -0,0 +1,23 @@ + + +{%- css %} +.content__nav { + padding: 1.2em clamp(1em, 5%, 1.5em); + background-color: var(--clr-content-bg); +} + +.content__nav--title { font-size: 1.7rem; } +{% endcss %} diff --git a/src/_includes/main/content.njk b/src/_includes/main/content.njk new file mode 100644 index 00000000..79e86d45 --- /dev/null +++ b/src/_includes/main/content.njk @@ -0,0 +1,5 @@ +--- +layout: main/base +--- + +{% extends "global/content.njk" %} \ No newline at end of file diff --git a/src/_includes/main/footer.njk b/src/_includes/main/footer.njk new file mode 100644 index 00000000..735b4118 --- /dev/null +++ b/src/_includes/main/footer.njk @@ -0,0 +1,29 @@ +{% extends "global/footer.njk" %} + +{% block footerContent %} +

    Footer Navigation:

    +{% set currentUrl %}{{ page.url }}{% endset %} + +

    Made with ♥ by {{ sitemeta.siteAuthor.name }} since 11 September 2022

    +{% endblock %} + diff --git a/src/_includes/main/hero.njk b/src/_includes/main/hero.njk new file mode 100644 index 00000000..b1161e05 --- /dev/null +++ b/src/_includes/main/hero.njk @@ -0,0 +1,141 @@ +{% extends "global/hero.njk" %} + +{% block heroImg %} +Banner of Leilukin's Hub +{% endblock %} + +{% set heroDropShadow %} +drop-shadow(0.1rem 0.1rem 0.2rem black) +drop-shadow(0.1rem 0.1rem 0.2rem rgba(30, 30, 30, 0.8)) +{% endset%} +{%- css %}.hero img { filter: {{ heroDropShadow }}; }{% endcss %} + +{% block eventScript %} +const todayEvent = getTodayEvent(); + +if (todayEvent) { + heroTopBarEl.classList.remove('hidden'); + heroTopBarEl.innerHTML = todayEvent.blurb; + + if (todayEvent.class) { + headerImgEl.classList.add(todayEvent.class); + } +} + +function getTodayEvent() { + const date = new Date(); + const month = date.getMonth() + 1; + const day = date.getDate(); + const year = date.getFullYear(); + const weekOfMonth = Math.ceil(day / 7); + + const leilukinsHubLaunchDate = new Date("2022-09-11").getFullYear(); + const siteAnniversary = year - leilukinsHubLaunchDate; + + if (month === 3 && day === 1) + return { + blurb: `Today is Zero Discrimination Day`, + class: "flag-progress-intersex", + }; + else if (month === 3 && day === 8) + return { + blurb: `Today is International Women's Day`, + class: "symbol-venus", + }; + else if (month === 3 && day === 31) + return { + blurb: `Today is Trans Day of Visibility`, + class: "flag-trans", + }; + else if (month === 4 && day === 6) + return { + blurb: `Today is International Asexuality Day`, + class: "flag-ace", + }; + else if (month === 4 && day === 26) + return { + blurb: `Today is Lesbian Visibility Day`, + class: "flag-lesbian", + }; + else if (month === 4 && weekOfMonth === 4) + return { + blurb: `This week is Lesbian Visibility Week`, + class: "flag-lesbian", + }; + else if (month === 5 && day === 17) + return { + blurb: `Today is International Day Against Homophobia, Biphobia and Transphobia`, + class: "flag-progress", + }; + else if (month === 5 && day === 19) + return { + blurb: `Today is Agender Pride Day`, + class: "flag-agender", + }; + else if (month === 5 && day === 25) + return { + blurb: `Today is Pansexual and Panromantic Awareness and Visibility Day`, + class: "flag-pan", + }; + else if (month === 6) + return { + blurb: `Happy Pride Month!`, + class: "flag-progress-intersex", + }; + else if (month === 7 && day === 14) + return { + blurb: `Today is Non-Binary People's Day`, + class: "flag-non-binary", + }; + else if (month === 7 && day === 28) + return { + blurb: `Today is Leilukin's Birthday` + }; + else if (month === 7) + return{ + blurb: `Happy Disability Pride Month!`, + class: "flag-disability" + } + else if (month === 8 && day === 25) + return { + blurb: `Today is Aromantic Spectrum Visibility Day`, + class: "flag-aro", + }; + else if (month === 9 && day === 11) + return { + blurb: `Today is the ${siteAnniversary}-year anniversary of the launch of {{ sitemeta.siteName }}` + }; + else if (month === 9 && day === 23) + return { + blurb: `Today is Bi Visibility Day`, + class: "flag-bi", + }; + else if (month === 10 && day === 8) + return { + blurb: `Today is International Lesbian Day`, + class: "flag-lesbian", + }; + else if (month === 10 && day === 11) + return { + blurb: `Today is National Coming Out Day`, + class: "flag-rainbow", + }; + else if (month === 10 && day === 17) + return { + blurb: `Today is the start of Genderfluid Visibility Week`, + class: "flag-genderfluid", + }; + else if (month === 10 && day === 26) + return { + blurb: `Today is Intersex Awareness Day`, + class: "flag-intersex", + }; + else if (month === 11 && day === 13) + return { + blurb: `Today is the start of Transgender Awareness Week`, + class: "flag-trans", + }; + else + return null; +} +{% endblock %} diff --git a/src/_includes/main/links.njk b/src/_includes/main/links.njk new file mode 100644 index 00000000..79c8f6cb --- /dev/null +++ b/src/_includes/main/links.njk @@ -0,0 +1,48 @@ +--- +layout: main/content.njk +articleElement: true +isContentDivided: true +--- +{% set linkGroups = collections["link groups"] %} + +
    +

    Link to My Website

    + {% include "main/my-button.njk" %} +
    + +
    +

    Links by Category

    + +

    Use the following tabs to view my link collection by category.

    + +
    + +
    + {% for group in linkGroups %} +
    + {% headingAnchor 2 %}{{ group.data.title }}{% endheadingAnchor %} + + {% if group.data.toc %} +
    +

    Table of Contents

    + {{ group.content | toc | safe }} +
    + {% endif %} + + {{ group.content | safe }} + + {% if group.data.updated %} +

    (This {{ group.data.title }} list was last updated on )

    + {% endif %} + + Back to tabs +
    + {%- endfor %} +
    diff --git a/src/_includes/main/my-button.njk b/src/_includes/main/my-button.njk new file mode 100644 index 00000000..c6a27631 --- /dev/null +++ b/src/_includes/main/my-button.njk @@ -0,0 +1,13 @@ +

    You can link to my website using my site button. I strongly recommend you to upload my site button to your own website instead of hotlinking the button.

    + +
    + Leilukin's Hub website button with 88×31 pixel size + Leilukin's Hub website button with 200×40 pixel size +
    + +{%- css %} +.my-btn { + align-items: center; + margin-top: 1em; +} +{% endcss %} \ No newline at end of file diff --git a/src/_includes/main/navbar.njk b/src/_includes/main/navbar.njk new file mode 100644 index 00000000..c47459e9 --- /dev/null +++ b/src/_includes/main/navbar.njk @@ -0,0 +1,11 @@ +{% extends "global/navbar.njk" %} + +{% block navbarLinks %} +{% set currentUrl %}{{ page.url }}{% endset %} +{% set navPages = collections["navbar links"] | eleventyNavigation %} +{%- for entry in navPages %} +
  27. + {{ entry.title }} +
  28. +{%- endfor %} +{% endblock %} diff --git a/src/_includes/main/slashpage.njk b/src/_includes/main/slashpage.njk new file mode 100644 index 00000000..2bb2fe5d --- /dev/null +++ b/src/_includes/main/slashpage.njk @@ -0,0 +1,9 @@ +--- +layout: main/content +--- + +{{ content | safe }} + +{% if updated %} +

    (This {{ keyword if keyword else "page" }} was last updated on )

    +{% endif %} diff --git a/src/_includes/main/statuscafe.njk b/src/_includes/main/statuscafe.njk new file mode 100644 index 00000000..94f15aef --- /dev/null +++ b/src/_includes/main/statuscafe.njk @@ -0,0 +1,39 @@ +
    +

    My Lastest Status Update

    +
    +
    + +
    + +

    View my statuses on status.cafe

    +
    + +{%- css %}#statuscafe-content { margin-bottom: 0.5em; }{% endcss %} + +{%- js %} +const statusCafeContent = document.getElementById("statuscafe-content"); +statusCafeContent.innerHTML = ` +

    Fetching data from status.cafe...

    +`; + +const fetchStatusCafe = async () => { + try { + const res = await fetch('https://status.cafe/users/leilukin/status.json'); + const data = await res.json(); + + if (!data.content.length) { + document.getElementById("statuscafe-content").innerHTML = "No status yet." + return; + } + + document.getElementById("statuscafe-userinfo").innerHTML = data.face + ' ' + data.timeAgo; + statusCafeContent.innerHTML = data.content; + } catch (error) { + console.error(error); + document.getElementById("statuscafe-content").textContent = `[ERROR] ${error}`; + } +}; +fetchStatusCafe(); +{% endjs %} diff --git a/src/_includes/main/support-me.njk b/src/_includes/main/support-me.njk new file mode 100644 index 00000000..231409fd --- /dev/null +++ b/src/_includes/main/support-me.njk @@ -0,0 +1,15 @@ +

    If you enjoy my work, you can support me on Ko-Fi.

    +
    + + Buy Me a Coffee at ko-fi.com +
    + +{%- css %} +.support-me { + display: flex; + flex-wrap: wrap; + gap: 1em; + align-items: center; + margin-top: 0.7em; +} +{% endcss %} diff --git a/src/_includes/main/webcliques.njk b/src/_includes/main/webcliques.njk new file mode 100644 index 00000000..a2953a70 --- /dev/null +++ b/src/_includes/main/webcliques.njk @@ -0,0 +1,56 @@ +{%- css %}.color-bg { padding: 0.125em 0.3em; }{% endcss %} + +{%- macro webCliqueImg(file, width, height, alt="") -%} +{{ alt }} +{%- endmacro -%} + + + +

    Pixel cliques I joined can be found on my Adoptables page.

    diff --git a/src/_includes/misc/404.njk b/src/_includes/misc/404.njk new file mode 100644 index 00000000..493fdc8b --- /dev/null +++ b/src/_includes/misc/404.njk @@ -0,0 +1,12 @@ +--- +layout: misc/base +title: "404: Page Not Found" +h1: "404: Page Not Found" +eleventyExcludeFromCollections: true +--- + +

    Oops! Either the page you are looking for does not exist, or it has been moved to a diffrent part of this site.

    + +
    + 🏠 Back to Home +
    \ No newline at end of file diff --git a/src/_includes/misc/base.njk b/src/_includes/misc/base.njk new file mode 100644 index 00000000..468c6de5 --- /dev/null +++ b/src/_includes/misc/base.njk @@ -0,0 +1,29 @@ + + + + + + + + {# Open Graph meta #} + + {% include "global/meta.njk" %} + + {# Feeds #} + {% include "global/feeds.njk" %} + + {# Style #} + {% include "global/fonts.njk" %} + + + {% if title %} {{ title }} | {% endif %} {{ sitemeta.siteName }} + + +
    + {{ sitemeta.siteName }} website banner +

    {{ h1 }}

    + + {{ content | safe }} +
    + + diff --git a/src/_includes/pokemonoras/base.njk b/src/_includes/pokemonoras/base.njk new file mode 100644 index 00000000..e53c5261 --- /dev/null +++ b/src/_includes/pokemonoras/base.njk @@ -0,0 +1,19 @@ +{%- css %}{% include "src/assets/css/pokemonoras.css" %}{%- endcss %} + +{% extends "global/baselayout.njk" %} + +{% block metaTitle %} + +{% endblock %} + +{% block pageTitle %} +{{ title + " | " if title }}Pokémon Omega Ruby and Alpha Sapphire Shrine | {{ sitemeta.siteName | safe }} +{% endblock %} + +{% block favicon %} + +{% endblock %} + +{% block hero %}{% include "pokemonoras/hero.njk" %}{% endblock %} +{% block navbar %}{% include "pokemonoras/navbar.njk" %}{% endblock %} +{% block footer %}{% include "pokemonoras/footer.njk" %}{% endblock %} diff --git a/src/_includes/pokemonoras/content.njk b/src/_includes/pokemonoras/content.njk new file mode 100644 index 00000000..913a7c50 --- /dev/null +++ b/src/_includes/pokemonoras/content.njk @@ -0,0 +1,7 @@ +--- +layout: pokemonoras/base +--- + +{% extends "global/content.njk" %} + +{% block shrineInfo %}{% include "pokemonoras/shrineinfo.njk" %}{% endblock %} \ No newline at end of file diff --git a/src/_includes/pokemonoras/footer.njk b/src/_includes/pokemonoras/footer.njk new file mode 100644 index 00000000..9254a355 --- /dev/null +++ b/src/_includes/pokemonoras/footer.njk @@ -0,0 +1,6 @@ +{% extends "global/footer.njk" %} + +{% block footerContent %} +

    Made with ♥ by {{ sitemeta.siteAuthor.name }} • Shrine Launched: 21 November 2024

    +{% endblock %} + diff --git a/src/_includes/pokemonoras/hero.njk b/src/_includes/pokemonoras/hero.njk new file mode 100644 index 00000000..82e06ca8 --- /dev/null +++ b/src/_includes/pokemonoras/hero.njk @@ -0,0 +1,34 @@ +{% extends "global/hero.njk" %} + +{% block heroImg %} + + + Banner of Pokémon Omega Ruby and Alpha Sapphire Shrine + +{% endblock %} + +{% block eventScript %} +const todayEvent = getTodayEvent(); + +if (todayEvent) { + heroTopBarEl.classList.remove('hidden'); + heroTopBarEl.innerHTML = todayEvent; +} + +function getTodayEvent() { + const date = new Date(); + const month = date.getMonth() + 1; + const day = date.getDate(); + const year = date.getFullYear(); + + const orasReleaseDate = new Date("2014-11-21").getFullYear(); + const orasAnniversary = year - orasReleaseDate; + + if (month === 11 && day === 21) + return ` + Today is the ${orasAnniversary}-year anniversary of the release of Pokémon Omega Ruby" and Alpha Sapphire! + `; + else + return null; +} +{% endblock %} diff --git a/src/_includes/pokemonoras/navbar.njk b/src/_includes/pokemonoras/navbar.njk new file mode 100644 index 00000000..2392998d --- /dev/null +++ b/src/_includes/pokemonoras/navbar.njk @@ -0,0 +1,11 @@ +{% extends "global/navbar.njk" %} +{% set shrineHomeUrl = "/shrines/pokemonoras/" %} + +{% block navbarLinks %} +{% set navPages = collections.all | eleventyNavigation("ORAS Shrine") %} +{%- for entry in navPages %} +
  29. + {{ entry.title }} +
  30. +{%- endfor %} +{% endblock %} diff --git a/src/_includes/pokemonoras/shrineinfo.njk b/src/_includes/pokemonoras/shrineinfo.njk new file mode 100644 index 00000000..4ae40c0a --- /dev/null +++ b/src/_includes/pokemonoras/shrineinfo.njk @@ -0,0 +1,10 @@ +{% extends "global/shrineinfo.njk" %} + +{% block shrineAbout %} +

    Welcome to {{ sitemeta.siteAuthor.name }}'s shrine for {% cite "Pokémon Omega Ruby and Alpha Sapphire" %}, remakes of the 2002 Game Boy Advance role-playing video games {% cite "Pokémon Ruby" %} and {% cite "Pokémon Sapphire" %}. The games are part of the sixth generation of the {% cite "Pokémon" %} main series of video games, developed by Game Freak and published by The Pokémon Company and Nintendo for the Nintendo 3DS.

    +{% endblock %} + +{% block shrineLinks %} +
  31. Bulbapedia
  32. +
  33. Pokémon Ruby, Sapphire, Omega Ruby and Alpha Sapphire fanlisting
  34. +{% endblock %} diff --git a/src/_includes/starwarskotor/base.njk b/src/_includes/starwarskotor/base.njk new file mode 100644 index 00000000..8045ec4a --- /dev/null +++ b/src/_includes/starwarskotor/base.njk @@ -0,0 +1,19 @@ +{%- css %}{% include "src/assets/css/starwarskotor.css" %}{%- endcss %} + +{% extends "global/baselayout.njk" %} + +{% block metaTitle %} + +{% endblock %} + +{% block pageTitle %} +{{ title + " | " if title }}Star Wars: Knights of the Old Republic Shrine | {{ sitemeta.siteName | safe }} +{% endblock %} + +{% block favicon %} + +{% endblock %} + +{% block hero %}{% include "starwarskotor/hero.njk" %}{% endblock %} +{% block navbar %}{% include "starwarskotor/navbar.njk" %}{% endblock %} +{% block footer %}{% include "starwarskotor/footer.njk" %}{% endblock %} diff --git a/src/_includes/starwarskotor/content.njk b/src/_includes/starwarskotor/content.njk new file mode 100644 index 00000000..d502e4c4 --- /dev/null +++ b/src/_includes/starwarskotor/content.njk @@ -0,0 +1,7 @@ +--- +layout: starwarskotor/base +--- + +{% extends "global/content.njk" %} + +{% block shrineInfo %}{% include "starwarskotor/shrineinfo.njk" %}{% endblock %} \ No newline at end of file diff --git a/src/_includes/starwarskotor/footer.njk b/src/_includes/starwarskotor/footer.njk new file mode 100644 index 00000000..6cf5e10b --- /dev/null +++ b/src/_includes/starwarskotor/footer.njk @@ -0,0 +1,6 @@ +{% extends "global/footer.njk" %} + +{% block footerContent %} +

    Made with ♥ and the Force by {{ sitemeta.siteAuthor.name }} • Shrine Launched: 17 February 2023

    +{% endblock %} + diff --git a/src/_includes/starwarskotor/hero.njk b/src/_includes/starwarskotor/hero.njk new file mode 100644 index 00000000..4f0f50f6 --- /dev/null +++ b/src/_includes/starwarskotor/hero.njk @@ -0,0 +1,40 @@ +{% extends "global/hero.njk" %} + +{% block heroImg %} + + + anner of Star Wars: Knights of the Old Republic Shrine + +{% endblock %} + +{% block eventScript %} +const todayEvent = getTodayEvent(); + +if (todayEvent) { + heroTopBarEl.classList.remove('hidden'); + heroTopBarEl.innerHTML = todayEvent; +} + +function getTodayEvent() { + const date = new Date(); + const month = date.getMonth() + 1; + const day = date.getDate(); + const year = date.getFullYear(); + + const kotor1ReleaseDate = new Date("2003-07-15").getFullYear(); + const kotor2ReleaseDate = new Date("2004-12-06").getFullYear(); + const kotor1Anniversary = year - kotor1ReleaseDate; + const kotor2Anniversary = year - kotor2ReleaseDate; + + if (month === 7 && day === 15) + return ` + Today is the ${kotor1Anniversary}-year anniversary of the release of Star Wars: Knihgts of the Old Republic + `; + else if (month === 12 && day === 6) + return ` + Today is the ${kotor2Anniversary}-year anniversary of the release of Star Wars: Knights of the Old Republic II — The Sith Lords + `; + else + return null; +} +{% endblock %} diff --git a/src/_includes/starwarskotor/modlist-info.md b/src/_includes/starwarskotor/modlist-info.md new file mode 100644 index 00000000..238e763e --- /dev/null +++ b/src/_includes/starwarskotor/modlist-info.md @@ -0,0 +1,67 @@ +{% set kotor2FullTitle %}{{ " II: The Sith Lords" if page.url.includes("kotor2") else ""}}{% endset %} +{% set kotor2ShortTitle %}{{ " 2" if page.url.includes("kotor2") else ""}}{% endset %} + +{% container "article", "content__section" %} +## Spoiler Warning + +WARNING: The full list of my mod build contains spoilers for Star Wars: Knights of the Old Republic{{ kotor2FullTitle }}! + +My mod build is not designed for new KotOR{{ kotor2ShortTitle }} players, so I will not censor any information that contains spoilers for the game. In general, I do not recommend using mods in your very first playthrough of any video game, so you can judge and choose which mods you want to use after finishing the game for the first time. The only exceptions are the [KotOR 1 Community Patch](https://deadlystream.com/files/file/1258-kotor-1-community-patch/) for {% cite "KotOR 1" %} and [The Sith Lords Restored Content Mod](https://deadlystream.com/files/file/578-tsl-restored-content-mod/) for KotOR{{ kotor2ShortTitle }}, which are absolutely essential mods that even if you want to use them in your first playthrough, you definitely have my support. + +If you are going to play KotOR{{ kotor2ShortTitle }} for the first time, and you do not mind using mods, I would suggest checking out the Spoiler-Free version of [KotOR Community Portal’s KotOR mod builds](https://kotor.neocities.org/modding/) instead. +{% endcontainer %} + +{% container "article", "content__section" %} +## Mod Categories + +The mods I included in my mod build are divided into the following categories, which clarifies the types of changes the mod makes: + +Added Content +: Added content is an entirely fan-made new content that is not intended in the vanilla game. + +Appearance Change +: Appearance change is not inherently graphics improvement, but rather a modification to the default appearance of a character, item, location, interface, etc. + +Bugfix +: As the name implies, this type of mod fixes bugs with the vanilla game. + +Graphics Improvement +: This type of mod improves the graphics in the vanilla game in some way, by retexturing and/or remodeling a character, item, location, etc. Usually these mods come with high-resolution textures. + +Immersion +: These mods are not inherently bugfixes, but changes done to improve the internal consistency of the game’s content. + +Mechanics Change +: This type of mod makes changes to the game’s system which directly impacts the way you play the game, varying from changing the camera angle of a location to altering the core stats of a class. + +Modified Content +: Modified content is not inherently new content, but rather alterations to the vanilla game’s content because the vanilla content has some shortcomings. The changes made by this kind of mod were never intended to be in the vanilla game. + +Patch +: A patch is a simple mod that changes the function of another mod, either by fixing bugs, resolving mod conflicts or altering content made by another mod. + +Restored Content +: This type of mod restores content that has been cut from the vanilla game. + +Sound Change +: As the name implies, these mods make changes to the sound in the vanilla game. The sound could be music or ambient audios. +{% endcontainer %} + +{% container "article", "content__section" %} +## Mod Tiers + +The tiers for each mod included in my mod build are not necessarily a judgement on the quality of the mods themselves. In my mod builds, mod tiers are ranked on a scale of 1-4, based on how important the individual mods are for my experience with the {% cite "KotOR" %} games. + +Tier 1 - Essential +: This tier indicates mods that I cannot play the {% cite "KotOR" %} games without. Usually this is because I find those mods make very crucial changes to the game, typically by fixing things that bother me the most in the vanilla game. Similarly, mods of the Patch category that belong to this tier make critical changes to other mods. I consider excluding Tier 1 mods will negatively affect my experience with the {% cite "KotOR" %} games. + +Tier 2 - Very Important +: This tier indicates mods that vastly improve my experience with the game. Mods belong to this tier are the bread and butter of my mod build. That said, unlike Tier 1 mods, excluding Tier 2 mods from my playthrough does not actively make my {% cite "KotOR" %} experience worse either. + +Tier 3 - Somewhat Important +: This tier indicates mods that make changes that are in smaller scope or more subjective compared to Tier 1 and Tier 2 mods. Usually this is because the changes made by Tier 3 mods are less noticeable or more of a matter of personal taste. + +Tier 4 - Optional +: This tier indicates mods that make even smaller or more subjective changes than Tier 3 mods, to the point that using these mods is optional. I include Tier 4 mods in my build for the purpose of maximizing my immersion, or because I use these mods for customization purposes for my characters. +{.deflist-1col} +{% endcontainer %} \ No newline at end of file diff --git a/src/_includes/starwarskotor/navbar.njk b/src/_includes/starwarskotor/navbar.njk new file mode 100644 index 00000000..83928c31 --- /dev/null +++ b/src/_includes/starwarskotor/navbar.njk @@ -0,0 +1,11 @@ +{% extends "global/navbar.njk" %} +{% set shrineHomeUrl = "/shrines/starwarskotor/" %} + +{% block navbarLinks %} +{% set navPages = collections.all | eleventyNavigation("KotOR Shrine") %} +{%- for entry in navPages %} +
  35. + {{ entry.title }} +
  36. +{%- endfor %} +{% endblock %} diff --git a/src/_includes/starwarskotor/shrineinfo.njk b/src/_includes/starwarskotor/shrineinfo.njk new file mode 100644 index 00000000..5edeadc5 --- /dev/null +++ b/src/_includes/starwarskotor/shrineinfo.njk @@ -0,0 +1,11 @@ +{% extends "global/shrineinfo.njk" %} + +{% block shrineAbout %} +

    Welcome to {{ sitemeta.siteAuthor.name }}'s shrine for {% cite "Star Wars: Knights of the Old Republic" %}, a series of role-playing video games set in the {% cite "Star Wars" %} universe, taking place almost 4,000 years before the events of the Skywalker film saga.

    +{% endblock %} + +{% block shrineLinks %} +
  37. KOTOR Community Portal
  38. +
  39. Star Wars: KotOR fanlisting
  40. +
  41. Star Wars: KotOR II fanlisting
  42. +{% endblock %} diff --git a/src/articles/articles.11tydata.js b/src/articles/articles.11tydata.js new file mode 100644 index 00000000..7dfcddea --- /dev/null +++ b/src/articles/articles.11tydata.js @@ -0,0 +1,13 @@ +export default { + tags: ["articles", "contents", "feed items"], + layout: "main/content", + permalink: "/articles/{{ page.fileSlug }}/", + isArticle: true, + eleventyComputed: { + title: (data) => `${data.articleTitle} | Articles`, + eleventyNavigation: { + key: (data) => data.articleTitle, + parent: "Articles" + } + } +} \ No newline at end of file diff --git a/src/articles/featured/featured.11tydata.js b/src/articles/featured/featured.11tydata.js new file mode 100644 index 00000000..e55943de --- /dev/null +++ b/src/articles/featured/featured.11tydata.js @@ -0,0 +1,3 @@ +export default { + tags: "featured articles" +} \ No newline at end of file diff --git a/src/articles/featured/kotor2-modder-interview-ars-technica.md b/src/articles/featured/kotor2-modder-interview-ars-technica.md new file mode 100644 index 00000000..5d203949 --- /dev/null +++ b/src/articles/featured/kotor2-modder-interview-ars-technica.md @@ -0,0 +1,23 @@ +--- +articleTitle: The modders who spent 15 years fixing Knights of the Old Republic 2 @ Ars Technica +date: 2022-09-11 +desc: Ars Technica's article on the KotOR 2's modding community to celebrate the game's 15th anniversary. I was interviewed for my same-gender romance mods for KotOR 2. +categories: ["my interviews", "star wars kotor 2", "video game mods"] +--- + +On 6 December 2019, to celebrate the 15th anniversary of {% cite "Star Wars: Knights of the Old Republic 2" %}, Ars Technica has published [an article about the modding community of KotOR 2](https://arstechnica.com/gaming/2019/12/the-modders-that-spent-15-years-fixing-knights-of-the-old-republic-2/). I was interviewed by the author of this article, Austin Taylor, for my same-gender romance mods for {% cite "KotOR 2" %}. + +> ### Romance? Yes, Please +> +> [Unlike the first KOTOR](https://starwars.fandom.com/wiki/Juhani), there are no same-gender romance options in Obsidian’s sequel. Leilukin, a modder on the Nexus Forums, has focused much of her modding work since 2016 on [fixing that oversight.](https://www.nexusmods.com/kotor2/videogamemods/927) +> +> “As much as I love KOTOR2, I have always been frustrated by the fact that the romance content with the companions and certain NPCs… are all heterosexual,” she said. +> +> Some of these fixes are relatively simple. In vanilla KOTOR2, for instance, only male characters can recruit The Handmaiden upon leaving Telos, while female characters are the only ones who can recruit The Disciple during the main quest on Dantooine. By default, Leiluken’s mod simply flips that gender check, so only male characters can recruit the Disciple and only females can recruit The Handmaiden. +> +> But Leiluken’s mod goes further than that. The most challenging part, she said, was finding every reference to the Exile’s gender throughout the game spoken by gender-specific party members, then “add\[ing\] extra dialogue that replaces the pronouns and splic\[ing\] voiceover files myself.” +> +> To recruit both The Handmaiden and The Disciple at the same time, players can install the [PartySwap mod by DarthTyren](https://deadlystream.com/files/file/544-partyswap/). That mod was initially lacking the same-gender romance dialogue from Leiluken’s mod. But Leiluken has since added a compatibility installation option, letting the two mods now work together and fully opening up the same-gender romance options of your dreams. + +Read the full article on Ars Technica here: +[The modders who spent 15 years fixing Knights of the Old Republic 2](https://arstechnica.com/gaming/2019/12/the-modders-that-spent-15-years-fixing-knights-of-the-old-republic-2/) \ No newline at end of file diff --git a/src/articles/featured/lgbtq-booklet-interview-misi-bawang.md b/src/articles/featured/lgbtq-booklet-interview-misi-bawang.md new file mode 100644 index 00000000..9ddea4da --- /dev/null +++ b/src/articles/featured/lgbtq-booklet-interview-misi-bawang.md @@ -0,0 +1,40 @@ +--- +articleTitle: "Floating in a Sky Full of Pride: LGBTQ+ Booklet Artist Interview from MISI:Bawang" +date: 2022-09-11 +desc: My submission for MISI:Bawang's booklet about LGBTQ+ Malaysians was accepted and published. Here is MISI:Bawang's interview with me regarding my work and my queer identity. +categories: ["my interviews", "lgbtq+", "malaysia", "a summer's end"] +--- + +

    (This article is also available on my art blog on Tumblr)

    + +[Floating in a Sky Full of Pride](https://bawangqueerbooklet.msolidariti.org/), the LGBTQ+ booklet of [MISI:Bawang](https://misibawang.msolidariti.org/), a Malaysian digital booklet project, has been released on Valentine’s Day 2022. Since my submitted art piece, Life of a Bee with Pride, has been selected to be included in the booklet, I had received the honour of being interviewed by MISI:Bawang to share my personal experience with my LGBTQ+ identity, favourite queer art/media, and a ✨ special message to the Malaysian LGBTQ+ community. 🏳‍🌈 + +![First slide of MISI:Bawang's interview with me for their LGBTQ+ booklet](/assets/images/articles/lgbtq-booklet-interview-misi-bawang/Bawang-Booklet-Interview-Leilukin-1.avif) + +![Second slide of MISI:Bawang's interview with me for their LGBTQ+ booklet](/assets/images/articles/lgbtq-booklet-interview-misi-bawang/Bawang-Booklet-Interview-Leilukin-2.avif) + +![Third slide of MISI:Bawang's interview with me for their LGBTQ+ booklet](/assets/images/articles/lgbtq-booklet-interview-misi-bawang/Bawang-Booklet-Interview-Leilukin-3.avif) + +MISI:Bawang has shared their interview with me and other Malaysian LGBTQ+ artists and authors who submitted their work to the booklet on Twitter and Instagram. Here are the [Twitter thread](https://twitter.com/misi_bawang/status/1470247663471763464) and [Instagram post](https://www.instagram.com/p/CXSlIbsJXsM/) that include my interview. + +Text version of my interview below: + +## **“What was your experience discovering your LGBTQ+ identity?”** + +> The first clear signs of my attraction to women I was aware of started from my secondary school days. However, due to lack of knowledge and awareness of same-gender attraction and identities, I brushed it off as a teenage phase. +> +> However, that changed as I started becoming active on Tumblr since I was 19. At first, I joined Tumblr to connect with people who share my interest in Star Wars and BioWare games. This led me to get to know LGBTQ+ from different parts of the world, which is especially helped by the fact that BioWare games are known for LGBTQ+ representation, therefore LGBTQ+ people are visible in BioWare player communities. This started my journey of questioning my sexuality and gender. +> +> As I continue to stay on Tumblr, my engagement with LGBTQ+ people on Tumblr had gone beyond shared interest in entertainment media. Through Tumblr, I discovered many LGBTQ+ resources that helped me figure out my identity. As a result, at the age of 22, I eventually realised that I am a non-binary lesbian. + +## **“Are there any LGBTQ+ related art (books, films, etc) that gives you comfort, inspiration, and strength? If so, tell us about them!”** + +> A Summer’s End - Hong Kong 1986 is the LGBTQ+ art that gives me comfort, inspiration and strength the most. It is an indie visual novel developed by the Asian Canadian studio Oracle and Bone. The story is about a lesbian romance that takes place in Hong Kong in the year of 1986. +> +> A Summer’s End is the LGBTQ+ art I relate to most because it strongly resonates with my identity as a Cantonese-speaking Chinese lesbian who has grown up with Hong Kong media. I relate to both the protagonists, Michelle and Sam, as their characters represent different parts of my life as a Chinese lesbian. I also relate to the story’s theme of hoping for the future of our homeland despite the political uncertainties. + +## **“Do you have a message to LGBTQ+ community living in Malaysia?”** + +> First and foremost, you are not alone. LGBTQ+ Malaysians have a community that continues to survive despite the hardship we have to face due to society’s bigotry and misunderstanding of LGBTQ+ people and identities. +> +> I hope the LGBTQ+ community in Malaysia will continue to grow and thrive, and more LGBTQ+ Malaysians who are still questioning and feeling lonely could be reached out. Let us work towards a future where we could live freely. \ No newline at end of file diff --git a/src/articles/myarticles/accessible-footnotes.md b/src/articles/myarticles/accessible-footnotes.md new file mode 100644 index 00000000..7becde19 --- /dev/null +++ b/src/articles/myarticles/accessible-footnotes.md @@ -0,0 +1,335 @@ +--- +articleTitle: How I (Tried to) Implement Accessible Footnotes +date: 2024-08-06T00:04:00+0800 +updated: 2024-12-03T23:51:27+0800 +desc: "How I implement accessible footnotes, at least to the best of my ability. Written for 32-Bit Cafe's Community Code Jam #5." +categories: ["32-bit cafe", "accessibility", "html", "css", "eleventy", "markdown-it"] +toc: true +hasCodeBlock: true +--- + +[![32-Bit Cafe "Back to School" Code Jam button](/assets/images/articles/accessible-footnotes/32bitcafe-backtoschool.png)](https://32bit.cafe/~xandra/events/codejam5/){.inline-img} +{.center-text} + +(32-Bit Cafe "Back to School" button made by [Loren](https://ribo.zone/)){.center-text} + +[32-Bit Cafe](https://32bit.cafe/) is holding its fifth community code jam, titled ["Back to School"](https://32bit.cafe/~xandra/events/codejam5/), from 4 to 17 August 2024. I have been looking forward to participating in 32-Bit Cafe's community code jam for the first time, so I am excited. This motivates me to finally write a how-to article I have been meaning to do for a while: how to implement accessible footnotes on Leilukin's Hub, or at least, I tried to do so to the best of my abilities. + +On [32-Bit Cafe's Discourse forum](https://discourse.32bit.cafe/), I made a [post on 28 June 2024](https://discourse.32bit.cafe/t/handling-citations-and-or-footnotes/1061/2?u=leilukin) in response to [solaria](https://solaria.neocities.org/)'s thread ["Handling Citations and/or Footnotes"](https://discourse.32bit.cafe/t/handling-citations-and-or-footnotes/1061) to share my methods of adding footnotes on my website. Now, I am writing an extended version of that post of mine in the form of this article, so I could share what I learned about web page footnotes on my website as well. + +(Note: This article assumes a foundational familiarity with HTML and CSS) + +## About Footnotes + +Plagiarism.org [defines footnotes](https://www.plagiarism.org/article/what-are-footnotes) as notes placed at the bottom of a page, and what footnotes do is to cite references or comment on a designated part of the text above it. + +My use case of footnotes is citing sources of information, particularly citing the same source multiple times on the same page when information from the same source is spread across my page. As of this writing, my website pages that use footnotes include the [trivia page of my {% cite "A Summer’s End — Hong Kong 1986" %} shrine 1](/shrines/asummersend/trivia/) and the [facts page of my {% cite "Cassette Beasts" %} shrine](/shrines/cassettebeasts/facts/). You are free to look at the HTML and CSS for reference. + +Footnotes are used both on print and on the web. However, maintaining footnotes on the web can be tedious, especially if you want to update a web page to add or remove them, since you will need to change the number references of existing footnotes. + +## Attempted to Use CSS Counters + +When I was searching for how to implement accessible footnotes, I discovered [Kitty Giraudel](https://kittygiraudel.com/)'s article, ["Accessible Footnotes with CSS"](https://www.sitepoint.com/accessible-footnotes-css/) which teaches the method of using the combination of HTML [`aria-describedby`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-describedby) attribute and [CSS counters](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_counter_styles/Using_CSS_counters) to add numbered references, to reduce the hassle of manually re-numbering all existing footnotes in case you want to update or reorder the references. + +Her article also teaches adding a highlight background colour when heading to a footnote from a reference, as well as providing back links to head back to a reference from a footnote, by using the combination of the backlink Unicode icon (↩) and the HTML `aria-label` attribute with a value of “Back to content”. The uses of ARIA labels make footnotes more screen reader-friendly. + +Furthermore, Kitty created the [eleventy-plugin-footnotes plugin](https://github.com/KittyGiraudel/eleventy-plugin-footnotes) for the static site generator [Eleventy](https://www.11ty.dev/), and wrote a blog post about it, ["Footnotes in 11ty"](https://kittygiraudel.com/2020/12/02/footnotes-in-11ty/). Since I already had begun to [use Eleventy to build my website](/blog/posts/2024-04-21-april-2024-leilukins-hub-overhaul-with-eleventy), I tried Kitty's plugin. + +Unfortunately, a known limitation of using CSS counter method to generate footnotes is [not being able to reference the same footnote multiple times](https://github.com/KittyGiraudel/eleventy-plugin-footnotes/issues/83). As I want to be able to reference the same footnote more than once when I am citing sources on my shrine pages, I had to give up the plugin and look for an alternative. + +## Starting with markdown-it-footnote Plugin's Default Footnote Markup + +Kitty Giraudel's blog post about creating footnotes in Eleventy mentioned [markdown-it-footnote](https://github.com/markdown-it/markdown-it-footnote), the footnotes plugin for [markdown-it](https://github.com/markdown-it/markdown-it) Markdown parser, which is integrated in Eleventy by default to convert Markdown to HTML. Kitty commented on the accessibility shortcomings of markdown-it-footnote in the blog post: + +> [...]it’s not super accessible (let alone by default), even considering all the customisation options. That’s because the footnote references end up being numbers (e.g. [1]) which are meaningless when listed or tabbed through because devoid of their surrounding context. + +That said, since the plugin is customisable, I still wanted to give it a shot to see if I could make configurations to improve its accessibility, so I installed markdown-it-footnote and looked into the plugin's default HTML markup output. + +Here is a sample of what the HTML markup output of markdown-it-footnote looks like: + +```html +

    This is a paragraph with the first footnote reference. [1]

    + +

    Here is the second paragraph with the second footnote reference. [2]

    + +

    This the third paragraph, but with a foootnote reference that points to the first footnote. [1:1]

    + +
    +
    +   
      +       
    1. First footnote ↩︎ ↩︎
    2. +       
    3. Second footnote ↩︎
    4. +   
    +
    +``` + +This is what this HTML markup will look like on a live web page: + +![Web page footnotes sample screenshot](/assets/images/articles/accessible-footnotes/footnote-sample.avif) + +What this HTML markup does: +- Adding a footnote reference as a superscript by using the [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sup) tag with numbers as the content. +- Using a `
    ` horizontal line element to separate the main body of the page and the footnote section; +- Using the `
      ` tag to render the footnotes as a numbered list; +- Each footnote list item has an `id` attribute +- If a footnote is referenced more than once, the additional footnote references are labelled with colons. + +(Note: the class names were added by markdown-it-footnote, but if you do not use it, you can rename the class name to whatever you want, and even if you use markdown-it-footnote, you can still change the class names if you want to go deep into it) + +Next step is trying to improve this HTML markup by making it accessible. + +## Make markdown-it-footnote's Markup More Accessible + +### Clarify Footnote Reference Labels + +As pointed out by Kitty Giraudel, labelling the footnote reference as mere numbers like [1] is an accessibility shortcoming, because these reference links become meaningless when being focused on by tabbing through the links, as these reference links would be devoid of context. + +What I did to tackle this was changing the reference labels by adding a word "Footnote" to clarify that these links are for footnotes. For example, [1] becomes [Footnote #1], so when screen readers focus on a footnote reference link, it will be read out as "Footnote number one link". +```html + + [1] + +``` + +Optionally, if you want your footnote labels to still display only numbers on screen, you can use a CSS class to [visually hide](https://www.a11yproject.com/posts/how-to-hide-content/) the extra characters in the footnote label. This `.visually-hidden` utility class is a useful tool in your arsenal for accessible web design, as it is often used to hide a content that you do not mean to show on screen, but you still want it to be read by assistive technology. + +```css +.visually-hidden { +    clip: rect(0 0 0 0); +    clip-path: inset(50%); +    height: 1px; +    overflow: hidden; +    position: absolute; +    white-space: nowrap; +    width: 1px; +} +``` + +To make my footnote reference labels display only a number on screen, I use a `span` tag with `visually-hidden` as the value of the `class` attribute to wrap around "Footnote #", so on screen, [Footnote #1] is changed to [1]. + +```html + + + [Footnote #1] + + +``` + +### Add ARIA Label to Footnote Back Links + +Next step is adding an ARIA label to the footnote backlinks, by adding an `aria-label` attribute with "Back to reference #[Insert reference number]" as its value. For example: + +```html +↩︎ +``` + +When a footnote back link is focused on via tabbing, screen readers will read it out as "Back to reference number one link". + +### Add Heading to Footnote Section + +To make it clear that the section is for footnotes, I add a HTML heading before the list of footnotes, such as: +```html +

      Footnotes

      +``` + +## Final HTML Markup for Accessible Footnotes + +Here is my final HTML markup sample to create accessible footnotes: + +```html +

      This is a paragraph with the first footnote reference. [Footnote #1]

      + +

      Here is the second paragraph with the second footnote reference. [Footnote #2]

      + +

      This the third paragraph, but with a foootnote reference that points to the first footnote. [Footnote #1:1]

      + +
      +
      +

      Footnotes

      +   
        +       
      1. +         First footnote +         ↩︎ +         ↩︎ +    
      2. +       
      3. +         Second footnote +         ↩︎ +    
      4. +   
      +
      +``` + +As for the CSS, in addition to using the `.visually-hidden` utility class, I refer to Kitty Giraudel's ["Accessible Footnotes with CSS"](https://www.sitepoint.com/accessible-footnotes-css/) article to style the highlight background color when heading to a footnote from a reference. + +## Configure markdown-it-footnote in Eleventy's Configuration File + +(If you do not use Eleventy, you may skip this section) + +My final step was to configure the markdown-it-footnote plugin, by editing Eleventy's configuration file (I named mine `eleventy.config.js`), so the plugin would render my accessible footnote HTML markup. + +```js +// markdown-it plugins +const markdownIt = require("markdown-it"); +const markdownItFootnote = require("markdown-it-footnote"); +let markdownLibrary; + +module.exports = function (eleventyConfig) { + /* Markdown Overrides */ + markdownLibrary = markdownIt({ + html: true, + }).use(markdownItFootnote); + + // Configure markdown-it-footnote + markdownLibrary.renderer.rules.footnote_block_open = () => ( + '
      \n' + + '
      \n' + + `

      Footnotes

      \n` + ); + + markdownLibrary.renderer.rules.footnote_anchor = (tokens, idx, options, env, slf) => { + let id = slf.rules.footnote_anchor_name(tokens, idx, options, env, slf); + + if (tokens[idx].meta.subId > 0) id += `:${tokens[idx].meta.subId}`; + + /* ↩ with escape code to prevent display as Apple Emoji on iOS */ + return ` \u21a9\uFE0E`; + }; + + const renderRules = { + footnote_caption: ['[', '[Footnote #'], + }; + Object.keys(renderRules).map(rule => { + let defaultRender = markdownLibrary.renderer.rules[rule]; + markdownLibrary.renderer.rules[rule] = (tokens, idx, options, env, self) => { + return defaultRender(tokens, idx, options, env, self).replace(...renderRules[rule]); + } + }); + + /* This is the part that tells 11ty to swap to our custom config */ + eleventyConfig.setLibrary("md", markdownLibrary); +} +``` + +If you are a fellow Eleventy user, feel free to borrow my markdown-it-footnote configurations in your own. Make sure you install markdown-it-footnote first by keying in the installation command in the terminal: + +```powershell +npm install markdown-it-footnote --save +``` + +## Bonus: Alternatives to Footnotes + +As you likely have realised, footnotes are really tricky to implement on web pages, so you may be wondering: is there any alternative to footnotes? + +For extra comments and tangents, by favourite approach is using HTML's details disclosure element with the `
      ` tag, with a [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/summary) element and a sibling element wrapping the content displayed when the disclosure is expanded. + +I have been using the disclosure element for additional comments or information on this website, like in my blog post, ["My Cassette Beasts Fanlisting Application has been Approved"](/blog/posts/2024-06-24-cassette-beasts-fanlisting-approved/). As for the styling, initially I indented the content inside the disclosure to differentiate the disclosure content from the rest of the content of the page, but recently I switched to adding borders to the content after being inspired by [Starbreaker](https://starbreaker.org/)'s website, who also has a post about footnotes, ["Footnotes: No Fun to Create, Either"](https://starbreaker.org/blog/tech/footnotes-no-fun-to-create-either/index.html). + +{% disclosure "More ways to use `
      ` and `` elements" %} +`
      ` and `` have become among my favourite HTML elements due to how useful they are. In addition to extra comments and info, Leilukin's Hub has also used the elements for the following purposes: +- Table of contents, like the one this very article has +- Hiding spoilers, like in my {% cite "Cassette Beasts" %} shrine article, ["How Cassette Beasts is Much More than a Pokémon Clone"](/shrines/cassettebeasts/articles/cassette-beasts-more-than-a-pokemon-clone/) +- Content warnings, like in my [{% cite "A Summer’s End — Hong Kong 1986" %} shrine's gallery page](/shrines/asummersend/gallery/), with its styling being inspired by another Kitty Giraudel's blog post, ["A content warning component"](https://kittygiraudel.com/2022/09/04/a-content-warning-component/) +{% enddisclosure %} + +As for citing sources, the simplest way would be naming and linking to the source in the main text of your page, though it does mean you may end up repeating the title of the source if you want to attribute to it more than once on your page. This was once the approach of my shrine pages, though I found the pages looked rather cluttered, so I eventually chose to use markdown-it-footnote alongside Eleventy. + +## Wrapping Up + +Creating and maintaining footnotes on web pages is tricky, so I hope my article about accessible footnotes is helpful if you want to create them. + +I am still not completely certain if my method is the best, although I tried to the best of my abilities, so I am interested in hearing feedback for my way of implementing accessible footnotes. + +## Update 3 December 2024: Enlarge Link Target Area + +On 3 December 2024, [~hedy](https://home.hedy.dev/) emailed me talking about this article, offering additional tips for improving footnotes. She also recommended me to check out [Seirdy](https://seirdy.one/)'s blog as a reference for formatting footnotes. + +I found ~hedy's suggestions good, so I made further improvements to my footnotes, by enlarging the target area of links. To achieve this, I changed the reference labels and footnote backlinks by using visible longer link text instead of ARIA labels. + +Specifically, for reference labels, I now use "[Note 1]" instead of just a number like "[1]", while for footnote backlinks, I use "↩︎ Back to reference 1" instead of just a ↩︎ symbol. + +In addition, I wrap each footnote backlink in a paragraph element (`

      `), to place each backlink per line to improve footnotes' readability. + +Larger link target area is even better because mobile device users would find it easier to tap on the reference links and the footnote backlinks, and sighted visitors on desktop are also benefited because they can see the purpose of these links on plain slight. + +### Updated HTML Markup + +Here is an example of how the final HTML markup would look like with larger link target area: + +```html +

      This is a paragraph with the first footnote reference. [Note 1]

      + +

      Here is the second paragraph with the second footnote reference. [Note 2]

      + +

      This the third paragraph, but with a foootnote reference that points to the first footnote. [Note 1:1]

      + +
      +
      +

      Footnotes

      +   
        +       
      1. +         First footnote +        

        ↩︎ Back to reference 1

        +        

        ↩︎ Back to reference 1:1

        +    
      2. +       
      3. +         Second footnote +        

        ↩︎ Back to reference 2

        +    
      4. +   
      +
      +``` + +### Updated markdown-it-footnotes Configuration + +Here is the code of the configuration for the markdown-it-footnotes plugin: + +```js +// markdown-it plugins +const markdownIt = require("markdown-it"); +const markdownItFootnote = require("markdown-it-footnote"); +let markdownLibrary; + +module.exports = function (eleventyConfig) { + /* Markdown Overrides */ + markdownLibrary = markdownIt({ + html: true, + }).use(markdownItFootnote); + + // Configure markdown-it-footnote + markdownLibrary.renderer.rules.footnote_block_open = () => ( + '
      \n' + + '
      \n' + + `

      Footnotes

      \n` + ); + + markdownLibrary.renderer.rules.footnote_anchor = (tokens, idx, options, env, slf) => { + let id = slf.rules.footnote_anchor_name(tokens, idx, options, env, slf); + + if (tokens[idx].meta.subId > 0) id += `:${tokens[idx].meta.subId}`; + + /* ↩ with escape code to prevent display as Apple Emoji on iOS */ + return ` +

      + + + Back to reference ${id} + +

      + `; + }; + + const renderRules = { + footnote_caption: ['[', '[Note '], + }; + Object.keys(renderRules).map(rule => { + let defaultRender = markdownLibrary.renderer.rules[rule]; + markdownLibrary.renderer.rules[rule] = (tokens, idx, options, env, self) => { + return defaultRender(tokens, idx, options, env, self).replace(...renderRules[rule]); + } + }); + + /* This is the part that tells 11ty to swap to our custom config */ + eleventyConfig.setLibrary("md", markdownLibrary); +} +``` \ No newline at end of file diff --git a/src/articles/myarticles/anti-harry-potter-jk-rowling-masterlist.md b/src/articles/myarticles/anti-harry-potter-jk-rowling-masterlist.md new file mode 100644 index 00000000..6655a160 --- /dev/null +++ b/src/articles/myarticles/anti-harry-potter-jk-rowling-masterlist.md @@ -0,0 +1,58 @@ +--- +articleTitle: Anti-Harry Potter and Anti-J. K. Rowling Masterlist +date: 2023-03-19 +updated: 2025-03-05T07:43:53+0800 +desc: My masterlist of criticisms of the Harry Potter series and J. K. Rowling. +categories: ["harry potter", "jk rowling"] +toc: true +--- + +{% imgFigure "/assets/banners/harry-potter-free-site.png", "An anime girl crossing arms with a sidelong look and a Harry Potter-free message" %} +This site is Harry Potter free. Lookin [sic] for it? Leave. +{% endimgFigure %} + +(Credit to Tumblr user [comradesaucegay](https://comradesaucegay.tumblr.com/post/621403039459426304) ([archived](https://web.archive.org/web/20241122135107/https://comradesaucegay.tumblr.com/post/621403039459426304/grumpsaesthetics-you-know-those-old-hentai-free)) for this Harry Potter-free website banner){.center-text} + +Like many Millennials, I grew up with the {% cite "Harry Potter" %} series and was a major fan of the series. I had read the original 7 books and watched their film adaptations. The series was a passion of mine during my early- to mid-teen years. While the {% cite "Harry Potter" %} novels were far from the first books I read, they were the first fantasy novels I read, and the series’ concept of a magical world set in a contemporary setting fascinated teenage me. + +However, even during my {% cite "Harry Potter" %} fixation years, there were things from the series that bothered me, from the idea of house elves being a slave race that naturally love being slaves, to Snape’s unconvincing “redemption” arc. As I got older and became more aware of social issues, I started to notice more problems with the series. In addition, reading more books has also made me realise that even on a technical writing level, the {% cite "Harry Potter" %} series was mediocre at best. As a result, I had stopped becoming a {% cite "Harry Potter" %} fan even before J. K. Rowling’s anti-trans sentiments got mainstream attention. + +Unfortunately, many adults with nostalgia goggles still refuse to let go of {% cite "Harry Potter" %}, and they believe {% cite "Harry Potter" %} can be separated or “reclaimed” by J. K. Rowling, despite how much Rowling’s worldview and prejudice are inextricably linked to her writing. + +Therefore, I am compiling this masterlist by curating various materials that are critical of the {% cite "Harry Potter" %} series and J. K. Rowling. Items are ordered in chronological order. This is far from a comprehensive list of all the pieces that criticise {% cite "Harry Potter" %} and Rowling; this list is my curated list of ones that I have read, watched or listened to, and I personally endorse. + +## Articles + +* [Harry Potter and the Universal Declaration of Human Rights](https://alinautrata.medium.com/all-the-things-that-are-fucked-up-about-harry-potter-58267e1bf3ee) by Alina Utrata (28 October 2016) +* [Addressing The Claims In JK Rowling’s Justification For Transphobia](https://katymontgomerie.medium.com/addressing-the-claims-in-jk-rowlings-justification-for-transphobia-7b6f761e8f8f) by Katy Montgomerie (16 June 2020) +* [The Antisemitism of ‘Harry Potter’ Returns in ‘Hogwarts Legacy’](https://www.themarysue.com/is-hogwarts-legacy-anti-semitic-hogwarts-legacy-anti-semitic-allegations-explained/) by Jack Doyle (8 February 2023) +* [Hogwarts Legacy wants to make everyone happy, but Harry Potter gets in the way](https://www.polygon.com/reviews/23603142/hogwarts-legacy-review-harry-potter-jk-rowling-transphobic-ps5-pc-xbox) by by Gita Jackson (17 February 2023) +* [Is J.K. Rowling transphobic? Let’s let her speak for herself.](https://www.vox.com/culture/23622610/jk-rowling-transphobic-statements-timeline-history-controversy) by Aja Romano (3 March 2023) +* [Talking Shit About Harry Potter](https://starbreaker.org/blog/entertainment/talking-shit-about-harry-potter/index.html) by Matthew Graybosch (19 June 2024) + + This post was in fact prompted by this very masterlist and our email exchange about the topic.{.item-list__indent} + +## Videos + +* [Harry Potter is GARBAGE, and Here's Why](https://www.youtube.com/watch?v=wPwWb9z3XSY) by satenmadpun (25 August 2020) +* [We need to talk about Dudley Dursley- Harry Potter and Fatphobia](https://www.youtube.com/watch?v=4AziZgoi3q0) by Ok2BeFat (30 May 2021) +* [Harry Potter](https://www.youtube.com/watch?v=-1iaJWSwUZs) by Shaun (4 March 2022) +* [JK Rowling's New Friends](https://www.youtube.com/watch?v=Ou_xvXJJk7k) by Shaun (14 October 2022) +* [Is Harry Potter Bad?](https://www.youtube.com/watch?v=U3dE0sYZqvI) by hoots (30 December 2022) +* [The Consumerist Dystopia of Harry Potter](https://www.youtube.com/watch?v=UBftW7FzOVI) by verilybitchie (21 January 2023) +* [Explaining JK Rowling’s Transphobia](https://www.youtube.com/watch?v=_GBUArD51KY) by Jessie Gender (27 January 2023) +* [Hogwarts Legacy and the Politics of Potter](https://www.youtube.com/watch?v=K1mHwn6eUUk) by Wisecrack (11 February 2023) +* [Hogwarts: A Legacy Of Hate (The Jimquisition)](https://www.youtube.com/watch?v=uNKyQVsgKLg) by James Stephanie Sterling (13 February 2023) +* [The ALLEGED Witch Trials of J.K. Rowling (What The Megan Phelps Podcast Won't Tell You)](https://www.youtube.com/watch?v=9ncYTEY7aVk) by Caelan Conrad (18 March 2023) +* [The Harry Potter Villains Were Trans?](https://www.youtube.com/watch?v=7xJF4XYarzI) by Brigitte Empire (3 April 2023) +* [Maybe The Wizard Game Just Wasn't Very Good (The Jimquisition)](https://www.youtube.com/watch?v=2pggtSI_95A) by James Stephanie Sterling (20 November 2023) +* [J.K. Rowling & Holocaust Denial](https://www.youtube.com/watch?v=whJJGqVtkEk) by Caelan Conrad (16 March 2024) +* [Did J.K. Rowling STEAL Harry Potter (Rip-off? Plagiarism?!)](https://www.youtube.com/watch?v=Cmx_YSPcujE) by Caelan Conrad (3 June 2024) +* [Harry Potter is Also Ableist](https://www.youtube.com/watch?v=oYgFHBXyVE4) by Ember Green (9 December 2024) +* [J. K. Rowling: The Real Story](https://www.youtube.com/watch?v=NeFUqCrmPC0) by Caelan Conrad (4 March 2025) + +## Podcasts + +* [The Shrieking Shack](https://soundcloud.com/shriekingshack), hosted by Xeecee and Liz + + A book reading podcast that originally started out as a {% cite "Harry Potter" %} reread podcast made by and for lapsed fans that goes through every chapter of the {% cite "Harry Potter" %} books and their film adaptations and analyses the writing and politics of the series and J. K. Rowling.{.item-list__indent} \ No newline at end of file diff --git a/src/articles/myarticles/designated-lesbian-syndrome-fandom.md b/src/articles/myarticles/designated-lesbian-syndrome-fandom.md new file mode 100644 index 00000000..fb599ae7 --- /dev/null +++ b/src/articles/myarticles/designated-lesbian-syndrome-fandom.md @@ -0,0 +1,26 @@ +--- +articleTitle: Designated Lesbian Syndrome in Fandom +date: 2023-08-18 +desc: On fandom's tokenisation of lesbians, and how I hate it as a lesbian myself. +categories: ["fandom culture"] +--- + +Over the years of interacting with and observing fandom, I have come to [dislike fandom and shipping culture](../my-dislike-of-shipping-culture) for many reasons. One major reason I want to talk about here is the "Designated Lesbian Syndrome" phenomenon. + +I first encountered this term from [Tumblr user desolationlesbian's post](https://desolationlesbian.tumblr.com/post/662432767484870656/designated-lesbian-syndrome-n-when-fans-of-a): + +> Designated Lesbian Syndrome (n.): When fans of a piece of media pick two female characters and pair them together as the token F/F ship and put them in everything, but do not bother to engage with their dynamic in any way more substantive than having them hold hands in the background. Everyone agrees it’s a good ship and it has nothing but their full support, yet this never materializes into real effort or content creation. +> +> Most common with works that have little-to-no narratively important women, but in rare cases can even happen to major and complex characters who are then reduced to token background lesbians as everyone hones in on the boys. + +The example I am most familiar with is the fandom of Grand Admiral Thrawn and the Chiss from {% cite "Star Wars" %} — specifically, some shippers of Thrawn/Eli Vanto, also known as Thranto, pair Ar'alani and Karyn Faro as their token "pair-the-spares" femslash ship. However, while Thranto shippers have create fan content about the Ar'alani/Karyn Faro ship, they do not do it with even a fraction of the interest and enthusiasm as they do Thranto. This is evident in the difference between the amount of fan works these two pairings have received on Archive On Our Own (AO3): as of this writing, the [Thrawn | Mitth'raw'nuruodo/Eli Vanto](https://archiveofourown.org/tags/Thrawn%20%7C%20Mitth'raw'nuruodo*s*Eli%20Vanto/works) tag contains 1,358 works, while the [Ar'alani/Karyn Faro](https://archiveofourown.org/tags/Ar'alani*s*Karyn%20Faro/works) tag contains 34 works only. It is also worth noting that if you use the tag page's filter function, you will notice that out of these 34 Ar'alani/Faro works, 23 of them are also tagged with Thrawn/Eli Vanto, proving the significant overlap between Thranto and Ar'alani/Faro shippers. + +Part of the Designated Lesbian Syndrome also involves shippers headcanonning the female characters who could be considered "threats" to their favourite ship that involved male characters as lesbians. It does not matter if the female characters are actually romantically involved with the male characters' in the source material or not. Thrawn never has a canon love interest in both Legends and the Disney continuities, but the fact that Ar'alani and Faro are close to Thrawn as his long-time friend and protégée respectively is enough to make them the go-to candidates for lesbian headcanons from shippers who ship Thrawn with anyone else. Lesbian Ar'alani and Faro headcanons are most common among Thrawn/Eli shippers, but I had seen at least one Thrawn/Governor Pryce (a pairing that I cannot stand at all) shipper literally headcanons Ar'alani as a lesbian so Pryce does not need to worry about Ar'alani fighting with Pryce over Thrawn. + +Ar'alani and Karyn Faro are unfortunately perfect examples of the above post by desolationlesbian of major female characters who are reduced to token background lesbians by shippers. As a huge fan of both Ar'alani and Faro as characters, I find it immensely frustrating, to the extent that the Thrawn shipping fandom has utterly turned me off on both Thranto and Ar'alani/Faro ships. + +As a lesbian myself, I loathe the Designated Lesbian Syndrome with a passion, because this phenomenon is literally tokenism, specifically tokenisation of lesbians. As a consequence, I have reached the point where when it comes to fandoms with big Male/Male (M/M) ships that are not canon, I only trust lesbian headcanons from fellow lesbians. Yes, this means I do not trust lesbian Ar'alani and Karyn Faro headcanons from people who are not lesbians. + +I really hate that it comes to this because as a lesbian, in theory I am in favour of lesbian headcanons for female characters who are cishet-coded or who do not have a canon sexuality. Unfortunately, lesbian headcanons have been used as a progressive way to get female characters out of the way of Male/Male ships (and occasionally Male/Female ships as well, though this phenomenon is more common in fandoms of M/M ships), not because these shippers actually care about lesbians and the female characters. + +These shippers rarely put as much energy in talking about or creating fan content for the female characters they headcanon as lesbians as they do the male characters from their ships. These shippers can pretend they care about lesbians all they want, but my lesbian ass can see through their performative bullshit, and recognise their lesbian headcanons are nothing more than tokenism. diff --git a/src/articles/myarticles/living-with-retinitis-pigmentosa.md b/src/articles/myarticles/living-with-retinitis-pigmentosa.md new file mode 100644 index 00000000..fd55824c --- /dev/null +++ b/src/articles/myarticles/living-with-retinitis-pigmentosa.md @@ -0,0 +1,26 @@ +--- +articleTitle: Living with Retinitis Pigmentosa +date: 2024-12-15T13:14:07+0800 +desc: I talk about being visually impaired, particularly with a genetic eye disease that causes gradual vision loss and currently has no cure. +categories: ["personal life", "disability", "retinitis pigmentosa"] +--- + +On 30 November 2024, I was diagnosed with retinitis pigmentosa (RP) after seeing an eye doctor. + +My feelings after learning that I have this genetic eye disease that causes gradual vision loss and currently has no cure was more relieved than upset, because I was relieved that to have finally understood the reason behind a lot of the difficulties in my daily life as I grew older, in addition to my autism. + +Furthermore, my parents and I already suspected that I have inherited an eye condition that causes visual impairment after learning that some of my relatives on my father's side are starting to have eyesight problems. Therefore, I have accepted the possibility that I might have some incurable eye condition even before my official RP diagnosis. I had relied on glasses throughout most of my life due to having myopia and astigmatism, so I was already not new to vision conditions. + +In retrospect, my RP symptoms started to manifest to the point of impacting my daily life in my early 20s. I started to bump into things more often when I walk. My eyes got more sensitive to bright light, including sunlight, to the extent that I found it difficult to see things under sunlight and thus needing sunglasses. My subconscious began to get afraid of falling, causing me to get much more cautious when I walk, especially when walking on steps and crossing over drains, especially in places I was not familiar with. I also had a hard time seeing things not directly in front of me without turning my head. + +For a while, my parents and I thought this was because of my autism, as it makes me find it difficult to multitask, including paying attention to all my surroundings at once outside, and me spending too much time sitting in front of a computer, especially since my jobs have all involved a large amount of computer usage, and thus getting less physical exercise. However, now that I was diagnosed with RP, things finally clicked into place: turns out, my peripheral vision had started to get weaker, and my eyes became more sensitive to bright light, including sunlight. In addition, my eye doctor discovered that I am having a mild cataract as a complication of RP. + +Since there is currently no cure for RP, the best I can do is to take care of my remaining vision as much as I can, mainly by continuing to wear sunglasses every time I go out in daytime to protect my eyes from sunlight. I am also adjusting my habits of using digital devices, by making the font sizes of my devices larger to make things more comfortable for me to read and trying to take regular breaks from digital screens. + +Being diagnosed with a genetic eye disease that can cause vision loss also made me glad that I have started to learn to use screen readers. Even before my diagnosis, I have been using screen readers such as NVDA on Windows and TalkBack on Android to test website accessibility, including my own websites. It is a good idea to prepare myself for the possibility of losing enough vision to the degree of needing low vision aid and assistive technologies. In fact, since I was diagnosed with RP through a dilated eye exam, I was unable to see things clearly for about 12 hours after receiving the eye drop that dilated my eyes, so for the immediate couple of hours after seeing my eye doctor, I needed to activate TalkBack to be able to read things on my Android phone. Furthermore, I am also planning on learning braille. + +I do not write this article to ask for pity. I have accepted that I am visually impaired and autistic, and my disabilities are a huge part of who I am, as much as being a non-binary lesbian on the asexual and aromantic spectrum. Instead, I am sharing my story to let other people who have similar conditions that they are not alone, and we are worthy. + +I coded a [responsive Disability Pride flag in CSS](/projects/snippets/disability-pride-flag-background) during the Disability Pride Month in July (which is also my birth month) 2024, so it would be fitting to conclude this article with this Pride flag I coded. + + \ No newline at end of file diff --git a/src/articles/myarticles/love-letter-to-myself.md b/src/articles/myarticles/love-letter-to-myself.md new file mode 100644 index 00000000..052cf16c --- /dev/null +++ b/src/articles/myarticles/love-letter-to-myself.md @@ -0,0 +1,40 @@ +--- +articleTitle: A Love Letter to Myself +date: 2025-02-10T20:31:26+0800 +desc: I decided to take the opportunity of 32-Bit Cafe's 2025 Valentine's Day code jam to write a love letter to myself. +categories: ["personal life"] +--- + +[![I am my own Valentine! - 32-Bit Cafe "Party for One" Code Jam button](/assets/images/articles/love-letter-to-myself/32bitcafe-partyforone.png)](https://32bit.cafe/vday25/){.inline-img} +{.center-text} + +[32-Bit Cafe](https://32bit.cafe/) is hosting a code jam for Valentine's Day 2025, titled ["Party for One"](https://32bit.cafe/vday25/), as the theme is making a digital Valentine's Day gift dedicated to yourself. After much consideration, I decided to take this opportunity to write a love letter to myself, as a Valentine's Day gift to myself and a reminder of my self-worth. + +--- + +Dear Leilukin, + +You and I go way back to the beginning of your life, and we have stuck with each other through thick and thin. There is so much I want to tell you, and I hope by writing this letter, you will appreciate how much I cherish, admire and respect you. + +You have come a long way since your childhood and adolescence. You have grown from an insecure child with low self-esteem after enduring years of bullying at school, desperate for external validation and other people's approval, to an adult who takes pride in who they are and does not care about what others think of them. Therefore, it is unsurprising that you said that while adulthood certainly has its challenges, you do not miss being a child or teenager, and you actually enjoy being an adult. + +I know very well that your self-confidence did not come easy, and it did not happen overnight either. After being traumatised by years-long abuse from a secondary school bully and later a personal betrayal from someone who sided with said bully, whom you thought was your friend, you went on to struggled with trust issues and lack of faith in yourself throughout your early adulthood, even though you never met those people who hurt you the most again, until you attended therapy when you were approaching your late 20s. With your therapist's help, you learned that life is like a train, with the people you have met in your life as your passengers, and after the people who hurt you and vandalised your train left, you can choose to redecorate your train and welcome new people in your life who would treat you better. Learning this metaphor was what finally made you learn that it is not worth letting the people who hurt you to continue to define your life. + +I am proud of you for figuring out you are a queer, autistic, non-binary lesbian on the asexual and aromantic spectrum as an adult, despite the lack of queer and autistic resources and media representation when you grew up. It is fortunate that you encountered online queer and autistic communities and resources that helped you figure yourself out, but at the end of the day, it was you who decided to take active steps in understanding yourself better, so you know how to live your life better, and to not be afraid to be different. When you were a kid, fellow students in school had bullied you for being a socially awkward and friendless "weird" kid, but normality is a social construct, so your worth as a person is not determined by how "normal" you are perceived by others. You are unique, and your uniqueness is worth celebrating. You do not need to rely on someone else for your happiness, either. + +The self-worth you spent years in building up has also given you the strength to accept your [retinitis pigmentosa diagnosis](living-with-retinitis-pigmentosa.md), as you understand that the possibility of losing sight is not the end of the world. Queer and disability pride in the face of a cisheternormative and ableist society is an act of rebellion. Being a non-binary lesbian who refuses to conform to traditional gender roles is also a defiance to a patriarchy. + +Learning to look after your well-being and to set boundaries are crucial for a happy and fulfilling life, so I applaud you for making decisions out of consideration for your well-being, including: + +- Going to therapy to improve your mental health; +- Leaving an openly anti-gay church to join a queer-affirming one; +- Switching your career path to web development, a field you actually feel confident and interested in doing, after being burned out from graphic design as a profession; +- Seeing an eye doctor to get diagnosed with your eye problems; +- [Quitting your first web developer job](/blog/posts/2024-12-16-leaving-my-first-developer-job) when it is clear that your web developer skills were not valued by your employers enough, and the job will likely make you more miserable in the long run if you stayed. + +Furthermore, I admire your spirit of treating learning as a lifelong process, and understanding the importance of thinking for yourself, by keeping yourself curious and not being afraid of learning new things, while remaining true to yourself, by standing firm with your convictions to be kind and striving to be authentic. + +Together we will live the best life we can possibly have. No matter what happens, I will always love you. + +Love,
      +Me \ No newline at end of file diff --git a/src/articles/myarticles/my-dislike-of-shipping-culture.md b/src/articles/myarticles/my-dislike-of-shipping-culture.md new file mode 100644 index 00000000..0bfc9c57 --- /dev/null +++ b/src/articles/myarticles/my-dislike-of-shipping-culture.md @@ -0,0 +1,19 @@ +--- +articleTitle: My Disinterest in Shipping and Dislike of Shipping Culture +date: 2023-08-14 +desc: About my lack of interest in shipping and dislike of shipping culture in fandom, and why. +categories: ["fandom culture"] +--- + +*(Note: The original version of this writing was posted on my Tumblr blog on 3 May 2021)* +{.center-text} + +I feel that the older I get, the less interested I am in shipping in general, and the less I can understand grown adults in late 20s or older who build their personality around shipping and cannot engage with any fiction without shipping something (before I remade my Tumblr account in 2015, I used to follow a 30-something-year-old fandom blogger who was literally like this). + +I have also come to actually dislike shipping culture, especially the mindset of engaging with media primarily through a shipping lens at the expense of the characterisation, non-romantic relationships, themes, and general content of a piece of media. Throughout my years of experience with various fandoms, I have witnessed so many incredible characters and non-romantic relationships get ignored or underappreciated by the fandom because they’re not part of a popular ship. On the other hand, there are also many amazing characters get mischaracterised to make a fanon ship work, or get reduced to a handful of tropes as shippers Flanderise them in their shipping fan works. + +Do not even get me started on the shippers who will complain about not being able to enjoy a piece of media just because “there’s no couple to ship”. For example, I’ve literally seen people on Tumblr make such complaints about the film {% cite "Parasite" %}, as if a profound piece of art that brutally critiques the class system does not matter if it does not provide any shipping material. It’s honestly very infuriating to see shippers like these are so willing to ignore art with meaningful story, characters and themes just because it lacks shipping fodder for them to project fanon onto. + +Speaking of fanon, I really hate it when shippers, particularly shippers of popular non-canon pairings, expect anyone who is a fan of the same piece of media or any of the characters involved in the pairing to care about ships and treat the popular fanon ships as canon. These shippers also tend to act like their fanon and headcanons are universal, using languages like “the fandom has decided–” and “everyone has agreed that–”. And these shippers wonder why others who do not engage with that piece of media for shipping get sick and tired of shipping taking over discussions about said piece of media. + +If you are so invested in shipping to the point that you are willing to disregard a piece of media just because you cannot find anything to ship, or you treat it as a personal attack when people talk about being sick and tired of shipping culture as well as how shipping dominates discussions about a piece of media, maybe you need to consider taking a step back from shipping and learning to take your shipping goggles off when you interact with a piece of media. \ No newline at end of file diff --git a/src/articles/myarticles/myarticles.11tydata.js b/src/articles/myarticles/myarticles.11tydata.js new file mode 100644 index 00000000..513f9624 --- /dev/null +++ b/src/articles/myarticles/myarticles.11tydata.js @@ -0,0 +1,3 @@ +export default { + tags: "my articles" +} \ No newline at end of file diff --git a/src/articles/myarticles/palestine-masterlist.md b/src/articles/myarticles/palestine-masterlist.md new file mode 100644 index 00000000..1e231e20 --- /dev/null +++ b/src/articles/myarticles/palestine-masterlist.md @@ -0,0 +1,185 @@ +--- +articleTitle: Palestine Masterlist +date: 2024-06-19T22:19:00+0800 +updated: 2024-12-11T23:46:44+0800 +desc: My masterlist of resources related to Palestine. +categories: ["palestine"] +toc: true +--- + +![Stand with Palestine](/assets/buttons/misc/standwithpalestine.png) + +(Credit to [rosemary](https://hillhouse.neocities.org/journal/notes/palestine) for the Stand with Palestine button) + +From the river to the sea, Palestine will be free. + +Here, I am compiling a list of resources related to Palestine. This list is not comprehensive by any means, but I still want to do my part in using my platform to support an important cause. + +## Educate Yourself + +* [Decolonize Palestine](https://decolonizepalestine.com/) +* [The Palestine Academy](https://www.thepalestineacademy.com/) +* Haymarket's [Free Ebooks for a Free Palestine](https://www.haymarketbooks.org/blogs/495-free-ebooks-for-a-free-palestine) +* [Palestine, Today: Explore how Palestine has been transformed since the Nakba](https://today.visualizingpalestine.org/) +* [Palestine Open Maps](https://palopenmaps.org/) +* [Palestine Remembered](https://www.palestineremembered.com/) + +## Articles + +* [What is the Ethical Way to Climb Out of Hell?](https://medium.com/@thegriefwitch/what-is-the-ethical-way-to-climb-out-of-hell-8ed51bdc327b) by The Grief Witch (17 October 2023) +* [What Does It Mean to Be Palestinian Now?](https://www.thenation.com/article/world/what-does-it-mean-to-be-palestinian-now/) by The Nation (25 January 2024) + +## Petitions + +* [An Open Letter from Palestinian Christians to Western Church Leaders and Theologians](https://www.change.org/p/an-open-letter-from-palestinian-christians-to-western-church-leaders-and-theologians) + +## Donations and Charities + +* [Daily click to help Palestine on arab.org](https://arab.org/click-to-help/palestine/) +* [Palestine Children's Relief Fund](https://www.pcrf.net/) +* [eSims for Gaza](https://gazaesims.com/) +* [Crips for eSims for Gaza](https://chuffed.org/project/crips-for-esims-for-gaza) +* [Gaza Soup Kitchen](https://gazasoupkitchen.org/) +* [Gaza Funds](https://gazafunds.com) +* [Operation Olive Branch](https://docs.google.com/spreadsheets/d/1vtMLLOzuc6GpkFySyVtKQOY2j-Vvg0UsChMCFst_WLA/htmlview) +* [Operation Poppy Flower](https://www.operationpoppyflower.com/) +* [Strawberry Seed Collective](https://linktr.ee/strawberryseedcollective) +* [Project Watermelon](https://linktr.ee/projectwatermelon) +* [Bees And Watermelons](https://linktr.ee/beesandwatermelons) +* [The ButterflyEffect Project](https://docs.google.com/spreadsheets/u/0/d/e/2PACX-1vTKQYInYewFiGUX4afdHK-rANJDT4dgOC4IV6elKYNvYI2HvOTf_6IsTqt5m2KXcr_pGxcqR8AvsAJi/pubhtml) +* [el-shab-hussein and nabulsi's Vetted Gaza Evacuation Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0) +* [GazaVetters](https://www.tumblr.com/gazavetters) ([Gaza Vetters spreadsheet](https://docs.google.com/spreadsheets/d/1YGgkXoyam7tnbXb-vqWsHFs3Puyf_xYeXY2dPrZQY1M/edit?gid=0#gid=0)) +* [Ottawa4Palestine](https://linktr.ee/ottawa4palestine)'s [Gaza Evacuation Relief Fund](https://docs.google.com/spreadsheets/d/1FC1fK-3r-w3wPi2AdYho5_0j148QC6wkFIMdJA5kX4c/edit?gid=0#gid=0) +* [GoFund(water)Me(lons)](https://docs.google.com/spreadsheets/d/1o_kH9RnGmKOXmEcMUBTWcMhgdTKIequ__xiPym7RGtE/edit?gid=0#gid=0) +* [Helping the People of Gaza - Mutual Aid Fund](https://www.gofundme.com/f/helping-the-people-of-gaza-mutual-aid-fund) +* [Care for Gaza](https://x.com/careforgaza) +* [Direct Aid for Gaza](https://x.com/GazaDirectAid) +* [Life For Gaza](https://gaza-city.ensany.com/campaign/6737?lang=en) +* [Taawon](https://www.taawon.org/en/content/gaza-needs-us-now) +* [World Food Programme (WFP)](https://www.wfp.org/emergencies/palestine-emergency) +* [Medical Aid for Palestinians](https://www.map.org.uk/) +* [Help Dr. Ibrahem to treat the pateints homeless people](https://www.gofundme.com/f/urgent-help-dribrahem-to-treat-the-pateints-homeless-people) +* [Support for Tents in Gaza](https://www.gofundme.com/f/support-for-marginalized-refugees-in-jordan) +* [Gaza Municipality's water project](https://gaza-city.ensany.com/campaign/6737?lang=EN) + +## Boycotts + +* [BDS Movement](https://bdsmovement.net/) +* [No Tech For Apartheid](https://www.notechforapartheid.com/) +* Attention to website owners: [Boycott Wix](https://boycottwix.org/) — The BDS movement has [listed Wix as an organic boycott target](https://bdsmovement.net/Act-Now-Against-These-Companies-Profiting-From-Genocide), meaning the BDS movement did not initiate this grassroots boycott campaign, but supports it due to the boycotted brand's complicity in Israel's genocide and apartheid against Palestinians. + +## Spotlight Crowdfunding Campaigns + +There are Palestinians who have reached out to me on Tumblr to ask for help with sharing their fundraising campaigns, so I am using my platform to share them. These campaigns have been verified by other Palestinians and trusted sources (including ones who are on Tumblr), so I encourage you to help to donate and share at the best of your abilities. + +* [Help...Save a Pregnant Mother's Life and Support Her Family](https://www.gofundme.com/f/ne9gzx-help-them-to-survive) (verified by [nabulsi](https://www.tumblr.com/nabulsi/751944563232587777) and shared by [90-ghost](https://www.tumblr.com/90-ghost/752304563682476032)) +* [Help Sahar and Her Family to Evacuate Gaza](https://www.gofundme.com/f/help-sahar-and-her-family-to-evacuate-gaza) (verified by [el-shab-hussein](https://www.tumblr.com/el-shab-hussein/749777880017502208/another-fundraiser-i-trust)) +* [Help Us Escape Gaza: A Mother's Plea for Safety](https://www.gofundme.com/f/help-us-escape-gaza-a-mothers-plea-for-safety) (#182 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0&range=A186)) +* [From War to Education: Abdelrahman Resilient Journey](https://www.gofundme.com/f/from-war-to-education-abdelrahmans-resilient-journey) (verified by [nabulsi](https://www.tumblr.com/nabulsi/753544070688915456) and shared by [90-ghost](https://www.tumblr.com/90-ghost/753258782216404992)) +* [Please Help Tahani save her children and husband](https://www.gofundme.com/f/i-have-nothing-left-my-home-and-workplace-have-be) (verified by [el-shab-hussein](https://www.tumblr.com/el-shab-hussein/748756401076207616/list-of-fundraisers-for-direct-contacts-from)) +* [Please help Shamaly family SURVIVE Gaza & start a new life!](https://www.gofundme.com/f/please-help-shamaly-family-start-a-new-life) (verified by [nabulsi](https://www.tumblr.com/nabulsi/753715707609530368)) +* [Help us reunite with our kids who are stuck in Gaza](https://www.gofundme.com/f/reunite-us-with-our-beloved-4-kids-stuck-in-gaza) (shared by [90-ghost](https://www.tumblr.com/90-ghost/754096091530723328/donate-to-help-us-reunite-with-our-kids-who-are)) +* [Urgent ! Save kids life .](https://www.gofundme.com/f/help-alaa-family-to-survive-the-war-in-gaza) (shared by [90-ghost](https://www.tumblr.com/90-ghost/751443466082484224)) +* [Trapped Family in Gaza Appeals for Help to Survive](https://www.gofundme.com/f/wyuehr-trapped-family-in-gaza-appeals-for-help-to-survive) (#174 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0&range=A178); also shared by [fairuzfan](https://www.tumblr.com/fairuzfan/752928036559749120) and [90-ghost](https://www.tumblr.com/90-ghost/752026987709825024)) +* [Help Ahmed family to travel to a save place](https://www.gofundme.com/f/help-ahmed-family-to-travel) (veridied by [nabulsi](https://www.tumblr.com/nabulsi/752576616277868544/hello-how-are-you-my-name-is-ahmed-im-from)) +* [Help my family escape Gaza](https://www.gofundme.com/f/byt93-help-my-family-escape-gaza) (#231 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0&range=A235)) +* [Hope for Gaza: Support Ashraf's Family Rebuild Their Lives](https://www.gofundme.com/f/hope-for-gaza-support-ashrafs-family-rebuild-their-lives) (verified by [90-ghost](https://www.tumblr.com/90-ghost/754535164856664064/legit-fundraiser)) +* [A Father's Plea: Help Save My Family](https://www.gofundme.com/f/btuqqt-save-my-familys-life) (verified by [el-shab-hussein](https://www.tumblr.com/el-shab-hussein/754087744556449792/vetted-family-fundraiser-masterpost-3)) +* [Help Moamen Majed rebuild his life after the war](https://www.gofundme.com/f/help-moamen-majed-rebuild-his-life-after-the-war) (verified by [90-ghost](https://www.tumblr.com/90-ghost/755355718664830976/moamenmajed-gaza-are-they-a-vetted-fundraiser)) +* [Save Gaza: A Brighter Future for Aya and Her Family](https://www.gofundme.com/f/save-gaza-a-brighter-future-for-aya-and-her-family) (shared by [90-ghost](https://www.tumblr.com/90-ghost/754992024939347968)) +* [EMERGENCY: help my relatives evacuate to safety](https://www.gofundme.com/f/emergency-help-my-relatives-evacuate-to-safety) (#137 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0&range=A141); also shared by [90-ghost](https://www.tumblr.com/90-ghost/756556584649424896)) +* [Help Palestine and Family Survive the Gaza Crisis](https://www.gofundme.com/f/help-palestine-and-family-survive-the-gaza-crisis) (shared by [90-ghost](https://www.tumblr.com/90-ghost/756556732829974528)) +* [Support Safaa's Quest To Get Her Family To Safety](https://www.gofundme.com/f/support-safaas-quest-to-get-her-family-to-safety) (shared by [90-ghost](https://www.tumblr.com/90-ghost/756556669674274816)) +* [Help Doaa Rebuild Her Sewing Business](https://www.gofundme.com/f/help-doaa-rebuild-her-sewing-business) (shared by [90-ghost](https://www.tumblr.com/90-ghost/756556522290626560)) +* [Help the Munna Tashmali Family Rebuild Their Home and Future](https://www.gofundme.com/f/help-the-munna-tashmali-family-rebuild-their-home-and-future) (verified by [nabulsi](https://www.tumblr.com/nabulsi/754393532315353089/donate-to-help-the-munna-tashmali-family-rebuild)) +* [Help Gaza Family Evacuate to Safety](https://www.gofundme.com/f/helping-gaza-family-to-get-out) (shared by [90-ghost](https://www.tumblr.com/90-ghost/756899215473606656)) + * [Help me save my children from death in the Gaza war](https://www.gofundme.com/f/help-me-save-my-children-from-death-in-the-gaza-war) ([verified by association](https://www.tumblr.com/ana-bananya/759290042834386944/dina-is-mahmoud-1995s-sister-confirmed-here); this fundraising campaign belongs to the sister of Mahmoud Alkhaldi, whose campaign is linked just above) +* [Help us for the sake of God](https://www.gofundme.com/f/help-us-for-the-sake-of-god) (verified by [90-ghost](https://www.tumblr.com/90-ghost/755446251161632768/faites-un-don-%C3%A0-help-us-for-the-sake-of-god)) +* [we need help](https://www.gofundme.com/f/bfth82-we-need-help) (shared by [90-ghost](https://www.tumblr.com/90-ghost/756901702912868352)) +* [Help little children of Gaza stay safe and alive!](https://www.gofundme.com/f/help-our-families-evacuate-gaza-before-too-late) (verified by [nabulsi](https://www.tumblr.com/nabulsi/751214090403430400/donate-to-help-little-children-stay-safe-and)) +* [Support Fatima's Family in Gaza After Heartbreaking Tragedy](https://www.gofundme.com/f/support-fatimas-family-in-gaza-after-heartbreaking-tragedy) (shared by [90-ghost](https://www.tumblr.com/90-ghost/756556061504307200)) +* [Get my relatives out of Gaza](https://www.gofundme.com/f/3b6yr-get-my-relatives-out-of-gaza) (verified by [90-ghost](https://www.tumblr.com/90-ghost/757079385198215168/legit-fundraiser)) +* [Help Shaima's family reunite in Egypt](https://www.gofundme.com/f/help-shymaas-family-reunite-in-egypt) (#141 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0&range=A145)) +* [Save the life of an innocent child](https://www.gofundme.com/f/save-the-life-of-an-innocent-child) (shared by [90-ghost](https://www.tumblr.com/90-ghost/755122452856700928) and listed as #406 in [The ButterflyEffect Project's Verified Campaigns](https://docs.google.com/spreadsheets/d/e/2PACX-1vTKQYInYewFiGUX4afdHK-rANJDT4dgOC4IV6elKYNvYI2HvOTf_6IsTqt5m2KXcr_pGxcqR8AvsAJi/pubhtml?urp=gmail_link&gxid=-8203366#)) +* [Save Ibrahim and his children](https://www.gofundme.com/f/save-ibrahim-and-his-children) (verified by [90-ghost](https://www.tumblr.com/90-ghost/757288769795850240/legit-fundraiser)) +* [Help Shahd in Gaza!](https://www.gofundme.com/f/help-shahd-in-gaza) (#224 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0&range=A228)) +* [Save Dr. Farhat's family from genocide in Gaza](https://www.gofundme.com/f/saving-dr-farhats-family-towards-hope) (#248 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0&range=A252)) +* [Assist in evacuating my family from the war in Gaza.](https://www.gofundme.com/f/Help-Mohammed-alhabil-Family) (#166 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0&range=A170)) + * [Family relief and survival from massacres](https://www.gofundme.com/f/family-relief-and-survival-from-massacres) ([verified by association](https://www.tumblr.com/a-shade-of-blue/761542408474345472); this fundraiser belongs to a niece of Muhammad Al-Habil, whose fundraiser is linked just above) + * [Help me and my family escape to safety](https://www.gofundme.com/f/help-me-and-my-family-escape-to-safety) ([verified by association](https://www.tumblr.com/a-shade-of-blue/762595796863647744/only-330-raised-of-50000-goal-last-donation); this fundraiser belongs to a nephew of Muhammad Al-Habil, whose fundraiser is linked just above) +* [Emergency: Help Evacuate My Family From GAZA WAR](https://www.gofundme.com/f/help-save-the-lives-of-my-family-in-gaza) (#26 in [Operation Olive Branch spreadsheet's masterlist tab](https://docs.google.com/spreadsheets/d/1vtMLLOzuc6GpkFySyVtKQOY2j-Vvg0UsChMCFst_WLA/edit?gid=1061843896#gid=1061843896&fvid=647479800); also listed in [Project Watermelon Donation Links spreadsheet's Donate to Families in Gaza tab](https://docs.google.com/spreadsheets/d/16XhzsCbsRV-cMAzRA8gTNxaYt_FAbf6nq3ZNGP4Q9U8/edit?gid=1452518893#gid=1452518893), under the family name Haya Nahed Alshawish) +* [Urgent Help Needed to Evacuate My Family from Gaza](https://www.gofundme.com/f/e6vc7g-urgent-help-needed-to-evacuate-my-family-from-gaza) (shared by [90-ghost](https://www.tumblr.com/90-ghost/756556255005491200)) +* [Help Nour and his family escape from the war in Gaza](https://www.gofundme.com/f/donate-to-help-nour-and-his-family-escape-the-war-in-gaza) (verified by [roadimusprime](https://www.tumblr.com/roadimusprime/757885015014227968/and-at-the-time-that-i-am-writing-this-our) who helped setting up this fundraiser) +* [Help Musab and his family,my pets survive this war in Gaza.](https://www.gofundme.com/f/help-musab-and-his-family-survive-this-war-in-gaza-they-nee) (Musab's story was shared by [90-ghost](https://www.tumblr.com/90-ghost/755436620006686720), but this new fundraiser [needed to be created for Musab due to a scam](https://www.tumblr.com/musababed/757808283298004993)) +* [Hope and Safety for Amal and Her Children in Gaza](https://www.gofundme.com/f/hope-and-safety-for-amal-and-her-children-in-gaza) (shared by [90-ghost](https://www.tumblr.com/90-ghost/755297146774978560)) +* [Please Save What's Left of My Family](https://www.gofundme.com/f/donate-to-restore-the-lives-of-the-balousha-family) (verified by [90-ghost](https://www.tumblr.com/90-ghost/757288369570152448/legit-fundraiser)) +* [Save Mohamed and his elderly parents from genocide](https://www.gofundme.com/f/save-mohamed-and-his-elderly-parents-from-genocide?attribution_id=sl:7b8ea3b1-7192-4e6d-ac64-285c74c9c372) (verified by [90-ghost](https://www.tumblr.com/90-ghost/755378263140024320/legit-fundraiser)) +* [Support Gaza Family's Journey to Recovery](https://www.gofundme.com/f/fzgga8-support-gaza-familys-journey-to-recovery) (shared by [90-ghost](https://www.tumblr.com/90-ghost/757170837598126080)) +* [Help us build new hope for me and my family](https://www.gofundme.com/f/help-us-build-new-hope-for-me-and-my-family) (shared by [90-ghost](https://www.tumblr.com/90-ghost/754544734691786752) and [northgazaupdates](https://www.tumblr.com/northgazaupdates/754969078935044096)) +* [Helping the Helles family achieve a better future](https://www.gofundme.com/f/helping-the-helles-family-achieve-a-better-future) (verified by [90-ghost](https://www.tumblr.com/90-ghost/757170722766454784/legit-fundraiser)) +* [Help save my family to survive the genocide in Gaza](https://www.gofundme.com/f/Stand-With-AlBalawi-Family) (verified by [90-ghost](https://www.tumblr.com/90-ghost/754486025365209088/legit-fundraiser)) +* [Helping my family rebuild our home](https://www.gofundme.com/f/dr66mz-helping-my-family-rebuild-our-home) (#198 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0&range=A202)) +* [Help Mohamed's children escape from the Gaza war to Safety](https://www.gofundme.com/f/please-help-this-family-get-out-of-the-gaza-war) (shared by [90-ghost](https://www.tumblr.com/90-ghost/755749578786127872)) +* [Death chases my family in Gaza; help me save them](https://www.gofundme.com/f/death-chases-my-family-in-gaza-help-me-save-them) (#151 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0&range=A155)) +* [Help My Family Evacuate to Safety](https://www.gofundme.com/f/gtuw5-help-my-family-evacuate-to-safety) (verified by association; this fundraiser was [shared by their friend Mohi](https://www.tumblr.com/dlxxv-vetted-donations/758442260915421184), whose [fundraiser](https://www.gofundme.com/f/support-mohis-fight-for-survival-in-gaza) was shared by [90-ghost](https://www.tumblr.com/90-ghost/757063664601858048)) +* [Help Youssef Provide Medicine and Shelter](https://www.gofundme.com/f/help-youssef-provide-medicine-and-shelter) (#255 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0&range=A259); row 132 in [Bees and Watermelons](https://linktr.ee/beesandwatermelons)' [priority campaigns spreadsheet](https://docs.google.com/spreadsheets/d/1J-1KNHXmvY098fuCDWiOIm1fcphAgkXA8nnWqOSXouw/edit?gid=283092143#gid=283092143&range=B132)) +* [Save Malak's Dreams and Family from Gaza](https://www.gofundme.com/f/save-malaks-dreams-and-family-from-gaza) (verified by [90-ghost](https://www.tumblr.com/90-ghost/756023439469477889/legit-fundraiser)) +* [Help Alaa family from this hard war](https://www.gofundme.com/f/sp46z-help-my-family-to-travel-to-a-safe-place) (#99 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?pli=1&gid=0#gid=0&range=A103)) +* [Help Ahmed Jehad and his newborn survive!](https://www.gofundme.com/f/ahmed-jehad-and-his-newborn-need-to-survive) (Row 171 in [Bees and Watermelons](https://linktr.ee/beesandwatermelons)' [priority campaigns spreadsheet](https://docs.google.com/spreadsheets/d/1J-1KNHXmvY098fuCDWiOIm1fcphAgkXA8nnWqOSXouw/edit?gid=283092143#gid=283092143&range=B171)) +* [Help Evacuate My Family from Gaza to Safety](https://www.gofundme.com/f/reconstruction-of-a-destroyed-house) (#125 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0&range=A129)) +* [Help my family survive and start a new life](https://www.gofundme.com/f/help-baby-omar-and-his-family-survive) (shared by [90-ghost](https://www.tumblr.com/90-ghost/758166499964878848)) +* [Evacuate Yousef and his family from Gaza](https://www.gofundme.com/f/evacuate-yousef-and-his-family-from-gaza) (#246 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0&range=A250)) +* [Help Nour and her Family Achieve a Better Future](https://www.gofundme.com/f/save-nour-and-her-family-from-war-help-them-escape) (shared by [90-ghost](https://www.tumblr.com/90-ghost/756899183536078848)) +* [Support Aseeel Fight for Life and Family in Gaza](https://www.gofundme.com/f/support-aseels-fight-for-life-and-family-in-gaza) (verified by [90-ghost](https://www.tumblr.com/90-ghost/757064652185337856/legit)) +* [Support & Help My Family From Gaza Strip](https://www.gofundme.com/f/help-the-family-of-misk-sohaib-get-out-to-safety) (shared by [90-ghost](https://www.tumblr.com/90-ghost/757065363567640576)) +* [Help Oday And Family Evacuate Gaza , Rebuild Lives](https://www.gofundme.com/f/help-oday-and-family-evacuate-gaza-rebuild-lives) (#261 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0&range=A265)) +* [Help heba and his family to survive their life](https://www.gofundme.com/f/help-heba-and-his-family-to-survive-their-life) (shared by [90-ghost](https://www.tumblr.com/90-ghost/757185259555127296)) +* [Defend my brother's family from genocide in gaza](https://www.gofundme.com/f/help-poor-injyred-in-gaza) (shared by [90-ghost](https://www.tumblr.com/90-ghost/758172410029719552)) +* [Support Asil Fight for Life and Family in Gaza](https://www.gofundme.com/f/support-aseels-fight-for-life-and-family-in-gaza) (verified by [90-ghost](https://www.tumblr.com/90-ghost/757743956823048192/dont-forget-to-help-asel)) +* [Support Family escape from rafah to save place](https://www.gofundme.com/f/help-ayahs-family-escape-gaza-crisis) (verified by association; this fundraiser was [shared by their friend Mohi](https://www.tumblr.com/ana-bananya/758258451537395712/this-campaign-belongs-to-a-friend-of-mohiy-gaza), whose [fundraiser](https://www.gofundme.com/f/support-mohis-fight-for-survival-in-gaza) was shared by [90-ghost](https://www.tumblr.com/90-ghost/757063664601858048)) +* [Bara El Shaer Family Survival Fund](https://www.gofundme.com/f/el-shaer-family-survival-fund) (Baraa has an [Instagram account](https://www.instagram.com/bara_belal038/) that has been used for years, and this fundraiser has also been shared by another Instagram user, [river2cgza](https://www.instagram.com/river2cgza/), along with other verified fundraisers) +* [Help Safaa secure her children‘s lives after war](https://www.gofundme.com/f/help-safaa-secure-her-familys-life-after-war) (#135 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0&range=A139)) +* [Desperate plea: Help my family evacuate Gaza war!](https://www.gofundme.com/f/karamsaid) (#109 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0&range=A113)) +* [Help us build new hope for me and my family](https://www.gofundme.com/f/a6mv2z-help-us-build-new-hope-for-me-and-my-family) ([verified by association](https://www.tumblr.com/a-shade-of-blue/759269512056029184/donate-to-help-us-build-new-hope-for-me-and-my); Hassan is a nephew of Mohammed Alhabeel, whose fundraiser is lited as #166 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0&range=A170). Note that this is not the same fundraiser as the above that shared the same title) +* [Help Dr. Shahad and Farah complete their education](https://www.gofundme.com/f/help-dr-shahad-and-farah) (shared by [90-ghost](https://www.tumblr.com/90-ghost/756898822254395392) and vetted by association; Farah is [Nesma's sister](https://www.tumblr.com/nesmamomen/755734008155996160/only-5-seconds-of-your-time), and Nesma's fundraiser has been vetted by [el-shab-hussein](https://www.tumblr.com/el-shab-hussein/749848198102827008/hello-good-sir-ive-been-supporting-a-family-but) and shared by [nabulsi](https://www.tumblr.com/nabulsi/752822250810605568)) +* [Amira's Story: Between Hope and Resilience - A Call for Soli](https://www.gofundme.com/f/amiras-story-between-hope-and-resilience-a-call-for-soli) (verified by [nabulsi](https://www.tumblr.com/nabulsi/752577548412731392/donate-to-amiras-story-between-hope-and)) +* [Help Save Ahmed Family From Gaza](https://www.gofundme.com/f/help-save-ahmed-family-from-gaza) ([verified by association](https://www.tumblr.com/a-shade-of-blue/759268417249361920); Ahmed is the brother of Mohammed Alhabeel, whose fundraiser is lited as #166 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0&range=A170).) +* [From Rubble to Success: Helping Osama Rebuild His Dream](https://www.gofundme.com/f/Helping-Osama-Rebuild-His-Dream) (shared by [90-ghost](https://www.tumblr.com/90-ghost/760346545235329024)) + * [Support a Family's Journey to Safety and Peace](https://www.gofundme.com/f/support-a-family-journey-to-safety-and-peace) ([verified by association](https://www.tumblr.com/c-u-c-koo-4-40k/763044851084296192/everyone-this-is-a-friend-of-osama-basil-sh); this fundraiser belongs to a friend of Osama, whose fundraiser is linked just above. Also shared by [90-ghost](https://www.tumblr.com/90-ghost/763057383436107776)) +* [Please help my family in Gaza](https://www.gofundme.com/f/q37qd5-please-help-my-family-in-gaza) (shared by [90-ghost](https://www.tumblr.com/90-ghost/760328893428367360)) +* [Help Eslam Save Her Family](https://www.gofundme.com/f/help-eslam-save-her-family) (row 175 in [Bees and Watermelons](https://linktr.ee/beesandwatermelons)' [priority campaigns spreadsheet](https://docs.google.com/spreadsheets/d/1J-1KNHXmvY098fuCDWiOIm1fcphAgkXA8nnWqOSXouw/edit?gid=283092143#gid=283092143&range=D175)) + * [Helping my family to evacuate from Gaza](https://www.gofundme.com/f/kr85g-safe-my-family) (verified by [gaza-evacuation-funds](https://www.tumblr.com/gaza-evacuation-funds/760224788809695232/todays-vetted-fundraisers); also [verified by association](https://www.tumblr.com/dlxxv-vetted-donations/759148525328220160/this-campaign-is-vetted-by-association-through); Ayaa Mahmoud, the person this fundraiser belongs to, is the sister-in-law of Eslam, another Palestinian whose fundraiser is linked just above) + * [Helping Lama & Mohammed to evacuate from Gaza](https://www.gofundme.com/f/helping-lama-mohammed-to-evacuate-from-gaza) ([verified by association](https://www.tumblr.com/dlxxv-vetted-donations/759976289261305856/lama-is-indeed-vetted-by-association-through); Lama's husband is an acquaintance of Ayaa Mahmoud, whose fundraiser is linked just above) +* [Help Abood From the War](https://www.gofundme.com/f/help-abboud-from-the-war) ([verified by association](https://www.tumblr.com/dlxxv-vetted-donations/758342969132728320); this fundraiser belongs to the brother of Mohi, whose [fundraiser](https://www.gofundme.com/f/support-mohis-fight-for-survival-in-gaza) was shared by [90-ghost](https://www.tumblr.com/90-ghost/757063664601858048)) +* [Save My Family from the War Nightmare in Gaza](https://www.gofundme.com/f/abgwv-help-us) (shared by [northgazaupdates](https://www.tumblr.com/northgazaupdates/756089494338420736)) +* [Help Salem Family From Gaza](https://www.gofundme.com/f/help-salem-family-from-gaza) (verified by [90-ghost](https://www.tumblr.com/90-ghost/757065439413174272/legit)) +* [Please save me, my family and my future from the brutal war](https://www.gofundme.com/f/help-me-to-complete-my-education-in-gaza) (verified by [90-ghost](https://www.tumblr.com/90-ghost/755122761409642496/legit-fundraiser)) +* [Help Nour and his family escape from the war in Gaza](https://www.gofundme.com/f/donate-to-help-nour-and-his-family-escape-the-war-in-gaza) (shared by [90-ghost](https://www.tumblr.com/90-ghost/760377411969875968)) +* [Help Muhammad and his family live a better life](https://www.gofundme.com/f/znu6m-help-muhammad-and-his-family-live-a-better-life) (verified by [90-ghost](https://www.tumblr.com/90-ghost/760285761067253760/legit-fundraiser)) +* [Donate to Ahmed's Journey to Safety and Education](https://www.gofundme.com/f/donate-to-ahmeds-journey-to-safety-and-education) (shared by [90-ghost](https://www.tumblr.com/90-ghost/758711734896918528)) +* [Support Amal's Family in War-Torn Gaza Escape to Egypt](https://www.gofundme.com/f/support-amals-family-in-wartorn-gaza-escape-to-egypt) ([verified by association](https://www.tumblr.com/acepumpkinpatrick/761630225423646720); this fundraiser belongs to the brother of [Asmaa](https://www.tumblr.com/asmaamajed2/761630455342776320), whose [fundraiser](https://www.gofundme.com/f/8wewmz-help-asmaa-to-continue-school-outside-of-gaza) has been shared by [90-ghost](https://www.tumblr.com/90-ghost/758170896860151808)) +* [Help Us Escape the Ravages of War: Emergency Evacuation Fund](https://www.gofundme.com/f/help-us-escape-the-ravages-of-war-emergency-evacuation-fund) (#212 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0&range=A216)) +* [Help Nevin alserr family escape the war](https://www.gofundme.com/f/support-niveen-familys-journey-to-safety) (#314 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0&range=A318)) +* [Help Displaced Family in Gaza](https://www.gofundme.com/f/gga9a-help-displaced-families-in-gaza) (shared by [Salaah Bilaal](https://www.tumblr.com/bilal-salah0/759280967486767104/please-share-the-post), whose fundraiser is #132 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0&range=A136)) +* [Your help is the only hope to save Abdallah & his family from genocide](https://gogetfunding.com/your-help-is-the-only-hope-to-save-abdallah-his-family-from-genocide/) (#315 in [el-shab-hussein and nabulsi’s Vetted Gaza Fundraiser List](https://docs.google.com/spreadsheets/d/1yYkNp5U3ANwILl2MknJi9G7ArY4uVTEEQ1CVfzR8Ioo/edit?gid=0#gid=0&range=A319)) +* [Rising from the Ashes: Ghada’s Journey of Hope and Resilien](https://www.gofundme.com/f/rising-from-the-ashes-ghadas-journey-of-hope-and-resilien) (#6 in [GazaVetters](https://www.tumblr.com/gazavetters)' [spreadsheet](https://docs.google.com/spreadsheets/d/1YGgkXoyam7tnbXb-vqWsHFs3Puyf_xYeXY2dPrZQY1M/edit?gid=0#gid=0&range=A11)) +* [Urgent,Help us Recover our Home, Education,Work and FAMILY](https://www.gofundme.com/f/urgent-help-us-recover-our-home-education-and-work) (shared by [gaza-evacuation-funds](https://www.tumblr.com/gaza-evacuation-funds/762875245776502784/donate-to-urgenthelp-us-recover-our-home)) +* [Ahmed's Autism Journey: a Path of Hope and Healing](https://www.paypal.com/donate?campaign_id=EJ892Z3JYTPYS) ([vetted by association](https://www.tumblr.com/a-shade-of-blue/762812657802838016/vetted-by-association-as-you-can-see-above-this); this campaign was [promoted by Nesma Ahmed](https://www.tumblr.com/nesmamomen/762057439135842304), whose [fundraiser](https://www.gofundme.com/f/help-nesmas-and-her-family-evacuate) had been vetted by [el-shab-hussein](https://www.tumblr.com/el-shab-hussein/749848198102827008/hello-good-sir-ive-been-supporting-a-family-but)) +* [Help my family survive and start a new life](https://www.gofundme.com/f/urgent-help-needed-a-journey-from-gaza-to-safety) (#75 in [GazaVetters](https://www.tumblr.com/gazavetters)' [spreadsheet](https://docs.google.com/spreadsheets/d/1YGgkXoyam7tnbXb-vqWsHFs3Puyf_xYeXY2dPrZQY1M/edit?gid=0#gid=0&range=A80). Note that this is not the same fundraiser as the above that shared the same title) +* [Help Anas & Ahmed rebuild their future in Gaza](https://www.gofundme.com/f/Help-Anas-and-Ahmed-in-Gaza) (verified by [90-ghost](https://www.tumblr.com/90-ghost/762445389624492032/legit) and listed as #83 in [GazaVetters](https://www.tumblr.com/gazavetters)' [spreadsheet](https://docs.google.com/spreadsheets/d/1YGgkXoyam7tnbXb-vqWsHFs3Puyf_xYeXY2dPrZQY1M/edit?gid=0#gid=0&range=A88)) +* [Help Mahmoud's Family Overcome War Tragedy](https://www.gofundme.com/f/help-mahmouds-family-overcome-war-tragedy) (verified by [90-ghost](https://www.tumblr.com/90-ghost/755121680324657152/legit-fundraiser)) +* [Help me get food water and medicine for my little kids !!](https://www.gofundme.com/f/r8kj4-help-me-get-food-water-and-medicine-for-my-little-kids) ([verified by Salaah Bilaal](https://www.tumblr.com/mohammedayyads-blog/760010459463254016/donate-to-help-me-get-food-water-and-medicine-for)) +* [Emergency Appeal: Help Save My Children's](https://www.gofundme.com/f/emergency-appeal-help-save-my-childrens) (#187 in [GazaVetters](https://www.tumblr.com/gazavetters)' [spreadsheet](https://docs.google.com/spreadsheets/d/1YGgkXoyam7tnbXb-vqWsHFs3Puyf_xYeXY2dPrZQY1M/edit?gid=0#gid=0&range=A192)) +* [Help me get my family out of Gaza. Their lives have become v](https://www.gofundme.com/f/help-me-get-my-family-out-of-gaza-their-lives-have-become-v) (#192 in [GazaVetters](https://www.tumblr.com/gazavetters)' [spreadsheet](https://docs.google.com/spreadsheets/d/1YGgkXoyam7tnbXb-vqWsHFs3Puyf_xYeXY2dPrZQY1M/edit?gid=0#gid=0&range=A197)) +* [Save the family of Salman Hellis from the Gaza Strip](https://www.gofundme.com/f/save-the-family-of-salman-hellis-from-the-gaza-strip) (verified by [90-ghost](https://www.tumblr.com/90-ghost/761647879548993536)) +* [Support Khawla's Family in Gaza Crisis](https://www.gofundme.com/f/support-khawlas-family-in-gaza-crisis) ([verified by association](https://www.tumblr.com/ana-bananya/761532739985047552/donate-to-support-khawlas-family-in-gaza-crisis); this fundraiser belongs to the sister of Mohi, whose [fundraiser](https://www.gofundme.com/f/support-mohis-fight-for-survival-in-gaza) was shared by [90-ghost](https://www.tumblr.com/90-ghost/757063664601858048)) +* [Help Ahlam Rebuild Her Life and Dreams](https://www.gofundme.com/f/help-ahlam-rebuild-her-life-and-dreams) (#73 in [GazaVetters](https://www.tumblr.com/gazavetters)' [spreadsheet](https://docs.google.com/spreadsheets/d/1YGgkXoyam7tnbXb-vqWsHFs3Puyf_xYeXY2dPrZQY1M/edit?gid=0#gid=0&range=A78)) +* [Help Zaen and Yehya to get out of Gaza](https://www.gofundme.com/f/help-zaen-and-yehya-to-get-out-of-gaza) (#127 in [GazaVetters](https://www.tumblr.com/gazavetters)' [spreadsheet](https://docs.google.com/spreadsheets/d/1YGgkXoyam7tnbXb-vqWsHFs3Puyf_xYeXY2dPrZQY1M/edit?gid=0#gid=0&range=A132)) +* [Help this family to get out of Gaza](https://www.gofundme.com/f/help-this-family-to-get-out-of-gaza) (#111 in [GazaVetters](https://www.tumblr.com/gazavetters)' [spreadsheet](https://docs.google.com/spreadsheets/d/1YGgkXoyam7tnbXb-vqWsHFs3Puyf_xYeXY2dPrZQY1M/edit?gid=0#gid=0&range=A116)) +* [Help me to evacuate from this crazy war in Gaza](https://www.gofundme.com/f/m6hdrt-support-ahmad-to-complete-his-education) (#119 in [GazaVetters](https://www.tumblr.com/gazavetters)' [spreadsheet](https://docs.google.com/spreadsheets/d/1YGgkXoyam7tnbXb-vqWsHFs3Puyf_xYeXY2dPrZQY1M/edit?gid=0#gid=0&range=A124)) +* [Help Ahmed Continue His Education and Support His Family](https://www.gofundme.com/f/help-ahmed-continue-his-education-and-support-his-family) (#303 in [GazaVetters](https://www.tumblr.com/gazavetters)' [spreadsheet](https://docs.google.com/spreadsheets/d/1YGgkXoyam7tnbXb-vqWsHFs3Puyf_xYeXY2dPrZQY1M/edit?gid=0#gid=0&range=A308)) +* [Support Ibrahim’s Fight For Survival](https://www.gofundme.com/f/support-ibrahims-fight-for-survival) (#220 in [GazaVetters](https://www.tumblr.com/gazavetters)' [spreadsheet](https://docs.google.com/spreadsheets/d/1YGgkXoyam7tnbXb-vqWsHFs3Puyf_xYeXY2dPrZQY1M/edit?gid=0#gid=0&range=A225)) +* [Please help us with travel and treatment for urgent need](https://www.gofundme.com/f/please-help-us-with-travel-and-treatment-for-urgent-need) (#99 in [GazaVetters](https://www.tumblr.com/gazavetters)' [spreadsheet](https://docs.google.com/spreadsheets/d/1YGgkXoyam7tnbXb-vqWsHFs3Puyf_xYeXY2dPrZQY1M/edit?gid=0#gid=0&range=A104)) +* [Donate to help Mona's famil to evacuate from Gaza](https://www.gofundme.com/f/donate-to-help-monas-famil-to-evacuate-from-gaza) (#253 in [GazaVetters](https://www.tumblr.com/gazavetters)' [spreadsheet](https://docs.google.com/spreadsheets/d/1YGgkXoyam7tnbXb-vqWsHFs3Puyf_xYeXY2dPrZQY1M/edit?gid=0#gid=0&range=A258)) +* [Help me evacuate my family to safety and peace.](https://www.gofundme.com/f/help-me-evacuate-my-family-to-safety-and-peace) (#284 in [GazaVetters](https://www.tumblr.com/gazavetters)' [spreadsheet](https://docs.google.com/spreadsheets/d/1YGgkXoyam7tnbXb-vqWsHFs3Puyf_xYeXY2dPrZQY1M/edit?gid=0#gid=0&range=A289)) +* [Help my family](https://www.gofundme.com/f/3td2x-help-my-family) (shared by [90-ghost](https://www.tumblr.com/90-ghost/768134181180129280)) \ No newline at end of file diff --git a/src/assets/adoptables/32bitcafe-vacation/alexandra-stamp.png b/src/assets/adoptables/32bitcafe-vacation/alexandra-stamp.png new file mode 100644 index 00000000..8f514238 Binary files /dev/null and b/src/assets/adoptables/32bitcafe-vacation/alexandra-stamp.png differ diff --git a/src/assets/adoptables/32bitcafe-vacation/passport.png b/src/assets/adoptables/32bitcafe-vacation/passport.png new file mode 100644 index 00000000..2fcc0d1c Binary files /dev/null and b/src/assets/adoptables/32bitcafe-vacation/passport.png differ diff --git a/src/assets/adoptables/32bitcafe-vacation/ribose-riverfish.png b/src/assets/adoptables/32bitcafe-vacation/ribose-riverfish.png new file mode 100644 index 00000000..0b94bf54 Binary files /dev/null and b/src/assets/adoptables/32bitcafe-vacation/ribose-riverfish.png differ diff --git a/src/assets/adoptables/alexandra-diddles.png b/src/assets/adoptables/alexandra-diddles.png new file mode 100644 index 00000000..9428a3f3 Binary files /dev/null and b/src/assets/adoptables/alexandra-diddles.png differ diff --git a/src/assets/adoptables/kittyfriends/artwork-bat.gif b/src/assets/adoptables/kittyfriends/artwork-bat.gif new file mode 100644 index 00000000..ae9787b0 Binary files /dev/null and b/src/assets/adoptables/kittyfriends/artwork-bat.gif differ diff --git a/src/assets/adoptables/kittyfriends/artwork-pumpkin.gif b/src/assets/adoptables/kittyfriends/artwork-pumpkin.gif new file mode 100644 index 00000000..afea50bf Binary files /dev/null and b/src/assets/adoptables/kittyfriends/artwork-pumpkin.gif differ diff --git a/src/assets/adoptables/kittyfriends/artwork-vampire.gif b/src/assets/adoptables/kittyfriends/artwork-vampire.gif new file mode 100644 index 00000000..b5c79c1a Binary files /dev/null and b/src/assets/adoptables/kittyfriends/artwork-vampire.gif differ diff --git a/src/assets/adoptables/kittyfriends/artwork-witch.gif b/src/assets/adoptables/kittyfriends/artwork-witch.gif new file mode 100644 index 00000000..75ab6cd3 Binary files /dev/null and b/src/assets/adoptables/kittyfriends/artwork-witch.gif differ diff --git a/src/assets/adoptables/kittyfriends/krish.png b/src/assets/adoptables/kittyfriends/krish.png new file mode 100644 index 00000000..44802248 Binary files /dev/null and b/src/assets/adoptables/kittyfriends/krish.png differ diff --git a/src/assets/adoptables/kittyfriends/leilukin-blackkitty.png b/src/assets/adoptables/kittyfriends/leilukin-blackkitty.png new file mode 100644 index 00000000..d512f470 Binary files /dev/null and b/src/assets/adoptables/kittyfriends/leilukin-blackkitty.png differ diff --git a/src/assets/adoptables/kittyfriends/leilukin-purplekitty.png b/src/assets/adoptables/kittyfriends/leilukin-purplekitty.png new file mode 100644 index 00000000..18f919ef Binary files /dev/null and b/src/assets/adoptables/kittyfriends/leilukin-purplekitty.png differ diff --git a/src/assets/adoptables/kittyfriends/lina-strawberry-kitty.gif b/src/assets/adoptables/kittyfriends/lina-strawberry-kitty.gif new file mode 100644 index 00000000..a3bfdaa7 Binary files /dev/null and b/src/assets/adoptables/kittyfriends/lina-strawberry-kitty.gif differ diff --git a/src/assets/adoptables/kittyfriends/owl-small-owlcat.gif b/src/assets/adoptables/kittyfriends/owl-small-owlcat.gif new file mode 100644 index 00000000..904aca52 Binary files /dev/null and b/src/assets/adoptables/kittyfriends/owl-small-owlcat.gif differ diff --git a/src/assets/adoptables/kittyfriends/rosemary-ghostcat.gif b/src/assets/adoptables/kittyfriends/rosemary-ghostcat.gif new file mode 100644 index 00000000..45c8ccb7 Binary files /dev/null and b/src/assets/adoptables/kittyfriends/rosemary-ghostcat.gif differ diff --git a/src/assets/adoptables/kittyfriends/sakuradreams-Simba.gif b/src/assets/adoptables/kittyfriends/sakuradreams-Simba.gif new file mode 100644 index 00000000..34fa97c2 Binary files /dev/null and b/src/assets/adoptables/kittyfriends/sakuradreams-Simba.gif differ diff --git a/src/assets/adoptables/kittyfriends/solaria-creampuffs.png b/src/assets/adoptables/kittyfriends/solaria-creampuffs.png new file mode 100644 index 00000000..14715569 Binary files /dev/null and b/src/assets/adoptables/kittyfriends/solaria-creampuffs.png differ diff --git a/src/assets/adoptables/kittyfriends/solaria-garfield.gif b/src/assets/adoptables/kittyfriends/solaria-garfield.gif new file mode 100644 index 00000000..9242e8c9 Binary files /dev/null and b/src/assets/adoptables/kittyfriends/solaria-garfield.gif differ diff --git a/src/assets/adoptables/lostletters-moomin.png b/src/assets/adoptables/lostletters-moomin.png new file mode 100644 index 00000000..9262fd51 Binary files /dev/null and b/src/assets/adoptables/lostletters-moomin.png differ diff --git a/src/assets/adoptables/lou-frog.gif b/src/assets/adoptables/lou-frog.gif new file mode 100644 index 00000000..cfc2317b Binary files /dev/null and b/src/assets/adoptables/lou-frog.gif differ diff --git a/src/assets/adoptables/lou-greenkaoani.gif b/src/assets/adoptables/lou-greenkaoani.gif new file mode 100644 index 00000000..9d37391a Binary files /dev/null and b/src/assets/adoptables/lou-greenkaoani.gif differ diff --git a/src/assets/adoptables/lou-maneki-neko.png b/src/assets/adoptables/lou-maneki-neko.png new file mode 100644 index 00000000..a244bbc9 Binary files /dev/null and b/src/assets/adoptables/lou-maneki-neko.png differ diff --git a/src/assets/adoptables/lou-tamagotchi.gif b/src/assets/adoptables/lou-tamagotchi.gif new file mode 100644 index 00000000..d3569adb Binary files /dev/null and b/src/assets/adoptables/lou-tamagotchi.gif differ diff --git a/src/assets/adoptables/pantson/00-join.gif b/src/assets/adoptables/pantson/00-join.gif new file mode 100644 index 00000000..62d49967 Binary files /dev/null and b/src/assets/adoptables/pantson/00-join.gif differ diff --git a/src/assets/adoptables/pantson/anna-kale.png b/src/assets/adoptables/pantson/anna-kale.png new file mode 100644 index 00000000..4cf3da58 Binary files /dev/null and b/src/assets/adoptables/pantson/anna-kale.png differ diff --git a/src/assets/adoptables/pantson/anna-not-a-brick.png b/src/assets/adoptables/pantson/anna-not-a-brick.png new file mode 100644 index 00000000..464763f6 Binary files /dev/null and b/src/assets/adoptables/pantson/anna-not-a-brick.png differ diff --git a/src/assets/adoptables/pantson/ebony-mosstone.png b/src/assets/adoptables/pantson/ebony-mosstone.png new file mode 100644 index 00000000..ec45b3c6 Binary files /dev/null and b/src/assets/adoptables/pantson/ebony-mosstone.png differ diff --git a/src/assets/adoptables/pantson/ebony-total-eclipse.png b/src/assets/adoptables/pantson/ebony-total-eclipse.png new file mode 100644 index 00000000..3835a0a9 Binary files /dev/null and b/src/assets/adoptables/pantson/ebony-total-eclipse.png differ diff --git a/src/assets/adoptables/pantson/fritzi-magical-tour.png b/src/assets/adoptables/pantson/fritzi-magical-tour.png new file mode 100644 index 00000000..adacb797 Binary files /dev/null and b/src/assets/adoptables/pantson/fritzi-magical-tour.png differ diff --git a/src/assets/adoptables/pantson/fritzi-plastic-ono.png b/src/assets/adoptables/pantson/fritzi-plastic-ono.png new file mode 100644 index 00000000..8c8f10f2 Binary files /dev/null and b/src/assets/adoptables/pantson/fritzi-plastic-ono.png differ diff --git a/src/assets/adoptables/pantson/fritzi-rubber-soul.png b/src/assets/adoptables/pantson/fritzi-rubber-soul.png new file mode 100644 index 00000000..8280f01e Binary files /dev/null and b/src/assets/adoptables/pantson/fritzi-rubber-soul.png differ diff --git a/src/assets/adoptables/pantson/ginnygravity-robins-egg.png b/src/assets/adoptables/pantson/ginnygravity-robins-egg.png new file mode 100644 index 00000000..d74ca728 Binary files /dev/null and b/src/assets/adoptables/pantson/ginnygravity-robins-egg.png differ diff --git a/src/assets/adoptables/pantson/joejenett-chocolato.png b/src/assets/adoptables/pantson/joejenett-chocolato.png new file mode 100644 index 00000000..50723520 Binary files /dev/null and b/src/assets/adoptables/pantson/joejenett-chocolato.png differ diff --git a/src/assets/adoptables/pantson/leilukin-grape-juice.png b/src/assets/adoptables/pantson/leilukin-grape-juice.png new file mode 100644 index 00000000..b2d9f454 Binary files /dev/null and b/src/assets/adoptables/pantson/leilukin-grape-juice.png differ diff --git a/src/assets/adoptables/pantson/lina-morning-mist.png b/src/assets/adoptables/pantson/lina-morning-mist.png new file mode 100644 index 00000000..da12d797 Binary files /dev/null and b/src/assets/adoptables/pantson/lina-morning-mist.png differ diff --git a/src/assets/adoptables/pantson/manyface-lizard.png b/src/assets/adoptables/pantson/manyface-lizard.png new file mode 100644 index 00000000..86bfe3d1 Binary files /dev/null and b/src/assets/adoptables/pantson/manyface-lizard.png differ diff --git a/src/assets/adoptables/pantson/manyface-psyche.png b/src/assets/adoptables/pantson/manyface-psyche.png new file mode 100644 index 00000000..69da3078 Binary files /dev/null and b/src/assets/adoptables/pantson/manyface-psyche.png differ diff --git a/src/assets/adoptables/pantson/sakuradreams-lilac-dreams.png b/src/assets/adoptables/pantson/sakuradreams-lilac-dreams.png new file mode 100644 index 00000000..4e10b293 Binary files /dev/null and b/src/assets/adoptables/pantson/sakuradreams-lilac-dreams.png differ diff --git a/src/assets/adoptables/pantson/sakuradreams-sakura-pink.png b/src/assets/adoptables/pantson/sakuradreams-sakura-pink.png new file mode 100644 index 00000000..58c9dc6a Binary files /dev/null and b/src/assets/adoptables/pantson/sakuradreams-sakura-pink.png differ diff --git a/src/assets/adoptables/pantson/v-star-sticker.png b/src/assets/adoptables/pantson/v-star-sticker.png new file mode 100644 index 00000000..9a66f4b0 Binary files /dev/null and b/src/assets/adoptables/pantson/v-star-sticker.png differ diff --git a/src/assets/adoptables/pantson/velvet-cherry-red.png b/src/assets/adoptables/pantson/velvet-cherry-red.png new file mode 100644 index 00000000..ae388cbc Binary files /dev/null and b/src/assets/adoptables/pantson/velvet-cherry-red.png differ diff --git a/src/assets/adoptables/pixelcliques/madebyagirl.png b/src/assets/adoptables/pixelcliques/madebyagirl.png new file mode 100644 index 00000000..877a20ea Binary files /dev/null and b/src/assets/adoptables/pixelcliques/madebyagirl.png differ diff --git a/src/assets/adoptables/pixelcliques/theapple.gif b/src/assets/adoptables/pixelcliques/theapple.gif new file mode 100644 index 00000000..4a31dec8 Binary files /dev/null and b/src/assets/adoptables/pixelcliques/theapple.gif differ diff --git a/src/assets/adoptables/salad-magazine/semper-inksnail-black.png b/src/assets/adoptables/salad-magazine/semper-inksnail-black.png new file mode 100644 index 00000000..fa10b8fc Binary files /dev/null and b/src/assets/adoptables/salad-magazine/semper-inksnail-black.png differ diff --git a/src/assets/adoptables/salad-magazine/semper-inksnail-sparkle.png b/src/assets/adoptables/salad-magazine/semper-inksnail-sparkle.png new file mode 100644 index 00000000..eb80f36e Binary files /dev/null and b/src/assets/adoptables/salad-magazine/semper-inksnail-sparkle.png differ diff --git a/src/assets/adoptables/wings-dolphinclassic.gif b/src/assets/adoptables/wings-dolphinclassic.gif new file mode 100644 index 00000000..f84afe96 Binary files /dev/null and b/src/assets/adoptables/wings-dolphinclassic.gif differ diff --git a/src/assets/adoptables/wings-rainbowmoon.png b/src/assets/adoptables/wings-rainbowmoon.png new file mode 100644 index 00000000..c5338e5a Binary files /dev/null and b/src/assets/adoptables/wings-rainbowmoon.png differ diff --git a/src/assets/banners/harry-potter-free-site.png b/src/assets/banners/harry-potter-free-site.png new file mode 100644 index 00000000..21d8814a Binary files /dev/null and b/src/assets/banners/harry-potter-free-site.png differ diff --git a/src/assets/buttons/badges/coffee-powered.svg b/src/assets/buttons/badges/coffee-powered.svg new file mode 100644 index 00000000..cd39516e --- /dev/null +++ b/src/assets/buttons/badges/coffee-powered.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/buttons/badges/fight-fascism.jpg b/src/assets/buttons/badges/fight-fascism.jpg new file mode 100644 index 00000000..abd142fa Binary files /dev/null and b/src/assets/buttons/badges/fight-fascism.jpg differ diff --git a/src/assets/buttons/badges/people-pledge.svg b/src/assets/buttons/badges/people-pledge.svg new file mode 100644 index 00000000..4376a6c3 --- /dev/null +++ b/src/assets/buttons/badges/people-pledge.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/assets/buttons/badges/valid-atom.png b/src/assets/buttons/badges/valid-atom.png new file mode 100644 index 00000000..11a853b0 Binary files /dev/null and b/src/assets/buttons/badges/valid-atom.png differ diff --git a/src/assets/buttons/communities/32-bit-cafe.png b/src/assets/buttons/communities/32-bit-cafe.png new file mode 100644 index 00000000..52edf506 Binary files /dev/null and b/src/assets/buttons/communities/32-bit-cafe.png differ diff --git a/src/assets/buttons/communities/saladmagazine.png b/src/assets/buttons/communities/saladmagazine.png new file mode 100644 index 00000000..19f21253 Binary files /dev/null and b/src/assets/buttons/communities/saladmagazine.png differ diff --git a/src/assets/buttons/directories/accessiblenet.png b/src/assets/buttons/directories/accessiblenet.png new file mode 100644 index 00000000..1054d02d Binary files /dev/null and b/src/assets/buttons/directories/accessiblenet.png differ diff --git a/src/assets/buttons/directories/bukmarkclub.png b/src/assets/buttons/directories/bukmarkclub.png new file mode 100644 index 00000000..d0db15f1 Binary files /dev/null and b/src/assets/buttons/directories/bukmarkclub.png differ diff --git a/src/assets/buttons/directories/indieseek.png b/src/assets/buttons/directories/indieseek.png new file mode 100644 index 00000000..265a8ee6 Binary files /dev/null and b/src/assets/buttons/directories/indieseek.png differ diff --git a/src/assets/buttons/directories/linklane.png b/src/assets/buttons/directories/linklane.png new file mode 100644 index 00000000..a6771431 Binary files /dev/null and b/src/assets/buttons/directories/linklane.png differ diff --git a/src/assets/buttons/directories/list-me.png b/src/assets/buttons/directories/list-me.png new file mode 100644 index 00000000..e5858061 Binary files /dev/null and b/src/assets/buttons/directories/list-me.png differ diff --git a/src/assets/buttons/directories/responsiveweb.png b/src/assets/buttons/directories/responsiveweb.png new file mode 100644 index 00000000..13694150 Binary files /dev/null and b/src/assets/buttons/directories/responsiveweb.png differ diff --git a/src/assets/buttons/directories/smoothsailing.png b/src/assets/buttons/directories/smoothsailing.png new file mode 100644 index 00000000..adec903d Binary files /dev/null and b/src/assets/buttons/directories/smoothsailing.png differ diff --git a/src/assets/buttons/misc/ko-fi.webp b/src/assets/buttons/misc/ko-fi.webp new file mode 100644 index 00000000..46402609 Binary files /dev/null and b/src/assets/buttons/misc/ko-fi.webp differ diff --git a/src/assets/buttons/misc/standwithpalestine.png b/src/assets/buttons/misc/standwithpalestine.png new file mode 100644 index 00000000..70a5e9eb Binary files /dev/null and b/src/assets/buttons/misc/standwithpalestine.png differ diff --git a/src/assets/buttons/pride/9_stripe.png b/src/assets/buttons/pride/9_stripe.png new file mode 100644 index 00000000..195e8911 Binary files /dev/null and b/src/assets/buttons/pride/9_stripe.png differ diff --git a/src/assets/buttons/pride/agender.png b/src/assets/buttons/pride/agender.png new file mode 100644 index 00000000..e03c95e3 Binary files /dev/null and b/src/assets/buttons/pride/agender.png differ diff --git a/src/assets/buttons/pride/bigender.png b/src/assets/buttons/pride/bigender.png new file mode 100644 index 00000000..3d4cbcba Binary files /dev/null and b/src/assets/buttons/pride/bigender.png differ diff --git a/src/assets/buttons/pride/demigirl.png b/src/assets/buttons/pride/demigirl.png new file mode 100644 index 00000000..5f8333cf Binary files /dev/null and b/src/assets/buttons/pride/demigirl.png differ diff --git a/src/assets/buttons/pride/disability.png b/src/assets/buttons/pride/disability.png new file mode 100644 index 00000000..e801e463 Binary files /dev/null and b/src/assets/buttons/pride/disability.png differ diff --git a/src/assets/buttons/pride/greyromantic.png b/src/assets/buttons/pride/greyromantic.png new file mode 100644 index 00000000..2e7d80c9 Binary files /dev/null and b/src/assets/buttons/pride/greyromantic.png differ diff --git a/src/assets/buttons/pride/greysexual.png b/src/assets/buttons/pride/greysexual.png new file mode 100644 index 00000000..872f5ea2 Binary files /dev/null and b/src/assets/buttons/pride/greysexual.png differ diff --git a/src/assets/buttons/pride/lesbian.png b/src/assets/buttons/pride/lesbian.png new file mode 100644 index 00000000..63e3b80c Binary files /dev/null and b/src/assets/buttons/pride/lesbian.png differ diff --git a/src/assets/buttons/pride/nonbinary.png b/src/assets/buttons/pride/nonbinary.png new file mode 100644 index 00000000..e0377abe Binary files /dev/null and b/src/assets/buttons/pride/nonbinary.png differ diff --git a/src/assets/buttons/pride/progress.png b/src/assets/buttons/pride/progress.png new file mode 100644 index 00000000..2b27b04e Binary files /dev/null and b/src/assets/buttons/pride/progress.png differ diff --git a/src/assets/buttons/sites/10kph.png b/src/assets/buttons/sites/10kph.png new file mode 100644 index 00000000..472099b9 Binary files /dev/null and b/src/assets/buttons/sites/10kph.png differ diff --git a/src/assets/buttons/sites/alyaza.gif b/src/assets/buttons/sites/alyaza.gif new file mode 100644 index 00000000..00ea8b3e Binary files /dev/null and b/src/assets/buttons/sites/alyaza.gif differ diff --git a/src/assets/buttons/sites/autisticasfxxk.gif b/src/assets/buttons/sites/autisticasfxxk.gif new file mode 100644 index 00000000..022e28e2 Binary files /dev/null and b/src/assets/buttons/sites/autisticasfxxk.gif differ diff --git a/src/assets/buttons/sites/ballonlea.png b/src/assets/buttons/sites/ballonlea.png new file mode 100644 index 00000000..35ed8af7 Binary files /dev/null and b/src/assets/buttons/sites/ballonlea.png differ diff --git a/src/assets/buttons/sites/beepbird.gif b/src/assets/buttons/sites/beepbird.gif new file mode 100644 index 00000000..f0b6857a Binary files /dev/null and b/src/assets/buttons/sites/beepbird.gif differ diff --git a/src/assets/buttons/sites/chrisburnell.gif b/src/assets/buttons/sites/chrisburnell.gif new file mode 100644 index 00000000..c033fe5a Binary files /dev/null and b/src/assets/buttons/sites/chrisburnell.gif differ diff --git a/src/assets/buttons/sites/darylsun.webp b/src/assets/buttons/sites/darylsun.webp new file mode 100644 index 00000000..4e457ce7 Binary files /dev/null and b/src/assets/buttons/sites/darylsun.webp differ diff --git a/src/assets/buttons/sites/divergentrays.png b/src/assets/buttons/sites/divergentrays.png new file mode 100644 index 00000000..13a30b00 Binary files /dev/null and b/src/assets/buttons/sites/divergentrays.png differ diff --git a/src/assets/buttons/sites/dryadglen.png b/src/assets/buttons/sites/dryadglen.png new file mode 100644 index 00000000..9e708cb3 Binary files /dev/null and b/src/assets/buttons/sites/dryadglen.png differ diff --git a/src/assets/buttons/sites/frills.png b/src/assets/buttons/sites/frills.png new file mode 100644 index 00000000..97f9b349 Binary files /dev/null and b/src/assets/buttons/sites/frills.png differ diff --git a/src/assets/buttons/sites/groundedwren.png b/src/assets/buttons/sites/groundedwren.png new file mode 100644 index 00000000..3ed78c84 Binary files /dev/null and b/src/assets/buttons/sites/groundedwren.png differ diff --git a/src/assets/buttons/sites/grubdog.png b/src/assets/buttons/sites/grubdog.png new file mode 100644 index 00000000..96c8e525 Binary files /dev/null and b/src/assets/buttons/sites/grubdog.png differ diff --git a/src/assets/buttons/sites/jasminesjournal.png b/src/assets/buttons/sites/jasminesjournal.png new file mode 100644 index 00000000..275e383c Binary files /dev/null and b/src/assets/buttons/sites/jasminesjournal.png differ diff --git a/src/assets/buttons/sites/jefbecker.png b/src/assets/buttons/sites/jefbecker.png new file mode 100644 index 00000000..fbcc2fef Binary files /dev/null and b/src/assets/buttons/sites/jefbecker.png differ diff --git a/src/assets/buttons/sites/kalechips.png b/src/assets/buttons/sites/kalechips.png new file mode 100644 index 00000000..de731020 Binary files /dev/null and b/src/assets/buttons/sites/kalechips.png differ diff --git a/src/assets/buttons/sites/lina.gif b/src/assets/buttons/sites/lina.gif new file mode 100644 index 00000000..60c602d9 Binary files /dev/null and b/src/assets/buttons/sites/lina.gif differ diff --git a/src/assets/buttons/sites/lostletters.gif b/src/assets/buttons/sites/lostletters.gif new file mode 100644 index 00000000..08062813 Binary files /dev/null and b/src/assets/buttons/sites/lostletters.gif differ diff --git a/src/assets/buttons/sites/manyface.png b/src/assets/buttons/sites/manyface.png new file mode 100644 index 00000000..738952f9 Binary files /dev/null and b/src/assets/buttons/sites/manyface.png differ diff --git a/src/assets/buttons/sites/melvian.png b/src/assets/buttons/sites/melvian.png new file mode 100644 index 00000000..d96e63df Binary files /dev/null and b/src/assets/buttons/sites/melvian.png differ diff --git a/src/assets/buttons/sites/mycorrhiza.png b/src/assets/buttons/sites/mycorrhiza.png new file mode 100644 index 00000000..65e7f3ed Binary files /dev/null and b/src/assets/buttons/sites/mycorrhiza.png differ diff --git a/src/assets/buttons/sites/pinkvampyr.gif b/src/assets/buttons/sites/pinkvampyr.gif new file mode 100644 index 00000000..37f136f6 Binary files /dev/null and b/src/assets/buttons/sites/pinkvampyr.gif differ diff --git a/src/assets/buttons/sites/ribose.png b/src/assets/buttons/sites/ribose.png new file mode 100644 index 00000000..0283328c Binary files /dev/null and b/src/assets/buttons/sites/ribose.png differ diff --git a/src/assets/buttons/sites/sakuradreams.gif b/src/assets/buttons/sites/sakuradreams.gif new file mode 100644 index 00000000..0f94d1df Binary files /dev/null and b/src/assets/buttons/sites/sakuradreams.gif differ diff --git a/src/assets/buttons/sites/sanguineroyal.gif b/src/assets/buttons/sites/sanguineroyal.gif new file mode 100644 index 00000000..0af30f2f Binary files /dev/null and b/src/assets/buttons/sites/sanguineroyal.gif differ diff --git a/src/assets/buttons/sites/solaria.png b/src/assets/buttons/sites/solaria.png new file mode 100644 index 00000000..c33c5e17 Binary files /dev/null and b/src/assets/buttons/sites/solaria.png differ diff --git a/src/assets/buttons/sites/starbreaker.avif b/src/assets/buttons/sites/starbreaker.avif new file mode 100644 index 00000000..90f179ed Binary files /dev/null and b/src/assets/buttons/sites/starbreaker.avif differ diff --git a/src/assets/buttons/sites/symliadoo.png b/src/assets/buttons/sites/symliadoo.png new file mode 100644 index 00000000..198e53c7 Binary files /dev/null and b/src/assets/buttons/sites/symliadoo.png differ diff --git a/src/assets/buttons/sites/whiona.png b/src/assets/buttons/sites/whiona.png new file mode 100644 index 00000000..0d35601a Binary files /dev/null and b/src/assets/buttons/sites/whiona.png differ diff --git a/src/assets/buttons/sites/wings.png b/src/assets/buttons/sites/wings.png new file mode 100644 index 00000000..1e5f1716 Binary files /dev/null and b/src/assets/buttons/sites/wings.png differ diff --git a/src/assets/buttons/sites/xandra.png b/src/assets/buttons/sites/xandra.png new file mode 100644 index 00000000..79990e6d Binary files /dev/null and b/src/assets/buttons/sites/xandra.png differ diff --git a/src/assets/buttons/webrings/queercoded-left.png b/src/assets/buttons/webrings/queercoded-left.png new file mode 100644 index 00000000..e38d6110 Binary files /dev/null and b/src/assets/buttons/webrings/queercoded-left.png differ diff --git a/src/assets/buttons/webrings/queercoded-right.png b/src/assets/buttons/webrings/queercoded-right.png new file mode 100644 index 00000000..a4eaa35e Binary files /dev/null and b/src/assets/buttons/webrings/queercoded-right.png differ diff --git a/src/assets/buttons/webrings/queercoded.png b/src/assets/buttons/webrings/queercoded.png new file mode 100644 index 00000000..e907872f Binary files /dev/null and b/src/assets/buttons/webrings/queercoded.png differ diff --git a/src/assets/cliques/30plusclub.gif b/src/assets/cliques/30plusclub.gif new file mode 100644 index 00000000..76ec96f7 Binary files /dev/null and b/src/assets/cliques/30plusclub.gif differ diff --git a/src/assets/cliques/OTF.png b/src/assets/cliques/OTF.png new file mode 100644 index 00000000..5cbecb2e Binary files /dev/null and b/src/assets/cliques/OTF.png differ diff --git a/src/assets/cliques/breloom.png b/src/assets/cliques/breloom.png new file mode 100644 index 00000000..fd162b2d Binary files /dev/null and b/src/assets/cliques/breloom.png differ diff --git a/src/assets/cliques/caffeineNATION.png b/src/assets/cliques/caffeineNATION.png new file mode 100644 index 00000000..f1d795fb Binary files /dev/null and b/src/assets/cliques/caffeineNATION.png differ diff --git a/src/assets/cliques/dogperson.png b/src/assets/cliques/dogperson.png new file mode 100644 index 00000000..6df52a8d Binary files /dev/null and b/src/assets/cliques/dogperson.png differ diff --git a/src/assets/cliques/linked.png b/src/assets/cliques/linked.png new file mode 100644 index 00000000..5b033208 Binary files /dev/null and b/src/assets/cliques/linked.png differ diff --git a/src/assets/cliques/myjam.png b/src/assets/cliques/myjam.png new file mode 100644 index 00000000..eb3453ca Binary files /dev/null and b/src/assets/cliques/myjam.png differ diff --git a/src/assets/cliques/unexpectedsong.png b/src/assets/cliques/unexpectedsong.png new file mode 100644 index 00000000..6b3c9da0 Binary files /dev/null and b/src/assets/cliques/unexpectedsong.png differ diff --git a/src/assets/css/a11y-syntax-highlighting-dark.css b/src/assets/css/a11y-syntax-highlighting-dark.css new file mode 100644 index 00000000..b565c0d5 --- /dev/null +++ b/src/assets/css/a11y-syntax-highlighting-dark.css @@ -0,0 +1,218 @@ +/* + * a11y theme for JavaScript, CSS, and HTML + * Based on the okaidia theme: https://github.com/PrismJS/prism/blob/gh-pages/themes/prism-okaidia.css + * @author ericwbailey + */ + +/* + * MARK: Setup + */ + @layer vendor-prism { + @media (forced-colors: none), (forced-colors: active) { + :root { + --prism-a11y-border-radius: 0.3em; + --prism-a11y-font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + --prism-a11y-line-height: 1.5; + --prism-a11y-code-block-margin: 0.5em 0; + --prism-a11y-code-block-padding: 1em; + --prism-a11y-code-inline-padding: 0.1em; + --prism-a11y-width-border: 1px; + --prism-a11y-width-tab: 2; + } + } + + @media (forced-colors: none), (forced-colors: active) { + :root { + --prism-a11y-color-background: hsla(0, 0%, 17%, 1); + --prism-a11y-color-text-no-token: hsla(60, 30%, 96%, 1); + --prism-a11y-color-text-comment: hsla(54, 32%, 75%, 1); + --prism-a11y-color-text-blue: hsla(180, 100%, 44%, 1); + --prism-a11y-color-text-green: hsla(80, 75%, 55%, 1); + --prism-a11y-color-text-gray: hsla(60, 30%, 96%, 1); + --prism-a11y-color-text-purple: hsla(291, 30%, 83%, 1); + --prism-a11y-color-text-red: hsla(17, 100%, 74%, 1); + --prism-a11y-color-text-yellow: hsla(51, 100%, 50%, 1); + --prism-a11y-plugin-color-border: hsla(51, 100%, 50%, 0.55); + --prism-a11y-plugin-color-background: hsla(51, 100%, 50%, 0.1); + } + } + + + @media (forced-colors: none), (forced-colors: active) { + /* + * MARK: Theme + */ + :where( + code[class*="language-"], + pre[class*="language-"] + ) { + color: var(--prism-a11y-color-text-no-token); + background: var(--prism-a11y-color-background); + font-family: var(--prism-a11y-font-family); + text-align: start; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: var(--prism-a11y-line-height); + + -moz-tab-size: var(--prism-a11y-width-tab); + -o-tab-size: var(--prism-a11y-width-tab); + tab-size: var(--prism-a11y-width-tab); + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; + } + + /* Code blocks */ + pre[class*="language-"] { + padding: var(--prism-a11y-code-block-padding); + margin: var(--prism-a11y-code-block-margin); + overflow: auto; + border-radius: var(--prism-a11y-border-radius); + } + + :where( + :not(pre) > code[class*="language-"], + pre[class*="language-"] + ) { + background: var(--prism-a11y-color-background); + } + + /* Inline code */ + :not(pre) > code[class*="language-"] { + padding: var(--prism-a11y-code-inline-padding); + border-radius: var(--prism-a11y-border-radius); + white-space: normal; + } + + :where( + .token.comment, + .token.prolog, + .token.doctype, + .token.cdata + ) { + color: var(--prism-a11y-color-text-comment); + } + + .token.punctuation { + color: var(--prism-a11y-color-text-gray); + } + + :where( + .token.property, + .token.tag, + .token.constant, + .token.symbol, + .token.deleted + ) { + color: var(--prism-a11y-color-text-red); + } + + :where( + .token.operator, + .token.entity, + .token.url, + .language-css .token.string, + .style .token.string, + .token.variable, + .token.keyword + ) { + color: var(--prism-a11y-color-text-blue); + } + + :where( + .token.selector, + .token.attr-name, + .token.string, + .token.char, + .token.builtin, + .token.inserted + ) { + color: var(--prism-a11y-color-text-green); + } + + :where( + .token.atrule, + .token.attr-value, + .token.function, + .token.regex, + .token.important + ) { + color: var(--prism-a11y-color-text-yellow); + } + + :where( + .token.boolean, + .token.number, + .token.keyword + ) { + color: var(--prism-a11y-color-text-purple); + } + + :where( + .token.important, + .token.bold + ) { + font-weight: bold; + } + + .token.italic { + font-style: italic; + } + + .token.entity { + cursor: help; + } + + + /* + * MARK: Plugin support + */ + /* Line highlight */ + .line-highlight { + background: var(--prism-a11y-plugin-color-background); + border-top: var(--prism-a11y-width-border) solid var(--prism-a11y-plugin-color-border); + border-bottom: var(--prism-a11y-width-border) solid var(--prism-a11y-plugin-color-border); + } + + /* Line numbers */ + .line-numbers .line-numbers-rows { + border-right: var(--prism-a11y-width-border) solid var(--prism-a11y-color-text-no-token); + } + + .line-numbers-rows > span:before { + color: var(--prism-a11y-color-text-comment); + } + } + + + /* + * MARK: Forced color mode support + */ + @media (forced-colors: active) { + :root { + --prism-a11y-color-background: Canvas; + --prism-a11y-color-text-no-token: CanvasText; + --prism-a11y-color-text-comment: GrayText; + --prism-a11y-color-text-blue: LinkText; + --prism-a11y-color-text-gray: LinkText; + --prism-a11y-color-text-green: CanvasText; + --prism-a11y-color-text-purple: CanvasText; + --prism-a11y-color-text-red: CanvasText; + --prism-a11y-color-text-yellow: GrayText; + --prism-a11y-plugin-color-border: LinkText; + --prism-a11y-plugin-color-background: Canvas; + } + + :where( + .token.boolean, + .token.number, + .token.keyword + ) { + font-weight: bold; + } + } +} \ No newline at end of file diff --git a/src/assets/css/asummersend.css b/src/assets/css/asummersend.css new file mode 100644 index 00000000..a2ea7501 --- /dev/null +++ b/src/assets/css/asummersend.css @@ -0,0 +1,32 @@ +:root { + --clr-body-bg: #1f0033; + --img-body-bg: none; + --clr-body-txt: #fceaff; + --clr-content-bg: #101010; + + --clr-top-btn-bg: #fd60e1; + --clr-top-btn-txt: #101010; + + --clr-main-heading: #FF29D8; + --clr-sub-heading: #FF29D8; + --clr-title-border: #d3aad5; + --clr-bold-txt: #ff9933; + --clr-link: #d270ff; + --clr-link-hover: #7E4197; + --clr-quote-bg: #222121; + --clr-quote-border: #4d4385; + + --clr-code-bg: #241445; + --clr-code-border: #82668f; + --clr-dates: rgb(158, 203, 255); + + --clr-link-btn-bg: #873eb5; + --clr-link-btn-txt: white; + --clr-link-btn-hover: #241445; + + --clr-hero-bg: #101010; + --clr-navbar-bg: #181818; + --clr-navbar-link: white; + + --clr-main-footer-bg: #181818; +} diff --git a/src/assets/css/cassettebeasts.css b/src/assets/css/cassettebeasts.css new file mode 100644 index 00000000..8303fe8f --- /dev/null +++ b/src/assets/css/cassettebeasts.css @@ -0,0 +1,40 @@ +:root { + color-scheme: light dark; + + --clr-body-bg: light-dark(#e4e3e3, #141414); + --clr-body-txt: light-dark(#141414, #fff); + --clr-content-bg: light-dark(#ffffff, #242424); + + --clr-top-btn-bg: light-dark(#552190, #552190); + --clr-top-btn-txt: #ffffff; + + --clr-main-heading: light-dark(#171717, #daaced); + --clr-sub-heading: light-dark(#111111, #fff); + --clr-title-border: light-dark(#7629db, #9964de); + --clr-bold-txt: light-dark(#da4500, #ff9869); + --clr-link: light-dark(#7629db, #ce97ff); + --clr-link-hover: light-dark(#270e48, #b366f7); + --clr-quote-bg: light-dark(#f3f2f2, #141414); + --clr-quote-border: light-dark(#414141, #f3f2f2); + --clr-cw-hover: #fae5e5; + + --clr-code-bg: #f3f2f2; + --clr-code-border: #414141; + --clr-dates: #3a96ff; + + --clr-link-btn-bg: #873eb5; + --clr-link-btn-txt: white; + --clr-link-btn-hover: #241445; + + --clr-hero-bg: #7944B6; + --clr-navbar-bg: light-dark(#9b59b6, #3a0873); + --clr-navbar-link: white; + + --clr-main-footer-bg: light-dark(#9b59b6, #3a0873); +} + +.hero__top-bar, +.footer, +.footer a { color: var(--clr-navbar-link); } + +.footer a:focus { outline-color: var(--clr-navbar-link); } \ No newline at end of file diff --git a/src/assets/css/components.css b/src/assets/css/components.css new file mode 100644 index 00000000..76434589 --- /dev/null +++ b/src/assets/css/components.css @@ -0,0 +1,242 @@ +/* Text Box */ +.text-box { + background: var(--clr-quote-bg); + border: 0.1em solid var(--clr-main-heading); + padding: 0.8em; + margin: 1em 0; + display: grid; + gap: 1em; +} + +/* Inline Navigation */ +.inline-nav { + --inline-nav-gap: 0.5em; + list-style-type: ""; + margin: 0; + padding: 0; + display: flex; + gap: 0.25em var(--inline-nav-gap); + flex-wrap: wrap; +} + +.inline-nav li:not(:last-child)::after { + content: '•'; + padding-left: var(--inline-nav-gap); +} + +/* Mod Entry */ +.mod-entry, +.mod-entry__downloads { + display: grid; + align-items: center; +} + +.mod-entry { + gap: 1em; + background: var(--clr-mod-entry-bg); + margin: 1em 0; + padding: 1em; +} + +.mod-entry__downloads { gap: 0.5em; } + +/* Tablet screen size */ +@media only screen and (min-width: 37.5rem) { + .mod-entry__downloads { + grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); + } +} + +/* Skip to content button */ +.skip-btn a { + position: absolute; + display: inline-block; + left: 0; + top: -1000px; + overflow: hidden; + transition: top 0.5s ease; + background: var(--clr-content-bg); + font-size: 1.25rem; + z-index: 1000; + padding: 0.3em 0.7em; +} + +.skip-btn a:focus { + top: 0; + transition: top 0.3s ease; +} + +/* Link button */ +.link-btn--wrapper { + list-style-type: ""; + padding: 0; + display: flex; + flex-wrap: wrap; + gap: 0.5em; +} + +.link-btn { + --btn-right-padding: 0.8em; + text-align: center; + display: inline-block; + border: 0.1em solid var(--clr-link-btn-bg); + border-radius: 0.5em; + padding: 0.4em var(--btn-right-padding); + background: var(--clr-link-btn-bg); + color: var(--clr-link-btn-txt); + font-weight: 700; +} + +.link-btn, +.link-btn:hover, +.link-btn:visited { text-decoration: none; } + +.link-btn:hover { + background: var(--clr-link-btn-hover); + transition: 0.2s; +} + +.link-btn:focus { + outline: 0.15em solid var(--clr-link-btn-txt); + outline-offset: -0.25em; +} + +a.link-btn[href^="http"]:not([href*="leilukin.com"]) { padding-right: calc(var(--btn-right-padding) + var(--sz-external-link)); } + +/* Button to copy code snippets */ +.cc-btn { + font-size: 0.8em; + display: flex; + align-items: center; + gap: 0.2em; + border: 0.15em solid var(--clr-code-border); + border-radius: 0.2em; + background: var(--clr-link-btn-bg); + color: var(--clr-link-btn-txt); +} + +/* Content Disclosure */ +* + .content-disclosure { margin-top: var(--sz-paragraph-margin); } +.content-disclosure__summary { font-weight: 700; } +.content-disclosure__content, +.content-disclosure__content p + p { margin-top: 1em; } + +.content-disclosure__content { + padding: 1em; + border: 0.15em solid var(--clr-title-border); +} + +/* Content warning disclosure */ +* + .contnet-warning { margin-top: var(--sz-paragraph-margin); } + +.contnet-warning { + border: 0.1em solid var(--clr-title-border); + border-radius: 0.2em; +} + +.contnet-warning__warning { + padding: 0.8em; + --stripe-color: var(--clr-quote-bg); + background-image: repeating-linear-gradient( + 45deg, + transparent, + transparent 0.5em, + var(--stripe-color) 0.5em, + var(--stripe-color) 1em + ); +} + +.contnet-warning__warning:hover, +.contnet-warning__warning:focus { --stripe-color: var(--clr-cw-hover); } +.contnet-warning__content { padding: 1em; } + +/* Web graphic lists */ +.web-graphics { + display: flex; + flex-wrap: wrap; + gap: 0.5em; + list-style-type: ""; + padding: 0; + margin: 0; + overflow-x: clip; + overflow-clip-margin: 0.5em; +} +@media only screen and (min-width: 60rem) { + .web-graphics { + overflow-x: unset; + overflow-clip-margin: unset; + } +} + +.adoptables { align-items: flex-end; } +p + .adoptables { margin-top: 1em; } + +.web-badges { + justify-content: center; + align-items: center; + margin-bottom: 0.5em; +} + +/* Tabs */ +.tabwrap section { display: none; } +.tabwrap section:target, +.tabwrap section:has(*:target) { display: block; } + +.tabs { + list-style-type: ""; + padding: 0; + margin: 0; + display: flex; + flex-wrap: wrap; + gap: 0.5em; +} + +.tab__btn { + display: inline-block; + color: var(--clr-code-bg); + font-weight: 700; + background-color: var(--clr-title-border); + text-decoration: none; + padding: 0.4em 0.8em; +} + +.tab__btn:hover { background-color: #d5c2d6; } +.tab__btn:focus { + outline: 0.2em solid var(--clr-title-border); + outline-offset: 0.15em; +} + +.tabwrap__toc { + background-color: var(--clr-quote-bg); + padding: 0.85em 1em 1.35em; +} +.tab__back { margin-top: 3em; } + +/* Web ring */ +.webring { + border: 0.08em outset; + text-align: center; +} + +.webring__name { + margin: 0; + padding: 0.2em 0.5em; + border: 0.08em solid; +} + +.webring__links { + list-style-type: ""; + padding: 0; + margin: 0 !important; + display: flex; + flex-wrap: wrap; +} + +.webring__link { + flex: 1; + border: 0.08em solid; + padding: 0.2em 0.4em; +} + +/* Remove external link icon from Website Carbon badge */ +#wcb_a::after { all: revert; } \ No newline at end of file diff --git a/src/assets/css/content.css b/src/assets/css/content.css new file mode 100644 index 00000000..719a5648 --- /dev/null +++ b/src/assets/css/content.css @@ -0,0 +1,58 @@ +/* MAIN CONTENT */ +content-wrapper, +.content--divided { display: grid; } + +content-wrapper, +.content--divided { gap: 1rem; } + +.content:not(.content--divided), +.content__section { padding: 1.5rem var(--sz-main-padding); } + +.main__header { + padding: 2.5rem var(--sz-main-padding); + text-align: center; + display: grid; +} + +.content:not(.content--divided), +.content__section { background-color: var(--clr-content-bg); } + +.article__info { + text-align: center; + display: grid; + gap: 0.2em; +} + +.content > * + .h2, +.content__section > * + .h2 { margin-block-start: 2em; } + +.content > * + :not([class]:not([class*="language-"])), +.content__section > * + :not([class]:not([class*="language-"])) { + margin-block-start: var(--sz-paragraph-margin); +} + +.content ul:not([class]), .content ol:not([class]) { + display: grid; + gap: var(--sz-content-list-gap); +} + +.content ul ul, .content ol ol, +.content ul ol, .content ol ul { margin-block-start: var(--sz-content-list-gap); } + +.sidebar--sticky { + position: sticky; + top: var(--sz-navbar-ht); +} + +/* Desktop main content layout */ +@media only screen and (min-width: 60rem) { + content-wrapper { + padding: 0 var(--sz-main-padding); + grid-template-areas: 'leftbar content rightbar'; + grid-template-columns: minmax(0, 18vw) minmax(min(60ch, 40vw), 2.5fr) minmax(0, 18vw); + } + + .content { grid-area: content; } + .left-sidebar { grid-area: leftbar; } + .right-sidebar { grid-area: rightbar; } +} diff --git a/src/assets/css/general.css b/src/assets/css/general.css new file mode 100644 index 00000000..aec978bb --- /dev/null +++ b/src/assets/css/general.css @@ -0,0 +1,125 @@ +/* GENERAL STYLES */ +body { + display: flex; + align-items: center; + flex-direction: column; + font-family: var(--ff-default); + color: var(--clr-body-txt); + background: var(--clr-body-bg); +} + +main { + width: 100%; + font-size: var(--fs-main); +} + +h1 { + color: var(--clr-main-heading); + font-size: var(--fs-h1); + border-bottom: 0.18rem solid var(--clr-title-border); + padding-bottom: 0.3em; + margin-bottom: 0.5em; +} + +h2, h3, h4, h5, h6 { color: var(--clr-sub-heading); } +h1, h2, h3 { line-height: 1.2; } +h2, .h2 { font-size: var(--fs-h2); } +h3, .h3 { font-size: var(--fs-h3); } + +h2:has(+ *[class]:not(.heading-anchor)), .h2:has(+ *[class]), +h3:has(+ *[class]:not(.heading-anchor)), .h3:has(+ *[class]) { margin-bottom: 0.5em; } + +h4, .h4 { font-size: var(--fs-h4); } + +strong { color: var(--clr-bold-txt); } + +:focus { outline: 0.15em solid currentColor; } + +a { color: var(--clr-link); } +a:hover { color: var(--clr-link-hover); } +a:not([class]):focus { outline: 0.15rem solid var(--clr-link); } +a:hover img, a:focus img { outline: 0.2em solid currentColor; } + +a[href^="http"]:not([href*="leilukin.com"]):not(:has(img, svg, picture)), +.external-link { padding-right: var(--sz-external-link); } + +a[href^="http"]:not([href*="leilukin.com"]):not(:has(img, svg, picture))::after, +.external-link::after { + position: absolute; + content: ""; + display: inline-block; + width: 1em; + height: 1em; + margin-left: 0.3em; + background-color: currentColor; + mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3C!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--%3E%3Cpath d='M320 0c-17.7 0-32 14.3-32 32s14.3 32 32 32h82.7L201.4 265.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L448 109.3V192c0 17.7 14.3 32 32 32s32-14.3 32-32V32c0-17.7-14.3-32-32-32H320zM80 32C35.8 32 0 67.8 0 112V432c0 44.2 35.8 80 80 80H400c44.2 0 80-35.8 80-80V320c0-17.7-14.3-32-32-32s-32 14.3-32 32V432c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16H192c17.7 0 32-14.3 32-32s-14.3-32-32-32H80z'/%3E%3C/svg%3E"); + mask-repeat: no-repeat; + mask-size: 90%; + transform: translateY(0.25em); +} + +:not(.c-blockquote) > blockquote, +.c-blockquote { + padding: 1em 1.4em 1.4em; + border-inline-start: 0.1em solid var(--clr-main-heading); + background-color: var(--clr-quote-bg); + margin-bottom: 1em; +} + +blockquote > * + :not([class]), +* + blockquote, +* + .c-blockquote, +.c-blockquote__attribution { margin-block-start: var(--sz-paragraph-margin); } + +details:focus { outline-offset: 0.2em; } +video { width: 100%; } + +figure { + margin-bottom: var(--sz-paragraph-margin); + display: grid; + place-content: center; + justify-items: center; +} + +figcaption { + text-align: center; + font-size: 0.9em; + margin-top: 0.2em; +} + +code { + font-family: var(--ff-monospace); + word-break: break-word; +} + +:not(pre) > code { + padding: 0.125em 0.25em; + background-color: var(--clr-code-bg); +} + +pre { + border: 0.1em solid var(--clr-code-border); + max-width: 90vw; + overflow: auto; + padding: 1rem; +} + +pre > code { white-space: pre; } + +dl { + container-type: inline-size; + display: grid; + gap: var(--sz-content-list-gap); +} + +dt { font-weight: 700; } +dd { margin-left: var(--sz-def-indent); } +dd ul { padding-left: 1em; } + +@container (min-width: 20rem) { + dl { grid-template-columns: 1fr 2fr; } + dd { + grid-column-start: 2; + margin-left: 0; + } +} \ No newline at end of file diff --git a/src/assets/css/global.css b/src/assets/css/global.css new file mode 100644 index 00000000..4476522a --- /dev/null +++ b/src/assets/css/global.css @@ -0,0 +1,108 @@ +/* ------------------- */ +/* Custom Properties */ +/* ------------------- */ +:root { + --clr-body-bg: #08031A; + --clr-body-txt: #fceaff; + --clr-content-bg: #3d2163; + + --clr-top-btn-bg: #FFD05A; + --clr-top-btn-txt: #08031A; + + --clr-main-heading: #ED64F5; + --clr-sub-heading: #e8b86f; + --clr-title-border: #d3aad5; + --clr-bold-txt: #ff9933; + --clr-link: #f98bff; + --clr-link-hover: #c355c9; + --clr-quote-bg: #13092D; + --clr-quote-border: #999999; + --clr-cw-hover: #3a0000; + + --clr-code-bg: #241445; + --clr-code-border: #82668f; + --clr-dates: #79b8ff; + + --clr-link-btn-bg: #873eb5; + --clr-link-btn-txt: white; + --clr-link-btn-hover: #241445; + + --clr-hero-bg: black; + --clr-navbar-bg: #222; + --clr-navbar-link: white; + --clr-main-footer-bg: #13092D; + + --clr-mod-entry-bg: #241445; + + --ff-default: 'Readex Pro', Avenir, Montserrat, Corbel, 'URW Gothic', source-sans-pro, sans-serif; + --ff-monospace: 'Intel One Mono', ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono', monospace; + + --fs-main: clamp(1.125rem, 1.104rem + 0.107vw, 1.2rem); + --fs-h1: clamp(2rem, 1.8rem + 1vw, 2.7rem); + --fs-h2: clamp(1.7rem, 1.557rem + 0.714vw, 2.2rem); + --fs-h3: clamp(1.5rem, 1.414rem + 0.429vw, 1.8rem); + --fs-h4: clamp(1.4rem, 1.343rem + 0.286vw, 1.6rem); + + --sz-paragraph-margin: 1.15em; + --sz-main-padding: clamp(1rem, 5%, 4rem); + --sz-navbar-ht: 4rem; + --sz-external-link: 1.25em; + --sz-content-list-gap: 0.7em; + --sz-def-indent: 1.5em; + + --ht-sticky-sidebar: 86vh; +} + +/* ------------------- */ +/* CSS Reset */ +/* ------------------- */ + +@layer reset { + *, *::before, *::after { + box-sizing: border-box; + } + + * { + margin: 0; + } + + body { + min-height: 100vh; + line-height: 1.5; + } + + h1, h2, h3, h4, h5, h6, + button, input, label { + line-height: 1.1; + } + + p, h1, h2, h3, h4, h5, h6 { + overflow-wrap: break-word; + } + + h1, h2, h3, h4, h5, h6 { + text-wrap: balance; + } + + img, picture, video, canvas { + max-width: 100%; + height: auto; + display: block; + } + + input, button, textarea, select { + font: inherit; + } + + textarea:not([rows]) { + min-height: 10em; + } + + :target { + scroll-margin-block: 5ex; + } + + [popover] { + margin: auto; + } +} diff --git a/src/assets/css/misc.css b/src/assets/css/misc.css new file mode 100644 index 00000000..2815a336 --- /dev/null +++ b/src/assets/css/misc.css @@ -0,0 +1,158 @@ +/* ------------------- */ +/* Custom Properties */ +/* ------------------- */ +:root { + --clr-body-bg: #08031A; + --clr-body-txt: #fceaff; + --clr-h1: #BA6FE8; + --clr-link-btn-bg: #7A37A3; + --clr-link-btn-hover: #BA6FE8; + + --ff-default: 'Lexend'; + + --fs-h1: clamp(2rem, 1.5rem + 5vw, 3.5rem); + --fs-p: 1.25rem; + --fs-link-btn: clamp(1.55rem, 1rem + 3vw, 2.15rem); + + --fw-reg: 400; + --fw-link-btn: 600; +} + +/* ------------------- */ +/* CSS Reset */ +/* ------------------- */ + +/* Box sizing rules */ +*, +*::before, +*::after { + box-sizing: border-box; +} + +/* Prevent font size inflation */ +html { + -moz-text-size-adjust: none; + -webkit-text-size-adjust: none; + text-size-adjust: none; +} + +/* Remove default margin in favour of better control in authored CSS */ +body, h1, h2, h3, h4, p, +figure, blockquote, dl, dd { + margin: 0; +} + +/* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */ +ul[role='list'], +ol[role='list'] { + list-style-type: ""; +} + +/* Set core body defaults */ +body { + min-height: 100vh; + line-height: 1.5; +} + +/* Set shorter line heights on headings and interactive elements */ +h1, h2, h3, h4, +button, input, label { + line-height: 1.1; +} + +/* Balance text wrapping on headings */ +h1, h2, +h3, h4 { + text-wrap: balance; +} + +/* A elements that don't have a class get default styles */ +a:not([class]) { + text-decoration-skip-ink: auto; + color: currentColor; +} + +/* Make images easier to work with */ +img, +picture { + max-width: 100%; + display: block; +} + +/* Inherit fonts for inputs and buttons */ +input, button, +textarea, select { + font: inherit; +} + +/* Make sure textareas without a rows attribute are not tiny */ +textarea:not([rows]) { + min-height: 10em; +} + +/* Anything that has been anchored to should have extra scroll margin */ +:target { + scroll-margin-block: 5ex; +} + +/* ------------------- */ +/* STYLING BEGINS */ +/* ------------------- */ + +body { + font-size: var(--clr-body-bg); + font-family: var(--ff-default), system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + color: var(--clr-body-txt); + background: var(--clr-body-bg); + text-align: center; +} + +body, main { + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; +} + +main { max-width: 90%; } + +h1 { + font-size: var(--fs-h1); + color: var(--clr-h1); + font-weight: var(--fw-reg); + letter-spacing: 0.08em; + margin: 2rem 0; + line-height: 1; +} + +p { font-size: var(--fs-p); } + +.index__btn-wrapper { + display: flex; + flex-wrap: wrap; + justify-content: center; + margin: 1.5rem 0; +} + +.index__link { + text-decoration: none; + font-size: var(--fs-link-btn); + font-weight: var(--fw-link-btn); + border: none; + border-radius: 0.4em; + padding: 0.4em 0.75em; + margin: 0.5rem; + background: var(--clr-link-btn-bg); + color: var(--clr-body-txt); + text-transform: uppercase; +} + +.index__link:hover { + background: var(--clr-link-btn-hover); + transition: 0.2s; +} + +.index__link:focus { + outline: 0.1em solid var(--clr-body-txt); + outline-offset: -0.15em; +} \ No newline at end of file diff --git a/src/assets/css/plugins.css b/src/assets/css/plugins.css new file mode 100644 index 00000000..e8513d52 --- /dev/null +++ b/src/assets/css/plugins.css @@ -0,0 +1,46 @@ +/* HEADING WRAPPER AND ANCHOR */ +.heading-wrapper { + display: flex; + gap: 0.3em; + align-items: baseline; +} + +* + .heading-wrapper { margin-top: 1.8em; } + +.heading-anchor { + order: -1; + text-underline-offset: 0.1em; +} + +.heading-anchor:focus { + outline: 0.13em solid currentColor; + outline-offset: 0.05em; +} + +.heading-anchor [hidden] { display: block; } + +/* BLOCKQUOTES With CITATIONS */ +.c-blockquote__attribution { text-align: left; } + +.c-blockquote__attribution::before { + content: "—"; + margin-right: 0.3em; +} + +/* FOOTNOTES */ +.footnote-ref { margin-left: 0.2em; } +.footnote-ref a:target { scroll-margin-block: calc(var(--sz-navbar-ht) + 5ex); } +.footnotes { padding-top: 2em; } +.footnotes-sep { margin-top: 2.5em; } + +.footnotes-list { + display: grid; + gap: 1em; +} + +.footnotes-list :target { + background-color: var(--clr-quote-bg); + outline: 0.1em dashed var(--clr-title-border); + outline-offset: 0.1em; +} +*:not([class]) + .footnote-item__back { margin-top: 0.5em; } \ No newline at end of file diff --git a/src/assets/css/pokemonoras.css b/src/assets/css/pokemonoras.css new file mode 100644 index 00000000..3e090b2f --- /dev/null +++ b/src/assets/css/pokemonoras.css @@ -0,0 +1,41 @@ +:root { + color-scheme: light dark; + + --clr-body-bg: linear-gradient(90deg, rgba(255,137,137,1) 0%, rgba(130,176,255,1) 100%); + --clr-body-txt: light-dark(#141414, #fff); + --clr-content-bg: light-dark(#ffffff, #242424); + + --clr-top-btn-bg: #000885; + --clr-top-btn-txt: #ffffff; + + --clr-main-heading: #171717; + --clr-sub-heading: light-dark(#111111, #fff); + --clr-title-border: #6e0000; + --clr-bold-txt: light-dark(#ff0000, #ff4444); + --clr-link: light-dark(#302aff, #7bb4ff); + --clr-link-hover: light-dark(rgb(1, 48, 110), #1c7dfd); + --clr-quote-bg: light-dark(#f3f2f2, #141414); + --clr-quote-border: light-dark(#c60000, #ff0000); + --clr-cw-hover: #fae5e5; + + --clr-code-bg: #f3f2f2; + --clr-code-border: #414141; + --clr-dates: #3a96ff; + + --clr-link-btn-bg: #873eb5; + --clr-link-btn-txt: white; + --clr-link-btn-hover: #241445; + + --clr-hero-bg: #7944B6; + --clr-navbar-bg: linear-gradient(90deg, rgba(193,0,0,1) 0%, rgba(0,70,189,1) 100%); + --clr-navbar-link: white; + + --clr-main-footer-bg: var(--clr-navbar-bg); +} + +.main__header p { color: var(--clr-main-heading); } +.hero__top-bar, +.footer, +.footer a { color: var(--clr-navbar-link); } + +.footer a:focus { outline-color: var(--clr-navbar-link); } \ No newline at end of file diff --git a/src/assets/css/pridesymbols.css b/src/assets/css/pridesymbols.css new file mode 100644 index 00000000..1e21cca4 --- /dev/null +++ b/src/assets/css/pridesymbols.css @@ -0,0 +1,225 @@ +/* + Pride flag CSS backgrounds + Credit: KOTOR Community Portal: https://kotor.neocities.org/ + */ + +.flag-rainbow { + background: linear-gradient( + #e40303 0 16.67%, + #ff8c00 0 33.33%, + #ffed00 0 50%, + #008026 0 66.67%, + #004dff 0 83.33%, + #750787 0 100% + ); +} + +.flag-lesbian { + background: linear-gradient( + #d52d00 0 14.29%, + #ef7627 0 28.57%, + #ff9a56 0 42.86%, + #ffffff 0 57.14%, + #d362a4 0 71.43%, + #b85490 0 86.71%, + #a30262 0 100% + ); +} + +.flag-bi { + background: linear-gradient( + #d60270 0 40%, + #9b4f97 0 60%, + #0038a7 0 100% + ); +} + +.flag-trans { + background: linear-gradient( + #5bcefa 0 20%, + #f5a9b8 0 40%, + #ffffff 0 60%, + #f5a9b8 0 80%, + #5bcefa 0 100% + ); +} + +.flag-intersex { + background: radial-gradient(closest-side circle at center, + #ffd800 44%, + #7902aa 44%, + #7902aa 56%, + #ffd800 56% + ); +} + +.flag-ace { + background: linear-gradient( + #000000 0 25%, + #a3a3a3 0 50%, + #ffffff 0 75%, + #800080 0 100% + ); +} + +.flag-aro { + background: linear-gradient( + #0a2 20%, + #7d6 0 40%, + white 0 60%, + darkgray 0 80%, + black 0 + ); +} + +.flag-non-binary { + background: linear-gradient( + #fff430 0 25%, + #ffffff 0 50%, + #9c59d1 0 75%, + #000000 0 100% + ); +} + +.flag-pan { + background: linear-gradient( + #ff218c 0 33.33%, + #ffd800 0 66.67%, + #21b1ff 0 100% + ); +} + +.flag-genderfluid { + background: linear-gradient( + #ff76a4 0 20%, + #ffffff 0 40%, + #c011d7 0 60%, + #000000 0 80%, + #2f3cbe 0 100% + ); +} + +.flag-agender { + background: linear-gradient( + black 0 14.28%, + silver 0 28.57%, + white 0 42.85%, + #a3fa73 0 57.14%, + white 0 71.42%, + silver 0 85.71%, + black 0 + ); +} + +.flag-demigirl { + background: linear-gradient( + #7F7F7F 0 14.28%, + #C4C4C4 0 28.57%, + #FDADC8 0 42.85%, + white 0 57.14%, + #FDADC8 0 71.42%, + #C4C4C4 0 85.71%, + #7F7F7F 0 + ); +} + +.flag-bigender { + background: linear-gradient( + #d074a2 0 14.28%, + #f8a1cd 0 28.57%, + #d9c6ea 0 42.85%, + white 0 57.14%, + #d9c6ea 0 71.42%, + #90c8ec 0 85.71%, + #6583d5 0 + ); +} + +.flag-gilbert-baker { + background: linear-gradient( + #FF6599 12.5%, + #e40303 0 25%, + #ff8c00 0 37.5%, + #ffed00 0 50%, + #008026 0 62.5%, + #00C0C0 0 75%, + #004dff 0 87.5%, + #750787 0 + ); +} + +.flag-gilbert-baker-2017 { + background: linear-gradient( + #CD66FF 11.1%, + #FF6599 0 22.2%, + #e40303 0 33.3%, + #ff8c00 0 44.4%, + #ffed00 0 55.5%, + #008026 0 66.6%, + #00C0C0 0 77.7%, + #004dff 0 88.8%, + #750787 0 + ); +} + +.flag-progress { + background: + conic-gradient(at 14% 50%, #0000 221.25deg, #ffffff 222deg 318deg, #0000 318.25deg), + conic-gradient(at 23% 50%, #0000 221.25deg, #f5a9b8 222deg 318deg, #0000 318.25deg), + conic-gradient(at 32% 50%, #0000 221.25deg, #5bcefa 222deg 318deg, #0000 318.25deg), + conic-gradient(at 41% 50%, #0000 221.25deg, #784F17 222deg 318deg, #0000 318.25deg), + conic-gradient(at 50% 50%, #0000 221.25deg, black 222deg 318deg, #0000 318.25deg), + linear-gradient(#e40303 0 16.66%, #ff8c00 0 33.33%, #ffed00 0 50%, #008026 0 66.66%, #004dff 0 83.33%, #750787 0); +} + +.flag-progress-intersex { + background: + radial-gradient(circle at 9.75% 50%, #0000 6.66%, #7902aa 6.7% 8.33%, #0000 8.4%), + conic-gradient(at 26.66% 50%, #0000 222.75deg, #ffd800 0 317.25deg, #0000 0), + conic-gradient(at 33% 50%, #0000 222.75deg, #ffffff 0 317.25deg, #0000 0), + conic-gradient(at 39% 50%, #0000 222.75deg, #f5a9b8 0 317.25deg, #0000 0), + conic-gradient(at 45.66% 50%, #0000 222.75deg, #5bcefa 0 317.25deg, #0000 0), + conic-gradient(at 52% 50%, #0000 222.75deg, #753000 0 317.25deg, #0000 0), + conic-gradient(at 58.33% 50%, #0000 222.75deg, #000 0 317.25deg, #0000 0), + linear-gradient(#e40303 0 16.66%, #ff8c00 0 33.33%, #ffed00 0 50%, #008026 0 66.66%, #004dff 0 83.33%, #750787 0); +} + +.flag-progress-intersex-lesbian { + background: + radial-gradient(circle at 9.75% 50%, #0000 6.66%, #7902aa 6.7% 8.33%, #0000 8.4%), + conic-gradient(at 26.66% 50%, #0000 222.75deg, #ffd800 0 317.25deg, #0000 0), + conic-gradient(at 33% 50%, #0000 222.75deg, #ffffff 0 317.25deg, #0000 0), + conic-gradient(at 39% 50%, #0000 222.75deg, #f5a9b8 0 317.25deg, #0000 0), + conic-gradient(at 45.66% 50%, #0000 222.75deg, #5bcefa 0 317.25deg, #0000 0), + conic-gradient(at 52% 50%, #0000 222.75deg, #753000 0 317.25deg, #0000 0), + conic-gradient(at 58.33% 50%, #0000 222.75deg, #000 0 317.25deg, #0000 0), + linear-gradient(#d52d00 0 14.29%, #ef7627 0 28.57%, #ff9a56 0 42.86%, #ffffff 0 57.14%, #d362a4 0 71.43%, #b85490 0 86.71%, #a30262 0 100%); +} + +.symbol-venus { + background-image: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='12pt' height='12pt' viewBox='0 0 12 12' version='1.1'%3E%3Cg id='surface1'%3E%3Cpath style='fill:none;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(35.15%25,0%25,64.85%25);stroke-opacity:1;stroke-miterlimit:10;' d='M 85 85 C 85 98.789062 73.789062 110 60 110 C 46.210938 110 35 98.789062 35 85 C 35 71.210938 46.210938 60 60 60 C 73.789062 60 85 71.210938 85 85 Z M 85 85 ' transform='matrix(0.1,0,0,-0.1,0,12)'/%3E%3Cpath style='fill:none;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(35.15%25,0%25,64.85%25);stroke-opacity:1;stroke-miterlimit:10;' d='M 60 10 L 60 60 ' transform='matrix(0.1,0,0,-0.1,0,12)'/%3E%3Cpath style='fill:none;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(35.15%25,0%25,64.85%25);stroke-opacity:1;stroke-miterlimit:10;' d='M 35 35 L 85 35 ' transform='matrix(0.1,0,0,-0.1,0,12)'/%3E%3C/g%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-size: 100% 100%; +} + +/* Coded by myself */ +.flag-disability { + background: + linear-gradient( + 37deg, + #595959 0 35%, + #CF7280 30% 41%, + #EEDE77 30% 47%, + #E8E8E8 30% 53%, + #7bc2e0 30% 59%, + #3BB07D 30% 65%, + #595959 0 + ); +} + +.flag-el { + display: inline-block; + width: 100%; + aspect-ratio: 14 / 9; +} +.flag-el.flag-disability { aspect-ratio: 4 / 3; } \ No newline at end of file diff --git a/src/assets/css/starwarskotor.css b/src/assets/css/starwarskotor.css new file mode 100644 index 00000000..93e74599 --- /dev/null +++ b/src/assets/css/starwarskotor.css @@ -0,0 +1,32 @@ +:root { + --clr-body-bg: #212121; + --img-body-bg: none; + --clr-body-txt: #fceaff; + --clr-content-bg: #000000; + + --clr-top-btn-bg: #FFD05A; + --clr-top-btn-txt: #000000; + + --clr-main-heading: #ffae00; + --clr-sub-heading: #ffae00; + --clr-title-border: #ffe387; + --clr-bold-txt: #ff9933; + --clr-link: #bb9671; + --clr-link-hover: #94575a; + --clr-quote-bg: #2f2d2d; + --clr-quote-border: #4d4385; + + --clr-code-bg: #241445; + --clr-code-border: #e4dbbe; + --clr-dates: rgb(158, 203, 255); + + --clr-link-btn-bg: #873eb5; + --clr-link-btn-txt: white; + --clr-link-btn-hover: #241445; + + --clr-hero-bg: black; + --clr-navbar-bg: #171717; + --clr-navbar-link: white; + + --clr-main-footer-bg: #171717; +} \ No newline at end of file diff --git a/src/assets/css/tooltips.css b/src/assets/css/tooltips.css new file mode 100644 index 00000000..334310f2 --- /dev/null +++ b/src/assets/css/tooltips.css @@ -0,0 +1,49 @@ +/* ARIA Tooltips by Scott O'Hara: https://github.com/scottaohara/a11y_tooltips */ + +[data-tooltip] { + display: inline-block; + position: relative; +} + +[data-tooltip-block] { display: block; } + +.tooltip { + font-size: .825rem; + left: 0; + min-width: 20ch; + max-width: 44ch; + pointer-events: none; + position: absolute; + top: 100%; + z-index: 2; +} + +.push-up .tooltip { + bottom: 100%; + top: auto; +} + +.push-right .tooltip { + left: auto; + right: 0; +} + +.tooltip__content { + background-color: var(--clr-quote-bg); + border: 0.15em solid var(--clr-main-heading); + display: inline-block; + opacity: 0; + padding: .625em; + visibility: hidden; +} + +.tooltip__content > * { margin: .5em 0; } +.tooltip__content :last-child { margin-bottom: 0; } +.tooltip__content :first-child { margin-top: 0; } + +.tooltip--show .tooltip__content { + opacity: 1; + pointer-events: auto; + transition: opacity .1s ease-in; + visibility: visible; +} diff --git a/src/assets/css/utility.css b/src/assets/css/utility.css new file mode 100644 index 00000000..8f0abcd7 --- /dev/null +++ b/src/assets/css/utility.css @@ -0,0 +1,68 @@ +/* UTILITY CLASSES */ +.bold-text { font-weight: 700; } +.center-text { text-align: center; } +.inline-img { display: inline-block; } +.update-info { margin-top: 3em; } + +.indent-text { + padding: 1em 0 1em 2em; + display: grid; + gap: 1em; +} + +.date-style { + font-weight: 700; + color: var(--clr-dates); +} + +.inline-icon { + display: inline-block; + vertical-align: -10%; + height: 1em; + fill: currentColor; +} +a > .inline-icon { padding-inline-end: .25em; } + +.inline-list { + display: flex; + flex-wrap: wrap; + gap: 0.7em 1.5em; +} + +.item-list { + display: grid; + gap: 1em; + padding-left: 1em; +} + +.item-list__title { + font-size: var(--fs-h4); + line-height: 1.3; + margin-bottom: 0.2em; +} + +.item-list__indent { margin: 0.3em 0 0 1.25em; } +.email-encoded b { display: none; } + +.deflist-1col { grid-template-columns: unset; } +* + .deflist-1col { margin-block-start: var(--sz-def-indent); } +.deflist-1col dd { + grid-column-start: unset; + margin-left: var(--sz-def-indent); +} + +.hidden { display: none; } + +.visually-hidden { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0,0,0,0); + white-space: nowrap; + border: 0; + outline: 0; + outline-offset: 0; +} \ No newline at end of file diff --git a/src/assets/favicon/apple-touch-icon.png b/src/assets/favicon/apple-touch-icon.png new file mode 100644 index 00000000..81ef2aee Binary files /dev/null and b/src/assets/favicon/apple-touch-icon.png differ diff --git a/src/assets/favicon/favicon.ico b/src/assets/favicon/favicon.ico new file mode 100644 index 00000000..dc33b04b Binary files /dev/null and b/src/assets/favicon/favicon.ico differ diff --git a/src/assets/fonts/fonts.css b/src/assets/fonts/fonts.css new file mode 100644 index 00000000..7d204770 --- /dev/null +++ b/src/assets/fonts/fonts.css @@ -0,0 +1,52 @@ +/* Readex Pro */ +@font-face { + font-display: swap; + font-family: 'Readex Pro'; + font-style: normal; + font-weight: 600; + src: url('/assets/fonts/readex-pro/readex-pro-v22-latin-600.woff2') format('woff2'); +} +/* Intel One Mono */ +@font-face { + font-display: swap; + font-family: 'Intel One Mono'; + font-style: normal; + font-weight: 400; + src: url('/assets/fonts/intel-one-mono/IntelOneMono-Regular.woff2') format('woff2'); +} + +@font-face { + font-display: swap; + font-family: 'Intel One Mono'; + font-style: italic; + font-weight: 400; + src: url('/assets/fonts/intel-one-mono/IntelOneMono-Italic.woff2') format('woff2'); +} +@font-face { + font-display: swap; + font-family: 'Intel One Mono'; + font-style: normal; + font-weight: 600; + src: url('/assets/fonts/intel-one-mono/IntelOneMono-Medium.woff2') format('woff2'); +} +@font-face { + font-display: swap; + font-family: 'Intel One Mono'; + font-style: italic; + font-weight: 600; + src: url('/assets/fonts/intel-one-mono/IntelOneMono-MediumItalic.woff2') format('woff2'); +} +@font-face { + font-display: swap; + font-family: 'Intel One Mono'; + font-style: normal; + font-weight: 700; + src: url('/assets/fonts/intel-one-mono/IntelOneMono-Bold.woff2') format('woff2'); +} +@font-face { + font-display: swap; + font-family: 'Intel One Mono'; + font-style: italic; + font-weight: 700; + src: url('/assets/fonts/intel-one-mono/IntelOneMono-BoldItalic.woff2') format('woff2'); +} diff --git a/src/assets/fonts/intel-one-mono/IntelOneMono-Bold.woff2 b/src/assets/fonts/intel-one-mono/IntelOneMono-Bold.woff2 new file mode 100644 index 00000000..ad52b0cb Binary files /dev/null and b/src/assets/fonts/intel-one-mono/IntelOneMono-Bold.woff2 differ diff --git a/src/assets/fonts/intel-one-mono/IntelOneMono-BoldItalic.woff2 b/src/assets/fonts/intel-one-mono/IntelOneMono-BoldItalic.woff2 new file mode 100644 index 00000000..2615c524 Binary files /dev/null and b/src/assets/fonts/intel-one-mono/IntelOneMono-BoldItalic.woff2 differ diff --git a/src/assets/fonts/intel-one-mono/IntelOneMono-Italic.woff2 b/src/assets/fonts/intel-one-mono/IntelOneMono-Italic.woff2 new file mode 100644 index 00000000..13ae19c1 Binary files /dev/null and b/src/assets/fonts/intel-one-mono/IntelOneMono-Italic.woff2 differ diff --git a/src/assets/fonts/intel-one-mono/IntelOneMono-Medium.woff2 b/src/assets/fonts/intel-one-mono/IntelOneMono-Medium.woff2 new file mode 100644 index 00000000..745887a2 Binary files /dev/null and b/src/assets/fonts/intel-one-mono/IntelOneMono-Medium.woff2 differ diff --git a/src/assets/fonts/intel-one-mono/IntelOneMono-MediumItalic.woff2 b/src/assets/fonts/intel-one-mono/IntelOneMono-MediumItalic.woff2 new file mode 100644 index 00000000..ad65b31b Binary files /dev/null and b/src/assets/fonts/intel-one-mono/IntelOneMono-MediumItalic.woff2 differ diff --git a/src/assets/fonts/intel-one-mono/IntelOneMono-Regular.woff2 b/src/assets/fonts/intel-one-mono/IntelOneMono-Regular.woff2 new file mode 100644 index 00000000..dd0187ec Binary files /dev/null and b/src/assets/fonts/intel-one-mono/IntelOneMono-Regular.woff2 differ diff --git a/src/assets/fonts/readex-pro/readex-pro-v22-latin-600.woff2 b/src/assets/fonts/readex-pro/readex-pro-v22-latin-600.woff2 new file mode 100644 index 00000000..dc699662 Binary files /dev/null and b/src/assets/fonts/readex-pro/readex-pro-v22-latin-600.woff2 differ diff --git a/src/assets/fonts/readex-pro/readex-pro-v22-latin-700.woff2 b/src/assets/fonts/readex-pro/readex-pro-v22-latin-700.woff2 new file mode 100644 index 00000000..27a6263c Binary files /dev/null and b/src/assets/fonts/readex-pro/readex-pro-v22-latin-700.woff2 differ diff --git a/src/assets/fonts/readex-pro/readex-pro-v22-latin-regular.woff2 b/src/assets/fonts/readex-pro/readex-pro-v22-latin-regular.woff2 new file mode 100644 index 00000000..e621f6bd Binary files /dev/null and b/src/assets/fonts/readex-pro/readex-pro-v22-latin-regular.woff2 differ diff --git a/src/assets/images/articles/accessible-footnotes/32bitcafe-backtoschool.png b/src/assets/images/articles/accessible-footnotes/32bitcafe-backtoschool.png new file mode 100644 index 00000000..f4e76db1 Binary files /dev/null and b/src/assets/images/articles/accessible-footnotes/32bitcafe-backtoschool.png differ diff --git a/src/assets/images/articles/accessible-footnotes/footnote-sample.avif b/src/assets/images/articles/accessible-footnotes/footnote-sample.avif new file mode 100644 index 00000000..99edf5bb Binary files /dev/null and b/src/assets/images/articles/accessible-footnotes/footnote-sample.avif differ diff --git a/src/assets/images/articles/lgbtq-booklet-interview-misi-bawang/Bawang-Booklet-Interview-Leilukin-1.avif b/src/assets/images/articles/lgbtq-booklet-interview-misi-bawang/Bawang-Booklet-Interview-Leilukin-1.avif new file mode 100644 index 00000000..c02902dc Binary files /dev/null and b/src/assets/images/articles/lgbtq-booklet-interview-misi-bawang/Bawang-Booklet-Interview-Leilukin-1.avif differ diff --git a/src/assets/images/articles/lgbtq-booklet-interview-misi-bawang/Bawang-Booklet-Interview-Leilukin-2.avif b/src/assets/images/articles/lgbtq-booklet-interview-misi-bawang/Bawang-Booklet-Interview-Leilukin-2.avif new file mode 100644 index 00000000..d76f0d7c Binary files /dev/null and b/src/assets/images/articles/lgbtq-booklet-interview-misi-bawang/Bawang-Booklet-Interview-Leilukin-2.avif differ diff --git a/src/assets/images/articles/lgbtq-booklet-interview-misi-bawang/Bawang-Booklet-Interview-Leilukin-3.avif b/src/assets/images/articles/lgbtq-booklet-interview-misi-bawang/Bawang-Booklet-Interview-Leilukin-3.avif new file mode 100644 index 00000000..f2469de4 Binary files /dev/null and b/src/assets/images/articles/lgbtq-booklet-interview-misi-bawang/Bawang-Booklet-Interview-Leilukin-3.avif differ diff --git a/src/assets/images/articles/love-letter-to-myself/32bitcafe-partyforone.png b/src/assets/images/articles/love-letter-to-myself/32bitcafe-partyforone.png new file mode 100644 index 00000000..3ad0c80a Binary files /dev/null and b/src/assets/images/articles/love-letter-to-myself/32bitcafe-partyforone.png differ diff --git a/src/assets/images/posts/a-summers-end-review/My-review-for-A-Summer-s-End-on-Steam.avif b/src/assets/images/posts/a-summers-end-review/My-review-for-A-Summer-s-End-on-Steam.avif new file mode 100644 index 00000000..a68232d6 Binary files /dev/null and b/src/assets/images/posts/a-summers-end-review/My-review-for-A-Summer-s-End-on-Steam.avif differ diff --git a/src/assets/images/posts/lesbian-visibility-day-cassette-beasts-anni/1-year-cassette-beasts-anniversary-mastodon-boost.avif b/src/assets/images/posts/lesbian-visibility-day-cassette-beasts-anni/1-year-cassette-beasts-anniversary-mastodon-boost.avif new file mode 100644 index 00000000..af2957f0 Binary files /dev/null and b/src/assets/images/posts/lesbian-visibility-day-cassette-beasts-anni/1-year-cassette-beasts-anniversary-mastodon-boost.avif differ diff --git a/src/assets/images/posts/lesbian-visibility-day-cassette-beasts-anni/1-year-cassette-beasts-anniversary-twitter-reply.avif b/src/assets/images/posts/lesbian-visibility-day-cassette-beasts-anni/1-year-cassette-beasts-anniversary-twitter-reply.avif new file mode 100644 index 00000000..74d6ad13 Binary files /dev/null and b/src/assets/images/posts/lesbian-visibility-day-cassette-beasts-anni/1-year-cassette-beasts-anniversary-twitter-reply.avif differ diff --git a/src/assets/images/posts/lesbian-visibility-day-cassette-beasts-anni/1-year-cassette-beasts-anniversary-twitter-repost.avif b/src/assets/images/posts/lesbian-visibility-day-cassette-beasts-anni/1-year-cassette-beasts-anniversary-twitter-repost.avif new file mode 100644 index 00000000..500f5c58 Binary files /dev/null and b/src/assets/images/posts/lesbian-visibility-day-cassette-beasts-anni/1-year-cassette-beasts-anniversary-twitter-repost.avif differ diff --git a/src/assets/images/posts/lesbian-visibility-day-cassette-beasts-anni/leilukin-s-hub-cassette-beasts-anniversary.avif b/src/assets/images/posts/lesbian-visibility-day-cassette-beasts-anni/leilukin-s-hub-cassette-beasts-anniversary.avif new file mode 100644 index 00000000..f01d0be7 Binary files /dev/null and b/src/assets/images/posts/lesbian-visibility-day-cassette-beasts-anni/leilukin-s-hub-cassette-beasts-anniversary.avif differ diff --git a/src/assets/images/posts/lesbian-visibility-day-cassette-beasts-anni/leilukin-s-hub-lesbian-visibility-day.avif b/src/assets/images/posts/lesbian-visibility-day-cassette-beasts-anni/leilukin-s-hub-lesbian-visibility-day.avif new file mode 100644 index 00000000..6ce4531e Binary files /dev/null and b/src/assets/images/posts/lesbian-visibility-day-cassette-beasts-anni/leilukin-s-hub-lesbian-visibility-day.avif differ diff --git a/src/assets/images/posts/my-2025-lunar-new-year/bak-baan-1.avif b/src/assets/images/posts/my-2025-lunar-new-year/bak-baan-1.avif new file mode 100644 index 00000000..fc4e04de Binary files /dev/null and b/src/assets/images/posts/my-2025-lunar-new-year/bak-baan-1.avif differ diff --git a/src/assets/images/posts/my-2025-qingming/bak-baan-1.avif b/src/assets/images/posts/my-2025-qingming/bak-baan-1.avif new file mode 100644 index 00000000..2d3ba842 Binary files /dev/null and b/src/assets/images/posts/my-2025-qingming/bak-baan-1.avif differ diff --git a/src/assets/images/posts/my-2025-qingming/bak-baan-2.avif b/src/assets/images/posts/my-2025-qingming/bak-baan-2.avif new file mode 100644 index 00000000..2db435a0 Binary files /dev/null and b/src/assets/images/posts/my-2025-qingming/bak-baan-2.avif differ diff --git a/src/assets/images/posts/my-2025-qingming/cendol.avif b/src/assets/images/posts/my-2025-qingming/cendol.avif new file mode 100644 index 00000000..9fd98cf6 Binary files /dev/null and b/src/assets/images/posts/my-2025-qingming/cendol.avif differ diff --git a/src/assets/images/posts/my-first-smartwatch/my-xiaomi-smart-band-9.avif b/src/assets/images/posts/my-first-smartwatch/my-xiaomi-smart-band-9.avif new file mode 100644 index 00000000..7342393a Binary files /dev/null and b/src/assets/images/posts/my-first-smartwatch/my-xiaomi-smart-band-9.avif differ diff --git a/src/assets/images/posts/nexusmods-lifetime-premium/Screenshot-2024-03-06-at-20-49-26-Nexus-Mods-Home.avif b/src/assets/images/posts/nexusmods-lifetime-premium/Screenshot-2024-03-06-at-20-49-26-Nexus-Mods-Home.avif new file mode 100644 index 00000000..c3b4a3b2 Binary files /dev/null and b/src/assets/images/posts/nexusmods-lifetime-premium/Screenshot-2024-03-06-at-20-49-26-Nexus-Mods-Home.avif differ diff --git a/src/assets/images/posts/nexusmods-lifetime-premium/Screenshot-2024-03-06-at-20-52-27-Nexus-Mods-Users.avif b/src/assets/images/posts/nexusmods-lifetime-premium/Screenshot-2024-03-06-at-20-52-27-Nexus-Mods-Users.avif new file mode 100644 index 00000000..dd19604e Binary files /dev/null and b/src/assets/images/posts/nexusmods-lifetime-premium/Screenshot-2024-03-06-at-20-52-27-Nexus-Mods-Users.avif differ diff --git a/src/assets/images/posts/nexusmods-lifetime-premium/thunderbird-2024-03-06-20-45-36-381.avif b/src/assets/images/posts/nexusmods-lifetime-premium/thunderbird-2024-03-06-20-45-36-381.avif new file mode 100644 index 00000000..f9746c69 Binary files /dev/null and b/src/assets/images/posts/nexusmods-lifetime-premium/thunderbird-2024-03-06-20-45-36-381.avif differ diff --git a/src/assets/images/posts/pombomb-plushie/2023-10-11-14-25-27.avif b/src/assets/images/posts/pombomb-plushie/2023-10-11-14-25-27.avif new file mode 100644 index 00000000..9400605c Binary files /dev/null and b/src/assets/images/posts/pombomb-plushie/2023-10-11-14-25-27.avif differ diff --git a/src/assets/images/posts/pombomb-plushie/2023-10-11-14-28-36.avif b/src/assets/images/posts/pombomb-plushie/2023-10-11-14-28-36.avif new file mode 100644 index 00000000..bd4babef Binary files /dev/null and b/src/assets/images/posts/pombomb-plushie/2023-10-11-14-28-36.avif differ diff --git a/src/assets/images/posts/pombomb-plushie/2023-10-11-14-29-09.avif b/src/assets/images/posts/pombomb-plushie/2023-10-11-14-29-09.avif new file mode 100644 index 00000000..a65c1fac Binary files /dev/null and b/src/assets/images/posts/pombomb-plushie/2023-10-11-14-29-09.avif differ diff --git a/src/assets/images/posts/pombomb-plushie/2023-10-11-14-30-36.avif b/src/assets/images/posts/pombomb-plushie/2023-10-11-14-30-36.avif new file mode 100644 index 00000000..01b71803 Binary files /dev/null and b/src/assets/images/posts/pombomb-plushie/2023-10-11-14-30-36.avif differ diff --git a/src/assets/images/posts/pombomb-plushie/Bytten-Studio-on-my-Pombomb-plushie.avif b/src/assets/images/posts/pombomb-plushie/Bytten-Studio-on-my-Pombomb-plushie.avif new file mode 100644 index 00000000..b02b0249 Binary files /dev/null and b/src/assets/images/posts/pombomb-plushie/Bytten-Studio-on-my-Pombomb-plushie.avif differ diff --git a/src/assets/js/copycode.js b/src/assets/js/copycode.js new file mode 100644 index 00000000..938719ac --- /dev/null +++ b/src/assets/js/copycode.js @@ -0,0 +1,63 @@ +/* + Based on ttntm's code to add a button to copy code snippets: + https://ttntm.me/blog/adding-a-copy-button-to-code-blocks/ +*/ + +function createCopyBtn(blockIndex) { + return `
      + +
      `; +} + +async function copyCode(block) { + const code = document.querySelector(`[data-block-id="${block}"]`); + const doCopy = async() => await navigator.clipboard.writeText(code?.innerText ?? ''); + + if (!navigator.userAgent.includes('Firefox')) { + const result = await navigator.permissions.query({ name: 'clipboard-write' }); + + if (result.state === 'granted' || result.state === 'prompt') { + doCopy(); + } + } else { + doCopy(); + } +} + +async function handleCopyBtnClick(event) { + const btn = event?.target; + const btnTarget = btn?.getAttribute('data-target'); + + if (btn && btnTarget) { + const originalText = btn.innerHTML; + + await copyCode(btnTarget); + + btn.innerHTML = ' Copied!'; + + setTimeout(() => { + btn.innerHTML = originalText; + }, 1500); + } +} + +document.addEventListener('DOMContentLoaded', () => { + const allCodeBlocks = Array.from(document.querySelectorAll('pre[class^="language-"]')); + + allCodeBlocks.forEach((b, i) => { + const code = b.childNodes[0]; + const codeBlockIndex = `cb-${i}`; + + b.insertAdjacentHTML('afterend', createCopyBtn(codeBlockIndex)); + code.setAttribute('data-block-id', codeBlockIndex); + }) + + const allCopyBtns = Array.from(document.querySelectorAll('.cc-btn')); + + allCopyBtns.forEach((btn) => { + btn.addEventListener('click', handleCopyBtnClick); + }) +}) \ No newline at end of file diff --git a/src/assets/js/tooltips.js b/src/assets/js/tooltips.js new file mode 100644 index 00000000..acba6d27 --- /dev/null +++ b/src/assets/js/tooltips.js @@ -0,0 +1,310 @@ +/* ARIA Tooltips by Scott O'Hara: https://github.com/scottaohara/a11y_tooltips */ + +'use strict'; + +if (typeof Object.assign != 'function') { + // Must be writable: true, enumerable: false, configurable: true + Object.defineProperty(Object, "assign", { + value: function assign(target, varArgs) { // .length of function is 2 + 'use strict'; + if (target == null) { // TypeError if undefined or null + throw new TypeError('Cannot convert undefined or null to object'); + } + + var to = Object(target); + + for (var index = 1; index < arguments.length; index++) { + var nextSource = arguments[index]; + + if (nextSource != null) { // Skip over if undefined or null + for (var nextKey in nextSource) { + // Avoid bugs when hasOwnProperty is shadowed + if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { + to[nextKey] = nextSource[nextKey]; + } + } + } + } + return to; + }, + writable: true, + configurable: true + }); +} + +var util = { + keyCodes: { + ESC: 27 + }, + + generateID: function ( base ) { + return base + Math.floor(Math.random() * 999); + } +}; + + +(function ( w, doc, undefined ) { + /** + * ARIA Tooltips + * Widget to reveal a short description, or + * the element's accessible name on hover/focus. + * + * Author: Scott O'Hara + * Version: 1.0.0 + * License: MIT + */ + + var tipConfig = { + baseID: 'tt_', + ariaHiddenTip: true, + + tipWrapperClass: 'tooltip', + tipContentClass: 'tooltip__content', + + tipTypeAttr: 'data-tooltip', + tipContentAttr: 'data-tooltip-content', + + tipSelector: '[data-tooltip-tip]', + triggerSelector: '[data-tooltip-trigger]' + }; + + + var ARIAtip = function ( inst, options ) { + var el = inst; + var elID; + var elTip; + var elTipID; + var elTrigger; + var tipContent; + var tipType; + var _options = Object.assign(tipConfig, options); + + + var init = function () { + // if an element has an ID, use that as the + // basis for the tooltip's ID. Or, generate one. + elID = el.id || util.generateID(_options.baseID); + // the element that will trigger the tooltip on hover or focus. + elTrigger = el.querySelector(_options.triggerSelector); + // base the tip's ID off from the element's tip + elTipID = elID + '_tip'; + // determine the type of tip + tipType = tipType(); + // retrieve the content for the tip (flatted text string) + tipContent = getTipContent(); + // create the tip + createTip(); + // add/modify the necessary attributes of the trigger. + setupTrigger(); + // get the generated tooltip + elTip = el.querySelector('.'+_options.tipContentClass); + // Attach the various events to the triggers + attachEvents(); + }; + + + /** + * A tooltip can either provide a description to + * the element that it is associated with, or it + * can provide a means to visually display the element's + * accessible name (making it not actually a tooltip then, + * but rather the accessible name that is revealed on + * hover/focus). + */ + var tipType = function () { + if ( el.getAttribute(_options.tipTypeAttr) === 'label' ) { + return 'label'; + } + else { + return 'description'; + } + }; + + + /** + * The content of a tooltip can come from different sources + * so as to allow for fallback content in case this script + * cannot run. + * + * A tip could be sourced from an element in the DOM via + * the attribute data-tooltip-tip (a child of the widget), + * or an ID referenced from data-tooltip-source (does not + * have to be a child of the widget), + * the trigger's title or aria-label attribute + */ + var getTipContent = function () { + var returnTextString; // text string to return + var tipAttrContent = el.getAttribute(_options.tipContentAttr); + var tipAriaLabel = elTrigger.getAttribute('aria-label'); + var widgetChild = el.querySelector(_options.tipSelector); + + if ( tipAttrContent ) { + returnTextString = tipAttrContent; + } + else if ( widgetChild ) { + returnTextString = widgetChild.textContent; + widgetChild.parentNode.removeChild(widgetChild); + } + else if ( tipAriaLabel && tipType === 'label' ) { + returnTextString = tipAriaLabel; + elTrigger.removeAttribute('aria-label'); + } + else if ( elTrigger.title ) { + returnTextString = elTrigger.title; + } + + // an element cannot have both a custom tooltip + // and a tooltip from a title attribute. So no + // matter what, remove the title attribute. + elTrigger.removeAttribute('title'); + + return returnTextString; + }; + + + /** + * Create the necessary tooltip components for each + * instance of the widget. + */ + var createTip = function () { + var tipOuter = doc.createElement('span'); + var tipInner = doc.createElement('span'); + + tipOuter.classList.add(_options.tipWrapperClass); + tipInner.classList.add(_options.tipContentClass); + tipInner.textContent = tipContent; + tipInner.id = elTipID; + + if ( tipType !== 'label') { + tipInner.setAttribute('role', 'tooltip'); + } + // this is a bit silly, as it shows how unnecessary the + // tooltip role is, but it ensures that a screen reader's + // virtual cursor cannot interact with the tooltip by itself, + // and helps reduce Chrome on PC w/JAWS and NVDA announcing the tooltip + // multiple times, when it's shown/hidden. + // If you want to reveal the tips anyway, + // set the ariaHiddenTip config to false. + if ( _options.ariaHiddenTip ) { + tipInner.setAttribute('aria-hidden', 'true'); + } + + tipOuter.appendChild(tipInner); + el.appendChild(tipOuter); + }; + + + /** + * Ensure the tooltip trigger has the appropriate + * attributes on it, and that they point to the + * correct IDs. + */ + var setupTrigger = function () { + if ( tipType === 'label' ) { + elTrigger.setAttribute('aria-labelledby', elTipID); + } + else { + elTrigger.setAttribute('aria-describedby', elTipID); + } + }; + + + /** + * Check the current viewport to determine if the tooltip + * will be revealed outside of the current viewport's bounds. + * If so, try to reposition to ensure it's within. + */ + var checkPositioning = function () { + var bounding = elTip.getBoundingClientRect(); + + if ( bounding.bottom > w.innerHeight ) { + el.classList.add('push-up'); + } + + if ( bounding.right > w.innerWidth ) { + el.classList.add('push-right'); + } + }; + + + /** + * Remove the positioning classes, assuming the next time + * the element is interacted with, it will require the + * default positioning. + */ + var resetPositioning = function () { + el.classList.remove('push-up', 'push-right'); + }; + + + /** + * Add class to show tooltip. + * Checks positioning to help ensure within viewport. + * Adds global event to escape tip. + */ + var showTip = function () { + el.classList.add(_options.tipWrapperClass + '--show'); + checkPositioning(); + doc.addEventListener('keydown', globalEscape, false); + doc.addEventListener('touchend', hideTip, false); + }; + + + /** + * Removes classes for show and/or suppressed tip. + * Removes classes for positioning. + * Removes global event to escape tip. + */ + var hideTip = function () { + el.classList.remove(_options.tipWrapperClass + '--show'); + resetPositioning(); + doc.removeEventListener('keydown', globalEscape); + doc.addEventListener('touchend', hideTip); + }; + + + /** + * Global event to allow the ESC key to close + * an invoked tooltip, regardless of where focus/hover + * is in the DOM. + * + * Calls both hideTip and suppressTip functions to help + * better replicate native tooltip suppression behavior. + */ + var globalEscape = function ( e ) { + var keyCode = e.keyCode || e.which; + + switch ( keyCode ) { + case util.keyCodes.ESC: + e.preventDefault(); + hideTip(); + break; + + default: + break; + } + }; + + + var attachEvents = function () { + elTrigger.addEventListener('mouseenter', showTip, false); + elTrigger.addEventListener('focus', showTip, false); + + el.addEventListener('mouseleave', hideTip, false); + elTrigger.addEventListener('blur', hideTip, false); + }; + + + init.call(this); + return this; + }; // ARIAtip + + w.ARIAtip = ARIAtip; +})( window, document ); + +var selector = '[data-tooltip]'; +var els = document.querySelectorAll(selector); + +for ( var i = 0; i < els.length; i++ ) { + var dm = new ARIAtip( els[i] ); +} \ No newline at end of file diff --git a/src/assets/layouts/Leilukins-Hub-blog-layout-2023-09.avif b/src/assets/layouts/Leilukins-Hub-blog-layout-2023-09.avif new file mode 100644 index 00000000..99f95d95 Binary files /dev/null and b/src/assets/layouts/Leilukins-Hub-blog-layout-2023-09.avif differ diff --git a/src/assets/layouts/Leilukins-Hub-blog-layout-2024-04.avif b/src/assets/layouts/Leilukins-Hub-blog-layout-2024-04.avif new file mode 100644 index 00000000..c4283e93 Binary files /dev/null and b/src/assets/layouts/Leilukins-Hub-blog-layout-2024-04.avif differ diff --git a/src/assets/layouts/Leilukins-Hub-layout-2022-index.avif b/src/assets/layouts/Leilukins-Hub-layout-2022-index.avif new file mode 100644 index 00000000..3a29d58a Binary files /dev/null and b/src/assets/layouts/Leilukins-Hub-layout-2022-index.avif differ diff --git a/src/assets/layouts/Leilukins-Hub-layout-2022-page.avif b/src/assets/layouts/Leilukins-Hub-layout-2022-page.avif new file mode 100644 index 00000000..5d1cc7dd Binary files /dev/null and b/src/assets/layouts/Leilukins-Hub-layout-2022-page.avif differ diff --git a/src/assets/layouts/Leilukins-Hub-layout-2023-01.avif b/src/assets/layouts/Leilukins-Hub-layout-2023-01.avif new file mode 100644 index 00000000..c24a118b Binary files /dev/null and b/src/assets/layouts/Leilukins-Hub-layout-2023-01.avif differ diff --git a/src/assets/layouts/Leilukins-Hub-layout-2023-06.avif b/src/assets/layouts/Leilukins-Hub-layout-2023-06.avif new file mode 100644 index 00000000..8d0440ff Binary files /dev/null and b/src/assets/layouts/Leilukins-Hub-layout-2023-06.avif differ diff --git a/src/assets/layouts/Leilukins-Hub-layout-2024-04.avif b/src/assets/layouts/Leilukins-Hub-layout-2024-04.avif new file mode 100644 index 00000000..ceb0d923 Binary files /dev/null and b/src/assets/layouts/Leilukins-Hub-layout-2024-04.avif differ diff --git a/src/assets/leilukin/Leilukins-Hub-button-200x40.png b/src/assets/leilukin/Leilukins-Hub-button-200x40.png new file mode 100644 index 00000000..dff60bd1 Binary files /dev/null and b/src/assets/leilukin/Leilukins-Hub-button-200x40.png differ diff --git a/src/assets/leilukin/Leilukins-Hub-button-88x31.png b/src/assets/leilukin/Leilukins-Hub-button-88x31.png new file mode 100644 index 00000000..eda445f6 Binary files /dev/null and b/src/assets/leilukin/Leilukins-Hub-button-88x31.png differ diff --git a/src/assets/leilukin/Leilukins-Hub-website-banner.avif b/src/assets/leilukin/Leilukins-Hub-website-banner.avif new file mode 100644 index 00000000..d5de58dc Binary files /dev/null and b/src/assets/leilukin/Leilukins-Hub-website-banner.avif differ diff --git a/src/assets/leilukin/leilukin-bee.avif b/src/assets/leilukin/leilukin-bee.avif new file mode 100644 index 00000000..d3415583 Binary files /dev/null and b/src/assets/leilukin/leilukin-bee.avif differ diff --git a/src/assets/leilukin/leilukins-hub-meta-img.png b/src/assets/leilukin/leilukins-hub-meta-img.png new file mode 100644 index 00000000..a0346aa9 Binary files /dev/null and b/src/assets/leilukin/leilukins-hub-meta-img.png differ diff --git a/src/assets/projects/art/bee-diamond-hibiscus.avif b/src/assets/projects/art/bee-diamond-hibiscus.avif new file mode 100644 index 00000000..89d4acab Binary files /dev/null and b/src/assets/projects/art/bee-diamond-hibiscus.avif differ diff --git a/src/assets/projects/art/joltik-finds-oran-berry.avif b/src/assets/projects/art/joltik-finds-oran-berry.avif new file mode 100644 index 00000000..9b26787b Binary files /dev/null and b/src/assets/projects/art/joltik-finds-oran-berry.avif differ diff --git a/src/assets/projects/art/life-of-a-bee-with-pride.avif b/src/assets/projects/art/life-of-a-bee-with-pride.avif new file mode 100644 index 00000000..fde6afc7 Binary files /dev/null and b/src/assets/projects/art/life-of-a-bee-with-pride.avif differ diff --git a/src/assets/projects/art/pride-hibiscuses.avif b/src/assets/projects/art/pride-hibiscuses.avif new file mode 100644 index 00000000..f1f6398b Binary files /dev/null and b/src/assets/projects/art/pride-hibiscuses.avif differ diff --git a/src/assets/projects/kotor1mods/Bastila-and-Carth-Romance-Removal.avif b/src/assets/projects/kotor1mods/Bastila-and-Carth-Romance-Removal.avif new file mode 100644 index 00000000..bc76baf6 Binary files /dev/null and b/src/assets/projects/kotor1mods/Bastila-and-Carth-Romance-Removal.avif differ diff --git a/src/assets/projects/kotor1mods/Belaya-Unique-Look.avif b/src/assets/projects/kotor1mods/Belaya-Unique-Look.avif new file mode 100644 index 00000000..b389f220 Binary files /dev/null and b/src/assets/projects/kotor1mods/Belaya-Unique-Look.avif differ diff --git a/src/assets/projects/kotor1mods/Carth-Onasi-and-Male-PC-Romance.avif b/src/assets/projects/kotor1mods/Carth-Onasi-and-Male-PC-Romance.avif new file mode 100644 index 00000000..f7509f98 Binary files /dev/null and b/src/assets/projects/kotor1mods/Carth-Onasi-and-Male-PC-Romance.avif differ diff --git a/src/assets/projects/kotor1mods/Darth-Revan-Texture-for-Star-Forge-Robes.avif b/src/assets/projects/kotor1mods/Darth-Revan-Texture-for-Star-Forge-Robes.avif new file mode 100644 index 00000000..a37e8ac1 Binary files /dev/null and b/src/assets/projects/kotor1mods/Darth-Revan-Texture-for-Star-Forge-Robes.avif differ diff --git a/src/assets/projects/kotor1mods/Human-Xor-Restoration.avif b/src/assets/projects/kotor1mods/Human-Xor-Restoration.avif new file mode 100644 index 00000000..79327342 Binary files /dev/null and b/src/assets/projects/kotor1mods/Human-Xor-Restoration.avif differ diff --git a/src/assets/projects/kotor1mods/Human-Xor-Unique-Look.avif b/src/assets/projects/kotor1mods/Human-Xor-Unique-Look.avif new file mode 100644 index 00000000..3d6d5b57 Binary files /dev/null and b/src/assets/projects/kotor1mods/Human-Xor-Unique-Look.avif differ diff --git a/src/assets/projects/kotor1mods/Jolee-in-Unique-Outfit-Introduction.avif b/src/assets/projects/kotor1mods/Jolee-in-Unique-Outfit-Introduction.avif new file mode 100644 index 00000000..0ca8f084 Binary files /dev/null and b/src/assets/projects/kotor1mods/Jolee-in-Unique-Outfit-Introduction.avif differ diff --git a/src/assets/projects/kotor1mods/Juhani-Dialogue-Restoration.avif b/src/assets/projects/kotor1mods/Juhani-Dialogue-Restoration.avif new file mode 100644 index 00000000..c4b5fc44 Binary files /dev/null and b/src/assets/projects/kotor1mods/Juhani-Dialogue-Restoration.avif differ diff --git a/src/assets/projects/kotor1mods/K1-No-Gendered-Dialogue-Male-NPCs.avif b/src/assets/projects/kotor1mods/K1-No-Gendered-Dialogue-Male-NPCs.avif new file mode 100644 index 00000000..032d080f Binary files /dev/null and b/src/assets/projects/kotor1mods/K1-No-Gendered-Dialogue-Male-NPCs.avif differ diff --git a/src/assets/projects/kotor1mods/K1-Twilek-Female-NPC-Diversity.avif b/src/assets/projects/kotor1mods/K1-Twilek-Female-NPC-Diversity.avif new file mode 100644 index 00000000..59e01ff1 Binary files /dev/null and b/src/assets/projects/kotor1mods/K1-Twilek-Female-NPC-Diversity.avif differ diff --git a/src/assets/projects/kotor1mods/K1-Twilek-Male-NPC-Diversity.avif b/src/assets/projects/kotor1mods/K1-Twilek-Male-NPC-Diversity.avif new file mode 100644 index 00000000..bae04c13 Binary files /dev/null and b/src/assets/projects/kotor1mods/K1-Twilek-Male-NPC-Diversity.avif differ diff --git a/src/assets/projects/kotor1mods/KotOR-1-Improved-Party-Outfits.avif b/src/assets/projects/kotor1mods/KotOR-1-Improved-Party-Outfits.avif new file mode 100644 index 00000000..c779dc76 Binary files /dev/null and b/src/assets/projects/kotor1mods/KotOR-1-Improved-Party-Outfits.avif differ diff --git a/src/assets/projects/kotor1mods/Leilukins-Juhanis-Outfit-Reskin-Pack.avif b/src/assets/projects/kotor1mods/Leilukins-Juhanis-Outfit-Reskin-Pack.avif new file mode 100644 index 00000000..16c99789 Binary files /dev/null and b/src/assets/projects/kotor1mods/Leilukins-Juhanis-Outfit-Reskin-Pack.avif differ diff --git a/src/assets/projects/kotor1mods/Mysterious-Box-Music-for-Unknown-World.avif b/src/assets/projects/kotor1mods/Mysterious-Box-Music-for-Unknown-World.avif new file mode 100644 index 00000000..eaaf7c36 Binary files /dev/null and b/src/assets/projects/kotor1mods/Mysterious-Box-Music-for-Unknown-World.avif differ diff --git a/src/assets/projects/kotor1mods/PC-Dialogue-with-Daviks-Slaves-Change.avif b/src/assets/projects/kotor1mods/PC-Dialogue-with-Daviks-Slaves-Change.avif new file mode 100644 index 00000000..b39ef334 Binary files /dev/null and b/src/assets/projects/kotor1mods/PC-Dialogue-with-Daviks-Slaves-Change.avif differ diff --git a/src/assets/projects/kotor1mods/Trask-Ulgo-Without-Tutorials.avif b/src/assets/projects/kotor1mods/Trask-Ulgo-Without-Tutorials.avif new file mode 100644 index 00000000..4486742a Binary files /dev/null and b/src/assets/projects/kotor1mods/Trask-Ulgo-Without-Tutorials.avif differ diff --git a/src/assets/projects/kotor2mods/Alternate-Revan-Romances.avif b/src/assets/projects/kotor2mods/Alternate-Revan-Romances.avif new file mode 100644 index 00000000..5219cd07 Binary files /dev/null and b/src/assets/projects/kotor2mods/Alternate-Revan-Romances.avif differ diff --git a/src/assets/projects/kotor2mods/Atton-Rand-and-Male-Exile-Romance.avif b/src/assets/projects/kotor2mods/Atton-Rand-and-Male-Exile-Romance.avif new file mode 100644 index 00000000..a8199e60 Binary files /dev/null and b/src/assets/projects/kotor2mods/Atton-Rand-and-Male-Exile-Romance.avif differ diff --git a/src/assets/projects/kotor2mods/Consistent-Bastila-Recognition.avif b/src/assets/projects/kotor2mods/Consistent-Bastila-Recognition.avif new file mode 100644 index 00000000..095e7d34 Binary files /dev/null and b/src/assets/projects/kotor2mods/Consistent-Bastila-Recognition.avif differ diff --git a/src/assets/projects/kotor2mods/Dahnis-Flirt-Option-for-Female-PC.avif b/src/assets/projects/kotor2mods/Dahnis-Flirt-Option-for-Female-PC.avif new file mode 100644 index 00000000..f6fd16ba Binary files /dev/null and b/src/assets/projects/kotor2mods/Dahnis-Flirt-Option-for-Female-PC.avif differ diff --git a/src/assets/projects/kotor2mods/Dahnis-Unique-Look.avif b/src/assets/projects/kotor2mods/Dahnis-Unique-Look.avif new file mode 100644 index 00000000..5af1deaa Binary files /dev/null and b/src/assets/projects/kotor2mods/Dahnis-Unique-Look.avif differ diff --git a/src/assets/projects/kotor2mods/Darth-Sion-and-Male-Exile-Mod.avif b/src/assets/projects/kotor2mods/Darth-Sion-and-Male-Exile-Mod.avif new file mode 100644 index 00000000..9b63e30f Binary files /dev/null and b/src/assets/projects/kotor2mods/Darth-Sion-and-Male-Exile-Mod.avif differ diff --git a/src/assets/projects/kotor2mods/Exiles-Trial-Overlay-Removal.avif b/src/assets/projects/kotor2mods/Exiles-Trial-Overlay-Removal.avif new file mode 100644 index 00000000..49bd286d Binary files /dev/null and b/src/assets/projects/kotor2mods/Exiles-Trial-Overlay-Removal.avif differ diff --git a/src/assets/projects/kotor2mods/Handmaiden-Disciple-Same-Gender-Romances.avif b/src/assets/projects/kotor2mods/Handmaiden-Disciple-Same-Gender-Romances.avif new file mode 100644 index 00000000..83256ff8 Binary files /dev/null and b/src/assets/projects/kotor2mods/Handmaiden-Disciple-Same-Gender-Romances.avif differ diff --git a/src/assets/projects/kotor2mods/Juhani-Item-Pack-for-TSL.avif b/src/assets/projects/kotor2mods/Juhani-Item-Pack-for-TSL.avif new file mode 100644 index 00000000..62134de0 Binary files /dev/null and b/src/assets/projects/kotor2mods/Juhani-Item-Pack-for-TSL.avif differ diff --git a/src/assets/projects/kotor2mods/Leilukins-Kreia-Reskin.avif b/src/assets/projects/kotor2mods/Leilukins-Kreia-Reskin.avif new file mode 100644 index 00000000..9f59b113 Binary files /dev/null and b/src/assets/projects/kotor2mods/Leilukins-Kreia-Reskin.avif differ diff --git a/src/assets/projects/kotor2mods/Lonna-Vash-Mod-for-TSLRCM.avif b/src/assets/projects/kotor2mods/Lonna-Vash-Mod-for-TSLRCM.avif new file mode 100644 index 00000000..ae4f139b Binary files /dev/null and b/src/assets/projects/kotor2mods/Lonna-Vash-Mod-for-TSLRCM.avif differ diff --git a/src/assets/projects/kotor2mods/Love-Between-Brianna-and-the-Exile-TSLRCM.avif b/src/assets/projects/kotor2mods/Love-Between-Brianna-and-the-Exile-TSLRCM.avif new file mode 100644 index 00000000..8ed68d7e Binary files /dev/null and b/src/assets/projects/kotor2mods/Love-Between-Brianna-and-the-Exile-TSLRCM.avif differ diff --git a/src/assets/projects/kotor2mods/No-Jealousy-Lock-Handmaiden.avif b/src/assets/projects/kotor2mods/No-Jealousy-Lock-Handmaiden.avif new file mode 100644 index 00000000..195a4924 Binary files /dev/null and b/src/assets/projects/kotor2mods/No-Jealousy-Lock-Handmaiden.avif differ diff --git a/src/assets/projects/kotor2mods/PartySwap-ExtEnclave-Comp-Patch.avif b/src/assets/projects/kotor2mods/PartySwap-ExtEnclave-Comp-Patch.avif new file mode 100644 index 00000000..c90b4dea Binary files /dev/null and b/src/assets/projects/kotor2mods/PartySwap-ExtEnclave-Comp-Patch.avif differ diff --git a/src/assets/projects/kotor2mods/PartySwap.avif b/src/assets/projects/kotor2mods/PartySwap.avif new file mode 100644 index 00000000..bb5dde19 Binary files /dev/null and b/src/assets/projects/kotor2mods/PartySwap.avif differ diff --git a/src/assets/projects/kotor2mods/Prologue-Item-Recovery.avif b/src/assets/projects/kotor2mods/Prologue-Item-Recovery.avif new file mode 100644 index 00000000..97867370 Binary files /dev/null and b/src/assets/projects/kotor2mods/Prologue-Item-Recovery.avif differ diff --git a/src/assets/projects/kotor2mods/Remote-Tells-Influence-Patch.avif b/src/assets/projects/kotor2mods/Remote-Tells-Influence-Patch.avif new file mode 100644 index 00000000..c4a76594 Binary files /dev/null and b/src/assets/projects/kotor2mods/Remote-Tells-Influence-Patch.avif differ diff --git a/src/assets/projects/kotor2mods/TSL-Improved-Party-Outfits.avif b/src/assets/projects/kotor2mods/TSL-Improved-Party-Outfits.avif new file mode 100644 index 00000000..3666e56c Binary files /dev/null and b/src/assets/projects/kotor2mods/TSL-Improved-Party-Outfits.avif differ diff --git a/src/assets/projects/kotor2mods/TSL-Twilek-Male-NPC-Diversity.avif b/src/assets/projects/kotor2mods/TSL-Twilek-Male-NPC-Diversity.avif new file mode 100644 index 00000000..20924dd4 Binary files /dev/null and b/src/assets/projects/kotor2mods/TSL-Twilek-Male-NPC-Diversity.avif differ diff --git a/src/assets/projects/kotor2mods/TSL-Workbnch-Lightsaber-Creation.avif b/src/assets/projects/kotor2mods/TSL-Workbnch-Lightsaber-Creation.avif new file mode 100644 index 00000000..01f43922 Binary files /dev/null and b/src/assets/projects/kotor2mods/TSL-Workbnch-Lightsaber-Creation.avif differ diff --git a/src/assets/projects/kotor2mods/Visas-Marr-and-Female-Exile-Romance.avif b/src/assets/projects/kotor2mods/Visas-Marr-and-Female-Exile-Romance.avif new file mode 100644 index 00000000..e55b1299 Binary files /dev/null and b/src/assets/projects/kotor2mods/Visas-Marr-and-Female-Exile-Romance.avif differ diff --git a/src/assets/projects/kotor2mods/Visas-Visible-Jedi-Robes.avif b/src/assets/projects/kotor2mods/Visas-Visible-Jedi-Robes.avif new file mode 100644 index 00000000..a5bba2d7 Binary files /dev/null and b/src/assets/projects/kotor2mods/Visas-Visible-Jedi-Robes.avif differ diff --git a/src/assets/projects/playlists/Mandopop-LGBTQ+-Anthem-Cover.avif b/src/assets/projects/playlists/Mandopop-LGBTQ+-Anthem-Cover.avif new file mode 100644 index 00000000..68baec74 Binary files /dev/null and b/src/assets/projects/playlists/Mandopop-LGBTQ+-Anthem-Cover.avif differ diff --git a/src/assets/projects/playlists/My-Dear-Summer-Lover-cover.avif b/src/assets/projects/playlists/My-Dear-Summer-Lover-cover.avif new file mode 100644 index 00000000..3993e14b Binary files /dev/null and b/src/assets/projects/playlists/My-Dear-Summer-Lover-cover.avif differ diff --git a/src/assets/shrines/asummersend/images/ASE_Key_art_intro.avif b/src/assets/shrines/asummersend/images/ASE_Key_art_intro.avif new file mode 100644 index 00000000..e3e98978 Binary files /dev/null and b/src/assets/shrines/asummersend/images/ASE_Key_art_intro.avif differ diff --git a/src/assets/shrines/asummersend/images/ASE_Key_art_main.avif b/src/assets/shrines/asummersend/images/ASE_Key_art_main.avif new file mode 100644 index 00000000..f656d9ad Binary files /dev/null and b/src/assets/shrines/asummersend/images/ASE_Key_art_main.avif differ diff --git a/src/assets/shrines/asummersend/images/asummersend-header-320.avif b/src/assets/shrines/asummersend/images/asummersend-header-320.avif new file mode 100644 index 00000000..4e80bdc2 Binary files /dev/null and b/src/assets/shrines/asummersend/images/asummersend-header-320.avif differ diff --git a/src/assets/shrines/asummersend/images/asummersend-header.avif b/src/assets/shrines/asummersend/images/asummersend-header.avif new file mode 100644 index 00000000..dabddaf2 Binary files /dev/null and b/src/assets/shrines/asummersend/images/asummersend-header.avif differ diff --git a/src/assets/shrines/asummersend/images/favicon.ico b/src/assets/shrines/asummersend/images/favicon.ico new file mode 100644 index 00000000..2cd00bb0 Binary files /dev/null and b/src/assets/shrines/asummersend/images/favicon.ico differ diff --git a/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-01.avif b/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-01.avif new file mode 100644 index 00000000..8c982619 Binary files /dev/null and b/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-01.avif differ diff --git a/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-02.avif b/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-02.avif new file mode 100644 index 00000000..93069133 Binary files /dev/null and b/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-02.avif differ diff --git a/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-03.avif b/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-03.avif new file mode 100644 index 00000000..a8b20a28 Binary files /dev/null and b/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-03.avif differ diff --git a/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-04.avif b/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-04.avif new file mode 100644 index 00000000..d6084c34 Binary files /dev/null and b/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-04.avif differ diff --git a/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-05.avif b/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-05.avif new file mode 100644 index 00000000..1b3a4973 Binary files /dev/null and b/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-05.avif differ diff --git a/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-06.avif b/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-06.avif new file mode 100644 index 00000000..90e90177 Binary files /dev/null and b/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-06.avif differ diff --git a/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-07.avif b/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-07.avif new file mode 100644 index 00000000..450203e4 Binary files /dev/null and b/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-07.avif differ diff --git a/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-08.avif b/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-08.avif new file mode 100644 index 00000000..7f29a3b1 Binary files /dev/null and b/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-08.avif differ diff --git a/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-09.avif b/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-09.avif new file mode 100644 index 00000000..163593ff Binary files /dev/null and b/src/assets/shrines/asummersend/screenshots/ASE-Screenshot-09.avif differ diff --git a/src/assets/shrines/cassettebeasts/gamelog/cb-character-kristine.avif b/src/assets/shrines/cassettebeasts/gamelog/cb-character-kristine.avif new file mode 100644 index 00000000..e64a0e64 Binary files /dev/null and b/src/assets/shrines/cassettebeasts/gamelog/cb-character-kristine.avif differ diff --git a/src/assets/shrines/cassettebeasts/images/CassetteBeasts_keyart_16_9.avif b/src/assets/shrines/cassettebeasts/images/CassetteBeasts_keyart_16_9.avif new file mode 100644 index 00000000..d36505ac Binary files /dev/null and b/src/assets/shrines/cassettebeasts/images/CassetteBeasts_keyart_16_9.avif differ diff --git a/src/assets/shrines/cassettebeasts/images/cassettebeasts-header-320.avif b/src/assets/shrines/cassettebeasts/images/cassettebeasts-header-320.avif new file mode 100644 index 00000000..b99b18e1 Binary files /dev/null and b/src/assets/shrines/cassettebeasts/images/cassettebeasts-header-320.avif differ diff --git a/src/assets/shrines/cassettebeasts/images/cassettebeasts-header-640.avif b/src/assets/shrines/cassettebeasts/images/cassettebeasts-header-640.avif new file mode 100644 index 00000000..b50919bf Binary files /dev/null and b/src/assets/shrines/cassettebeasts/images/cassettebeasts-header-640.avif differ diff --git a/src/assets/shrines/cassettebeasts/images/cassettebeasts-website-header-bg.avif b/src/assets/shrines/cassettebeasts/images/cassettebeasts-website-header-bg.avif new file mode 100644 index 00000000..f52279e0 Binary files /dev/null and b/src/assets/shrines/cassettebeasts/images/cassettebeasts-website-header-bg.avif differ diff --git a/src/assets/shrines/cassettebeasts/images/cassettebeasts-website_screenshot_02-1.avif b/src/assets/shrines/cassettebeasts/images/cassettebeasts-website_screenshot_02-1.avif new file mode 100644 index 00000000..6afcb8f3 Binary files /dev/null and b/src/assets/shrines/cassettebeasts/images/cassettebeasts-website_screenshot_02-1.avif differ diff --git a/src/assets/shrines/cassettebeasts/images/cassettebeasts-website_screenshot_02.avif b/src/assets/shrines/cassettebeasts/images/cassettebeasts-website_screenshot_02.avif new file mode 100644 index 00000000..7f83d04a Binary files /dev/null and b/src/assets/shrines/cassettebeasts/images/cassettebeasts-website_screenshot_02.avif differ diff --git a/src/assets/shrines/cassettebeasts/images/cassettebeasts-website_screenshot_07.avif b/src/assets/shrines/cassettebeasts/images/cassettebeasts-website_screenshot_07.avif new file mode 100644 index 00000000..b80cf2d3 Binary files /dev/null and b/src/assets/shrines/cassettebeasts/images/cassettebeasts-website_screenshot_07.avif differ diff --git a/src/assets/shrines/cassettebeasts/images/favicon.ico b/src/assets/shrines/cassettebeasts/images/favicon.ico new file mode 100644 index 00000000..f0033780 Binary files /dev/null and b/src/assets/shrines/cassettebeasts/images/favicon.ico differ diff --git a/src/assets/shrines/cassettebeasts/socmed/Screenshot-2023-10-05-at-14-27-39-Lockstin-on-X.avif b/src/assets/shrines/cassettebeasts/socmed/Screenshot-2023-10-05-at-14-27-39-Lockstin-on-X.avif new file mode 100644 index 00000000..aa542d8d Binary files /dev/null and b/src/assets/shrines/cassettebeasts/socmed/Screenshot-2023-10-05-at-14-27-39-Lockstin-on-X.avif differ diff --git a/src/assets/shrines/pokemonoras/images/Hoenn_ORAS.avif b/src/assets/shrines/pokemonoras/images/Hoenn_ORAS.avif new file mode 100644 index 00000000..5cfd5b21 Binary files /dev/null and b/src/assets/shrines/pokemonoras/images/Hoenn_ORAS.avif differ diff --git a/src/assets/shrines/pokemonoras/images/Primal_Groudon_and_Primal_Kyogre_artwork.avif b/src/assets/shrines/pokemonoras/images/Primal_Groudon_and_Primal_Kyogre_artwork.avif new file mode 100644 index 00000000..bf2cb794 Binary files /dev/null and b/src/assets/shrines/pokemonoras/images/Primal_Groudon_and_Primal_Kyogre_artwork.avif differ diff --git a/src/assets/shrines/pokemonoras/images/favicon.ico b/src/assets/shrines/pokemonoras/images/favicon.ico new file mode 100644 index 00000000..5c5a7c9e Binary files /dev/null and b/src/assets/shrines/pokemonoras/images/favicon.ico differ diff --git a/src/assets/shrines/pokemonoras/images/pokemonoras-header-320.avif b/src/assets/shrines/pokemonoras/images/pokemonoras-header-320.avif new file mode 100644 index 00000000..671fc800 Binary files /dev/null and b/src/assets/shrines/pokemonoras/images/pokemonoras-header-320.avif differ diff --git a/src/assets/shrines/pokemonoras/images/pokemonoras-header-640.avif b/src/assets/shrines/pokemonoras/images/pokemonoras-header-640.avif new file mode 100644 index 00000000..11fec089 Binary files /dev/null and b/src/assets/shrines/pokemonoras/images/pokemonoras-header-640.avif differ diff --git a/src/assets/shrines/pokemonoras/images/pokemonoras-keyart.avif b/src/assets/shrines/pokemonoras/images/pokemonoras-keyart.avif new file mode 100644 index 00000000..99fd0d9a Binary files /dev/null and b/src/assets/shrines/pokemonoras/images/pokemonoras-keyart.avif differ diff --git a/src/assets/shrines/starwarskotor/articles/juhani-lesbian-in-game-evidence.avif b/src/assets/shrines/starwarskotor/articles/juhani-lesbian-in-game-evidence.avif new file mode 100644 index 00000000..548956ab Binary files /dev/null and b/src/assets/shrines/starwarskotor/articles/juhani-lesbian-in-game-evidence.avif differ diff --git a/src/assets/shrines/starwarskotor/articles/partyswap-ownership-takeover.avif b/src/assets/shrines/starwarskotor/articles/partyswap-ownership-takeover.avif new file mode 100644 index 00000000..276dcc89 Binary files /dev/null and b/src/assets/shrines/starwarskotor/articles/partyswap-ownership-takeover.avif differ diff --git a/src/assets/shrines/starwarskotor/images/favicon.ico b/src/assets/shrines/starwarskotor/images/favicon.ico new file mode 100644 index 00000000..db1cdcc4 Binary files /dev/null and b/src/assets/shrines/starwarskotor/images/favicon.ico differ diff --git a/src/assets/shrines/starwarskotor/images/swkotor-header-320.avif b/src/assets/shrines/starwarskotor/images/swkotor-header-320.avif new file mode 100644 index 00000000..aa78ea0d Binary files /dev/null and b/src/assets/shrines/starwarskotor/images/swkotor-header-320.avif differ diff --git a/src/assets/shrines/starwarskotor/images/swkotor-header.avif b/src/assets/shrines/starwarskotor/images/swkotor-header.avif new file mode 100644 index 00000000..2b99d641 Binary files /dev/null and b/src/assets/shrines/starwarskotor/images/swkotor-header.avif differ diff --git a/src/assets/shrines/starwarskotor/universes/myexile-yunhua-yang.avif b/src/assets/shrines/starwarskotor/universes/myexile-yunhua-yang.avif new file mode 100644 index 00000000..9c7247ee Binary files /dev/null and b/src/assets/shrines/starwarskotor/universes/myexile-yunhua-yang.avif differ diff --git a/src/assets/shrines/starwarskotor/universes/myrevan-jiaxuan-cheng.avif b/src/assets/shrines/starwarskotor/universes/myrevan-jiaxuan-cheng.avif new file mode 100644 index 00000000..cd130562 Binary files /dev/null and b/src/assets/shrines/starwarskotor/universes/myrevan-jiaxuan-cheng.avif differ diff --git a/src/blog/posts.njk b/src/blog/posts.njk new file mode 100644 index 00000000..7ff513b0 --- /dev/null +++ b/src/blog/posts.njk @@ -0,0 +1,40 @@ +--- +title: Blog Archive +layout: main/content +tags: blog pages +eleventyComputed: + desc: Archive of blog posts on {{ sitemeta.siteName | safe }} +eleventyNavigation: + key: Blog Archive + parent: Blog +--- + + + +{%- css %} +.blog__postlist { + display: grid; + gap: 1em; + padding-left: 1em; +} + +.blog__postlist--title { + font-size: clamp(1.55rem, 1rem + 3vw, 1.3rem); + line-height: 1.3; + margin-bottom: 0.2em; +} +{% endcss %} diff --git a/src/blog/posts/2023-01-26-new-year-leilukins-hub-redesign.md b/src/blog/posts/2023-01-26-new-year-leilukins-hub-redesign.md new file mode 100644 index 00000000..016c0732 --- /dev/null +++ b/src/blog/posts/2023-01-26-new-year-leilukins-hub-redesign.md @@ -0,0 +1,29 @@ +--- +articleTitle: 2023 New Year Redesign of Leilukin's Hub +desc: About giving my website a new design in light of a new year of 2023. +date: 2023-01-26 +categories: ["site updates"] +--- + +![A screenshot of Leilukin's Hub home page, with its layout design released on January 26, 2023](/assets/layouts/Leilukins-Hub-layout-2023-01.avif) + +In light of a new year, the Leilukin's Hub website has received a new design on 26 January 2023! + +I have wanted to rewrite and redesign this site after learning HTML and CSS more and getting better at writing those languages. With Visual Studio Code and the [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer) extension installed, I have also finally found a good workflow for me to write and test HTML and CSS. + +Looking at other Neocities websites have also given me more ideas in enhancing my own website. Special thanks to [sadgrl.online](https://sadgrl.online/), whose various web building resources, including the Layout Builder, have helped tremendously in redesigning this site. + +With this 2023 new year redesign of this website, the index page, which is for when you visit the link leilukin.neocities.org, you will be presented with a very simple splash page, but when you click the "Enter" button to enter, you will be brought to my website's home page, and can start properly browsing my website, and enjoying the new design! + +Highlights of the 2023 New Year redesign of Leilukin's Hub: + +* Uses purple colour schemes primarily, as purple is one of my favourite colours. +* Each page category has their own CSS file, allowing me to give certain pages unique elements. However, the site still has a main CSS file to be imported into CSS files of other pages, saving me time to edit the CSS files one by one just to tweak a certain part of the main layout design. +* Background image added. +* Sidebars added, with the contents being sticky, so you can still see them while scrolling through. +* The navigation links are now on the right sidebar. Previously, the navigation links of my website are in a row placed at the header section. +* The table of contents of some of my pages is now placed on the left sidebar. +* The [website changelog](/changelogs/) page adds archives for the layout designs of this site and old changelog. +* My [video game mod pages](/mymods) have added a filter function, so you can use buttons to view a specific category of mods. + +After spending many hours on this site redesign, I am very pleased with how it turns out. Hope you enjoy it! \ No newline at end of file diff --git a/src/blog/posts/2023-01-28-leilukins-hub-now-has-a-blog.md b/src/blog/posts/2023-01-28-leilukins-hub-now-has-a-blog.md new file mode 100644 index 00000000..0875b928 --- /dev/null +++ b/src/blog/posts/2023-01-28-leilukins-hub-now-has-a-blog.md @@ -0,0 +1,18 @@ +--- +articleTitle: Leilukin's Hub Now has a Blog! +desc: I have finally set up a blog on my own website. +date: 2023-01-28 +updated: 2024-04-16 +categories: ["site updates"] +--- + +I finally built a blog on my own website! + +After launching this site in September 2022, I had been considering setting up a blog here, as I want a blog that is hosted on my own site, but it was not until I discovered [Zonelets](https://zonelets.net/), a HTML blogging engine created with Neocities in mind, and it was exactly what I was looking for to build a blog on my own Neocities site: it is simple enough for beginners to use, yet also open for more customisation and flexibility for users who have enough knowledge about HTML, CSS and JavaScript. + +My site does have an [articles](/articles) section, but what makes this blog different from the articles is that the articles are meant to be timeless, sort of like my public statements for certain topics, while posts from this blog are more like journals or reactions to a timely subject. + +Welcome to my blog! Hope you enjoy your stay on this blog and my website! + +**UPDATE on 16 April 2024:** +After discovering the static site generator [Eleventy](https://www.11ty.dev/), I decided to rebuild my entire website, including this blog, with Eleventy. Therefore, I no longer use Zonelets, and now this blog is powered by Eleventy. \ No newline at end of file diff --git a/src/blog/posts/2023-05-09-onboard-the-dracula-daily-hype-train.md b/src/blog/posts/2023-05-09-onboard-the-dracula-daily-hype-train.md new file mode 100644 index 00000000..bf30ec04 --- /dev/null +++ b/src/blog/posts/2023-05-09-onboard-the-dracula-daily-hype-train.md @@ -0,0 +1,12 @@ +--- +articleTitle: Onboard the Dracula Daily Hype Train +desc: I have signed up to join the Dracula Daily hype. +date: 2023-05-09 +categories: ["dracula daily"] +--- + +[Dracula Daily](https://draculadaily.com/), the free subscription newsletter that sends Bram Stoker's 1897 novel Dracula to subscribers via email, became an internet sensation, especially on Tumblr. Some of my Tumblr mutuals were also on the hype train, though I missed it. + +Fortunately, Dracula Daily returns in 2023, so I decided to sign up to subscribe to the newsletter and join the hype. This year, [Re: Dracula](https://redracula.live/), the audio drama podcast adaptation of Dracula, also debuts. Like Dracula Daily, Re: Dracula releases new entries in as close to real time as it happens, meaning you can now enjoy Dracula Daily in audio form as well, with excellent voice acting and sound design to enhance the experience. + +Confession: This is actually my first time reading Dracula, so I am looking forward to this serialised way of reading the novel! diff --git a/src/blog/posts/2023-06-23-june-2023-leilukins-hub-layout-rewrite.md b/src/blog/posts/2023-06-23-june-2023-leilukins-hub-layout-rewrite.md new file mode 100644 index 00000000..a172cd54 --- /dev/null +++ b/src/blog/posts/2023-06-23-june-2023-leilukins-hub-layout-rewrite.md @@ -0,0 +1,24 @@ +--- +articleTitle: June 2023 Leilukin's Hub Layout Rewrite +desc: The HTML, CSS and JavaScript of my entire website have been rewritten in June 2023 to improve its layout. +date: 2023-06-23 +categories: ["site updates"] +--- + +![A screenshot of Leilukin's Hub home page, with its new layout released on June 23, 2023](/assets/layouts/Leilukins-Hub-layout-2023-06.avif) + +Happy Pride Month! It is always Pride on this literally [queer-coded](https://isaacfish.neocities.org/webring/) (as in, literally coded by a queer person) website, so Leilukin's Hub decided to celebrate Pride Month with a major update — rewriting the entire website's layout! + +This new layout remains the same colour scheme as the previous one, which went live in January this year. The most noticeable change you would see in this new layout is the sticky navigation bar, a feature that previously only existed in [my shrines](/shrines/). However, under the hood the HTML, CSS and JavaScript all have been rewritten from the ground up to optimise the site's layout. + +Highlights of the June 2023 layout rewrite of Leilukin's Hub: + +* A new navigation bar throughout the entire website, instead of putting links to this site's pages on the sidebar. The design of this navigation bar is inspired by the dropdown menu bar at the end of this article: [6 Best Practices for Building Responsive Dropdown Menus](https://webdesign.tutsplus.com/articles/best-practices-for-responsive-dropdown-menus--cms-35212). +* Rewrite the HTML elements to improve the website's layout. +* Use a mobile-first workflow to rewrite the CSS of this website to make the website more responsive to various screen sizes (mobile, tablet and desktop). +* Streamline the CSS of the main parts of the site into one CSS file. The only pages that also have their own CSS due to unique elements with custom classes exclusive to the pages are [my mod pages](/mymods/). The shrines still have their own CSS files, however. +* Use [Andy Bell's modern CSS reset](https://andy-bell.co.uk/a-modern-css-reset/) for the CSS of the entire website. +* The header, navigation bar and footer have their own scripts to dynamically render the content of these elements with JavaScript's [`innerHTML`](https://www.javascripttutorial.net/javascript-dom/javascript-innerhtml/) property. +* Add a "Back to top" link to the footer to quickly scroll back to the top of the page you are viewing + +Rewriting the layout of this entire website has taken me many hours on this site redesign. Nevertheless, I am very pleased with how it turns out. Enjoy! \ No newline at end of file diff --git a/src/blog/posts/2023-07-28-my-first-birthday-after-the-launch-of-leilukins-hub.md b/src/blog/posts/2023-07-28-my-first-birthday-after-the-launch-of-leilukins-hub.md new file mode 100644 index 00000000..1730167c --- /dev/null +++ b/src/blog/posts/2023-07-28-my-first-birthday-after-the-launch-of-leilukins-hub.md @@ -0,0 +1,16 @@ +--- +articleTitle: My First Birthday After the Launch of Leilukin's Hub +desc: 28th July 2023 marks my first birthday after the launch of this personal website. +date: 2023-07-28 +categories: ["my birthday", "cassette beasts"] +--- + +28 July is my birthday, and in 2023, it also marks my first birthday after the launch of this personal website. I have had a nice birthday this year. + +I spent the moments counting down to my birthday by playing Cassette Beasts, which has become one of my all-time favourite video games, to the extent that I am planning to make a shrine for it on this site. I defeated [Lamento Mori](https://wiki.cassettebeasts.com/wiki/Lamento_Mori), who in the lore of Cassette Beasts is an [Archangel](https://wiki.cassettebeasts.com/wiki/Archangel), one of the eldritch entities in the game's settings, that specifically embodies humanity's fear of death. It is both amusing and poetic that I celebrated the countdown to my birthday by defeating a boss in a video game that represents death. + +Since I have been playing and loving Cassette Beasts, and I want to support indie developers of indie games I love, I decided to purchase the Deluxe Edition on Steam, which includes the soundtrack, the art book and the Cosplay Pack as a birthday gift for myself. I received the base game as a Steam gift from a friend, and now I chose to use my money to support the developers myself as well. Not to mention, the music of Cassette Beasts is amazing. "Same Old Story", the battle theme of the Archangels, in particular, has become one of my all-time favourite battle themes in video games. + +I had my birthday celebration with my family and received birthday wishes from friends. + +Happy Birthday to me! diff --git a/src/blog/posts/2023-09-11-happy-1st-anniversary-to-leilukins-hub.md b/src/blog/posts/2023-09-11-happy-1st-anniversary-to-leilukins-hub.md new file mode 100644 index 00000000..027f76b3 --- /dev/null +++ b/src/blog/posts/2023-09-11-happy-1st-anniversary-to-leilukins-hub.md @@ -0,0 +1,18 @@ +--- +articleTitle: Happy 1st Anniversary to Leilukin's Hub +desc: Celebrating the first anniversary of Leilukin's Hub and reflecting on the evolution of my website throughout past year. +date: 2023-09-11 +categories: ["site updates", "site anniversary"] +--- + +11 September 2023 marks the first anniversary of Leilukin's Hub, my personal website, hosted on Neocities. I am proud to be able to succeed in not only building my own website, but also updating, improving and maintaining my website to achieve my vision for my own personal hub on the internet outside social media platforms. + +I registered a Neocities account on 28 May 2022, while my own website, Leilukin's Hub, was officially launched on 11 September 2022. I set up this website because I wanted to have a personal web page outside social media platforms to gather various stuff and resources I had created or compiled on online spaces throughout the years. Furthermore, I settled for Neocities because I like the flexibility of customisation by coding my website with HTML, CSS and JavaScript. Initially, I considered and tried [Carrd](https://carrd.co/) to create my web pages, but free accounts on Carrd can only add up to 100 elements on a web page, which is not enough for my purpose. + +This site's [changelog](/changelogs/) and [layout archive](/changelogs/layouts) document the evolution of Leilukin's Hub throughout the past year: from the humble beginning of a simple black background with white text and light brown titles, to the responsive, mobile-friendly, full-fledged personal website with its own site button, [RSS feed](/feed.xml), a [blog](/blog) and multiple [shrines](/shrines). + +Coding my own website was also an excellent way to put my HTML and CSS knowledge and skills into good use. I already had basic knowledge of HTML and CSS from what I learned from my teenage years of customising my blog on Blogger. + +Working on Leilukin's Hub had ignited my interest in coding, so I took courses to learn more about HTML, CSS, JavaScript and more about coding, and in turn, I put my new coding knowledge into good use by improving and adding more features to Leilukin's Hub, which was totally worth it. Therefore, I have also [compiled resources for building websites](/resources/web-building-resources) here for those who need it. + +You may feel intimidated by the idea of building your website because you do not know how to code, but good news! There are plenty of resources for you to learn HTML, CSS and JavaScript, including free courses. Neocities also has [its own HTML course](/tutorial/html/) for you to get started. Happy coding! diff --git a/src/blog/posts/2023-10-13-my-cassette-beasts-pombomb-plushie-arrived.md b/src/blog/posts/2023-10-13-my-cassette-beasts-pombomb-plushie-arrived.md new file mode 100644 index 00000000..d16549a0 --- /dev/null +++ b/src/blog/posts/2023-10-13-my-cassette-beasts-pombomb-plushie-arrived.md @@ -0,0 +1,30 @@ +--- +articleTitle: My Cassette Beasts Pombomb Plushie Arrived! +desc: The official Cassette Beasts Pombomb plushie I purchased finally arrived. +date: 2023-10-13 +categories: ["cassette beasts"] +--- + +YAAAYYYYYYYY! I finally received my Pombomb plushie on 11 October 2023! + +![Official Cassette Beasts Pombom plushie wrapped in a plastic bag](/assets/images/posts/pombomb-plushie/2023-10-11-14-25-27.avif) + +![Side view of the official Cassette Beasts Pombom plushie](/assets/images/posts/pombomb-plushie/2023-10-11-14-28-36.avif) + +![Front view of the official Cassette Beasts Pombom plushie](/assets/images/posts/pombomb-plushie/2023-10-11-14-29-09.avif) + +![Back view of the official Cassette Beasts Pombom plushie](/assets/images/posts/pombomb-plushie/2023-10-11-14-30-36.avif) + +(Original uncompressed photos can be viewed in [my Pombomb plushie gallery on Postimage](https://postimg.cc/gallery/pMCCDPVt)) + +Cassette Beasts has become my favourite monster collecting game and one of my all-time favourite games since the first time I played it. In fact, I have created a [Cassette Beasts shrine](/shrines/cassettebeasts/) on my own website here. Among the monsters from Cassette Beasts, [Pombomb](https://wiki.cassettebeasts.com/wiki/Pombomb) is one of my favourites. + +I love Cassette Beasts and Pombomb so much that I am willing to spend money on not only the [official Pombomb plushie](https://www.symbiotestudios.com/online-store/Cassette-Beasts-Pombomb-p582974319) itself, but also the shipping fee to import it to my region. It took a month for this cutie to arrive at my home, but it is worth the wait! + +The plushie is very well-made; it is firm decently sized. + +Even better, when I shared my Pombomb plushie, Bytten Studio, the developer of Cassette Beasts [retweeted](https://twitter.com/ByttenStudio/status/1712191037957927126) me! + + + +![Screenshot of ByttenStudio's retweet of Leilukin's Cassette Beasts Pombomb plushie](/assets/images/posts/pombomb-plushie/Bytten-Studio-on-my-Pombomb-plushie.avif) diff --git a/src/blog/posts/2023-10-30-support-for-my-steam-review-of-a-summers-end.md b/src/blog/posts/2023-10-30-support-for-my-steam-review-of-a-summers-end.md new file mode 100644 index 00000000..8c22d44b --- /dev/null +++ b/src/blog/posts/2023-10-30-support-for-my-steam-review-of-a-summers-end.md @@ -0,0 +1,30 @@ +--- +articleTitle: Support for My Steam Review of A Summer’s End — Hong Kong 1986 +desc: A thank-you post for the people who have supported my Steam review of A Summer’s End — Hong Kong 1986. +date: 2023-10-30 +categories: ["a summer's end"] +--- + +As part of my effort to support and promote [A Summer’s End — Hong Kong 1986](https://www.asummersend.com/), the sapphic visual novel and my absolute favourite piece of queer art ever, I left a [glowing review on Steam](https://steamcommunity.com/id/leilukin/recommended/1111370/) on 17 August 2023, talking about how much A Summer’s End means too me as a Cantonese-speaking Chinese lesbian who grew up with Hong Kong media. I love A Summer’s End so much that I had created a [shrine](/shrines/asummersend/) for it on my own website here. + +Since then, as of the writing of this post on 30 October 2023, my review made to the top of the most helpful reviews in the past 90 days on the [Steam store page of A Summer’s End](https://steamcommunity.com/app/1111370) with 12 votes. + +![Screenshot of Leilukin's review of A Summer’s End — Hong Kong 1986 on Steam](/assets/images/posts/a-summers-end-review/My-review-for-A-Summer-s-End-on-Steam.avif) + +In addition, I have received multiple Steam awards, with Steam Points along with them, including: + +* Heartwarning, which awards 200 Steam Points, given by two people +* Golden Unicorn, which awards 800 Steam Points, given by one person +* Take My Points, which awards 1,600(!) Steam Points, given by one person + +Recently, on 22 October 2023, the [guestbook](https://web.archive.org/web/20240528231121/https%3A%2F%2Fleilukin.123guestbook.com%2F) of my website here have also received a message from someone named Rob, who expressed appreciation for my Steam review: + +> Thanks so much for your steam review of A Summer’s End!! So glad you have this board, so I could thank you for the heart warming review. I want to get this game for a friend of mine who is new to speaking english, and the story definitely will resonate with her. +> +> I am introducing her to visual novels to hopefully help aid in her learning and practice. + +I am amazed by the amount of appreciation my Steam review of A Summer’s End has been given. Thank you! A Summer’s End truly deserves all the love and support it can get. + +I cannot stress enough that A Summer’s End is important because LGBTQ+ Hong Kong people and Cantonese speakers are criminally underrepresented in media. This is why we need to be vocal about our support for queer art made by non-white people, to signify to both the creators and every LGBTQ+ people that stories of queer non-white people deserve to be told. + +Therefore, here is your reminder to check out A Summer’s End — Hong Kong 1986 if you have not already, especially you are also an Asian sapphic woman! diff --git a/src/blog/posts/2023-11-19-i-can-finally-game-on-a-solid-state-drive.md b/src/blog/posts/2023-11-19-i-can-finally-game-on-a-solid-state-drive.md new file mode 100644 index 00000000..8904d7ac --- /dev/null +++ b/src/blog/posts/2023-11-19-i-can-finally-game-on-a-solid-state-drive.md @@ -0,0 +1,16 @@ +--- +articleTitle: I Can Finally Game on a Solid-State Drive +desc: I just got the solid-state drive (SSD) of my 5-year-old gaming laptop replaced with a new onw with a larger storage capacity. +date: 2023-11-19 +categories: ["life updates"] +--- + +The laptop I am using for doing everything on desktop — including coding and managing this very website and blog — is the first gaming laptop I ever had. I bought this laptop in 2018, meaning I have used it for 5 years by the time of this writing. + +In 2018, I was able to purchase a budget gaming laptop with a solid-state drive (SSD) as its system drive. However, the SSD only had a 258GB storage capacity, which is paltry by today's hard drive standards, especially if you are a gamer, since the installation size of mainstream video games has grown bigger over time (which is actually one of the reasons I rarely play new AAA games any more). + +This means that even though I immediately experienced the night-and-day difference in how much the speed of booting my operating system compared to all the laptops I owned previously, I was unable to enjoy the benefit of gaming on an SSD, which is faster loading of games, because I still had to install video games on my hard disk drive to preserve the space of my SSD system drive... until now. + +After using my gaming laptop for 5 years, my SSD started displaying signs of age with random shutdowns and blue screens of death, followed by a "No Bootable Device" error even after my laptop restarted. As the issue became more frequent, and none of the possible solutions I found online worked at all, I finally asked for professional help to replace my corrupted SSD system drive. I chose a 1TB SSD with Windows 11 installed as my new system drive. + +As a result, on 16 November, my 5-year-old gaming laptop was reborn with a new SSD system drive. A new SSD with much larger storage capacity means I can finally experience gaming on an SSD, and the benefit that came with it. It truly felt like I had a new computer again, since I needed to reinstall all the apps I use, but it was a small price to pay, and I have always kept lists of apps I use in case I am in situations where I needed to restart my system like this. diff --git a/src/blog/posts/2023-11-20-finally-beat-a-bugs-life-video-game-24-years-later.md b/src/blog/posts/2023-11-20-finally-beat-a-bugs-life-video-game-24-years-later.md new file mode 100644 index 00000000..53f46cf9 --- /dev/null +++ b/src/blog/posts/2023-11-20-finally-beat-a-bugs-life-video-game-24-years-later.md @@ -0,0 +1,16 @@ +--- +articleTitle: Finally Beat A Bug's Life The Video Game — 24 Years Later +desc: My childhood goal of beating A Bug's Life video game was finally fulfilled. +date: 2023-11-20 +categories: ["a bug's life", "gaming"] +--- + +A Bug's Life was one of my favourite films in my childhood, to the extent I had lost count of how many times I rewatched it even just as a child alone by playing the CD on my house's television over and over. I was such a huge fan of A Bug's Life that I had also played its tie-in game, specifically the 3D action platformer game, and it became one of my childhood favourite video games as well. + +However, I had a regret relating to A Bug's Life the video game for years — I did not finish the game. I managed to reach Level 15, the final level of the game, but the reason I did not beat it was my CD-ROM of the game literally broke into pieces inside the CD-ROM drive, accompanied by a loud breaking sound, when I was playing Level 15, likely due to the CD-ROM being dislocated. It happened in 1999. Needless to say, the breaking of the CD-ROM of one of my childhood favourite video games broke my heart. My family and I had tried to look for a new copy of A Bug's Life video game, but with no success because at that time the stores in my local area no longer sold it. + +Over the years growing up, I still harbour nostalgia for A Bug's Life. While my love for the film had been tainted by the fact that [both Kevin Spacey, who voiced Hopper, and John Lasseter, the director, were accused of sexual misconduct](https://therottenappl.es/result/movie/9487/A-Bug's-Life), my wish of being able to finish the tie-in video game myself lingered from time to time. I had watched playthrough videos of A Bug's Life video game on YouTube to help to fill the void, but it was not the same as playing the game myself. The main obstacle that prevented my wish from being fulfilled was the fact that it was a very old game that its PC version is no longer officially sold, not even on online game stores such as Steam and GOG. In other words, A Bug's Life the video game had become an abandonware. As a result, I sought out [My Abandonware](https://www.myabandonware.com/), which does [provide the game to download for free](https://www.myabandonware.com/game/disney-pixar-a-bug-s-life-h0q). + +From My Abandonware, I downloaded and installed the Full-Rip with dgVoodoo by Destabilize version of A Bug's Life video game on my Windows 11. I was delighted when I successfully launched and played the old childhood favourite video game for the first time. Soon, I searched for a save file of the PC version of A Bug's Life video game that unlocked all levels, and found it on [The Tech Game](https://www.thetechgame.com/Downloads/id=62821/a-bugs-life.html). Finally, at long last, on 20 November 2023, after 24 years, I successfully beat A Bug's Life video game by myself. I did not aim for 100% completion because my main goal was to defeat Hopper, the final boss, myself. + +Given that the game was released in 1998, the graphics were obviously dated, and the camera and control were also awkward, but playing it again for the first time in decades brought back childhood memories of the game, and I still enjoy the game's soundtrack. This experience has also deepened my appreciation for internet archives, including ones that archive old video games. Thank you, My Abandonware, for allowing a childhood video game goal of mine got fulfilled decades later. diff --git a/src/blog/posts/2024-03-06-i-received-a-lifetime-premium-membership-on-nexus-mods-for-free.md b/src/blog/posts/2024-03-06-i-received-a-lifetime-premium-membership-on-nexus-mods-for-free.md new file mode 100644 index 00000000..8009ebc4 --- /dev/null +++ b/src/blog/posts/2024-03-06-i-received-a-lifetime-premium-membership-on-nexus-mods-for-free.md @@ -0,0 +1,36 @@ +--- +articleTitle: I Received a Lifetime Premium Membership on Nexus Mods for Free +desc: In light of my mods hosted on Nexus Mods reaching 30,000 unique downloads, I was rewarded a free lifetime Premium membership on Nexus Mods. +date: 2024-03-06 +categories: ["video game mods"] +--- + +![A partial email message from Nexus Mods about a free lifetime Premium membership reward](/assets/images/posts/nexusmods-lifetime-premium/thunderbird-2024-03-06-20-45-36-381.avif) + +[Image description: A partial email message from Nexus Mods that reads: + +> Hey leilukin, +> +> Congratulations! Many people are downloading your mods and your efforts have been recognised with a free Nexus Mods Premium reward. +> +> To see and redeem your rewards, you can visit your rewards tab on the billing page. +> +> Redeem now + +End desctiption.] + +![Nexus Mods website notification about a lifetime Premium membership reward](/assets/images/posts/nexusmods-lifetime-premium/Screenshot-2024-03-06-at-20-49-26-Nexus-Mods-Home.avif) + +[Image description: A notification on the Nexus Mods website that reads, "Your mods reached 30,000 UDLs! Enjoy Lifetime Premium membership on us." End description.] + +![The Membership tab on Nexus Mods account settings showing lifetime Premium membership](/assets/images/posts/nexusmods-lifetime-premium/Screenshot-2024-03-06-at-20-52-27-Nexus-Mods-Users.avif) + +[Image description: The Membership tab in the Nexus Mods account setting page, showing the current membershiup being "Mod Author Reward: Lifetime Premium", starting from 6th Mar 2024 with no end date. End description.] + +Wow, I just got informed by Nexus Mods via email and website notification that I have received a lifetime Premium membership for free on Nexus Mods as a mod author reward, since [all my mods that are hosted on Nexus Mods](https://www.nexusmods.com/users/3041255?tab=user+files) have reached 30,000 unique downloads in total! + +It was actually only through receiving this reward that I learned about Nexus Mods' [program to reward free Premium memberships to mod authors](https://www.nexusmods.com/news/14933). + +I never spent a single cent on Nexus Mods, and my mods are all passion projects, so I never expected to enjoy any extra benefits or privileges on Nexus Mods. + +That said, I cannot complain about receiving a premium membership on a website I use regularly for free, even though the unlimited mod download speed is the only benefit I am really interested in. After all, I do download a lot of mods for various video games from Nexus Mods. diff --git a/src/blog/posts/2024-04-21-april-2024-leilukins-hub-overhaul-with-eleventy.md b/src/blog/posts/2024-04-21-april-2024-leilukins-hub-overhaul-with-eleventy.md new file mode 100644 index 00000000..0ff02201 --- /dev/null +++ b/src/blog/posts/2024-04-21-april-2024-leilukins-hub-overhaul-with-eleventy.md @@ -0,0 +1,119 @@ +--- +articleTitle: April 2024 Leilukin's Hub Overhaul with Eleventy +desc: I rebuilt my website with the static site generator Eleventy in April 2024. +date: 2024-04-21T19:53:00+0800 +categories: ["site updates", "eleventy"] +toc: true +--- + +Leilukin's Hub just overgone a major overhaul: In April 2024, I have been rebuilding this entire website with the [static site generator](https://en.wikipedia.org/wiki/Static_site_generator) (SSG), [Eleventy](https://www.11ty.dev/), and the process was completed on 20 April 2024. + +After building this website for more than a year, Eleventy finally provided the solution for me to maintain, manage and update my website in more dynamic and sufficient ways to save time. + +## Challenges of Maintaining a Growing Website + +Leilukin's Hub has come a long way since launch on 11 September 2022, from a small website with a few pages and a simple layout, to a full-fledged personal website with multiple [articles](/articles), a [blog](/blog), a couple of [shrines](/shrines) with additional features such as sticky navigation bar, table of contents, etc. Meanwhile, I have also been learning web development, which helped to improve this website in multiple ways. + +However, more content on my website also means more work to maintain. In particular, I have been trying to find ways to render components that share across multiple pages on my site, such as the header, navigation bar and footer, without having to copy and pasting the code of these components over and over whenever I want to add a new page. I had used JavaScript for this, but it is still not the best solution because I still needed to add a link to my JavaScript file in HTML. Thankfully, I eventually discovered Eleventy as the solution. + +## Why Eleventy? + +There are [many static site generators](https://jamstack.org/generators/), so why I choose Eleventy over others? The main reason is Eleventy's flexibility. You can start building your website with Eleventy with something as simple as [an `index.md` Markdown file](https://hamatti.org/posts/index-md-is-valid-eleventy-project/). + +In addition, Eleventy's own features, support for many [template languages](https://www.11ty.dev/docs/languages/) and plugins allow me to have control over how I build and customise my own website, some of which I will highlight as I elaborate the changes and improvements I had made to this website below. + +## New Features of Leilukin's Hub + +### Pagination + +Leilukin's Hub [blog](/blog) and main [changelogs](/changelogs) page now has pagination, thanks to [Eleventy's built-in support for the feature](https://www.11ty.dev/docs/pagination/). + +### Estimated Reading Time for Articles and Blog Posts + +Thanks to [Emoji Read Time](https://www.npmjs.com/package/@11tyrocks/eleventy-plugin-emoji-readtime), a community plugin for Eleventy, my articles and blog posts now show the piece's estimated reading time before the main content. + +### Heading Anchor Links + +For the articles, blog posts and some other pages that have headings, I have enabled anchor links on the headings by referring to the [11ty Slugs and Anchors guide](https://11ty.rocks/eleventyjs/slugs-anchors/#enable-anchor-links-on-content-headings) from the website 11ty Rocks!, installing and configuring the [markdown-it-anchor](https://www.npmjs.com/package/markdown-it-anchor) plugin. + +Having a plugin that automatically generates heading anchor links also allows me to generate table of contents by installing [uncenter's eleventy-plugin-toc](https://www.npmjs.com/package/@uncenter/eleventy-plugin-toc) plugin. + +### Content Categories + +Eleventy's [collection](https://www.11ty.dev/docs/collections/) feature allows users to group site content by tags and create custom collections. This feature allows me to add categories to my articles and blog posts, and in turn allows visitors to browse my website by [categories](/categories). + +### Archive for All My Articles and Blog Posts + +Eleventy's collection feature also allows me to dynamically display links to my articles and posts when I make a new one, without needing to edit more pages to add the new links myself. Therefore, I took advantage of this feature by creating an [archive] page to display all my articles and blog posts. + +Furthermore, my articles, blog and posts now has a right sidebar with links to my articles, blog posts as well as their archives and categories. + +### Breadcrumbs + +Some contents on Leilukin's Hub now has [breadcrumbs](https://www.seoptimer.com/blog/breadcrumbs-website/), which shows the locations of these contents within this website and provides another means for visitors to navigate this site. + +### Now Page + +Inspired by the [nownownow.com](https://nownownow.com/about) website, I have added a [Now page](/now) to Leilukin's Hub. This page is about what I am doing and focusing at the moment. The page can be updated at any time, so feel free to check it out when you visit this website to learn what I am up to! + +## Improved Features of Leilukin's Hub + +### Blog + +Leilukin's Hub blog was [launched on 28 January 2023](/blog/posts/2023-01-28-leilukins-hub-now-has-a-blog/). Formerly, the blog was built with [Zonelets](https://zonelets.net/); now I take advantage of Eleventy's flexibility by recreating Leilukin's Hub blog with it, thus using the main site's layout for the blog instead of [using a different layout](/changelogs/layouts/#11-september-2023-blog-layout). This makes the blog actually feels like it is part of this website. + +### Site Map + +Visually, my [site map](/sitemap) does not change much other than tweaking the spacing, but under the hood, I use the Eleventy's official [Navigation](https://www.11ty.dev/docs/plugins/navigation/) plugin to generate the links to my pages in a hierarchical manner. + +### RSS Feed + +I had created an [RSS feed](/feed.xml) for Leilukin's Hub's changelogs and blog posts for a while, but previously I had to create new entries in the feed manually by using [RSS Builder](https://sourceforge.net/projects/rss-builder/). Now by installing and setting up Eleventy's official [RSS](https://www.11ty.dev/docs/plugins/rss/) plugin, new feed entries will be generated automatically when I make new changelogs, articles and blog posts. + +## Other Notable Changes of Leilukin's Hub + +The following changes are not related to any features inherent to Eleventy or its plugins, but they were part of my process of rebuilding Leilukin's Hub. + +### Direct Visit to Leilukin's Hub Home Page + +I have removed the splash page that was used as the very first page you saw when you visited the link leilukin.neocities.org. Now when you visit the link to my website, you will immediately see the home page wihout any extra step. + +## My Creation Page Renamed to Projects + +The page listing the things I have created has been renamed from "My Creation" to ["Projects"](/projects). + +### Site Updates being Blog Posts + +Previously, longer [site updates](/categories/site-updates/) were made into their own pages, since Leilukin's Hub did not have its own blog when I made the first site update post. Now these updates are converted into blog posts. + +### Featured Articles being Part of Articles + +Formerly, pages that featured my interviews were on their own page called "featured". Now, these [featured articles](/articles/#featured-articles) are merged into the [articles](/articles) page. + +### Responsive Shrine Header Images + +I have created two different resolutions of each header image of my [shrines](/shrines). Which version of the shrine header image gets displayed depends on if your screen is horizontal or vertical. + +### Scroll-to-Top Function + +Previously, this site's scroll-to-top function was placed in the footer. Now, I created a scroll-to-top button in the bottom right corner of the page when you scroll down. + +### Site Layout + +The main title of each page is now displayed above both the main content and sidebars, instead of just above the main content like in the [previous layout](/changelogs/layouts/#23-june-2023). This change was made so when this site is viewed on mobile, the table of contents of the left sidebar will be displayed above the main content but still below the page's main title. Previously, I had to place the table of contents on both the left sidebar and the main content's body, and hide the sidebar table of contents when viewed on mobile. + +I also use [CSS grid](https://css-tricks.com/snippets/css/complete-guide-grid/) to set the page layout in that the main content's width will remain the same instead of expanding if there is no sidebar on the page. + +## Use GitHub Actions to deploy Leilukin's Hub to Neocities + +Eleventy is great for reducing many workloads in maintaining and updating my website, so how about publishing the website to Neocities? That is where the [GitHub actions](https://docs.github.com/en/actions) comes in. + +Before I decided to use a static site generator to rebuild Leilukin's Hub, I discovered the GitHub action named [deploy-to-neocities](https://github.com/bcomnes/deploy-to-neocities), which as the name suggests, allows you to publish your website directly from a GitHub repository to Neocities. I succeeded in deploying all the files of Leilukin's Hub to Neocities with it even before starting to rebuild my website with Eleventy. + +I have been using Visual Studio Code to write the code for Leilukin's Hub, and saving a copy of all the files of my website on my own computer. The combination of creating a Git repository for Leilukin's Hub and using the deploy-to-neocities GitHub action saves the time and workload needed to log in to Neocities, navigate the files and folders and open a file to edit the code every time I want to make a change to my website. + +## A Week's Worth of Effort Well-Spent + +I had spent a whole week in rebuilding Leilukin's Hub from scratch with Eleventy, and at last completing the process on 20 April 2024. Most of the time rebuilding this website was spent on setting up layout templates, rather than changing the format of my articles and blog posts from HTML to markdown. However, the effort and time spent was worth it, and Leilukin's Hub feels new again. + +Welcome to the rebuilt Leilukin's Hub! 🥳 \ No newline at end of file diff --git a/src/blog/posts/2024-04-27-lesbian-visibility-day1-year-anniversary-of-cassette-beasts.md b/src/blog/posts/2024-04-27-lesbian-visibility-day1-year-anniversary-of-cassette-beasts.md new file mode 100644 index 00000000..99dd6eee --- /dev/null +++ b/src/blog/posts/2024-04-27-lesbian-visibility-day1-year-anniversary-of-cassette-beasts.md @@ -0,0 +1,40 @@ +--- +articleTitle: Happy Lesbian Visibility Day and 1-Year Anniversary of Cassette Beasts +desc: Celebrating both Lesbian Visibility Day and the 1st year anniversary of Cassette Beasts' release on 26 April 2024. +date: 2024-04-27T14:06:00+0800 +categories: ["lesbian", "cassette beasts"] +--- + +26 April 2024 was a day of celebration for me, as it was both Lesbian Visibility Day and the [first anniversary of the release of {% cite "Cassette Beasts" %}](https://store.steampowered.com/news/app/1321440/view/4179979397366287532), my all-time favourite video game. + +As a lesbian, [Lesbian Visibility Day and Lesbian Visibility Week](https://en.wikipedia.org/wiki/Lesbian_Visibility_Week) are an important annual event, as there can never be enough lesbians nor love for lesbians. It had been about 8 years ago when I finally realised I was a lesbian, and I am still happy and proud to be a lesbian. + +Meanwhile, {% cite "Cassette Beasts" %} has become my all-time favourite video game ever since I started playing it in July 2023, to the extent I had created a [shrine](/shrines/cassettebeasts/) for the game on my own website. There are no words adequate to describe the depth of my love for {% cite "Cassette Beasts" %}. + +As a lesbian fan of {% cite "Cassette Beasts" %}, I am also absolutely delighted by the fact that the initial release date of {% cite "Cassette Beasts" %} coincided with Lesbian Visibility Day on April 26. For bonus points, {% cite "Cassette Beasts" %} features not only LGBTQ+ representation in both the main and supporting cast, but also an actual canon old married lesbian couple in the supporting characters Ianthe and Wilma. + +To celebrate both Lesbian Visibility Day and the 1-year anniversary of {% cite "Cassette Beasts" %}' release, I made lesbian pride icons featuring the {% cite "Cassette Beasts" %} logo as well as Ianthe and Wilma both individually and together, and shared them on social media accounts, including [Tumblr](https://lesbiannova.tumblr.com/post/748826429723148288), [Twitter](https://twitter.com/Leilukin/status/1783736715641024828), [Mastodon](https://elekk.xyz/@leilukin/112336010189257467) and [Bluesky](https://bsky.app/profile/leilukin.bsky.social/post/3kqzahri66x2x). I had also shared them in the [official Bytten Studio Discord server](https://discord.gg/byttenstudio). + +
      https://www.tumblr.com/lesbiannova/748826429723148288/happy-lesbian-visibility-day-and-happy-birthday
      + +My {% cite "Cassette Beasts" %} lesbian pride icons have been well-received, by not only other fans of the game, but also the developer Bytten Studio themselves. On Twitter, Bytten Studio not only retweeted, but also replied to my icons. + +![Bytten Studio's Twitter account retweeted Leilukin's lesbian pride Cassette Beasts icons](/assets/images/posts/lesbian-visibility-day-cassette-beasts-anni/1-year-cassette-beasts-anniversary-twitter-repost.avif) + +![Twitter exchange between Bytten Studio and Leilukin about the lesbian pride Cassette Beasts icons](/assets/images/posts/lesbian-visibility-day-cassette-beasts-anni/1-year-cassette-beasts-anniversary-twitter-reply.avif) + +On Mastodon, Bytten Studio also boosted my icons. + +![The official Cassette Beasts account on Mastodon boosted Leilukin's lesbian pride Cassette Beasts icons](/assets/images/posts/lesbian-visibility-day-cassette-beasts-anni/1-year-cassette-beasts-anniversary-mastodon-boost.avif) + +Furthermore, I had set up my website's header to display the lesbian pride flag and a blurb about Lesbian Visibility Day, and my [Cassette Beasts shrine](/shrines/cassettebeasts/) to display a blurb about the game's release anniversary, both on April 26 annually. + +![Leilukin's Hub header displaying lesbian pride flag and a top blurb about Lesbian Visibility Day](/assets/images/posts/lesbian-visibility-day-cassette-beasts-anni/leilukin-s-hub-lesbian-visibility-day.avif) + +![Cassette Beasts shrine displaying a top blurb about the 1-year anniversary of Cassette Beasts' release](/assets/images/posts/lesbian-visibility-day-cassette-beasts-anni/leilukin-s-hub-cassette-beasts-anniversary.avif) + +In conclusion, this had been an exciting day for me as a lesbian gaymer. + +On a somewhat related note, I love the fact that this week is not only [Lesbian Visibility Week](https://www.lesbianvisibilityweek.com/), but also has two of my all-time favourite games, {% cite "Cassette Beasts" %} and {% cite "A Summer’s End — Hong Kong 1986" %} (which I had also created a [shrine](/shrines/asummersend) for), both of which happen to feature lesbian representation, celebrating their release anniversaries. + +**Happy Lesbian Visibility Day and Happy Birthday to {% cite "Cassette Beasts" %}!** diff --git a/src/blog/posts/2024-05-14-james-somerton-my-video-game-footage.md b/src/blog/posts/2024-05-14-james-somerton-my-video-game-footage.md new file mode 100644 index 00000000..e6f1dbae --- /dev/null +++ b/src/blog/posts/2024-05-14-james-somerton-my-video-game-footage.md @@ -0,0 +1,57 @@ +--- +articleTitle: James Somerton Used My Video Game Footage Without Credit or Permission +desc: "James Somerton used one of my Star Wars: Knights of the Old Republic footage in one of his videos without credit or permission." +date: 2024-05-14T11:02:00+0800 +updated: 2024-05-17 +categories: ["youtube"] +--- + +It has been five months since Hbomberguy released his ["Plagiarism and You(Tube)"](https://www.youtube.com/watch?v=yDp3cB5fHXQ) video essay on 2 December 2023, which [set off a YouTube plagiarism scandal](https://trending.knowyourmeme.com/editorials/guides/whats-up-with-hbomberguy-setting-off-a-youtube-plagiarism-scandal-the-internet-historian-and-james-somerton-controversies-explained), with another YouTuber [James Somerton](https://knowyourmeme.com/memes/events/hbomberguy-vs-james-somerton-plagiarism-scandal) being the main focus of Hbomberguy's video essay. I do not write this post to recap or rehash the entire James Somerton debacle. Instead, I want to talk about something personal related to one of James Somerton's videos — **James Somerton had used one of my video game footage in one of his videos without crediting me or asking for my permission**. + +On 5 November 2021, James Somerton released a video essay on his YouTube channel titled "Video Games and the Choice to be Gay". As of this writing, the video has been made private, but Somerton's videos have been archived on the Internet Archive with two playlists: [James Somerton youtube archive](https://archive.org/details/james-somerton-youtube-2023-12-03/) and [James Somerton- Public Records](https://archive.org/details/james-somerton-public-records), so you can still watch "Video Games and the Choice to be Gay" directly on the Internet Archive in both the [Youtube archive](https://archive.org/download/james-somerton-youtube-2023-12-03/20211105%20TQNKEkrPEfI%20Video%20Games%20and%20the%20Choice%20to%20be%20Gay.mp4) and the [Public Records](https://archive.org/download/james-somerton-public-records/Video%20Games%20and%20the%20Choice%20to%20be%20Gay.ia.mp4) playlists. Alternately, you can watch the video through one of the [Wayback Machine snapshots](https://web.archive.org/web/20230000000000*/https://www.youtube.com/watch?v=TQNKEkrPEfI). + +I first discovered "Video Games and the Choice to be Gay" through a {% cite "Dragon Age" %} fan blog on Tumblr shortly after the video was published. The video piqued my interest because LGBTQ+ representation in video games is relevant to me as a queer, non-binary lesbian gamer, and the video games discussed in Somerton's video included {% cite "Star Wars: Knights of the Old Republic" %}, {% cite "Dragon Age" %} and {% cite "Mass Effect" %}, which was also relevant to me since I used to be a huge fan of BioWare games. As a result, "Video Games and the Choice to be Gay" ended up being the first and only James Somerton video I have actually watched. + +Before finished watching it, one thing from "Video Games and the Choice to be Gay" that caught my attention was when Somerton talked about Juhani from {% cite "Star Wars: Knights of the Old Republic" %}, who was the very first confirmed gay and lesbian character from both BioWare games and the entire {% cite "Star Wars" %} franchise, including the old Expended Universe, one of the {% cite "Knights of the Old Republic" %} ({% cite "KotOR" %}) footage shown on screen in the video included one of my {% cite "KotOR" %} footage about Juhani and her romance with the female player character. + +Specifically, the clip from Somerton's video at the timestamp from 12:09 to 12:13 was actually from my [5 March 2016 video footage of Juhani's love confession](https://www.youtube.com/watch?v=oFQDmmRUx4E) with the [Juhani Romance Enhancement mod](https://deadlystream.com/files/file/772-juhani-romance-enhancement/), specifically at the timestamp [0:10](https://www.youtube.com/watch?v=oFQDmmRUx4E&t=10s) to [0:16](https://www.youtube.com/watch?v=oFQDmmRUx4E&t=16s). + +Here is a back-to-back comparison between the clips from my original footage and Somerton's video respectively, proving the clip from Somerton's video was originally from my footage: + + + + +I immediately recognised my clip through the appearance of the female player character and her outfit, which was from the [Segan Wyndh Jedi Armor mod](https://deadlystream.com/files/file/90-segan-wyndh-jedi-armor/). Furthermore, there are not many videos about Juhani's romance out there, so the player character's appearance, which can vary depending on how the player customises their character in the character creator or with mods, in Somerton's video only stood out to me even more. My footage of Juhani's love confession was part of my [Juhani romance and conversation video series](https://www.youtube.com/playlist?list=PL5z8DZr8LSLHZkdhBxGadvvaHlolKa-Vd), to compliment my [Juhani romance guide](/shrines/starwarskotor/guides/kotor-juhani-romance-guide/), which I am still proud to say is *the* most comprehensive guide about Juhani's romance on the internet. + +To be honest, even back then, I was already a little disappointed that James Somerton used my footage in his video without a single word about the clip's source, both in the video itself and the video description, nor had Somerton ever reached out to me about using my footage in his video (on a related note, Somerton and I never had any direct interactions). I do not own the intellectual property of {% cite "Star Wars" %} or {% cite "KotOR" %}, but capturing video game footage requires one to actually play through the game, which takes time, especially role-playing games like {% cite "KotOR" %}. In addition, I had spent a great deal of effort on promoting Juhani's romance, including writing a guide and recording video footage about it because Juhani's romance is also infamous for being buggy and tricky to successfully complete, to the extent many {% cite "KotOR" %} fans were not even aware that Juhani can actually be romanced by the (female) player character. + +However, I did not dare to say a word about Somerton's usage of my Juhani romance footage, because Somerton was already a fairly popular YouTuber with 138K subscribers by the time the video was released (at least according to the [Wayback Machine snapshot of the video on 5 November 2021](https://web.archive.org/web/20211105165815/https://www.youtube.com/watch?v=TQNKEkrPEfI)), while I do not even consider myself a YouTuber, since [my YouTube channel](https://www.youtube.com/Leilukin) only consists of video game footage I recorded myself without commentary. I did not bring up Somerton's usage of my Juhani romance footage because I did not want to come across as trying to start a drama or gain attention. I also tried to look at the positives by considering it an honour that at least my Juhani romance videos get noticed by a popular YouTuber. + +As for Somerton's "Video Games and the Choice to be Gay" video itself, my initial thoughts after watching were that it was an interesting take on queer representation in Video games. I elaborated my thoughts when I shared the video with a friend: +> Your mileage may vary on his opinions on certain individual examples from BioWare games that he brought up, and I cannot comment on Hades and The Last of Us 2 because I've never played them, but I very much agree with his main points about how LGBTQ+ representation in mainstream video games tend to be superficial and shallow because major game companies want their games to appeal as many people as possible, thus they're still unwilling to take too much risk so they won't offend the gamer bros too much. Honestly, this is how I feel about BioWare's games in general, despite BioWare's reputation as a progressive game company, especially when it comes to queer representation. I would give BioWare the benefit of the doubt for Juhani because she was the first confirmed queer character in both BioWare games and Star Wars, but when it comes to BioWare's original IPs, they could have done better. +> +> I also strongly agree with him about the importance of us LGBTQ+ gamers supporting indie queer developers and their work, instead of relying on mainstream video games (and mainstream media in general) for queer representation. + +That said, I did not bring up the fact that Somerton used my {% cite "KotOR" %} footage to my friend back then. + +As mentioned above, "Video Games and the Choice to be Gay" was the first and only James Somerton video I have ever watched. I did not subscribe to Somerton's channel, nor did I have the time nor enough interest to watch any other Somerton's videos. No YouTubers I followed referenced Somerton's videos or were associated with him, and no one in my social media circles talked about him either. Therefore, after watching "Video Games and the Choice to be Gay" in November 2021, Somerton simply went off of my radar until his plagiarism scandal broke out two years later in December 2023. + +After the James Somerton's plagiarism scandal broke out, it was revealed that "Video Games and the Choice to be Gay" plagiarised a paragraph of Robert Grosso's article ["Queer Characters in Gaming - A Brief History"](https://techraptor.net/gaming/features/queer-characters-in-gaming-brief-history) on TechRaptor and ripped off Verity Ritchie's (also known as verilybitchie) video essay ["Hοѡ Biѕeхυаlity Chaոɡeԁ Video Gaⅿes"](https://www.youtube.com/watch?v=iZGkxUTbDqw). + +"Video Games and the Choice to be Gay" was not covered in Hbomberguy's "Plagiarism and You(Tube)" video, so I did not realise that Somerton's video essay about queer representation in video games was also largely built upon other queer creators' works without credit, until one day before I began to write this post, when I searched about the video myself and discovered the sources through the website [James Somerton Transcripts](https://tustin2121.github.io/James_Somerton_Transcripts/videos/TQNKEkrPEfI). This led to me watching Verity Ritchie's original video as well as listening to and reading their [Patreon post and podcast episode about Somerton ripping off their video](https://www.patreon.com/posts/james-somerton-3-94126743), realising that the main framework and talking points from Somerton's video was actually from Verity's video. + +I felt guilty about giving Somerton credit for Verity's takes about queer representation in video games, although I still firmly stand by what I said about the importance of supporting indie queer developers and their work instead of relying on mainstream video games for queer representation. I was not aware of Verity when I discovered Somerton's video in 2021, but I became aware of Verity and their YouTube channel in early 2023, after discovering their ["The Consumerist Dystopia of Harry Potter"](https://www.youtube.com/watch?v=UBftW7FzOVI) video, which I included and recommended in my [Anti-Harry Potter and Anti-J. K. Rowling Masterlist](/articles/anti-harry-potter-jk-rowling-masterlist/), so I recommend fellow queer gamers to check out Verity's "Hοѡ Biѕeхυаlity Chaոɡeԁ Video Gaⅿes" if you are interested in the topic of queer representation in video games. + +The final push for me to write this post, was seeing Verity crediting the source of the gameplay footage featured in "Hοѡ Biѕeхυаlity Chaոɡeԁ Video Gaⅿes", as well as listening to them and their co-writer Ada Černoša talking about Somerton's lack of gameplay footage in "Video Games and the Choice to be Gay", doubting the gameplay footage in the video are his own, and that recording gameplay footage take time and effort. This made Somerton's usage of my video game footage without credit leave a more sour taste in my mouth, enough that I decided to, at last, talk about this and confirm that James Somerton had indeed used someone else's gameplay footage without credit or permission, with I being at least one of that someone else. + +I do not expect anything from writing this post. James Somerton has destroyed his own reputation and internet career at this point without my help, so I merely just want to get Somerton's uncredited usage of my video game footage off my chest after being hesitant to bring it up since 2021. + +*(**Update, 17 May 2024:** Re-uploaded my comparison video for better quality, and updated the links to Somerton's video on the Internet Archive)* \ No newline at end of file diff --git a/src/blog/posts/2024-05-29-new-guestbook-leilukins-hub.md b/src/blog/posts/2024-05-29-new-guestbook-leilukins-hub.md new file mode 100644 index 00000000..1efb984f --- /dev/null +++ b/src/blog/posts/2024-05-29-new-guestbook-leilukins-hub.md @@ -0,0 +1,32 @@ +--- +articleTitle: The Search for a Guestbook Solution for Leilukin's Hub +desc: I spent a great deal of time in searching for a guestbook for Leilukin's hub. +date: 2024-05-29T17:11:00+0800 +categories: ["site updates"] +--- + +On 4 May 2024, the guestbook service 123Guestbook announced that [their service would be closed on 1 July 2024](https://web.archive.org/web/20240504201300/https://www.123guestbook.com/news.php?id=closure). + +I created an account on 123Guestbook and started using it as Leilukin's Hub's guestbook since 25 July 2023. When my 123Guestbook guestbook was open, I received multiple nice messages expressing appreciation for my website and work, including my [{% cite "Cassette Beasts" %} shrine](/shrines/cassettebeasts) and my [{% cite "A Summer’s End — Hong Kong 1986" %} shrine](/shrines/asummersend) and [Steam review](../2023-10-30-support-for-my-steam-review-of-a-summers-end), so I am sad to see 123Guestbook go. 123Guestbook has been around since 2005, so its closure is a sad reminder that you cannot predict when your favourite website might be gone. + +In light of 123Guestbook's closure, I have disabled the function to add new messages to Leilukin's Hub's previous guestbook at 123Guestbook, and archived the old guestbook at the [Internet Archive](https://web.archive.org/web/20240528231121/https%3A%2F%2Fleilukin.123guestbook.com%2F) and [archive.today](https://archive.ph/9mtpl). + +123Guestbook shutting down means I need to find a replacement for Leilukin's Hub guestbook. This turned out to be a more difficult task than I expected, because I was struggling to find an alternative guestbook that satisfied my needs. + +Initially, I looked into other guestbook services such as [SmartGB](https://www.smartgb.com/), [UltraGuest](https://www.ultraguest.com/) and the new [Atabook](https://atabook.org/). Dedicated guestbook services offer the ability to moderate messages and change the guestbook's style, but I ended up finding their style customisation options too limited for my liking. It does not help that UltraGuest's guestbook is not mobile-friendly either. This was also when I realised that 123Guestbook's guestbook is also not mobile-friendly. + +In addition, I began to prefer to add features to my website by embedding it on my web page, so it looks like they are part of my website, instead of having to add an external link, or using the HTML ` + +
    1. + +
    2. +
    3. + +
      + + +
      +
    4. +
    5. +
      + + +
      +
    6. +
    7. + + + +
    8. +
    9. + +
    10. +
    11. +
      + + + +
      +
    12. +
    13. + +
    14. +
    15. + +
    16. +
    17. + +
    18. +
    19. +

      + This site is part of the Meta Ring:
      + [← Previous] + [Random] + [Next →] +

      +
    20. +
    21. +
      + + left arrow +   + + queer coded webring +   + + right arrow + +
      +
    22. +
    23. + +
    24. +
    25. + + +
    26. +
    27. + +
    28. +
    29. +
      + + +
      +
    30. + \ No newline at end of file diff --git a/src/links/linkgroups/linkgroups.11tydata.js b/src/links/linkgroups/linkgroups.11tydata.js new file mode 100644 index 00000000..c10ee977 --- /dev/null +++ b/src/links/linkgroups/linkgroups.11tydata.js @@ -0,0 +1,4 @@ +export default { + tags: ["link groups"], + permalink: false +} \ No newline at end of file diff --git a/src/links/linkgroups/resources.md b/src/links/linkgroups/resources.md new file mode 100644 index 00000000..3bc8bd39 --- /dev/null +++ b/src/links/linkgroups/resources.md @@ -0,0 +1,47 @@ +--- +title: Resources +date: 2024-08-02 +updated: 2025-02-24T08:50:56+0800 +toc: true +--- + +### Archives +* [The Anarchist Library](https://theanarchistlibrary.org/) +* [Internet Archive](https://archive.org/) +* [archive.today](https://archive.is/) + +### Bypass Paywalls +* [Paywall Reader](https://paywallreader.com/) +* [Bypass Paywall Clean](https://github.com/bpc-clone/bpc_updates) browser extension + +### Download Tools +* [cobalt](https://cobalt.tools/) — Download videos and audio from various platforms. + +### Gaming +* [3DS Hacks Guide](https://3ds.hacks.guide/) +* [Fuck off EA App](https://github.com/p0358/Fuck_off_EA_App) + +#### Video Game Mods +These are lists of video game mods I use for my own playthroughs. + + +### Images +* [Squoosh](https://squoosh.app/) — Privacy-friendly image compressor. + +### Privacy +* [Privacy Guides](https://www.privacyguides.org/) +* [WinScript](https://winscript.cc/) — Open-source tool to help you build custom scripts for Windows 10 and 11 for debloating, privacy, performance and more. + +### Software and Website Alternatives +* [AlternativeTo](https://alternativeto.net/) — Crowdsourced software recommendations. +* [Indie Wiki Buddy](https://getindie.wiki/) — Browser extension to discover indie wiki alternatives to Fandom.com wikis, and redirect Fandom.com wikis to a Breezewiki front end. + +### Web + +* [Unplatform](https://unplatform.fromthesuperhighway.com/) by ajazz — Interactive guidebook, online library, and recommendations database for escaping social media and joining the indie web. \ No newline at end of file diff --git a/src/links/linkgroups/webmastery.md b/src/links/linkgroups/webmastery.md new file mode 100644 index 00000000..2b395cd1 --- /dev/null +++ b/src/links/linkgroups/webmastery.md @@ -0,0 +1,56 @@ +--- +title: Webmastery +date: 2024-07-01 +updated: 2025-03-27T09:15:36+0800 +toc: true +--- + +### Webmastery Tutorials + +* [HTML for People](https://htmlforpeople.com/) by Blake Watson +* [Make Your Own Website](https://web.pixelshannon.com/make/) by Shannon Kay +* [Creating Your Own Website](https://32bit.cafe/cyowebsite/) by 32-Bit Cafe +* [Interacting with Other Websites](https://32bit.cafe/interactingontheweb/) by 32-Bit Cafe +* [How to build your own RSS Feed](https://caffeineandlasers.neocities.org/blogs/rss) by Cameron Jones +* [Roll your own RSS feed](https://thedabbler.patatas.ca/pages/roll_your_own_rss.html) by patatas + +### Webmastery Guides + +* [Reducing HTML Redundancy](https://owlsroost.xyz/articles/2023-12-23-reducing-html-redundancy.html) by Owl +* [How to Make Your Site Mobile-Friendly](https://owlsroost.xyz/articles/2024-06-24-how-to-make-your-site-mobile-friendly.html) by Owl +* [How to Favicon: Three files that fit most needs](https://evilmartians.com/chronicles/how-to-favicon-in-2021-six-files-that-fit-most-needs) by Irina Nazarova + +### Webmastery Resources + +* [Resources List for the Personal Web](https://discourse.32bit.cafe/t/resources-list-for-the-personal-web/49) by 32-Bit Cafe — I have also contributed to this list +* [Can I use...](https://caniuse.com/) — Check browser compatibility for web features +* [SVGOMG](https://jakearchibald.github.io/svgomg/) — SVG optimiser +* [URL-encoder for SVG](https://yoksel.github.io/url-encoder/) + +### Ideas for Your Website + +* [Ideas for Your Personal Website](https://32bit.cafe/websiteideas/) by 32-Bit Cafe +* [Slash Pages](https://slashpages.net/) +- [Bekah's Blog Idea Generator](https://www.thefrugalgamer.net/programming/blogPrompts/) + +### Web Accessibility + +* [The Access Manifesto](https://joeclark.org/book/sashay/serialization/AccessManifesto.html) by Joe Clark — Worth noting that this was originally written in 2002 +* [You Should Care About Accessibility](https://owlsroost.xyz/articles/2023-08-20-you-should-care-about-accessibility.html) by Owl +* [A Field Guide to Web Accessibility](https://theultimatemotherfuckingwebsite.com/) by Valery +* [Resources for Beginners to Learn About Web Accessibility and Web Design](https://www.tumblr.com/foxpunk/700063063948312576/hey-you-yeah-you-with-the-cool-neocities) curated by foxpunk +* [5 ways to make your neocities site more accessible](https://sleepydev.neocities.org/posts/5%20Ways%20to%20make%20your%20Neocities%20site%20more%20accessible) by Sleepy dev +* [Three Common Accessibility Problems and How to Fix Them](https://solaria.neocities.org/beginnersaccessibility) by Solaria +* [What I've Learned About Web Accessibility as a Dyslexic, Sighted, Mouse User](https://solaria.neocities.org/accessibility) by Solaria +* [Screen reader testing: how to test your website's accessibility](https://www.siteimprove.com/glossary/screen-reader-testing/) by Siteimprove + +### Eleventy +Resources for learning to use the static site generator [Eleventy](https://www.11ty.dev/), which is also used for building {{ sitemeta.siteName }}. + +* [The 11ty Bundle](https://11tybundle.dev/) — Collection of Eleventy resources +* [My Neocities workflow: using Eleventy and the CLI to speed up development](https://whiona.weblog.lol/2023/10/my-neocities-workflow:-using-eleventy-and-the-cli-to-speed-up-development) by Whiona — Written for Neocities users +* [Strawberry Starter](https://strawberrystarter.neocities.org/) by Kate Bagenzo — An Eleventy blog template aimed at website beginners that can be uploaded automatically to Neocities +* [Migrating to Eleventy](https://renkotsuban.com/posts/2023-11-15-Migrating-to-Eleventy.html) by Renkon — A beginner-friendly guide to get started with Eleventy +* [How I teach Eleventy from scratch](https://hamatti.org/posts/how-i-teach-eleventy-from-scratch/) by Juha-Matti Santala +* [Getting set up in Eleventy](https://cloudcannon.com/tutorials/eleventy-beginner-tutorial/) by Mike Neumegen +* [Learn Eleventy](https://learn-eleventy.pages.dev/) by uncenter \ No newline at end of file diff --git a/src/links/linkgroups/websites.njk b/src/links/linkgroups/websites.njk new file mode 100644 index 00000000..8ab92a55 --- /dev/null +++ b/src/links/linkgroups/websites.njk @@ -0,0 +1,82 @@ +--- +title: Websites +date: 2023-01-28 +toc: true +--- + +{%- macro siteButton(url, file, alt, tooltip=alt, width=88, height=31) -%} +
    31. + + {{ alt }} + +
    32. +{%- endmacro -%} + +{% headingAnchor 3 %}Personal Sites I Enjoy{% endheadingAnchor %} + +

      Websites with Buttons

      +
        + {{ siteButton("https://karuma.me/", "sites/10kph.png", "10kph") }} + {{ siteButton("https://alyaza.neocities.org/", "sites/alyaza.gif", "alyaza's birzeblog") }} + {{ siteButton("https://www.autisticasfxxk.com/", "sites/autisticasfxxk.gif", "Autistic As Fxxk") }} + {{ siteButton("https://ballonlea.net/", "sites/ballonlea.png", "Ballonlea") }} + {{ siteButton("https://www.beepbird.net/", "sites/beepbird.gif", "Beep Bird") }} + {{ siteButton("https://chrisburnell.com/", "sites/chrisburnell.gif", "Chris Burnell") }} + {{ siteButton("https://blog.darylsun.page/", "sites/darylsun.webp", "Daryl Sun's Journal") }} + {{ siteButton("https://divergentrays.com/", "sites/divergentrays.png", "Divergent Rays") }} + {{ siteButton("https://cyberneticdryad.neocities.org/", "sites/dryadglen.png", "Dryad Glen") }} + {{ siteButton("https://frills.dev/", "sites/frills.png", "Frills") }} + {{ siteButton("https://your-local-grubdog.neocities.org/", "sites/grubdog.png", "Grubdog") }} + {{ siteButton("https://groundedwren.com/", "sites/groundedwren.png", "Grounded Wren") }} + {{ siteButton("https://jasm1nii.xyz/", "sites/jasminesjournal.png", "jasmine's journal") }} + {{ siteButton("https://jefbecker.com/", "sites/jefbecker.png", "JEFBECKER") }} + {{ siteButton("https://kalechips.net/", "sites/kalechips.png", "Kalechips") }} + {{ siteButton("https://amalinalai.github.io/precipice/", "sites/lina.gif", "lina's home") }} + {{ siteButton("https://lostletters.neocities.org/", "sites/lostletters.gif", "Lost Letters") }} + {{ siteButton("https://manyface.neocities.org/", "sites/manyface.png", "manyface world") }} + {{ siteButton("https://melvian.net/", "sites/melvian.png", "Melvian.net") }} + {{ siteButton("https://mycorrhiza.space/", "sites/mycorrhiza.png", "Mycorrhiza's Space") }} + {{ siteButton("https://pinkvampyr.leprd.space/", "sites/pinkvampyr.gif", "Pinkvampyr") }} + {{ siteButton("https://ribo.zone/", "sites/ribose.png", "Ribose") }} + {{ siteButton("https://sakuradreams.neocities.org/", "sites/sakuradreams.gif", "Sakura Dreams") }} + {{ siteButton("https://sanguineroyal.com/", "sites/sanguineroyal.gif", "Sanguine Royal") }} + {{ siteButton("https://solaria.neocities.org/", "sites/solaria.png", "Solaria's Webspace") }} + {{ siteButton("https://starbreaker.org/", "sites/starbreaker.avif", "🤘 starbreaker.org 🤘") }} + {{ siteButton("https://symliadoo.com/", "sites/symliadoo.png", "sym's living room 🍨") }} + {{ siteButton("https://whiona.me/", "sites/whiona.png", "Whiona") }} + {{ siteButton("https://wings.nu/", "sites/wings.png", "Wings.NU") }} + {{ siteButton("https://xandra.cc/", "sites/xandra.png", "Museum of Alexandra") }} +
      +

      Websites without Buttons

      + + +{% headingAnchor 3 %}Web Directories{% endheadingAnchor %} +

      Directories with Site Buttons

      +
        + {{ siteButton("https://pinkvampyr.leprd.space/accessiblenet/", "directories/accessiblenet.png", "Accessibility Net Directory") }} + {{ siteButton("https://bukmark.club/", "directories/bukmarkclub.png", "BUKMARK.CLUB") }} + {{ siteButton("https://indieseek.xyz/", "directories/indieseek.png", "Indieseek.xyz Indie Web Directory") }} + {{ siteButton("https://linklane.net/", "directories/linklane.png", "Link Lane") }} + {{ siteButton("https://list-me.com/", "directories/list-me.png", "List-Me.com") }} + {{ siteButton("https://kalechips.net/responsive/", "directories/responsiveweb.png", "Responsive Web Directory") }} + {{ siteButton("https://smoothsailing.asclaria.org/", "directories/smoothsailing.png", "Smooth Sailing Listings") }} +
      +

      Directories without Site Buttons

      + + +{% headingAnchor 3 %}Communities{% endheadingAnchor %} +
        + {{ siteButton("https://32bit.cafe/", "communities/32-bit-cafe.png", "32-Bit Cafe") }} + {{ siteButton("https://zine.kalechips.net/index", "communities/saladmagazine.png", "Salad Magazine") }} +
      diff --git a/src/links/pages/mass-effect-le-mod-list.md b/src/links/pages/mass-effect-le-mod-list.md new file mode 100644 index 00000000..a6bd5b51 --- /dev/null +++ b/src/links/pages/mass-effect-le-mod-list.md @@ -0,0 +1,3385 @@ +--- +articleTitle: Leilukin's Mass Effect Legendary Edition Mod Build +desc: A list of Mass Effect Legendary Edition mods I use. +tags: ["contents", "mod lists"] +categories: ["mass effect", "video game mods"] +updated: 2025-02-23T17:14:33+0800 +isContentDivided: true +toc: true +--- + +{% container "article", "content__section" %} +Welcome to Leilukin’s {% cite "Mass Effect Legendary Edition" %} Mod Build! + +Here I’m compiling a list of all the modifications, or mods in short, that I use for {% cite "Mass Effect Legendary Edition" %}, remaster of the {% cite "Mass Effect" %} trilogy, a series of space opera role-playing video games developed by BioWare, for the best experience with the game. This document is made for my reference and to share with others. + +The format of this mod list is inspired by [KOTOR Community Portal's mod lists](https://kotor.neocities.org/modding/). + +(This mod list was last updated on ) +{% endcontainer %} + +{% container "article", "content__section" %} +## Important Notes + +In order to prevent mod conflicts as much as possible, installation order matters if you are using a lot of mods. Therefore, the full list of my mod build below has been arranged in the proper installation order to make all these mods compatible. If you are interested in following my mod build, you should install the mods in the order you are presented with them. + +It is important to note that **you cannot use mods for the original edition of the {% cite "Mass Effect" %} trilogy in the Legendary Edition, and vice versa**. Therefore, since the release of the Legendary Edition, mod authors need to either port or recreate the original trilogy mods, so they can be used for the Legendary Edition. +{% endcontainer %} + +{% container "article", "content__section" %} +## Mod Categories + +The mods I included in my mod build are divided into the following categories, which clarifies the types of changes the mod makes: + +Appearance Change +: Appearance change is not inherently graphics improvement, but rather a modification to the default appearance of a character, item, location, interface, etc. + +Bugfix +: As the name implies, this type of mod fixes bugs with the vanilla game. + +Framework +: These do not do anything noticeable in the game on their own after being installed, but some mods make use of them and require them to work. + +Graphics Improvement +: This type of mod improves the graphics in the vanilla game in some way, by retexturing and/or remodeling a character, item, location, etc. These mods usually come with high-resolution textures. + +Immersion +: These mods are not inherently bugfixes, but changes done to improve the internal consistency of the game’s content. + +Interface Change +: This type of mod makes changes to the game’s interface. + +Mechanics Change +: This type of mod makes changes to the game’s system which directly impacts the way you play the game, varying from changing the camera angle of a location to altering the core stats of a class. + +Modified Content +: Modified content is not inherently new content, but rather alterations to the vanilla game’s content because the vanilla content has some shortcomings. The changes made by this kind of mod were never intended to be in the vanilla game. + +Player Customisation +: This type of mod makes changes to customization options for the player character, by improving the vanilla customization options or adding new options, including face, hairstyle and outfits. + +Restored Content +: This type of mod restores content that has been cut from the vanilla game. In the case of Mass Effect Legendary Edition, some of the mods of this kind restores content that was present in the original edition, but is absent in the Legendary Edition. + +Sound Change +: As the name implies, these mods make changes to the sound in the vanilla game. The sound could be music or ambient audio. +{% endcontainer %} + +{% container "article", "content__section" %} +## {% cite "Mass Effect Legendary Edition" %} Modding Tools + +* [ME3Tweaks Mod Manager](https://me3tweaks.com/modmanager/): This mod manager can be used for both the original edition and the Legendary Edition of the Mass Effect trilogy. +* [Mass Effect Legendary Edition Character Code Translator](https://answers.ea.com/t5/Mass-Effect-Legendary-Edition/Import-your-Shepard-from-the-original-trilogy/td-p/10340553): This app allows you to convert your Shepard’s face code from the original edition of {% cite "Mass Effect 2" %} and {% cite "3" %} into the Legendary Edition. The Legendary Edition adds new options to the character creator, so you cannot just directly copy and paste the face code from the original edition and expect your Shepard to look the same in LE. [[(Download Mass Effect Legendary Edition Character Code Translator from Google Drive)](https://drive.google.com/drive/u/0/folders/1ixMj8Eyvfu6DVczMgSIR826xPO1GfMym)] +* [Trilogy Save Editor](https://www.nexusmods.com/masseffectlegendaryedition/mods/20): A save editor for the {% cite "Mass Effect" %} trilogy. If you are using any custom hair mods, using a save editor is required. +{% endcontainer %} + +{% container "article", "content__section" %} +## {% cite "Mass Effect 1" %} Legendary Edition Mods + +### Installed with ME3Tweaks Mod Manager + +#### LE1 Community Patch + +Mod Name +: [LE1 Community Patch](https://www.nexusmods.com/masseffectlegendaryedition/mods/23) + +Mod Author +: LE1 Community Patch Team + +Category +: Bugfix + +--- + +#### Myriad Pro Begone (LE1) + +Mod Name +: [Myriad Pro Begone](https://www.nexusmods.com/masseffectlegendaryedition/mods/1070) + +Mod Author +: Audemus + +Category +: Interface Change + +--- + +#### Vignette Remover (LE1) + +Mod Name +: [Vignette Remover](https://www.nexusmods.com/masseffectlegendaryedition/mods/428) + +Mod Author +: Mgamerz + +Category +: Graphics Improvement + +--- + +#### MELLO + +Mod Name +: [MELLO (Mass Effect 1 Legendary Lighting Overhaul)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1500) + +Mod Author +: Catachrism + +Category +: Graphics Improvement + +--- + +#### Appearance Modification Menu LE1 + +Mod Name +: [Appearance Modification Menu LE1](https://www.nexusmods.com/masseffectlegendaryedition/mods/2513) + +Mod Author +: DropTheSquid + +Category +: Player Customization & Appearance Changes + +--- + +#### Vanilla-like Femshep Hairstyles + +Mod Name +: [Vanilla-like Femshep Hairstyles (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1047) + +Mod Author +: spiderbabes + +Category +: Player Customization + +--- + +#### Halcyon Hairpack + +Mod Name +: [Halcyon Hairpack (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1497) + +Mod Author +: Mellin and Audemus + +Category +: Player Customization + +--- + +#### Proper Convo-Cutscene Skipper (LE1) + +Mod Name +: [Proper Convo-Cutscene Skipper (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1681) + +Mod Author +: 55tumbl + +Category +: Mechanics Change + +--- + +#### Flycam Keybinds (LE1) + +Mod Name +: [Flycam Keybinds (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1836) + +Mod Author +: Vegz + +Category +: Restored Content + +--- + +#### XP Rescale (LE1) + +Mod Name +: [XP Rescale (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/369) + +Mod Author +: 55tumbl + +Category +: Mechanics Change + +Installation Note +: I install the Default version. + +--- + +#### No Inventory Limit + +Mod Name +: [No Inventory Limit](https://www.nexusmods.com/masseffectlegendaryedition/mods/1391) + +Mod Author +: Herobrine24 + +Category +: Mechanics Change + +--- + +#### Instant Item Conversion + +Mod Name +: [Instant Item Conversion](https://www.nexusmods.com/masseffectlegendaryedition/mods/1523) + +Mod Author +: Herobrine24 + +Category +: Interface Change + +--- + +#### LE1 Definitive Audio Overhaul + +Mod Name +: [LE1 Definitive Audio Overhaul](https://www.nexusmods.com/masseffectlegendaryedition/mods/1560) + +Mod Author +: Devinite + +Category +: Sound Change + +--- + +#### Unlimited Sprint and Boost Duration + +Mod Name +: [Unlimited Sprint and Boost Duration](https://www.nexusmods.com/masseffectlegendaryedition/mods/337) + +Mod Author +: Sapphire/Nypheena + +Category +: Mechanics Change + +Installation Note +: Download and install Unlimited Sprint and Mako Boost LE1. + +--- + +#### Remove Screen Shake (LE1) + +Mod Name +: [Remove Screen Shake (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/110) + +Mod Author +: HenBagle + +Category +: Interface Change + +--- + +#### Quick Loot (LE1) + +Mod Name +: [Quick Loot (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1026) + +Mod Author +: rondeeno + +Category +: Mechanics Change + +--- + +#### Replenish Grenades LE1 + +Mod Name +: [Replenish Grenades LE1](https://www.nexusmods.com/masseffectlegendaryedition/mods/532) + +Mod Author +: HenBagle + +Category +: Added Content + +--- + +#### Skip Minigames (LE1) + +Mod Name +: [Skip Minigames (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/360) + +Mod Author +: 55tumbl + +Category +: Mechanics Change + +--- + +#### Paragade Persuasion (LE1) + +Mod Name +: [Paragade Persuasion (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1673) + +Mod Author +: rondeeno + +Category +: Mechanics Change + +--- + +#### Same-Gender Romances for LE1 + +Mod Name +: [Same-Gender Romances for LE1](https://www.nexusmods.com/masseffectlegendaryedition/mods/564) + +Mod Author +: rondeeno + +Category +: Modified Content & Restored Content + +Installation Note +: I also install the following components: +: * NPCs Flirt Regardless of Gender +: * Same-Gender LI Activates Beacon + +--- + +#### Saren Stages + +Mod Name +: [Saren Stages LE1](https://www.nexusmods.com/masseffectlegendaryedition/mods/666) + +Mod Author +: Catachrism + +Category +: Appearance Change & Immersion + +Installation Note +: I install the Noveria armor. + +--- + +#### Faster Airlock (LE1) + +Mod Name +: [Faster Airlock (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/753) + +Mod Author +: rondeeno + +Category +: Mechanics Change + +--- + +#### Normandy Rapid Transit (LE1) + +Mod Name +: [Normandy Rapid Transit (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/755) + +Mod Author +: rondeeno + +Category +: Mechanics Change + +--- + +#### Improved Wards Skybox (LE1) + +Mod Name +: [Improved Wards Skybox (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1176) + +Mod Author +: Audemus + +Category +: Appearance Change + +--- + +#### Morlan's Iconic Armor Store + +Mod Name +: [Morlan's Iconic Armor Store (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/684) + +Mod Author +: Kinkojiro + +Category +: Added Content + +--- + +#### Iconic Fashion Party (LE1) + +Mod Name +: [Iconic Fashion Party (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/745) + +Mod Author +: 55tumbl + +Category +: Appearance Change + +--- + +#### Casual Hubs for LE1 + +Mod Name +: [Casual Hubs for LE1](https://www.nexusmods.com/masseffectlegendaryedition/mods/574) + +Mod Author +: rondeeno + +Category +: Appearance Change + +--- + +#### Black Market License (LE1) + +Mod Name +: [Black Market License (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/661) + +Mod Author +: 55tumbl + +Category +: Mechanics Change + +--- + +#### Elements of Comparative Weaponry (LE1) + +Mod Name +: [Elements of Comparative Weaponry (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/639) + +Mod Author +: 55tumbl + +Category +: Interface Change + +--- + +#### Advanced Weapon Models for LE1 + +Mod Name +: [Advanced Weapon Models for LE1](https://www.nexusmods.com/masseffectlegendaryedition/mods/853) + +Mod Author +: Knighthawk + +Category +: Appearance Change + +--- + +#### LE1 Streamlined Weapon Loadouts + +Mod Name +: [LE1 Streamlined Weapon Loadouts](https://www.nexusmods.com/masseffectlegendaryedition/mods/870) + +Mod Author +: Knighthawk + +Category +: Mechanics Change + +--- + +#### Mission Timings (LE1) + +Mod Name +: [Mission Timings (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/754) + +Mod Author +: rondeeno + +Category +: Immersion + +--- + +#### Galaxy Map Trackers (LE1) + +Mod Name +: [Galaxy Map Trackers (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/426) + +Mod Author +: 55tumbl + +Category +: Mechanics Change + +Required Mod +: Private Message Terminal (LE1). + +--- + +#### Private Message Terminal (LE1) + +Mod Name +: [Private Message Terminal (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1525) + +Mod Author +: 55tumbl + +Category +: Appearance Change & Framework + +--- + +#### A Little Help From My Friends (LE1) + +Mod Name +: [A Little Help From My Friends (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1526) + +Mod Author +: 55tumbl + +Category +: Mechanics Change + +--- + +#### Eclectic Emails (LE1) + +Mod Name +: [Eclectic Emails (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1563) + +Mod Author +: TDA792 + +Category +: Mechanics Change + +--- + +#### Charted Worlds (LE1) + +Mod Name +: [Charted Worlds (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/524) + +Mod Author +: 55tumbl + +Category +: Mechanics Change + +--- + +#### Unique Moons + +Mod Name +: [Unique Moons](https://www.nexusmods.com/masseffectlegendaryedition/mods/1735) + +Mod Author +: SDeden + +Category +: Graphics Improvement + +Download Note +: I also download Galaxy Map Pictures. Install it after installing all the DLC mods I want to use via ME3Tweak Mod Manager. + +--- + +#### N7 MAKO (LE1) + +Mod Name +: [N7 MAKO (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/309) + +Mod Author +: 55tumbl + +Category +: Mechanics Change + +Installation Note +: I install the Tourist option. + +--- + +#### Mako Squadmate Banter + +Mod Name +: [Mako Squadmate Banter](https://www.nexusmods.com/masseffectlegendaryedition/mods/1310) + +Mod Author +: HenBagle + +Category +: Immersion + +Required Mod +: [LE1 Sideloader Framework](https://www.nexusmods.com/masseffectlegendaryedition/mods/1309) + +--- + +#### No Sexual Harassment (LE1) + +Mod Name +: [No Sexual Harassment (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/682) + +Mod Author +: rondeeno + +Category +: Restored Content & Modified Content + +Installation Note +: I install the following options: +: * No Sexist Dialogue +: * No Unwanted Touching + +--- + +#### Liara Consistency Mod (ME1LE) + +Mod Name +: [Liara Consistency Mod (ME1LE)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1183) + +Mod Author +: Khaar Machinima + +Category +: Appearance Change & Immersion + +Installation Note +: I install the LE3 face version. + +--- + +#### Alliance Uniform Consistency + +Mod Name +: [Alliance Uniform Consistency](https://www.nexusmods.com/masseffectlegendaryedition/mods/799) + +Mod Author +: Mistyvail + +Category +: Appearance Change & Immersion + +Download Note +: I also download Alliance Uniform Consistency (LE Launcher). + +--- + +#### Ashley Heavy Phoneix Armor Consistency + +Mod Name +: [Ashley Heavy Phoneix Armor Consistency](https://www.nexusmods.com/masseffectlegendaryedition/mods/1874) + +Mod Author +: UTILITY PAWN + +Category +: Immersion + +--- + +#### Wrex Heavy Mercenary Armor Consistency + +Mod Name +: [Wrex Heavy Mercenary Armor Consistency](https://www.nexusmods.com/masseffectlegendaryedition/mods/1876) + +Mod Author +: UTILITY PAWN + +Category +: Immersion + +--- + +#### New Casuals for Femshep LE1 + +Mod Name +: [New Casuals for Femshep LE1](https://www.nexusmods.com/masseffectlegendaryedition/mods/804) + +Mod Author +: rngdshep + +Category +: Appearance Change + +--- + +#### Ported Casuals for Male Shepard + +Mod Name +: [Ported Casuals for Male Shepard](https://www.nexusmods.com/masseffectlegendaryedition/mods/1071) + +Mod Author +: MentalHygiene + +Category +: Appearance Change + +--- + +#### ME3 Alliance Armor for LE1 + +Mod Name +: [ME3 Alliance Armor for LE1](https://www.nexusmods.com/masseffectlegendaryedition/mods/838) + +Mod Author +: Knighthawk + +Category +: Appearance Change & Immersion + +--- + +#### Eden Prime Red Sky Restored + +Mod Name +: [Eden Prime Red Sky Restored](https://www.nexusmods.com/masseffectlegendaryedition/mods/1367) + +Mod Author +: Vegz + +Category +: Appearance Change & Restored Content + +--- + +#### Easier Feros Persuasion Check + +Mod Name +: [Easier Feros Persuasion Check (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1261) + +Mod Author +: phoenixsoul13 + +Category +: Modified Content + +--- + +#### Mira Please Be Quiet + +Mod Name +: [Mira Please Be Quiet (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/734) + +Mod Author +: phoenixsoul13 + +Category +: Modified Content + +--- + +#### Dr. Heart Experiments + +Mod Name +: [Dr. Heart Experiments](https://www.nexusmods.com/masseffectlegendaryedition/mods/597) + +Mod Author +: Khaar Machinima + +Category +: Appearance Change & Immersion + +--- + +#### Virmire Savior Mod (LE1) + +Mod Name +: [Virmire Savior Mod (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1212) + +Mod Author +: Vegz + +Category +: Restored Content & Modified Content + +--- + +#### LE1 Diversification Project + +Mod Name +: [LE1 Diversification Project](https://www.nexusmods.com/masseffectlegendaryedition/mods/1172) + +Mod Author +: Audemus + +Category +: Appearance Change & Immersion + +Required Mods: LE1 Community Patch, Halcyon Hairpack (LE1), Advanced Weapon Models for LE1 + +--- + +#### Immersive Normandy Transmissions (LE1) + +Mod Name +: [Immersive Normandy Transmissions (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1728) + +Mod Author +: Audemus + +Category +: Immersion + +--- + +#### New Outfit for Matriarch Benezia + +Mod Name +: [New Outfit for Matriarch Benezia](https://www.nexusmods.com/masseffectlegendaryedition/mods/2255) + +Mod Author +: bejewledhanban + +Category +: Appearance Change + +--- + +#### Keepers Finders + +Mod Name +: [Keepers Finders (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1043) + +Mod Author +: 55tumbl + +Category +: Mechanics Change + +--- + +#### Hot Labs Restored + +Mod Name +: [Hot Labs Restored (LE1)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1708) + +Mod Author +: Vegz + +Category +: Restored Content + +--- + +#### Punch Charles Saracino + +Mod Name +: [Punch Charles Saracino](https://www.nexusmods.com/masseffectlegendaryedition/mods/1524) + +Mod Author +: beccatoria and Z794 + +Category +: Modified Content + +--- + +#### Anderson Alliance Uniform Consistency + +Mod Name +: [Anderson Alliance Uniform Consistency](https://www.nexusmods.com/masseffectlegendaryedition/mods/1955) + +Mod Author +: Utility Pawn + +Category +: Immersion + +--- + +#### Less Intense Vigil + +Mod Name +: [Less Intense Vigil](https://www.nexusmods.com/masseffectlegendaryedition/mods/822) + +Mod Author +: HenBagle + +Category +: Appearance Change + +--- + +#### Actual Effort Required + +Mod Name +: [Actual Effort Required (to save the Council)](https://www.nexusmods.com/masseffectlegendaryedition/mods/2027) + +Mod Author +: InvoicingEmu + +Category +: Immersion + +Installation Note +: I install the Easy option + +--- + +#### ALOV (LE1) + +Mod Name +: [A Lot Of Videos (ALOV)](https://www.nexusmods.com/masseffectlegendaryedition/mods/3) + +Mod Author +: Audemus and ALOV Team + +Category +: Graphics Improvement + +Installation Note +: “ALOV for ME1”. + +--- + +### Installed with Mass Effect Modder (MEM) + +#### Wraith Eyes (LE1) + +Mod Name +: [Wraith Eyes](https://www.nexusmods.com/masseffectlegendaryedition/mods/1085) + +Mod Author +: mulderitsme + +Category +: Graphics Improvement + +Installation Note +: Install Wraith Eyes LE1. + +--- + +#### Fix for Lighter Middle Part of Lipsticks for LE1 + +Mod Name +: [Fix for Lighter Middle Part of Lipsticks for LE1](https://www.nexusmods.com/masseffectlegendaryedition/mods/281) + +Mod Author +: MorningAngel + +Category +: Graphics Improvement + +--- + +#### Unique Moons (LE1) + +Mod Name +: [Unique Moons](https://www.nexusmods.com/masseffectlegendaryedition/mods/1735) + +Mod Author +: SDeden + +Category +: Graphics Improvement + +Download Note +: I also download and install Galaxy Map Pictures with Mass Effect Modder. + +--- + +#### Paramours (LE1) + +Mod Name +: [Paramours](https://www.nexusmods.com/masseffectlegendaryedition/mods/1132) **(WARNING: This link is Not Safe For Work)** + +Mod Author +: Anzella + +Category +: Graphics Improvement + +Download Note +: Download (LE1) Paramours. + +Installation Note +: I install (LE1) LCM LE3 Liara Nipples.mem and (LE1) 'Ashley' Nipples.mem. + +--- +{% endcontainer %} + +{% container "article", "content__section" %} +## {% cite "Mass Effect 2" %} Legendary Edition Mods + +### Installed with ME3Tweaks Mod Manager + +#### Unofficial LE2 Patch + +Mod Name +: [Unofficial LE2 Patch](https://www.nexusmods.com/masseffectlegendaryedition/mods/8) + +Mod Author +: Team Pyjak + +Category +: Bugfix + +IMPORTANT NOTE +: This unofficial patch is mandatory if you want to use multiple mods for Mass Effect 2 Legendary Edition, as this patch is required for those mods to work. + +--- + +#### Vignette Remover (LE2) + +Mod Name +: [Vignette Remover](https://www.nexusmods.com/masseffectlegendaryedition/mods/428) + +Mod Author +: Mgamerz + +Category +: Graphics Improvement + +--- + +#### Myriad Pro Begone (LE2) + +Mod Name +: [Myriad Pro Begone](https://www.nexusmods.com/masseffectlegendaryedition/mods/1070) + +Mod Author +: Audemus + +Category +: Interface Change + +--- + +#### Vanilla-like Femshep Hairstyles (LE2) + +Mod Name +: [Vanilla-like Femshep Hairstyles (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1048) + +Mod Author +: spiderbabes + +Category +: Player Customization + +--- + +#### No Shared Power Cooldowns (LE2) + +Mod Name +: [No Shared Power Cooldowns](https://www.nexusmods.com/masseffectlegendaryedition/mods/1699) + +Mod Author +: DropTheSquid + +Category +: Mechanics Change + +--- + +#### Proper Convo-Cutscene Skipper (LE2) + +Mod Name +: [Proper Convo-Cutscene Skipper (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1682) + +Mod Author +: 55tumbl + +Category +: Mechanics Change + +--- + +#### Shorter Notifications (LE2) + +Mod Name +: [Shorter Notifications (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/390) + +Mod Author +: 55tumbl + +Category +: Interface Change + +--- + +#### LE2 Mission Results Screen Fix + +Mod Name +: [LE2 Mission Results Screen Fix](https://www.nexusmods.com/masseffectlegendaryedition/mods/896) + +Mod Author +: Mgamerz + +Category +: Interface Change + +--- + +#### Paragade Persuasion (LE2) + +Mod Name +: [Paragade Persuasion (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1673) + +Mod Author +: rondeeno + +Category +: Mechanics Change + +--- + +#### LE2 Prologue Framework + +Mod Name +: [LE2 Prologue Framework](https://www.nexusmods.com/masseffectlegendaryedition/mods/2138) + +Mod Author +: beccatoria + +Category +: Framework + +--- + +#### Unlimited Sprint and Boost Duration (LE2) + +Mod Name +: [Unlimited Sprint and Boost Duration](https://www.nexusmods.com/masseffectlegendaryedition/mods/337) + +Mod Author +: Sapphire/Nypheena + +Category +: Mechanics Change + +Installation Note +: Download and install Unlimited Sprint LE2. + +--- + +#### Remove Storm Screen Shake for LE2 + +Mod Name +: [Remove Storm Screen Shake for LE2](https://www.nexusmods.com/masseffectlegendaryedition/mods/329) + +Mod Author +: Mgamerz + +Category +: Interface Change + +--- + +#### Skip Minigames for LE2 + +Mod Name +: [Skip Minigames for LE2](https://www.nexusmods.com/masseffectlegendaryedition/mods/304) + +Mod Author +: Mgamerz + +Category +: Mechanics Change + +Installation Note +: I install the Classic option. + +--- + +#### Stop Auto-Equipping Weapons + +Mod Name +: [Stop Auto-Equipping Weapons](https://www.nexusmods.com/masseffectlegendaryedition/mods/1432) + +Mod Author +: Mistyvail + +Category +: Interface Change + +Installation Note +: I install the Choose Loadout option. + +--- + +#### Faster Normandy (LE2) + +Mod Name +: [Faster Normandy (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1151) + +Mod Author +: 55tumbl + +Category +: Mechanics Change + +--- + +#### Zero Probe All Resources (LE2) + +Mod Name +: [Zero Probe All Resources (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1152) + +Mod Author +: 55tumbl + +Category +: Mechanics Change + +--- + +#### Honest Fuel Depot + +Mod Name +: [Honest Fuel Depot](https://www.nexusmods.com/masseffectlegendaryedition/mods/1655) + +Mod Author +: Leszek90 + +Category +: Mechanics Change + +--- + +#### Reformatted Emails + +Mod Name +: [Reformatted Emails](https://www.nexusmods.com/masseffectlegendaryedition/mods/1304) + +Mod Author +: LLinden + +Category +: Immersion + +--- + +#### Combined Ammo Mod (LE2) + +Mod Name +: [Combined Ammo Mod (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1817) + +Mod Author +: RepugnantPear + +Category +: Mechanics Change + +Required Mod +: [LE2 Improved Functionality](https://www.nexusmods.com/masseffectlegendaryedition/mods/1458) + +Installation Note +: I install all the options. + +--- + +#### EGM Fix Weapons in Cutscenes LE2 + +Mod Name +: [EGM Fix Weapons in Cutscenes LE2](https://www.nexusmods.com/masseffectlegendaryedition/mods/422?tab=files) + +Mod Author +: Kinkojiro + +Category +: Bugfix + +--- + +#### Full Weapon Recovery + +Mod Name +: [Full Weapon Recovery](https://www.nexusmods.com/masseffectlegendaryedition/mods/1503) + +Mod Author +: Herobrine24 + +Category +: Mechanics Change + +--- + +#### Easy Armor Stats (LE2) + +Mod Name +: [Easy Armor Stats (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/25) + +Mod Author +: Herobrine24 + +Category +: Added Content + +--- + +#### Casual Hubs for LE2 + +Mod Name +: [Casual Hubs for LE2](https://www.nexusmods.com/masseffectlegendaryedition/mods/1025) + +Mod Author +: rondeeno + +Category +: Appearance Change + +Installation Note +: I also install the following options: +: * Prison Uniform for Jack +: * Default Alternate Appearance Pack Outfit for Jack +: * Default Alternate Appearance Pack Armor for Miranda + +--- + +#### Expanded Armor Colors (LE2) + +Mod Name +: [Expanded Armor Colors (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1700) + +Mod Author +: Khaar Machinima + +Category +: Player Customization + +--- + +#### Expanded Shepard Armory (LE2) + +Mod Name +: [Expanded Shepard Armory (ME2LE)](https://www.nexusmods.com/masseffectlegendaryedition/mods/5) + +Mod Author +: Khaar Machinima & ThaliaGraces + +Category +: Appearance Change & Player Customization + +--- + +#### Expanded Squadmate Armory LE2 + +Mod Name +: [Expanded Squadmate Armory (ESA Addon) LE2](https://www.nexusmods.com/masseffectlegendaryedition/mods/1846) + +Mod Author +: Khaar Machinima & stasismind + +Category +: Appearance Change + +Required Mod +: [Expanded Shepard Armory (ME2LE)](https://www.nexusmods.com/masseffectlegendaryedition/mods/5) + +--- + +#### Anderson and Hackett Consistency + +Mod Name +: [Anderson and Hackett Consistency Mod (ME2LE)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1063) + +Mod Author +: Khaar Machinima + +Category +: Appearance Change & Immersion + +--- + +#### Cerberus and Alliance Uniform Consistency + +Mod Name +: [Cerberus and Alliance Uniform Consistency (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1021) + +Mod Author +: Audemus + +Category +: Appearance Change & Immersion + +Download Note +: I download and install both the files for LE2 and the LE launcher. + +--- + +#### Leather Jacket for Femshep LE2 + +Mod Name +: [Leather Jacket for Femshep LE2](https://www.nexusmods.com/masseffectlegendaryedition/mods/565) + +Mod Author +: rngdshep + +Category +: Player Customization + +--- + +#### The Illusive Woman LE2 + +Mod Name +: [The Illusive Woman (or a Suit for Femshep) LE2](https://www.nexusmods.com/masseffectlegendaryedition/mods/835) + +Mod Author +: rngdshep + +Category +: Player Customization + +--- + +#### Turtlenecks for Male Shepard (LE2) + +Mod Name +: [Turtlenecks for Male Shepard (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1658) + +Mod Author +: clericofshadows + +Category +: Player Customization + +--- + +#### Coats and Jackets for Male Shepard (LE2) + +Mod Name +: [Coats and Jackets for Male Shepard (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1669) + +Mod Author +: clericofshadows + +Category +: Player Customization + +--- + +#### Morning's Outfits for Femshep LE2 PT3 + +Mod Name +: [Morning's Outfits for Femshep LE2 PT3](https://www.nexusmods.com/masseffectlegendaryedition/mods/1653) + +Mod Author +: MorningAngel + +Category +: Player Customization + +Download Note +: I also download Texture mod options for the outfits. + +--- + +#### EGM Weapons in Cutscenes (LE2) + +Mod Name +: [EGM Weapons in Cutscenes (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/2059) + +Mod Author +: Kinkojiro + +Category +: Immersion + +--- + +#### EGM Armors for LE2 + +Mod Name +: [EGM Armors for LE2](https://www.nexusmods.com/masseffectlegendaryedition/mods/187) + +Mod Author +: Kinkojiro + +Category +: Player Customization + +--- + +#### Clear Mnemonic Visor (LE2) + +Mod Name +: [Clear Mnemonic Visor (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1757) + +Mod Author +: CDRFredryck + +Category +: Added Content & Player Customization + +--- + +#### Miranda Lawson's Armory (LE2) + +Mod Name +: [Miranda Lawson's Armory (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1988) + +Mod Author +: clericofshadows + +Category +: Added Content + +--- + +#### Jacob Taylor's Armory (LE2) + +Mod Name +: [Jacob Taylor's Armory (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/2342) + +Mod Author +: clericofshadows + +Category +: Added Content + +--- + +#### Original Trilogy Lighting Restoration (LE2) + +Mod Name +: [Original Trilogy Lighting Restoration (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1729) + +Mod Author +: Vegz + +Category +: Graphics Improvement + +--- + +#### Box Of Tweaks (LE2) + +Mod Name +: [Box Of Tweaks (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1572) + +Mod Author +: munchyfly + +Category +: Added Content, Modified Content & Immersion + +Installation Note +: I install the following components from Box of Tweaks: +: * Geth Pulse Rifle for All +: * Harvester: No Camera Shake +: * Firewalker: No Generator Camera Shake + +--- + +#### Assorted Bed Sheets (LE2) + +Mod Name +: [Assorted Bed Sheets (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1288) + +Mod Author +: munchyfly + +Category +: Appearance Change + +--- + +#### Pinnacle Station Apartment (LE2) + +Mod Name +: [Pinnacle Station Apartment (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1558) + +Mod Author +: vegz + +Category +: Added Content + +--- + +#### Kelly Chambers and Dr. Kenson Remastered Original Hair + +Mod Name +: [Kelly Chambers and Dr. Kenson Remastered Original Hair](https://www.nexusmods.com/masseffectlegendaryedition/mods/1644) + +Mod Author +: \_MaZ_TeR\_ + +Category +: Appearance Change + +--- + +#### Oriana looks like Miranda's Twin (LE2) + +Mod Name +: [Oriana looks like Miranda's Twin (ME2LE)](https://www.nexusmods.com/masseffectlegendaryedition/mods/413) + +Mod Author +: Khaar Machinima + +Category +: Appearance Change & Immersion + +--- + +#### Let Me Stay + +Mod Name +: [Let Me Stay (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1872) + +Mod Author +: Khaar Machinima + +Category +: Interface Change + +--- + +#### M-44 Battle Tank + +Mod Name +: [M-44 Battle Tank (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1316) + +Mod Author +: RepugnantPear + +Category +: Mechanics Change + +--- + +#### Hugo Gernsback Consistency + +Mod Name +: [Hugo Gernsback Consistency Mod](https://www.nexusmods.com/masseffectlegendaryedition/mods/1352) + +Mod Author +: RepugnantPear & Mistyvail + +Category +: Modified Content + +--- + +#### Apollo Spacesuit Restoration + +Mod Name +: [Apollo Spacesuit Restoration](https://www.nexusmods.com/masseffectlegendaryedition/mods/1712) + +Mod Author +: Khaar Machinima + +Category +: Restored Content + +--- + +#### 2175 Aeia Lighting Restored + +Mod Name +: [2175 Aeia Lighting Restored](https://www.nexusmods.com/masseffectlegendaryedition/mods/1729) + +Mod Author +: Vegz + +Category +: Restored Content + +--- + +#### Daddy Issues + +Mod Name +: [Daddy Issues](https://www.nexusmods.com/masseffectlegendaryedition/mods/1534) + +Mod Author +: Jenya66 + +Category +: Appearance Change & Immersion + +--- + +#### Instant Shadow Broker Rewards + +Mod Name +: [Instant Shadow Broker Rewards](https://www.nexusmods.com/masseffectlegendaryedition/mods/1180) + +Mod Author +: BtEtta + +Category +: Modified Content + +--- + +#### Virmire Savior Mod (LE2) + +Mod Name +: [Virmire Savior Mod (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1587) + +Mod Author +: Vegz + +Category +: Modified Content + +--- + +#### Platonic Post Horizon Emails + +Mod Name +: [Platonic Post Horizon Emails](https://www.nexusmods.com/masseffectlegendaryedition/mods/2083) + +Mod Author +: beckabooo + +Category +: Added Content + +--- + +#### Early Recruitment + +Mod Name +: [Early Recruitment (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/384) + +Mod Author +: beccatoria + +Category +: Modified Content + +--- + +#### Trigger Buttons (LE2) + +Mod Name +: [Trigger Buttons (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/383) + +Mod Author +: beccatoria + +Category +: Modified Content + +--- + +#### DLC Timings Mod (LE2) + +Mod Name +: [DLC Timings Mod (ME2LE)](https://www.nexusmods.com/masseffectlegendaryedition/mods/382) + +Mod Author +: Khaar Machinima + +Category +: Immersion + +--- + +#### No N7 Armor in Liara's Apartment + +Mod Name +: [No N7 Armor in Liara's Apartment](https://www.nexusmods.com/masseffectlegendaryedition/mods/1456) + +Mod Author +: InvoicingEmu + +Category +: Modified Content + +--- + +#### More Gay Romances (LE2) + +Mod Name +: [More Gay Romances](https://www.nexusmods.com/masseffectlegendaryedition/mods/489) + +Mod Author +: Mentlegen + +Category +: Modified Content + +--- + +#### No Sexual Harassment (LE2) + +Mod Name +: [No Sexual Harassment (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/682) + +Mod Author +: rondeeno + +Category +: Restored Content & Modified Content + +Installation Note +: I install the following options: +: * No Meln +: * No Donnelly Comments +: * No Sexist Dialogue + +--- + +#### Same-Gender Romances for LE2 + +Mod Name +: [Same-Gender Romances for LE2](https://www.nexusmods.com/masseffectlegendaryedition/mods/1115) + +Mod Author +: rondeeno + +Category +: Restored Content & Modified Content + +Installation Note +: I also install the NPC Flirts Regardless of Gender component, but I do so only for the Gianna Parasini flirt. I remove `BioD_OmgHub_500DenVIP_LOC_INT.pcc` and `BioD_OmgHub_221GarrusAcq_LOC_INT.pcc` from the mod folder after installing so the Blue Sun Merc and Meln will not sexually harass my FemShep, something I installed the No Sexual Harassment mod to avoid. + +--- + +#### Renegade Not Ableist (LE2) + +Mod Name +: [Renegade Not Ableist (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1263) + +Mod Author +: phoenixsoul13 + +Category +: Modified Content + +--- + +#### Kasumi Restored Memories (LE2) + +Mod Name +: [Kasumi - Restored Memories (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/2158) + +Mod Author +: mangobyte + +Category +: Restored Content + +--- + +#### Jacob Respects Thane and Tali + +Mod Name +: [Jacob Respects Thane and Tali](https://www.nexusmods.com/masseffectlegendaryedition/mods/1035) + +Mod Author +: Herobrine24 + +Category +: Modified Content + +--- + +#### Samara Camera Restoration + +Mod Name +: [Samara Camera Restoration](https://www.nexusmods.com/masseffectlegendaryedition/mods/1262) + +Mod Author +: beccatoria + +Category +: Restored Content + +--- + +#### F.I.S.H. Mod (LE2) + +Mod Name +: [F.I.S.H. Mod (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1134) + +Mod Author +: beccatoria + +Category +: Modified Content + +--- + +#### Optional Flirting Mod (LE2) + +Mod Name +: [Optional Flirting Mod (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/839) + +Mod Author +: phoenixsoul13 + +Category +: Modified Content + +--- + +#### Extended Romance Scenes + +Mod Name +: [Extended Romance Scenes](https://www.nexusmods.com/masseffectlegendaryedition/mods/1198) + +Mod Author +: Scottina123 + +Category +: Added Content + +--- + +#### Miranda Romance Mini Dress (LE2) + +Mod Name +: [Miranda Romance Mini Dress (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1244) + +Mod Author +: RepugnantPear + +Category +: Appearance Change + +--- + +#### Dossiers Reworked + +Mod Name +: [Dossiers Reworked](https://www.nexusmods.com/masseffectlegendaryedition/mods/1755) + +Mod Author +: SierraI07 + +Category +: Modified Content + +--- + +#### Samara Shadow Broker Dossiers Restored + +Mod Name +: [Samara Cut Shadow Broker Dossiers Restored](https://www.nexusmods.com/masseffectlegendaryedition/mods/1782) + +Mod Author +: Khaar Machinima + +Category +: Restored Content + +--- + +#### Liara Consistency Mod (LE2) + +Mod Name +: [Liara Consistency Mod (ME2LE)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1062) + +Mod Author +: Khaar Machinima + +Category +: Appearance Change & Immersion + +Installation Note +: I install the LE3 face version. + +--- + +#### Samara's New Armor (LE2) + +Mod Name +: [Samara's New Armor (MELE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/702) + +Mod Author +: Zeb + +Category +: Appearance Change + +Download Note +: I also download Samara's New Armor UI (MELE2). Install it with Mass Effect Modder after installing all the DLC mods I want to use. + +--- + +#### Justicar Samara's Armory (LE2) + +Mod Name +: [Justicar Samara's Armory (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/2080) + +Mod Author +: clericofshadows + +Category +: Added Content + +--- + +#### Practical Bodies for Shepard's Armors (LE2) + +Mod Name +: [Practical Bodies for Shepard's Armors (MELE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1553) + +Mod Author +: DeepSky27 + +Category +: Appearance Change + +--- + +#### No Headgear for Squadmates (LE2) + +Mod Name +: [(ME2LE) No Headgear for Squadmates](https://www.nexusmods.com/masseffectlegendaryedition/mods/377) + +Mod Author +: ThaliaGraces + +Category +: Appearance Change + +Installation Note +: I also download Squad Select Textures, then I install it after installing all the DLC mods I want to use via ME3Tweak Mod Manager. + +--- + +#### Miranda Hair Replacer (LE2) + +Mod Name +: [Miranda Hair Replacer](https://www.nexusmods.com/masseffectlegendaryedition/mods/680) + +Mod Author +: BubbleButton + +Category +: Appearance Change + +Required Mod +: LE2 Prologue Framework + +Installation Note +: I install the following options in order: +: 1. Miranda + LE2 Patch +: 2. Miranda + Hubs +: 3. Miranda + LE2 patch no visor + +--- + +#### Fate of Executor Pallin LE2 + +Mod Name +: [Fate of Executor Pallin LE2](https://www.nexusmods.com/masseffectlegendaryedition/mods/2087) + +Mod Author +: Khaar Machinima + +Category +: Immersion + +--- + +#### ALOV (LE2) + +Mod Name +: [A Lot Of Videos (ALOV)](https://www.nexusmods.com/masseffectlegendaryedition/mods/3) + +Mod Author +: Audemus and ALOV Team + +Category +: Graphics Improvement + +Installation Note +: “ALOV for ME2”. + +--- + +#### Immersive Citizens LE2 + +Mod Name +: [Immersive Citizens LE2](https://www.nexusmods.com/masseffectlegendaryedition/mods/1680) + +Mod Author +: Daxvapik + +Category +: Immersion + +--- + +### Installed with Mass Effect Modder (MEM) + +#### Wraith Eyes (LE2) + +Mod Name +: [Wraith Eyes](https://www.nexusmods.com/masseffectlegendaryedition/mods/1085) + +Mod Author +: mulderitsme + +Category +: Graphics Improvement + +Installation Note +: Install Wraith Eyes LE2 and Default Renegade Scars LE2. + +--- + +#### Fix for Lighter Middle Part of Lipsticks for LE2 + +Mod Name +: [Fix for Lighter Middle Part of Lipsticks for LE2](https://www.nexusmods.com/masseffectlegendaryedition/mods/281) + +Mod Author +: MorningAngel + +Category +: Graphics Improvement + +--- + +#### Cleaner Visor (LE2) + +Mod Name +: [Cleaner Visor](https://www.nexusmods.com/masseffectlegendaryedition/mods/744) + +Mod Author +: PorkinMemes + +Category +: Appearance Change + +Installation Note +: Install the VisorLE2.mem file + +--- + +#### Miranda Officer Outfit + +Mod Name +: [JeanLuc761's Miranda Officer Outfit](https://www.nexusmods.com/masseffectlegendaryedition/mods/1020) + +Mod Author +: JeanLuc761; ported by Rocketcat15 + +Category +: Appearance Change + +Installation Note +: I do not install the `JL761_style_Miranda_Romance.mem` file, since I used Miranda Romance Mini Dress to replace her outfit during her romance scene. + +--- + +#### Jack's Closet + +Mod Name +: [Jack's Closet by femshepping](https://www.nexusmods.com/masseffectlegendaryedition/mods/1564) + +Mod Author +: femshepping + +Category +: Appearance Change + +Installation Note +: I install Twisted Knit. + +--- + +#### Blue Scars for Garrus (LE2) + +Mod Name +: [Blue Scars for Garrus (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1030) + +Mod Author +: Emma Vakarian-Theirin + +Category +: Appearance Change & Graphics Improvement + +--- + +#### Morning's Combat Outfits for Kasumi LE2 + +Mod Name +: [Morning's Combat Outfits for Kasumi LE2](https://www.nexusmods.com/masseffectlegendaryedition/mods/2167) + +Mod Author +: MorningAngel + +Category +: Appearance Change + +--- + +#### Liara's Proper Doctorate + +Mod Name +: [Liara's Proper Doctorate](https://www.nexusmods.com/masseffectlegendaryedition/mods/1557) + +Mod Author +: FroodyMishky + +Category +: Immersion + +--- + +#### Goodbye Lens Flares (LE2) + +Mod Name +: [Goodbye Lens Flares (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1133) + +Mod Author +: Wisegal + +Category +: Appearance Change + +--- + +#### Samara's New Armor (LE2) + +Mod Name +: [Samara's New Armor (MELE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/702) + +Mod Author +: Zeb + +Category +: Appearance Change + +Installation Note +: I install Samara's New Armor UI (MELE2) with Mass Effect Modder after installing all the DLC mods I want to use via ME3Tweak Mod Manager. + +--- + +#### Paramours (LE2) + +Mod Name +: [Paramours](https://www.nexusmods.com/masseffectlegendaryedition/mods/1132) **(WARNING: This link is Not Safe For Work)** + +Mod Author +: Anzella + +Category +: Graphics Improvement + +Download Note +: Download (LE2) Paramours. + +Installation Note +: I install (LE2) LCM ERS LE3 Liara Nipples.mem and (LE2) 'Ashley' Nipples.mem. + +--- +{% endcontainer %} + +{% container "article", "content__section" %} +## {% cite "Mass Effect 3" %} Legendary Edition Mods + +### Installed with ME3Tweaks Mod Manager + +#### LE3 Community Patch + +Mod Name +: [LE3 Community Patch](https://www.nexusmods.com/masseffectlegendaryedition/mods/13) + +Mod Author +: LE3 Community Patch Team + +Category +: Bugfix & Framework + +IMPORTANT NOTE +: This Community Framework and Patch is practically mandatory if you want to use multiple mods for {% cite "Mass Effect 3" %} Legendary Edition, as this framework and patch is required for those mods to work. + +--- + +#### Myriad Pro Begone (LE3) + +Mod Name +: [Myriad Pro Begone](https://www.nexusmods.com/masseffectlegendaryedition/mods/1070) + +Mod Author +: Audemus + +Category +: Interface Change + +--- + +#### Vignette Remover (LE3) + +Mod Name +: [Vignette Remover](https://www.nexusmods.com/masseffectlegendaryedition/mods/428) + +Mod Author +: Mgamerz + +Category +: Graphics Improvement + +--- + +#### Vanilla-like Femshep Hairstyles (LE3) + +Mod Name +: [Vanilla-like Femshep Hairstyles (LE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1049) + +Mod Author +: spiderbabes + +Category +: Player Customization + +--- + +#### Shorter Hairstyles for Femshep (MELE3) + +Mod Name +: [Shorter Hairstyles for Femshep (MELE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1480) + +Mod Author +: deepsky27 + +Category +: Player Customization + +--- + +#### Shorter Hairstyles for Femshep II (LE3) + +Mod Name +: [Shorter Hairstyles for Femshep II (MELE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1540) + +Mod Author +: deepsky27 + +Category +: Player Customization + +--- + +#### Appearance Modification Menu LE3 + +Mod Name +: [Appearance Modification Menu LE3](https://www.nexusmods.com/masseffectlegendaryedition/mods/694) + +Mod Author +: DropTheSquid + +Category +: Interface Change & Player Customization + +--- + +#### No Shared Power Cooldowns (LE3) + +Mod Name +: [No Shared Power Cooldowns](https://www.nexusmods.com/masseffectlegendaryedition/mods/1699) + +Mod Author +: DropTheSquid + +Category +: Mechanics Change + +--- + +#### Proper Convo-Cutscene Skipper (LE3) + +Mod Name +: [Proper Convo-Cutscene Skipper (LE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1683) + +Mod Author +: 55tumbl + +Category +: Mechanics Change + +--- + +#### LE3 Opening Remaster + +Mod Name +: [LE3 Opening Remaster](https://www.nexusmods.com/masseffectlegendaryedition/mods/19) + +Mod Author +: Mellin and Audemus + +Category +: Graphics Improvement + +--- + +#### Expanded Galaxy Mod (LE) + +Mod Name +: [Expanded Galaxy Mod (LE)](https://www.nexusmods.com/masseffectlegendaryedition/mods/422) + +Mod Author +: Kinkojiro + +Category +: Added Content, Immersion, Restored Content & Bugfix + +Installation Note +: I also select the following components during installation: +: * Extra: GasBags on Eden Prime + +--- + +#### EGM Armors for LE3 + +Mod Name +: [EGM Armors for LE3](https://www.nexusmods.com/masseffectlegendaryedition/mods/187) + +Mod Author +: Kinkojiro + +Category +: Player Customization + +--- + +#### Journal Enhanced (LE3) + +Mod Name +: [Journal Enhanced (LE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1508) + +Mod Author +: 55tumbl + +Category +: Interface Change + +--- + +#### War Assets Tweaks (LE3) + +Mod Name +: [War Assets Tweaks (LE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1733) + +Mod Author +: 55tumbl + +Category +: Mechanics Change + +--- + +#### Metallic Armor Tints (LE3) + +Mod Name +: [Metallic Armor Tints](https://www.nexusmods.com/masseffectlegendaryedition/mods/482) + +Mod Author +: Kinkojiro + +Category +: Player Customization + +--- + +#### More Color Options for Tints and Patterns LE3 + +Mod Name +: [Morning's More Color Options for Tints and Patterns LE3](https://www.nexusmods.com/masseffectlegendaryedition/mods/2101) + +Mod Author +: MorningAngel + +Category +: Player Customization + +--- + +#### Clear Mnemonic Visor (LE3) + +Mod Name +: [Clear Mnemonic Visor (LE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1753) + +Mod Author +: CDRFredryck + +Category +: Added Content & Player Customization + +--- + +#### Morning's Outfits for Femshep LE3 PT3 + +Mod Name +: [Morning's Outfits for Femshep LE3 PT3](https://www.nexusmods.com/masseffectlegendaryedition/mods/1593) + +Mod Author +: MorningAngel + +Category +: Player Customization + +Download Note +: I also download Texture mod options for the outfits. + +--- + +#### Morning's Accessories for Shepard LE3 + +Mod Name +: [Morning's Accessories for Shepard LE3](https://www.nexusmods.com/masseffectlegendaryedition/mods/1571) + +Mod Author +: MorningAngel + +Category +: Player Customization + +--- + +#### New Outfits I For Shepard (MELE3) + +Mod Name +: [New Outfits I For Shepard (MELE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1638) + +Mod Author +: deepsky27 + +Category +: Player Customization + +--- + +#### Jane's Turtleneck Dress + +Mod Name +: [Jane's Turtleneck Dress](https://www.nexusmods.com/masseffectlegendaryedition/mods/1656) + +Mod Author +: Soriyumi + +Category +: Player Customization + +Download Note +: I also download the Optional Recolors and install one of the MEM files with Mass Effect Modder after all the DLC mods I want to use via ME3Tweak Mod Manager. + +--- + +#### Jane's Pajamas + +Mod Name +: [Jane's Pajamas](https://www.nexusmods.com/masseffectlegendaryedition/mods/1664) + +Mod Author +: Soriyumi + +Category +: Player Customization + +Download Note +: I also download the Optional Recolors and install Jane'sPajamas - BlackRecolor.mem with Mass Effect Modder after all the DLC mods I want to use via ME3Tweak Mod Manager. + +--- + +#### Leather Jacket for Femshep (LE3) + +Mod Name +: [Leather Jacket for Femshep](https://www.nexusmods.com/masseffectlegendaryedition/mods/440) + +Mod Author +: rngdshep + +Category +: Player Customization + +--- + +#### The Illusive Woman (LE3) + +Mod Name +: [The Illusive Woman (or a Suit for Femshep)](https://www.nexusmods.com/masseffectlegendaryedition/mods/671) + +Mod Author +: rngdshep + +Category +: Player Customization + +--- + +#### Turtlenecks for Male Shepard (LE3) + +Mod Name +: [Turtlenecks for Male Shepard (LE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1662) + +Mod Author +: clericofshadows + +Category +: Player Customization + +--- + +#### Coats and Jackets for Male Shepard (LE3) + +Mod Name +: [Coats and Jackets for Male Shepard (LE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1689) + +Mod Author +: clericofshadows + +Category +: Player Customization + +--- + +#### Practical Bodies for Shepard's Armors (LE3) + +Mod Name +: [Practical Bodies for Shepard's Armors (MELE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1423) + +Mod Author +: DeepSky27 + +Category +: Appearance Change + +Installation Note +: I install Version B. + +--- + +#### Practical Bodies for Casual Shepard (LE3) + +Mod Name +: [Practical Bodies for Casual Shepard (MELE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1410) + +Mod Author +: DeepSky27 + +Category +: Appearance Change + +--- + +#### Reduced Interaction Circle HUD + +Mod Name +: [Reduced interaction circle HUD](https://www.nexusmods.com/masseffectlegendaryedition/mods/1106) + +Mod Author +: daneeyul + +Category +: Interface Change + +--- + +#### Shorter Notifications (LE3) + +Mod Name +: [Shorter Notifications (LE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/803) + +Mod Author +: WiredTexan + +Category +: Interface Change + +--- + +#### Unlimited Sprint and Boost Duration + +Mod Name +: [Unlimited Sprint and Boost Duration](https://www.nexusmods.com/masseffectlegendaryedition/mods/337) + +Mod Author +: Sapphire/Nypheena + +Category +: Mechanics Change + +Installation Note +: Download and install Unlimited Sprint LE3. + +--- + +#### Combined Ammo Mod (LE2) + +Mod Name +: [Combined Ammo Mod (LE2)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1817) + +Mod Author +: RepugnantPear + +Category +: Mechanics Change + +Required Mod +: [LE2 Improved Functionality](https://www.nexusmods.com/masseffectlegendaryedition/mods/1458) + +Installation Note +: I install all the options. + +--- + +#### Stock Weapon Appearance + +Mod Name +: [Stock Weapon Appearance](https://www.nexusmods.com/masseffectlegendaryedition/mods/1502) + +Mod Author +: Herobrine24 + +Category +: Appearance Change + +--- + +#### No Sniper Zoom for SMGs HPs and ARs (LE3) + +Mod Name +: [No Sniper Zoom for SMGs HPs and ARs (LE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1279) + +Mod Author +: RepugnantPear + +Category +: Interface Change + +--- + +#### Weapon Legendary Warpack + +Mod Name +: [Weapon Legendary Warpack - Rescoped Avenger - Slim N7 Typhoon - Automatic Valkyrie](https://www.nexusmods.com/masseffectlegendaryedition/mods/925) + +Mod Author +: survivor686 + +Category & Tier: Appearance Change. + +Installation Note +: I install the Default option. + +--- + +#### Faster Normandy (LE3) + +Mod Name +: [Faster Normandy (LE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1179) + +Mod Author +: 55tumbl + +Category +: Mechanics Change + +--- + +#### Assorted Bed Sheets (LE3) + +Mod Name +: [Assorted Bed Sheets (LE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1294) + +Mod Author +: munchyfly + +Category +: Appearance Change + +--- + +#### Bakara's Gift + +Mod Name +: [Bakara's Gift](https://www.nexusmods.com/masseffectlegendaryedition/mods/1600) + +Mod Author +: munchyfly + +Category +: Added Content + +--- + +#### Padme's Cabin Additions and Memorials (LE3) + +Mod Name +: [Padme's Cabin Additions and Memorials (LE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/631) + +Mod Author +: Padme4000 + +Category +: Added Content + +--- + +#### shley Consistency Project (LE3) + +Mod Name +: [Ashley Consistency Project (MELE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1209) + +Mod Author +: Jenya66 + +Category +: Appearance Change + +--- + +#### Ashley Williams's Armory (LE3) + +Mod Name +: [Ashley Williams's Armory (LE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1759) + +Mod Author +: clericofshadows + +Category +: Added Content + +--- + +#### Liara Full Helmet + +Mod Name +: [Liara Full Helmet](https://www.nexusmods.com/masseffectlegendaryedition/mods/1452) + +Mod Author +: M1SZ3L Getorex + +Category +: Appearance Change + +--- + +#### EDI's Armory + +Mod Name +: [EDI's Armory](https://www.nexusmods.com/masseffectlegendaryedition/mods/1756) + +Mod Author +: clericofshadows + +Category +: Added Content + +--- + +#### Javik's New Armor (LE3) + +Mod Name +: [Javik's New Armor (LE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1153) + +Mod Author +: Zeb + +Category +: Added Content + +--- + +#### Traynor Long Hair + +Mod Name +: [Traynor Long Hair mod](https://www.nexusmods.com/masseffectlegendaryedition/mods/516) + +Mod Author +: Morax + +Category +: Appearance Change + +--- + +#### Bakara Visible Face + +Mod Name +: [Bakara Visible Face](https://www.nexusmods.com/masseffectlegendaryedition/mods/1231) + +Mod Author +: Aleirdra + +Category +: Appearance Change + +--- + +#### Virmire Savior Mod (LE3) + +Mod Name +: [Virmire Savior Mod (LE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1442) + +Mod Author +: Vegz + +Category +: Modified Content + +--- + +#### Shepard Can Agree With Anderson + +Mod Name +: [Shepard Can Agree With Anderson](https://www.nexusmods.com/masseffectlegendaryedition/mods/1013) + +Mod Author +: Pauju + +Category +: Modified Content + +--- + +#### Cerberus Retrofits + +Mod Name +: [Cerberus Retrofits](https://www.nexusmods.com/masseffectlegendaryedition/mods/709) + +Mod Author +: Tydeous + +Category +: Appearance Change + +--- + +#### IFF Dialogue Tweak + +Mod Name +: [IFF Dialogue Tweak](https://www.nexusmods.com/masseffectlegendaryedition/mods/1666) + +Mod Author +: LLinden + +Category +: Immersion + +--- + +#### Reegar Returns + +Mod Name +: [Reegar Returns](https://www.nexusmods.com/masseffectlegendaryedition/mods/2252) + +Mod Author +: Scottina123 + +Category +: Modified Content + +--- + +#### Reworked Kai Leng + +Mod Name +: [Reworked Kai Leng](https://www.nexusmods.com/masseffectlegendaryedition/mods/1038) + +Mod Author +: Pauju + +Category +: Modified Content + +Download Note +: I download the white armor version. + +--- + +#### MIranda Mod + +Mod Name +: [MIranda Mod (LE)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1350) + +Mod Author +: Kinkojiro + +Category +: Added Content + +Required Mod +: Expanded Galaxy Mod + +--- + +#### More Gay Romances (LE3) + +Mod Name +: [More Gay Romances](https://www.nexusmods.com/masseffectlegendaryedition/mods/489) + +Mod Author +: Mentlegen + +Category +: Modified Content + +--- + +#### Take Earth Back + +Mod Name +: [Take Earth Back](https://www.nexusmods.com/masseffectlegendaryedition/mods/16) + +Mod Author +: Mass Effect Modding Community, project leader Tydeous + +Category +: Mechanics Change, Immersion & Restored Content + +--- + +#### Audemus’ Happy Ending Mod + +Mod Name +: [Audemus’ Happy Ending Mod (AHEM)](https://www.nexusmods.com/masseffectlegendaryedition/mods/323) + +Mod Author +: Audemus + +Category +: Modified Content + +--- + +#### Project Variety (LE3) + +Mod Name +: [Project Variety (LE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1481) + +Mod Author +: Scottina123 + +Category +: Added Content, Modified Content, Player Customization, Restored Content, Mechanics Change & Immersion + +--- + +#### Thane Can Live + +Mod Name +: [Thane Can Live](https://www.nexusmods.com/masseffectlegendaryedition/mods/1282) + +Mod Author +: phoenixsoul13 + +Category +: Modified Content + +--- + +#### Emily Lives + +Mod Name +: [Emily Lives](https://www.nexusmods.com/masseffectlegendaryedition/mods/2199) + +Mod Author +: Scottina123 + +Category +: Modified Content + +--- + +#### Super Extra Party Time + +Mod Name +: [Super Extra Party Time](https://www.nexusmods.com/masseffectlegendaryedition/mods/1750) + +Mod Author +: beccatoria + +Category +: Modified Content + +Installation Note +: I select the Project Variety and Virmire Savior compatibility patches. + +--- + +#### Pinnacle Station Apartment (LE3) + +Mod Name +: [Pinnacle Station Apartment (LE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1588) + +Mod Author +: Scottina123 & LLinden + +Category & Tier: Added Content + +--- + +#### Various Dialogue Tweaks (LE3) + +Mod Name +: [Various Dialogue Tweaks (LE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1511) + +Mod Author +: phoenixsoul13 + +Category +: Modified Content + +Installation Note +: I install the Garrus dialogue tweak. + +--- + +#### No Movement Penalty During Rannoch Boss Fight + +Mod Name +: [No Movement Penalty During Rannoch Boss Fight](https://www.nexusmods.com/masseffectlegendaryedition/mods/1156) + +Mod Author +: Herobrine24 + +Category +: Mechanics Change + +--- + +#### Liara Mourns the Dead + +Mod Name +: [Liara Mourns the Dead](https://www.nexusmods.com/masseffectlegendaryedition/mods/1713) + +Mod Author +: beccatoria + +Category +: Added Content + +--- + +#### Omega Hub + +Mod Name +: [Omega Hub](https://www.nexusmods.com/masseffectlegendaryedition/mods/1597) + +Mod Author +: Tydeous + +Category +: Added Content + +--- + +#### Choose Your Friend + +Mod Name +: [Choose Your Friend](https://www.nexusmods.com/masseffectlegendaryedition/mods/996) + +Mod Author +: phoenixsoul13 + +Category +: Modified Content + +--- + +#### Prioritize Scar Comments (LE3) + +Mod Name +: [Prioritize Scar Comments (LE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1413) + +Mod Author +: phoenixsoul13 + +Category +: Modified Content + +--- + +#### Shepard's Archived Profile + +Mod Name +: [Shepard's Archived Profile](https://www.nexusmods.com/masseffectlegendaryedition/mods/2045) + +Mod Author +: Mistyvail + +Category +: Immersion + +--- + +#### Dreams Remade + +Mod Name +: [Dreams Remade](https://www.nexusmods.com/masseffectlegendaryedition/mods/1630) + +Mod Author +: Pauju + +Category +: Modified Content + +--- + +#### ALOV (LE3) + +Mod Name +: [A Lot Of Videos (ALOV)](https://www.nexusmods.com/masseffectlegendaryedition/mods/3) + +Mod Author +: Audemus and ALOV Team + +Category +: Graphics Improvement + +Installation Note +: “ALOV for ME3”. + +--- + +### Installed with Mass Effect Modder (MEM) + +#### Wraith Eyes (LE3) + +Mod Name +: [Wraith Eyes](https://www.nexusmods.com/masseffectlegendaryedition/mods/1085) + +Mod Author +: mulderitsme + +Category +: Graphics Improvement + +Installation Note +: Install Wraith Eyes LE3 and Default Renegade Scars LE3. + +--- + +#### Teeth fix for new hairstyles (ME3) + +Mod Name +: [Teeth fix for new hairstyles (ME3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/487) + +Mod Author +: xramina + +Category +: Bugfix + +Installation Note +: Install Wraith Eyes LE3 and Default Renegade Scars LE3. + +--- + +#### Fix for Lighter Middle Part of Lipsticks for LE3 + +Mod Name +: [Fix for Lighter Middle Part of Lipsticks for LE3](https://www.nexusmods.com/masseffectlegendaryedition/mods/281) + +Mod Author +: MorningAngel + +Category +: Graphics Improvement + +--- + +#### Cleaner Visor (LE3) + +Mod Name +: [Cleaner Visor](https://www.nexusmods.com/masseffectlegendaryedition/mods/744) + +Mod Author +: PorkinMemes + +Category +: Appearance Change + +Installation Note +: Install the VisorLE3.mem file + +--- + +#### GunMetal Weapon Textures (LE3) + +Mod Name +: [GunMetal Weapon Textures (LE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/1772) + +Mod Author +: SpaceWombat + +Category +: Graphics Improvement + +--- + +#### Ashley LE1 Complexion for LE3 + +Mod Name +: [Ashley LE1 Complexion for LE3](https://www.nexusmods.com/masseffectlegendaryedition/mods/1191) + +Mod Author +: Audemus + +Category +: Appearance Change + +--- + +#### HD Garrus Face Texture (LE3) + +Mod Name +: [ClearanceClarence's HD Garrus Face Texture (LE3)](https://www.nexusmods.com/masseffectlegendaryedition/mods/992) + +Mod Author +: ClearanceClarence & Emma Vakarian-Theirin + +Category +: Appearance Change & Graphics Improvement + +Installation Note +: I download and install both ClearanceClarence's HD Garrus Face Texture (LE3) and Blue Scars for Garrus (LE3). + +--- + +#### aJvik by Murderclan + +Mod Name +: [Javik by Murderclan](https://www.nexusmods.com/masseffectlegendaryedition/mods/1730) + +Mod Author +: MurderClan + +Category +: Appearance Change + +Download Note +: I download and install Javik's Black Sun Armour + +--- + +#### LE3 Main Menu Screen Reaplacer + +Mod Name +: [LE3 Main Menu Screen Reaplacer](https://www.nexusmods.com/masseffectlegendaryedition/mods/800) + +Mod Author +: Jenya66 + +Category +: Immersion + +--- + +#### Reduced Lens Flares (LE3) + +Mod Name +: [Reduced Lens Flares - LE3](https://www.nexusmods.com/masseffectlegendaryedition/mods/776) + +Mod Author +: Linus04 + +Category +: Appearance Change + +--- +{% endcontainer %} \ No newline at end of file diff --git a/src/links/pages/pages.11tydata.js b/src/links/pages/pages.11tydata.js new file mode 100644 index 00000000..c882c1c4 --- /dev/null +++ b/src/links/pages/pages.11tydata.js @@ -0,0 +1,12 @@ +export default { + layout: "main/content", + permalink: "/links/{{ page.fileSlug }}/", + hasBreadcrumbs: true, + eleventyComputed: { + title: (data) => `${data.articleTitle} | Links`, + eleventyNavigation: { + key: (data) => data.articleTitle, + parent: "Links" + } + } +} \ No newline at end of file diff --git a/src/links/pages/stardew-valley-mod-list.md b/src/links/pages/stardew-valley-mod-list.md new file mode 100644 index 00000000..674431dd --- /dev/null +++ b/src/links/pages/stardew-valley-mod-list.md @@ -0,0 +1,1358 @@ +--- +articleTitle: Leilukin's Stardew Valley Mod Build +desc: A list of Stardew Valley mods I use. +tags: ["contents", "mod lists"] +categories: ["stardew valley", "video game mods"] +updated: 2025-04-18T06:30:06+0800 +isContentDivided: true +toc: true +--- + +{% container "article", "content__section" %} +Welcome to Leilukin’s {% cite "Stardew Valley" %} Mod Build! + +Here I’m compiling a list of all the modifications, or mods in short, that I use for {% cite "Stardew Valley" %}, the independent farming simulator video game developed by ConcernedApe, for the best experience with the game. This document is made for my reference and to share with others. + +The format of this mod list is inspired by [KOTOR Community Portal's mod lists](https://kotor.neocities.org/modding/). + +(This mod list was last updated on ) +{% endcontainer %} + +{% container "article", "content__section" %} +## Mod Categories + +The mods I included in my mod build are divided into the following categories, which clarifies the types of changes the mod makes: + +Appearance Change +: Appearance change is not inherently graphics improvement, but rather a modification to the default appearance of a character, item, location, interface, etc. + +Immersion +: These mods are not inherently bugfixes, but changes done to improve the internal consistency of the game’s content. + +Interface Change +: As the name implies, this type of mod modifies the game’s interface. + +Mechanics Change +: This type of mod makes changes to the game’s system which directly impacts the way you play the game, varying from changing the camera angle of a location to altering the core stats of a class. +{% endcontainer %} + +{% container "article", "content__section" %} +## Mod Tiers + +The tiers for each mod included in my mod build are not necessary a judgement on the quality of the mods themselves. In my mod builds, mod tiers are ranked on a scale of 1-4, based on how important the individual mods are for my experience with {% cite "Stardew Valley" %}. + +Tier 1 - Essential +: This tier indicates mods that I cannot play {% cite "Stardew Valley" %} without. Usually this is because I find those mods make very crucial changes to the game, typically by fixing things that bother me the most in the vanilla game. Similarly, mods of the Patch category that belong to this tier make critical changes to other mods. I consider excluding Tier 1 mods will negatively affect my experience with {% cite "Stardew Valley" %}. + +Tier 2 - Very Important +: This tier indicates mods that vastly improve my experience with the game. Mods belong to this tier are the bread and butter of my mod build. That said, unlike Tier 1 mods, excluding Tier 2 mods from my playthrough does not actively make my {% cite "Stardew Valley" %} experience worse either. + +Tier 3 - Somewhat Important +: This tier indicates mods that make changes that are in smaller scope or more subjective compared to Tier 1 and Tier 2 mods. Usually this is because the changes made by Tier 3 mods are less noticeable or more of a matter of personal taste. + +Tier 4 - Optional +: This tier indicates mods that makes even smaller or more subjective changes than Tier 3 mods, to the point that using these mods are optional. I include Tier 4 mods in my build for the purpose of maximizing my immersion, or because I use these mods for customization purposes for my characters. +{.deflist-1col} +{% endcontainer %} + +{% container "article", "content__section" %} +## {% cite "Stardew Valley" %} Mod Build - Full List + +### Mod Tools + +Frameworks that are essential to install for {% cite "Stardew Valley" %} mods to function: + +* [Stardew Modding API](https://smapi.io/) by Pathoschild +* [Content Patcher](https://www.nexusmods.com/stardewvalley/mods/1915) by Pathoschild + +{% cite "Stardew Valley" %} mod manager: + +* [Stardrop](https://www.nexusmods.com/stardewvalley/mods/10455) + +--- + +### Generic Mod Config Menu + +Mod Name +: [Generic Mod Config Menu](https://www.nexusmods.com/stardewvalley/mods/5098) + +Mod Author +: spacechase0 + +Category +: Interface Change + +Tier +: Tier 1 - Essential + +SMAPI Required +: Yes + +Content Patcher Required +: No + +--- + +### Lookup Anything + +Mod Name +: [Lookup Anything](http://www.nexusmods.com/stardewvalley/mods/541) + +Mod Author +: Pathoschild + +Category +: Interface Change + +Tier +: Tier 1 - Essential + +SMAPI Required +: Yes + +Content Patcher Required +: No + +Leilukin’s Comment +: This mod is essential for me because it allows me to look up various information in-game without needing to pause the game just to check the Stardew Valley wiki. + +--- + +### NPC Map Locations + +Mod Name +: [NPC Map Locations](https://www.nexusmods.com/stardewvalley/mods/239) + +Mod Author +: Bouhm and Pathoschild + +Category +: Interface Change + +Tier +: Tier 1 - Essential + +SMAPI Required +: Yes + +Content Patcher Required +: No + +--- + +### Stardew Valley Map Teleport + +Mod Name +: [Stardew Valley Map Teleport](https://www.nexusmods.com/stardewvalley/mods/21381) + +Mod Author +: Richard2091 + +Category +: Interface Change + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: No + +--- + +### tardew Notifications + +Mod Name +: [Stardew Notifications](https://www.nexusmods.com/stardewvalley/mods/4713) + +Mod Author +: monopandora, maintained by Sakorona + +Category +: Interface Change + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: No + +--- + +### Stardew Progress + +Mod Name +: [Stardew Progress](https://www.nexusmods.com/stardewvalley/mods/9786) + +Mod Author +: seeinggreen + +Category +: Interface Change + +Tier +: Tier 3 - Somewhat Important + +SMAPI Required +: Yes + +Content Patcher Required +: No + +--- + +### TimeSpeed + +Mod Name +: [TimeSpeed](https://www.nexusmods.com/stardewvalley/mods/169) + +Mod Author +: cantorsdust and Pathoschild + +Category +: Mechanics Change + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: No + +--- + +### Chests Anywhere + +Mod Name +: [Chests Anywhere](https://www.nexusmods.com/stardewvalley/mods/518) + +Mod Author +: Pathoschild + +Category +: Interface Change + +Tier +: Tier 1 - Essential + +SMAPI Required +: Yes + +Content Patcher Required +: No + +--- + +### Always Hay + +Mod Name +: [Always Hay](https://www.nexusmods.com/stardewvalley/mods/20808) + +Mod Author +: Omek97 + +Category +: Mechanics Change + +Tier +: Tier 1 - Essential + +SMAPI Required +: Yes + +Content Patcher Required +: No + +Leilukin’s Comment +: What bothers me about the hay in {% cite "Stardew Valley" %} is that if your silos are full, you cannot collect hay at all, not even as extra items in your inventory. This mod fixes that. + +--- + +### No Fence Decay Redux + +Mod Name +: [No Fence Decay Redux](https://www.nexusmods.com/stardewvalley/mods/20802) + +Mod Author +: EnderTedi + +Category +: Mechanics Change + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: No + +--- + +### Automatic Gates + +Mod Name +: [Automatic Gates](https://www.nexusmods.com/stardewvalley/mods/3109) + +Mod Author +: Rakiin aka ScheKaa + +Category +: Mechanics Change + +Tier +: Tier 3 - Somewhat Important + +SMAPI Required +: Yes + +Content Patcher Required +: No + +--- + +### Better Junimos + +Mod Name +: [Better Junimos](https://www.nexusmods.com/stardewvalley/mods/2221) + +Mod Author +: hawkfalcon + +Category +: Mechanics Change + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: No + +--- + +### One Click Shed Reloader + +Mod Name +: [One Click Shed Reloader](https://www.nexusmods.com/stardewvalley/mods/2052) + +Mod Author +: BitwiseJon + +Category +: Mechanics Change + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: No + +--- + +### Automate + +Mod Name +: [Automate](https://www.nexusmods.com/stardewvalley/mods/1063) + +Mod Author +: Pathoschild + +Category +: Mechanics Change + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: No + +--- + +### Tractor Mod + +Mod Name +: [Tractor Mod](https://www.nexusmods.com/stardewvalley/mods/1401) + +Mod Author +: Pathoschild + +Category +: Mechanics Change + +Tier +: Tier 3 - Somewhat Important + +SMAPI Required +: Yes + +Content Patcher Required +: No + +--- + +### Friends Forever + +Mod Name +: [Friends Forever (1.6)](https://www.nexusmods.com/stardewvalley/mods/20702) + +Mod Author +: IsaacSDev + +Category +: Mechanics Change + +Tier +: Tier 1 - Essential + +SMAPI Required +: Yes + +Content Patcher Required +: No + +--- + +### Gender Neutrality Mod + +Mod Name +: [Gender Neutrality Mod](https://www.nexusmods.com/stardewvalley/mods/722) + +Mod Author +: Hana + +Category +: Immersion + +Tier +: Tier 1 - Essential + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +Other Required Files +: [Gender Neutrality Mod Tokens](https://www.nexusmods.com/stardewvalley/mods/14426) by Hana + +--- + +### Platonic Partners and Friendships + +Mod Name +: [Platonic Partners and Friendships](https://www.nexusmods.com/stardewvalley/mods/8146/) + +Mod Author +: Amaranthacyan + +Category +: Modified Content + +Tier +: Tier 1 - Essential + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +Leilukin’s Comment +: I have always wanted to be able to see all the heart events of the marriage candidates without romancing them, so this mod is a must-have for me. + +--- + +### Platonic Relationships + +Mod Name +: [Platonic Relationships](https://www.nexusmods.com/stardewvalley/mods/4668) + +Mod Author +: CherryChain + +Category +: Modified Content + +Tier +: Tier 1 - Essential + +SMAPI Required +: Yes + +Content Patcher Required +: No + +--- + +### Farmer Age Dialogue Tweaks + +Mod Name +: [SFG's Farmer Age Dialogue Tweaks](https://www.nexusmods.com/stardewvalley/mods/4211) + +Mod Author +: ShotFromGuns + +Category +: Modified Content + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### Polyamory + +Mod Name +: [Polyamory](https://github.com/EnderTedi/Polyamory) + +Mod Author +: EnderTedi + +Category +: Modified Content + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: No + +--- + +### Custom Spouse Rooms + +Mod Name +: [Custom Spouse Rooms - Continued](https://www.nexusmods.com/stardewvalley/mods/20966) + +Mod Author +: Datamancer + +Category +: Modified Content + +Tier +: Tier 3 - Somewhat Important + +SMAPI Required +: Yes + +Content Patcher Required +: No + +--- + +### Custom Spouse Patio + +Mod Name +: [Custom Spouse Patio Redux](https://www.nexusmods.com/stardewvalley/mods/10889) + +Mod Author +: aedenthorn + +Category +: Modified Content + +Tier +: Tier 3 - Somewhat Important + +SMAPI Required +: Yes + +Content Patcher Required +: No + +--- + +### Bed Tweaks + +Mod Name +: [Bed Tweaks](https://www.nexusmods.com/stardewvalley/mods/10023) + +Mod Author +: aedenthorn + +Category +: Appearance Change + +Tier +: Tier 3 - Somewhat Important + +SMAPI Required +: Yes + +Content Patcher Required +: No + +--- + +### Hugs and Kisses + +Mod Name +: [Hugs and Kisses Continued](https://www.nexusmods.com/stardewvalley/mods/21019) + +Mod Author +: JoXW + +Category +: Modified Content + +Tier +: Tier 3 - Somewhat Important + +SMAPI Required +: Yes + +Content Patcher Required +: No + +--- + +### Part of the Community + +Mod Name +: [Part of the Community](https://www.nexusmods.com/stardewvalley/mods/923) + +Mod Author +: Space Baby + +Category +: Mechanics Change + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: No + +--- + +### Misc Introduction Fixes + +Mod Name +: [Misc introduction fixes](https://www.nexusmods.com/stardewvalley/mods/12562) + +Mod Author +: mistyspring + +Category +: Modified Content + +Tier +: Tier 3 - Somewhat Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### Shane’s New Job + +Mod Name +: [Shane’s New Job](https://www.nexusmods.com/stardewvalley/mods/2894) + +Mod Author +: Ran + +Category +: Modified Content + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### No More War - Kent as Journalist + +Mod Name +: [SFG's No More War - Kent as Journalist](https://www.nexusmods.com/stardewvalley/mods/4217) + +Mod Author +: ShotFromGuns + +Category +: Modified Content + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### Kent Gets Therapy + +Mod Name +: [Kent Gets Therapy - 3 Heart Event Edit](https://www.nexusmods.com/stardewvalley/mods/14535) + +Mod Author +: Airyn + +Category +: Modified Content + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### Tolerable Pierre + +Mod Name +: [Tolerable Pierre](https://www.moddrop.com/stardew-valley/mods/734913-tolerable-pierre) + +Mod Author +: LavenderLight + +Category +: Modified Content + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### Marnie Deserves Better + +Mod Name +: [Marnie Deserves Better](https://www.nexusmods.com/stardewvalley/mods/7686) + +Mod Author +: IllogicalMoodSwing + +Category +: Modified Content + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### Less Corrupt Lewis + +Mod Name +: [Less Corrupt Lewis - No More Statue](https://www.nexusmods.com/stardewvalley/mods/14269) + +Mod Author +: Airyn + +Category +: Modified Content + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### sqbr's Dialogue Edits + +Mod Name +: [sqbr's Dialogue Edits](https://www.nexusmods.com/stardewvalley/mods/14156) + +Mod Author +: sqbr + +Category +: Modified Content + +Tier +: Tier 1 - Essential + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### No More Dialogue Differences + +Mod Name +: [No More Dialogue Differences](https://www.nexusmods.com/stardewvalley/mods/4459) + +Mod Author +: Isi + +Category +: Modified Content + +Tier +: Tier 1 - Essential + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### Demetrius's Tomato Dilemma + +Mod Name +: [Demetrius's Tomato Dilemma](https://www.nexusmods.com/stardewvalley/mods/7250) + +Mod Author +: Fuzzlepuzzle + +Category +: Modified Content + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### Robin and Demetrius's Better Bed Discussion + +Mod Name +: [Robin and Demetrius's Better Bed Discussion](https://www.nexusmods.com/stardewvalley/mods/14534) + +Mod Author +: Airyn + +Category +: Modified Content + +Tier +: Tier 3 - Somewhat Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### Mx. Qi + +Mod Name +: [Mx. Qi](https://www.nexusmods.com/stardewvalley/mods/4310) + +Mod Author +: Isi + +Category +: Modified Content + +Tier +: Tier 3 - Somewhat Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### Befriend Marlon and Gunther + +Mod Name +: [Befriend Marlon and Gunther](https://www.nexusmods.com/stardewvalley/mods/2569) + +Mod Author +: Yoshimax and Pathoschild + +Category +: Modified Content + +Tier +: Tier 3 - Somewhat Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### Pelican Town Potluck + +Mod Name +: [Pelican Town Potluck](https://www.moddrop.com/stardew-valley/mods/1032927-pelican-town-potluck/) + +Mod Author +: LenneDalben + +Category +: Modified Content + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### Fixed Luau Bridge + +Mod Name +: [Fixed Luau Bridge](https://www.nexusmods.com/stardewvalley/mods/19264) + +Mod Author +: Airyn + +Category +: Immersion + +Tier +: Tier 1 - Essential + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### Elaho's Babies and Toddlers Expanded + +Mod Name +: [Elaho's Babies and Toddlers Expanded](https://www.nexusmods.com/stardewvalley) + +Mod Author +: Elaho + +Category +: Appearance Change & Immersion + +Tier +: Tier 1 - Essential + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +Leilukin’s Comment +: This mod is essential for me because I find the generic appearance of the babies rather immersion-breaking. + +--- + +### Diverse Stardew Valley + +Mod Name +: [Diverse Stardew Valley (DSV)](https://diversestardewvalley.weebly.com/) + +Mod Author +: DSV Project Team. Original version of the mod made by notsnufffie. + +Category +: Appearance Change & Modified Content + +Tier +: Tier 1 - Essential + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +Other Required Files +: * [Generic Mod Config Menu](https://www.nexusmods.com/stardewvalley/mods/5098) by spacechase0 +: * [Cross-Mod Compatibility Tokens (CMCT)](https://www.nexusmods.com/stardewvalley/mods/28284) by Spiderbuttons +: * [Sprites in Detail](https://www.nexusmods.com/stardewvalley/mods/14487) by BleakCodex for the Marigold + +: Linus Modded config option + +Leilukin’s Comment +: As much as I like {% cite "Stardew Valley" %}, I cannot help but notice that the characters are overwhelmingly white. Therefore, the existence of the Diverse Stardew Valley mod is a gift and I consider this mod essential for my game. + +--- + +### Diverse Stardew Valley Additional Characters + +Mod Name +: [Diverse Stardew Valley (DSV) Additional Characters - Townspeople](https://www.nexusmods.com/stardewvalley/mods/23918) + +Mod Author +: DSV Project Team + +Category +: Appearance Change + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +Other Required Files +: [Diverse Stardew Valley (DSV)](https://diversestardewvalley.weebly.com/) + +Download Note +: I download and Install the Malaysian Indian Gus add-on + +Leilukin’s Comment +: I use the Malaysian Indian Gus add-on since I am Malaysian myself (albeit not Indian) and Malaysians get very little representation in video games. + +--- + +### inger Island NPC Overhaul + +Mod Name +: [Ginger Island NPC Overhaul](https://www.nexusmods.com/stardewvalley/mods/9242) + +Mod Author +: Zoedoll Lemurkat and AirynS + +Category +: Appearance Change + +Tier +: Tier 1 - Essential + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +Other Required Files +: * [Anti-Social NPCs](https://www.nexusmods.com/stardewvalley/mods/5371) by Super Aardvark +: * [Custom NPC Exclusions](https://www.nexusmods.com/stardewvalley/mods/7089) by Esca-MMC + +Leilukin’s Comment +: I highly recommend reading Tumblr user jojaqualityheadcanons‘ post about the [issues with the Ginger Island content](https://jojaqualityheadcanons.tumblr.com/post/646056190629052416/sdvs-15-update-contains-content-that-plays-into). + +--- + +### Elle's New Horses + +Mod Name +: [Elle's New Horses](https://www.nexusmods.com/stardewvalley/mods/3169) + +Mod Author +: junimods + +Category +: Appearance Change + +Tier +: Tier 3 - Somewhat Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### Elle's Dog Replacements + +Mod Name +: [Elle's Dog Replacements](https://www.nexusmods.com/stardewvalley/mods/3871) + +Mod Author +: junimods + +Category +: Appearance Change + +Tier +: Tier 3 - Somewhat Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### lle's Cat Replacements + +Mod Name +: [Elle's Cat Replacements](https://www.nexusmods.com/stardewvalley/mods/3872) + +Mod Author +: junimods + +Category +: Appearance Change + +Tier +: Tier 3 - Somewhat Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### Mopsy's Harvest Moon Animals + +Mod Name +: [Mopsy's Harvest Moon Animals](https://www.nexusmods.com/stardewvalley/mods/2188) + +Mod Author +: Mopquill + +Category +: Appearance Change + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +Usage Note +: Since I use Elle's Dog Replacements, I disable the dog replacement function of this mod. + +Leilukin’s Comment +: I have never actually played any of the Harvest Moon games, though I find the animals, especially the chubby cows, from this mod too cute to resist using it. + +--- + +### K's Goat Replacers + +Mod Name +: [K's Goat Replacers](https://www.nexusmods.com/stardewvalley/mods/2964) + +Mod Author +: Kwillow + +Category +: Appearance Change + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +Installation Note +: I install the Solid White version. + +--- + +### K's Pig Replacers + +Mod Name +: [K's Pig Replacers](https://www.nexusmods.com/stardewvalley/mods/2945) + +Mod Author +: Kwillow + +Category +: Appearance Change + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +Installation Note +: I install the Solid Pink version. + +--- + +### Elle's Seasonal Vanilla Buildings + +Mod Name +: [Elle's Seasonal Vanilla Buildings](https://www.nexusmods.com/stardewvalley/mods/6330) + +Mod Author +: junimods + +Category +: Appearance Change + +Tier +: Tier 3 - Somewhat Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### Elle's Farmhouse Pride + +Mod Name +: [Elle's Farmhouse Pride](https://www.nexusmods.com/stardewvalley/mods/14764) + +Mod Author +: junimods + +Category +: Appearance Change + +Tier +: Tier 3 - Somewhat Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### Super Cellar + +Mod Name +: [Super Cellar](https://www.nexusmods.com/stardewvalley/mods/12747) + +Mod Author +: N3rdGirl + +Category +: Appearance Change + +Tier +: Tier 2 - Very Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### Seasonal Tub o Flowers + +Mod Name +: [Seasonal Tub o Flowers](https://www.nexusmods.com/stardewvalley/mods/2758) + +Mod Author +: MouseyPounds + +Category +: Appearance Change + +Tier +: Tier 3 - Somewhat Important + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- + +### Gold Clock Sundial + +Mod Name +: [Gold Clock Sundial](https://www.nexusmods.com/stardewvalley/mods/7863) + +Mod Author +: birdblinder + +Category +: Appearance Change + +Tier +: Tier 4 - Optional + +SMAPI Required +: Yes + +Content Patcher Required +: Yes + +--- +{% endcontainer %} diff --git a/src/main b/src/main new file mode 100644 index 00000000..9b7ede98 --- /dev/null +++ b/src/main @@ -0,0 +1,7 @@ +--- +layout: global/content +--- + +{{ content | safe }} + +

      (This {{ keyword if keyword else "page" }} was last updated on )

      diff --git a/src/projects/art/art.11tydata.js b/src/projects/art/art.11tydata.js new file mode 100644 index 00000000..db5ec89a --- /dev/null +++ b/src/projects/art/art.11tydata.js @@ -0,0 +1,4 @@ +export default { + tags: ["artworks", "contents"], + categories: ["artworks"] +} \ No newline at end of file diff --git a/src/projects/code/bellabuffs-phpmailer.md b/src/projects/code/bellabuffs-phpmailer.md new file mode 100644 index 00000000..18dba385 --- /dev/null +++ b/src/projects/code/bellabuffs-phpmailer.md @@ -0,0 +1,30 @@ +--- +title: BellaBuffs with PHPMailer Integration +desc: My fork of BellaBuffs, with PHPMailer powering the email sending features. +eleventyNavigation: + order: 4 +--- + +* [Demo](https://fan.leilukin.com/cassettebeasts){.link-btn} +* [Source Code (GitHub)](https://github.com/helenclx/BellaBuffs-PHPMailer){.link-btn} +* [Source Code (Gitea)](https://git.32bit.cafe/Leilukin/BellaBuffs-PHPMailer){.link-btn} +* [Download (GitHub)](https://github.com/helenclx/BellaBuffs-PHPMailer/releases/latest){.link-btn} +{.link-btn--wrapper} + +This is a fork of the fanlisting PHP script [BullaBuffs](https://github.com/jemjabella/BellaBuffs), with the email sending library [PHPMailer](https://github.com/PHPMailer/PHPMailer) integrated. + +BellaBuffs includes the optional features to email new members after submitting the join form, email the fanlisting admin when a new member joins or email new members when their applications were approved. The original BellaBuffs script achieved this by using PHP's built-in `mail()` feature. + +This fork replaces the PHP `mail()` functions from BellaBuffs with PHPMailer, allowing a fanlisting to send out emails with SMTP, provided the fanlisting owner chooses to enable them, even if the hosting server does not support the PHP `mail()` function. + +I created this BellaBuffs fork when I was building the [{% cite "Cassette Beasts" %} fanlisting](https://fan.leilukin.com/cassettebeasts) with BellaBuffs and hosting the fanlisting on [InfinityFree](https://www.infinityfree.com/). I learned that InfinityFree's free hosting plan [does not support PHP `mail()` function](https://forum.infinityfree.com/t/sending-email-from-your-website-php-mail/49242), so incorporating PHPMailer was the solution to allow the {% cite "Cassette Beasts" %} fanlisting to send emails. + +More information about my BellaBuffs fork and instructions for how to use it can be found on [its GitHub repository](https://github.com/helenclx/BellaBuffs-PHPMailer) and [its Gitea repository mirror](https://git.32bit.cafe/Leilukin/BellaBuffs-PHPMailer). + +## Features +* Integrate PHPMailer for the email sending features, should the fanlisting owner enables these features +* Email sending features are enabled by default, but can be disabled in `prefs.php` +* HTML5 form validation, including E-mail and URL input types and the `required` attribute +* Update list of countries +* Add a buttons folder (with a placeholder file to enable the folder to be pushed via Git), so users do not need to manually create the folder to store uploaded buttons +* Allows fnalisting members to change their favourites with the update form if favourites field is enabled \ No newline at end of file diff --git a/src/projects/code/code.11tydata.js b/src/projects/code/code.11tydata.js new file mode 100644 index 00000000..e6412235 --- /dev/null +++ b/src/projects/code/code.11tydata.js @@ -0,0 +1,3 @@ +export default { + tags: ["code projects"] +} \ No newline at end of file diff --git a/src/projects/playlists.md b/src/projects/playlists.md new file mode 100644 index 00000000..2bc025b1 --- /dev/null +++ b/src/projects/playlists.md @@ -0,0 +1,25 @@ +--- +title: My Music Playlists +desc: Music playlists that I have created. +toc: true +eleventyNavigation: + order: 3 +--- +## My Dear Summer Lover + +{% from "asummersend/myplaylist.njk" import myASEPlaylist %} +{{ myASEPlaylist("A fanmix for the visual novel") }} + +## Mandopop LGBTQ+ Anthem [華語流行音樂同志國歌]{lang="zh"} + +{% imgFigure "/assets/projects/playlists/Mandopop-LGBTQ+-Anthem-Cover.avif", "Cover of the Mandopop LGBTQ+ Anthem playlist" %} +[Image description: A progress pride flag, with the Traditional Chinese words, [同志國歌]{lang="zh"}, meaning queer anthem on top.] +{% endimgFigure %} + +A collection of Mandarin queer anthems. + +I made this playlist after discovering Wikipedia's list of Chinese queer anthems on the article [同志國歌](https://zh.wikipedia.org/wiki/%E5%90%8C%E5%BF%97%E5%9C%8B%E6%AD%8C#%E8%8F%AF%E8%AA%9E){lang="zh"}, the Mandarin article for Gay Anthem. + +Listen on Spotify + + diff --git a/src/projects/projects.11tydata.js b/src/projects/projects.11tydata.js new file mode 100644 index 00000000..cce29528 --- /dev/null +++ b/src/projects/projects.11tydata.js @@ -0,0 +1,11 @@ +export default { + tags: "project pages", + layout: "main/content.njk", + hasBreadcrumbs: true, + eleventyComputed: { + eleventyNavigation: { + key: (data) => data.title, + parent: "Projects" + } + } +} \ No newline at end of file diff --git a/src/projects/snippets/disability-pride-flag-background.md b/src/projects/snippets/disability-pride-flag-background.md new file mode 100644 index 00000000..061d0eff --- /dev/null +++ b/src/projects/snippets/disability-pride-flag-background.md @@ -0,0 +1,48 @@ +--- +title: Responsive Disability Pride flag CSS Background +desc: CSS code snippet of Disability Pride flag background that can adapt to different widths and screen sizes. +eleventyNavigation: + order: 5 +--- + +There have been CSS code snippets of LGBTQ+ pride flag backgrounds out there, such as [Alvaro Montoro's LGBTQ+ Flags Coded in CSS demo](https://codepen.io/alvaromontoro/full/NWyBrZJ), but I could not find one for the [Disability Pride flag](https://www.womansday.com/life/a43964487/disability-pride-flag/), which was created by [Ann Magill](https://capri0mni.dreamwidth.org/837596.html) and released in 2021. + +Therefore, at the start of [Disability Pride Month](https://en.wikipedia.org/wiki/Disability_Pride_Month) in July 2024, I decided to code a Disability Pride flag background in CSS, and now I am releasing my code snippet for public use. + +My Disability Pride flag CSS background is done with a combination of the CSS [`background` property](https://developer.mozilla.org/en-US/docs/Web/CSS/background) and [`linuear-gradient()` function](https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/linear-gradient), and designed to be responsive, so it can adapt to different screen sizes and devices. + +I have used JavaScript to set up the header of the main part of this website, so it will display the Disability Pride flag as its background during July. + +Since Ann Magill released the Disability Pride flag to the public domain under [CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/), I am doing the same to my responsive Disability Pride flag CSS background. Therefore, you are free to use my code and do what you want with it without asking for permission or crediting me. + +## Demo +{% set demoHeight = "23rem" %} +{%- css %} +.flag-disability.demo { height: {{ demoHeight }}; } +{% endcss %} + + + +## Code + +CSS: + +```css +.disability-pride-flag { +    background: + linear-gradient( + 37deg, + #595959 0 35%, + #CF7280 30% 41%, + #EEDE77 30% 47%, + #E8E8E8 30% 53%, + #7bc2e0 30% 59%, + #3BB07D 30% 65%, + #595959 0 + ); +} +``` + +After copying the above snippet in a CSS stylesheet or the HTML `