Meet the Team page (#94)
continuous-integration/drone/push Build is passing Details

Includes mobile Team Member Card

Closes #9
Closes #42

Co-authored-by: Bonnie <bonniepeng2002@gmail.com>
Reviewed-on: #94
Reviewed-by: Aditya Thakral <a3thakra@csclub.uwaterloo.ca>
Co-authored-by: b38peng <b38peng@uwaterloo.ca>
Co-committed-by: b38peng <b38peng@uwaterloo.ca>
This commit is contained in:
b38peng 2021-08-23 11:11:42 -04:00
parent d1e6c89a0b
commit a8cae99c11
72 changed files with 793 additions and 91 deletions

View File

@ -4,9 +4,7 @@
"eslint.codeActionsOnSave.mode": "all",
"[css]": {
"editor.suggest.insertMode": "replace",
"gitlens.codeLens.scopes": [
"document"
],
"gitlens.codeLens.scopes": ["document"],
"editor.formatOnSave": true
},
"[javascript]": {
@ -39,8 +37,9 @@
"node_modules": true
},
"editor.tabSize": 2,
"files.eol": "\n",
"[markdown]": {
"editor.wordWrap": "on",
"editor.quickSuggestions": false
}
}
}

View File

@ -6,7 +6,7 @@ import { DefaultLayout } from "./DefaultLayout";
import styles from "./Bubble.module.css";
export default function Bubble(props: { children: React.ReactNode }) {
export function Bubble(props: { children: React.ReactNode }) {
return (
<div className={styles.container}>
<div className={styles.bubble} aria-hidden>

View File

@ -9,6 +9,7 @@
width: 100%;
border-radius: 50%;
margin: 0 auto;
object-fit: cover;
}
.caption {
@ -25,3 +26,15 @@
font-weight: 600;
color: var(--primary-heading);
}
@media only screen and (max-width: calc(768rem / 16)) {
.img {
width: 100%;
}
.caption {
text-align: center;
font-size: calc(14rem / 16);
margin-top: 1rem;
}
}

View File

@ -7,7 +7,7 @@ import styles from "./TeamMember.module.css";
interface TeamMemberProps {
name: string;
role: string;
image?: string;
image: string;
}
export const TeamMember: React.FC<TeamMemberProps> = ({
@ -17,11 +17,7 @@ export const TeamMember: React.FC<TeamMemberProps> = ({
}) => {
return (
<div className={styles.container}>
<Image
className={styles.img}
src={image ?? "/images/team-member-placeholder.svg"}
alt={`Picture of ${name}`}
/>
<Image className={styles.img} src={image} alt={`Picture of ${name}`} />
<div className={styles.caption}>
<div className={styles.name}>{name}</div>
<div className={styles.role}>{role}</div>

View File

@ -38,6 +38,7 @@
grid-area: role;
margin: 0;
color: var(--primary-heading);
font-size: calc(24rem / 16);
line-height: calc(40 / 24);
font-weight: 600;
@ -51,39 +52,110 @@
margin-top: 0;
}
/* TODO: Use the correct mobile styles from figma
@media only screen and (max-width: calc(375rem / 16)) {
.card {
grid-template-columns: calc(70rem / 16) auto;
grid-template-rows: auto calc(calc(14rem / 16) * 1.5 + calc(12rem / 16)) auto;
grid-template-areas:
"picture name"
"picture role"
"description description";
column-gap: 1.4375rem;
align-items: end;
/* Popup */
max-width: calc(190rem / 16);
@keyframes popup {
0% {
transform: scale(0.4) translate(0, -50%);
}
100% {
transform: scale(1) translate(0, -50%);
}
}
@keyframes revealBg {
0% {
opacity: 0;
}
100% {
opacity: 100%;
}
}
.popupBackground {
position: fixed;
z-index: 11;
background-color: var(--navbar-page-overlay);
width: 100%;
height: 100%;
top: 0;
left: 0;
animation: revealBg 0.2s forwards;
}
.popupContainer {
position: fixed;
display: flex;
z-index: 12;
flex-direction: column;
background-color: var(--secondary-background);
padding: calc(20rem / 16) calc(40rem / 16);
left: 0;
top: 50%;
animation: popup 0.7s forwards;
}
.closeBtn {
align-self: flex-end;
/* reset default button styling */
width: min-content;
background: transparent;
border: 0px solid transparent;
padding: 0;
font-family: inherit;
line-height: inherit;
}
.popupContent {
display: flex;
flex-direction: column;
align-items: center;
}
.popupImage {
width: 100%;
}
.popupName {
color: var(--primary-accent);
margin: calc(24rem / 16) 0 0 0;
font-size: calc(18rem / 16);
font-weight: 600;
}
.popupRole {
color: var(--primary-heading);
margin: 0 0 1rem 0;
text-align: center;
font-size: calc(18rem / 16);
font-weight: 600;
}
.popupDescription {
font-size: calc(14rem / 16);
}
@media only screen and (max-width: calc(768rem / 16)) {
.card {
display: flex;
flex-direction: column;
align-items: center;
max-width: calc(135rem / 16);
margin: 0;
}
.picture {
max-width: calc(70rem / 16);
max-height: calc(70rem / 16);
.name {
margin-top: calc(24rem / 16);
font-weight: 700;
}
.name,
.role,
.description {
line-height: 1.5;
}
.role {
margin-bottom: calc(12rem / 16);
text-align: center;
font-size: calc(14rem / 16);
}
.description {
justify-self: top;
margin-top: calc(12rem / 16);
margin-left: calc(12rem / 16);
display: none;
}
} */
}

View File

@ -1,29 +1,98 @@
import React from "react";
import React, { useState } from "react";
import { useWindowDimension } from "@/hooks/useWindowDimension";
import { Image } from "./Image";
import styles from "./TeamMemberCard.module.css";
interface TeamMemberCardProps {
export interface TeamMemberCardProps {
name: string;
role: string;
image?: string; // path to image of person, relative to public directory
image: string;
children: React.ReactNode;
}
export function TeamMemberCard(props: TeamMemberCardProps) {
interface TeamMemberInfoProps extends TeamMemberCardProps {
isPopup?: boolean;
}
function TeamMemberInfo({
name,
role,
image,
children,
isPopup = false,
}: TeamMemberInfoProps) {
return (
<article className={styles.card}>
<>
<div className={styles.picture}>
<Image
className={styles.image}
src={props.image ?? "/images/team-member-placeholder.svg"}
alt={`Picture of ${props.name}`}
className={isPopup ? styles.popupImage : styles.image}
src={image}
alt={`Picture of ${name}`}
/>
</div>
<h1 className={styles.name}>{props.name}</h1>
<h2 className={styles.role}>{props.role}</h2>
<div className={styles.description}>{props.children}</div>
</article>
<h1 className={isPopup ? styles.popupName : styles.name}>{name}</h1>
<h2 className={isPopup ? styles.popupRole : styles.role}>{role}</h2>
<div className={isPopup ? styles.popupDescription : styles.description}>
{children}
</div>
</>
);
}
export function TeamMemberCard({
name,
role,
image,
children,
}: TeamMemberCardProps) {
const { width } = useWindowDimension();
const [isOpen, setIsOpen] = useState(false);
const handleClick = () => {
if (isOpen || width <= 768) {
setIsOpen(!isOpen);
}
};
return (
<>
<article className={styles.card} onClick={handleClick}>
<TeamMemberInfo {...{ name, role, image }}>{children}</TeamMemberInfo>
</article>
{isOpen && (
<ExecPopup
name={name}
role={role}
image={image}
handleClick={handleClick}
>
{children}
</ExecPopup>
)}
</>
);
}
interface Propup extends TeamMemberCardProps {
handleClick: () => void;
}
function ExecPopup({ name, role, image, children, handleClick }: Propup) {
return (
<>
<div className={styles.popupBackground} onClick={handleClick} />
<div className={styles.popupContainer}>
<button className={styles.closeBtn} onClick={handleClick}>
<Image src="images/team/popup-close.svg" />
</button>
<div className={styles.popupContent}>
<TeamMemberInfo {...{ name, role, image }} isPopup={true}>
{children}
</TeamMemberInfo>
</div>
</div>
</>
);
}

View File

@ -166,16 +166,16 @@ export function TeamMemberDemo() {
</div>
<hr />
<div className={styles.teamMembers}>
<TeamMember {...dogeMetadata} />
<TeamMember {...dogeMetadata} />
<TeamMember {...dogeMetadata} />
<TeamMember {...dogeMetadata} />
<TeamMember {...dogeMetadata} />
<TeamMember {...dogeMetadata} />
<TeamMember {...dogeMetadata} />
<TeamMember {...dogeMetadata} />
<TeamMember {...dogeMetadata} />
<TeamMember {...dogeMetadata} />
<TeamMember {...dogeMetadata} image="/images/playground/doge.jpg" />
<TeamMember {...dogeMetadata} image="/images/playground/doge.jpg" />
<TeamMember {...dogeMetadata} image="/images/playground/doge.jpg" />
<TeamMember {...dogeMetadata} image="/images/playground/doge.jpg" />
<TeamMember {...dogeMetadata} image="/images/playground/doge.jpg" />
<TeamMember {...dogeMetadata} image="/images/playground/doge.jpg" />
<TeamMember {...dogeMetadata} image="/images/playground/doge.jpg" />
<TeamMember {...dogeMetadata} image="/images/playground/doge.jpg" />
<TeamMember {...dogeMetadata} image="/images/playground/doge.jpg" />
<TeamMember {...dogeMetadata} image="/images/playground/doge.jpg" />
</div>
</div>
);
@ -184,7 +184,7 @@ export function TeamMemberDemo() {
export function TeamMemberCardDemo() {
return (
<div className={styles.teamMemberCardDemo}>
<TeamMemberCard {...codeyMetadata}>
<TeamMemberCard {...codeyMetadata} image="/images/playground/doge.jpg">
<CodeyInfo />
</TeamMemberCard>
</div>

View File

@ -1,4 +1,4 @@
import Bubble from "@/components/Bubble";
import { Bubble } from "@/components/Bubble";
<Bubble>
@ -17,13 +17,13 @@ growth.
## Our <span>Vision</span>
1. Academic: Promoting the knowledge and interest of Computer Science, as well
as supporting students throughout their academic experiences.
as supporting students throughout their academic experiences.
2. Career: Providing career guidance and resources to help students gain
experience and knowledge for their own job search.
experience and knowledge for their own job search.
3. Community: Encouraging interpersonal relationships through community building
and social events for all computing students.
and social events for all computing students.
</Bubble>
@ -64,9 +64,9 @@ The CS Club office is located at room **MC 3036/3037**, in the Math & Computer
Building of the University of Waterloo.
- An office favorite is our $0.50 pop for members. We have a fridge in the
office which is stocked with many different kinds of pop.
office which is stocked with many different kinds of pop.
- We have lots of informative books, 5 computer terminals, and an array of
knowledgeable people to talk to.
knowledgeable people to talk to.
Come visit us on campus in our office! Meet new members and find out what's new
in the club.
@ -77,7 +77,7 @@ Computer Science Club <br />
Math & Computer 3036/3037 <br />
University of Waterloo <br />
200 University Avenue West <br />
Waterloo, ON N2L 3G1 <br />
Waterloo, ON N2L 3G1 <br />
Canada
Our office phone number is [(519) 888-4567 x33870](tel:+15198884567,33870)
@ -85,5 +85,3 @@ Our office phone number is [(519) 888-4567 x33870](tel:+15198884567,33870)
</address>
</Bubble>

View File

@ -0,0 +1,6 @@
---
name: Kallen Tu
role: President
---
words words words codey words words words words codey words words words words codey words words words words codey words words words words codey words words words words words codey words words words words codey words words words words codey words words words words codey words words words

View File

@ -0,0 +1,6 @@
---
name: Gordon Le
role: Vice President
---
words words words codey words words words words codey words words words words codey words words words words codey words words words words codey words words words words words codey words words words words codey words words words words codey words words words words codey words words words

View File

@ -0,0 +1,6 @@
---
name: Nakul Vijhani
role: Assistant Vice President
---
words words words codey words words words words codey words words words words codey words words words words codey words words words words codey words words words words words codey words words words words codey words words words words codey words words words words codey words words words

View File

@ -0,0 +1,6 @@
---
name: Neil Parikh
role: Treasurer
---
words words words codey words words words words codey words words words words codey words words words words codey words words words words codey words words words words words codey words words words words codey words words words words codey words words words words codey words words words

View File

@ -0,0 +1,6 @@
---
name: Max Erenberg
role: Systems Administrator
---
words words words codey words words words words codey words words words words codey words words words words codey words words words words codey words words words words words codey words words words words codey words words words words codey words words words words codey words words words

View File

@ -0,0 +1,6 @@
---
name: Codey
role: Mascot
---
The one, the only, Codey! Codey is ecstatic to be your mascot for this term. Codey loves programming and playing on their laptop. You can often find Codey posing for event promo graphics, or chilling in the CSC discord.

View File

@ -0,0 +1,114 @@
[
{
"name": "Brendan Wong",
"role": "Designer"
},
{
"name": "Kailin Chan",
"role": "Designer"
},
{
"name": "Karen Lee",
"role": "Designer"
},
{
"name": "Sam Honoridez",
"role": "Designer"
},
{
"name": "Anna Wang",
"role": "Events"
},
{
"name": "Jason Sang",
"role": "Events"
},
{
"name": "Ravindu Angammana",
"role": "Events"
},
{
"name": "Shi Han",
"role": "Events"
},
{
"name": "Stephanie Xu",
"role": "Events"
},
{
"name": "Yanni Wang",
"role": "Events"
},
{
"name": "Anjing Li",
"role": "Marketing"
},
{
"name": "Patrick He",
"role": "Marketing"
},
{
"name": "Richa Dalal",
"role": "Marketing"
},
{
"name": "Sherry Lev",
"role": "Marketing"
},
{
"name": "Alex Zhang",
"role": "Discord Mod"
},
{
"name": "Andrew Wang",
"role": "Discord Mod"
},
{
"name": "Charles Zhang",
"role": "Discord Mod"
},
{
"name": "Edwin Yang",
"role": "Discord Mod"
},
{
"name": "Mark Chen",
"role": "Discord Mod"
},
{
"name": "Aaron Choo",
"role": "Representative"
},
{
"name": "Athena Liu",
"role": "Representative"
},
{
"name": "Betty Guo",
"role": "Representative"
},
{
"name": "Chris Xie",
"role": "Representative"
},
{
"name": "Dora Su",
"role": "Representative"
},
{
"name": "Eden Chan",
"role": "Representative"
},
{
"name": "Felix Yang",
"role": "Representative"
},
{
"name": "Guneet Bola",
"role": "Representative"
},
{
"name": "Juthika Hoque",
"role": "Representative"
}
]

View File

@ -0,0 +1,18 @@
[
{
"name": "Max Erenberg",
"role": "Admin"
},
{
"name": "Andrew Wang",
"role": "Member"
},
{
"name": "Bill Xiang",
"role": "Member"
},
{
"name": "Raymond Li",
"role": "Member"
}
]

View File

@ -0,0 +1,38 @@
[
{
"name": "Aditya Thakral",
"role": "Team Lead"
},
{
"name": "Neil Parikh",
"role": "Team Lead"
},
{
"name": "Amy Wang",
"role": "Developer"
},
{
"name": "Bonnie Peng",
"role": "Developer"
},
{
"name": "Catherine Wan",
"role": "Developer"
},
{
"name": "Dora Su",
"role": "Developer"
},
{
"name": "Jared He",
"role": "Developer"
},
{
"name": "Linna Luo",
"role": "Developer"
},
{
"name": "William Tran",
"role": "Developer"
}
]

View File

@ -0,0 +1,37 @@
import { useEffect, useState } from "react";
interface WindowDimension {
width: number;
height: number;
}
function getWindowDimension() {
const { innerWidth: width, innerHeight: height } = window;
return {
width,
height,
};
}
export function useWindowDimension(): WindowDimension {
const [windowSize, setWindowDimension] = useState<WindowDimension>({
width: 0,
height: 0,
});
useEffect(() => {
const handleResize = () => {
setWindowDimension(getWindowDimension());
};
// Set size at the first client-side load
handleResize();
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
return windowSize;
}

55
lib/team.ts Normal file
View File

@ -0,0 +1,55 @@
import { readFile, readdir, access } from "fs/promises";
import path from "path";
import matter from "gray-matter";
import { serialize } from "next-mdx-remote/serialize";
const EXECS_PATH = path.join("content", "meet-the-team", "execs");
const fileType = ".md";
export interface Metadata {
name: string;
role: string;
image: string;
}
export async function getExecNames() {
return (await readdir(EXECS_PATH))
.filter((name) => name.endsWith(fileType))
.map((name) => name.slice(0, -1 * fileType.length));
}
export async function getExec(fileName: string, convert = true) {
const raw = await readFile(path.join(EXECS_PATH, `${fileName}${fileType}`));
const { content, data: metadata } = matter(raw);
const image = await getMemberImagePath(metadata.name);
return {
content: convert ? await serialize(content) : content,
metadata: { ...metadata, image } as Metadata,
};
}
async function getImage(imgPath: string) {
try {
await access(path.join("public", imgPath));
return imgPath;
} catch {
return undefined;
}
}
export async function getMemberImagePath(name: string) {
const imgPath = path.join("images", "team", name.replace(" ", ""));
const placeholder = path.join(
"images",
"team",
"team-member-placeholder.svg"
);
const img =
(await getImage(imgPath + ".jpg")) ??
(await getImage(imgPath + ".png")) ??
(await getImage(imgPath + ".gif")) ??
placeholder;
return img;
}

View File

@ -10,8 +10,8 @@
"build": "next build",
"start": "next start",
"export": "next export",
"lint": "eslint \"{pages,components,lib}/**/*.{js,ts,tsx,jsx}\" --quiet",
"lint:fix": "eslint \"{pages,components,lib}/**/*.{js,ts,tsx,jsx}\" --quiet --fix"
"lint": "eslint \"{pages,components,lib,hooks}/**/*.{js,ts,tsx,jsx}\" --quiet",
"lint:fix": "eslint \"{pages,components,lib,hooks}/**/*.{js,ts,tsx,jsx}\" --quiet --fix"
},
"dependencies": {
"@mdx-js/loader": "^1.6.22",

View File

@ -1,3 +1,7 @@
html {
scroll-behavior: smooth;
}
body {
/* Default is light theme */
--primary-background: #ffffff;

View File

@ -24,6 +24,11 @@
border: none;
}
.header {
font-size: calc(24rem / 16);
margin: 0;
}
.codey {
width: calc(100rem / 16);
}

View File

@ -1 +0,0 @@
# Meet the Team page

105
pages/about/team.module.css Normal file
View File

@ -0,0 +1,105 @@
.headerContainer {
display: flex;
flex-direction: row;
padding-bottom: calc(24rem / 16);
border-bottom: calc(1rem / 16) solid var(--primary-heading);
margin-bottom: calc(46rem / 16);
}
.nav {
display: none;
}
.headerTextContainer {
margin: auto 0 0 0;
}
.header {
color: var(--primary-heading);
font-size: calc(48rem / 16);
margin: 0 calc(53rem / 16) 0 0;
}
.subheading {
color: var(--primary-heading);
font-size: calc(36rem / 16);
font-weight: 600;
padding-bottom: calc(22rem / 16);
border-bottom: calc(1rem / 16) solid var(--primary-heading);
margin-bottom: calc(46rem / 16);
margin-top: calc(86rem / 16);
}
.codey {
width: calc(360rem / 16);
}
.execs {
display: flex;
flex-direction: column;
gap: calc(26rem / 16);
margin-bottom: calc(86rem / 16);
}
.members {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(calc(100rem / 16), 1fr));
row-gap: calc(43rem / 16);
column-gap: calc(53rem / 16);
justify-items: center;
}
.elections {
margin: 6rem 0;
}
.electionSubheading {
color: var(--primary-accent);
font-size: calc(36rem / 16);
font-weight: 600;
margin-top: 0;
}
@media only screen and (max-width: calc(768rem / 16)) {
.headerContainer {
flex-direction: column-reverse;
padding-bottom: 1rem;
}
.nav {
margin-top: calc(24rem / 16);
margin-bottom: calc(46rem / 16);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.codey {
width: calc(140rem / 16);
align-self: center;
}
.header {
font-size: calc(24rem / 16);
margin: calc(10rem / 16) 0 0 0;
text-align: center;
}
.subheading {
font-size: calc(24rem / 16);
padding-bottom: calc(15rem / 16);
}
.execs,
.members {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(calc(130rem / 16), 1fr));
justify-items: center;
column-gap: 0;
}
.electionSubheading {
font-size: calc(24rem / 16);
}
}

139
pages/about/team.tsx Normal file
View File

@ -0,0 +1,139 @@
import { GetStaticProps } from "next";
import { MDXRemote, MDXRemoteSerializeResult } from "next-mdx-remote";
import React from "react";
import { Bubble } from "@/components/Bubble";
import { DefaultLayout } from "@/components/DefaultLayout";
import { Image } from "@/components/Image";
import { Link } from "@/components/Link";
import { TeamMember } from "@/components/TeamMember";
import { TeamMemberCard } from "@/components/TeamMemberCard";
import {
getExec,
getExecNames,
Metadata,
getMemberImagePath,
} from "@/lib/team";
import programmeData from "../../content/meet-the-team/programme-committee.json";
import systemsData from "../../content/meet-the-team/systems-committee.json";
import websiteData from "../../content/meet-the-team/website-committee.json";
import styles from "./team.module.css";
interface SerializedExec {
content: MDXRemoteSerializeResult;
metadata: Metadata;
}
interface Props {
execs: SerializedExec[];
programme: Metadata[];
website: Metadata[];
systems: Metadata[];
}
export default function Team({ execs, programme, website, systems }: Props) {
return (
<>
<DefaultLayout>
<div className={styles.headerContainer}>
<div className={styles.headerTextContainer}>
<h1 className={styles.header}>Meet the Team!</h1>
<div className={styles.nav}>
<Link href="#execs">The Executives</Link>
<Link href="#programme">Programme Committee</Link>
<Link href="#website">Website Committee</Link>
<Link href="#system">Systems Committee</Link>
</div>
<h2
className={styles.subheading}
style={{ borderBottom: "none", margin: 0, padding: 0 }}
>
The Executives
</h2>
</div>
<Image src="images/team/team-codey.svg" className={styles.codey} />
</div>
<div className={styles.execs} id="execs">
{execs.map((exec) => {
return (
<div key={exec.metadata.name}>
<TeamMemberCard {...exec.metadata}>
<MDXRemote {...exec.content} />
</TeamMemberCard>
</div>
);
})}
</div>
<div id="programme">
<h2 className={styles.subheading}>Programme Committee</h2>
<MembersList team={programme} />
</div>
<div id="website">
<h2 className={styles.subheading}>Website Committee</h2>
<MembersList team={website} />
</div>
<div id="system">
<h2 className={styles.subheading}>Systems Committee</h2>
<MembersList team={systems} />
</div>
</DefaultLayout>
<div className={styles.elections}>
<Bubble>
<h2 className={styles.electionSubheading}>Elections</h2>
To find out when and where the next elections will be held, keep an
eye on on the <Link href="/#news">News</Link>. <br />
For details on the elections, read our
<Link href="/about/constitution"> Constitution</Link>
</Bubble>
</div>
</>
);
}
Team.Layout = function TeamLayout(props: { children: React.ReactNode }) {
return <div>{props.children}</div>;
};
interface MembersProps {
team: Metadata[];
}
function MembersList(props: MembersProps) {
return (
<div className={styles.members}>
{props.team.map((member) => (
<TeamMember {...member} key={member.name} />
))}
</div>
);
}
async function getTeamWithImages(team: Omit<Metadata, "image">[]) {
return await Promise.all(
team.map(async (member) => {
const image = await getMemberImagePath(member.name);
return {
...member,
image,
};
})
);
}
export const getStaticProps: GetStaticProps<Props> = async () => {
const execNames = await getExecNames();
const execs = (await Promise.all(
execNames.map((name) => getExec(name))
)) as SerializedExec[];
const [programme, website, systems] = await Promise.all([
getTeamWithImages(programmeData),
getTeamWithImages(websiteData),
getTeamWithImages(systemsData),
]);
return {
props: { execs, programme, website, systems },
};
};

View File

@ -68,7 +68,7 @@ export default function Home() {
))}
</div>
</section>
<section className={styles.news}>
<section className={styles.news} id="news">
<h1 className={styles.cardsHeading}>News</h1>
<p className={styles.cardsDescription}>
Updates from our execs! <br />

View File

@ -1,3 +0,0 @@
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="512" height="512" fill="#5CAFF9" fill-opacity="0.2"/>
</svg>

Before

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 877 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 786 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 847 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 968 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1012 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 526 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 897 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 785 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 738 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

View File

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="2.57333" height="30.8317" rx="1.28666" transform="matrix(0.795101 -0.606477 0.710338 0.703861 0 1.83057)" fill="#C4C4C4"/>
<rect width="2.58854" height="30.6416" rx="1.29427" transform="matrix(-0.820223 -0.572044 0.67815 -0.734924 2.87207 24)" fill="#C4C4C4"/>
</svg>

After

Width:  |  Height:  |  Size: 377 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 44 KiB