diff --git a/src/components/Bandwidth/Bandwidth.js b/src/components/Bandwidth/Bandwidth.js
new file mode 100644
index 0000000..90759a8
--- /dev/null
+++ b/src/components/Bandwidth/Bandwidth.js
@@ -0,0 +1,317 @@
+'use client';
+
+import { useState } from 'react';
+import classNames from 'classnames';
+
+import styles from './Bandwidth.module.css';
+
+/**
+ * The Pretendo mascot: it speaks! For the non-speaking svg, see
+ *
+ * @param {array} lines - The lines for Bandwidth to speak
+ * @param {number} size - Sets the height of Bnadwidth. Defaults to 192.
+ * @param {number} alignBubble - Can be 'left', 'center', or 'right'. The margin to align the bubble to.
+ * @param {boolean} alwaysShowBubble - Always show the text. Defaults to false (only shows on click)
+ * @param {string} className - Classname to apply to the component.
+ * @param {string} style - Custom styles to apply to the component.
+ *
+ * @example
+ *
+ *
+ */
+
+export default function Bandwidth(ctx) {
+ const { lines = [], size = 192, alwaysShowBubble = false, alignBubble = 'center', className, style } = ctx;
+
+ const [lineIndex, setLineIndex] = useState(-1 + alwaysShowBubble);
+ const [jump, setJump] = useState(false || alwaysShowBubble);
+
+ const active = lineIndex > -1;
+
+ const updateLine = () => {
+ setJump(true);
+ if (lineIndex === lines.length - 1) {
+ setLineIndex(0);
+ } else {
+ setLineIndex(lineIndex + 1);
+ }
+ };
+
+ if (!Array.isArray(lines) || !lines.length) {
+ return ;
+ } else {
+ return (
+
+ {active && (
+
+ )}
+
setJump(false)}
+ />
+
+ );
+ }
+}
+
+/**
+ * The Pretendo mascot! If you're looking for the speaking version, it's
+ *
+ * @param {number} size - Sets the height of Bnadwidth. Defaults to 192.
+ * @param {string} className - Classname to apply to the component.
+ * @param {string} style - Custom styles to apply to the component.
+ *
+ * @example
+ *
+ *
+ */
+
+export const VanillaBandwidth = (ctx) => {
+ const { size = 192, className, style, onClick, onAnimationEnd } = ctx;
+ return (
+
+ );
+};
diff --git a/src/components/Bandwidth/Bandwidth.module.css b/src/components/Bandwidth/Bandwidth.module.css
new file mode 100644
index 0000000..684def4
--- /dev/null
+++ b/src/components/Bandwidth/Bandwidth.module.css
@@ -0,0 +1,71 @@
+.wrapper {
+ position: relative;
+ width: fit-content;
+}
+
+.bubble {
+ position: absolute;
+ display: block;
+ width: 90vw;
+ height: min-content;
+ max-width: 24rem;
+ top: -1rem;
+ transform: translateY(-100%);
+ padding: 1.25rem;
+ border-radius: 0.5rem;
+
+ background: var(--bg-shade-3);
+}
+
+.bubble.left {
+ left: 0;
+}
+.bubble.right {
+ right: 0;
+}
+.bubble.center {
+ left: 50%;
+ transform: translate(-50%, -100%);
+}
+
+.wrapper.active:after {
+ content: '';
+ position: absolute;
+ display: block;
+ width: 0;
+ border-style: solid;
+ border-color: var(--bg-shade-3) transparent;
+ border-width: 12px 12px 0;
+ top: -1rem;
+ left: 50%;
+ transform: translateX(12px);
+}
+
+.bubble p {
+ margin: 0 !important;
+}
+
+.bandwidth {
+ cursor: pointer;
+ transform: rotate(0);
+ transition: transform 250ms ease-in-out;
+}
+
+.active .bandwidth {
+ transform: rotate(15deg);
+}
+
+.active .bandwidth.jump {
+ animation: jump 250ms ease-in-out;
+}
+@keyframes jump {
+ 0% {
+ transform: translateY(0) rotate(15deg);
+ }
+ 50% {
+ transform: translateY(-12px) rotate(15deg);
+ }
+ 100% {
+ transform: translateY(0) rotate(15deg);
+ }
+}
diff --git a/src/components/Footer/Footer.js b/src/components/Footer/Footer.js
index 69df453..a3eae4b 100644
--- a/src/components/Footer/Footer.js
+++ b/src/components/Footer/Footer.js
@@ -1,3 +1,4 @@
+import Bandwidth from '@/components/Bandwidth/Bandwidth';
import Logo from '@/components/Logo/Logo';
import Section from '@/components/Section/Section';
import Title from '@/components/Title/Title';
@@ -11,7 +12,7 @@ import Link from 'next/link';
import styles from './Footer.module.css';
export default function Footer(ctx) {
- const { locale } = getLocale('todo');
+ const { locale } = getLocale('TODO');
const year = new Date().getFullYear(); /* Can't have an outdated year this way :3 */
@@ -23,7 +24,7 @@ export default function Footer(ctx) {
Copyright ©{' '}
-
+
{year}
@@ -117,6 +118,12 @@ export default function Footer(ctx) {
+
{locale.footer.widget.captions[0]}
diff --git a/src/components/Footer/Footer.module.css b/src/components/Footer/Footer.module.css
index 40db10e..cdadf10 100644
--- a/src/components/Footer/Footer.module.css
+++ b/src/components/Footer/Footer.module.css
@@ -39,6 +39,10 @@
width: fit-content;
}
+.footer p:last-child {
+ margin-bottom: 0;
+}
+
.footer .link {
color: unset;
font-weight: unset;
@@ -73,10 +77,23 @@
.footer .discordWidget .link .arrow {
position: relative;
- top: 0.25rem;
+ top: 0.27rem;
margin-right: 0.5ch;
}
+.discordWidgetWrapper {
+ position: relative;
+ z-index: 2;
+ align-self: end;
+}
+
+.discordWidgetWrapper .bandwidth {
+ position: absolute;
+ right: 0;
+ top: -136px;
+ z-index: -1;
+}
+
@media screen and (max-width: 1080px) {
.footer {
flex-flow: column;
@@ -104,6 +121,7 @@
.footer .discordWidgetWrapper {
margin-top: 1rem;
+ width: 100%;
}
}
@@ -135,3 +153,9 @@
font-size: 1.1rem;
}
}
+
+@media screen and (max-width: 300px) {
+ .discordWidgetWrapper .bandwidth {
+ display: none;
+ }
+}