diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..a9723a97 Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore index bf26fa25..4314f5d9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .vscode dom-html.txt .scannerwork +**/.DS_Store + diff --git a/uli-website/.DS_Store b/uli-website/.DS_Store new file mode 100644 index 00000000..6c25ffc4 Binary files /dev/null and b/uli-website/.DS_Store differ diff --git a/uli-website/package-lock.json b/uli-website/package-lock.json index ab6d78d8..c49dc69e 100644 --- a/uli-website/package-lock.json +++ b/uli-website/package-lock.json @@ -8,6 +8,7 @@ "name": "uli", "version": "1.0.0", "dependencies": { + "@chenglou/pretext": "^0.0.4", "@mdx-js/react": "3.0.0", "babel-plugin-styled-components": "2.1.4", "gatsby": "5.12.9", @@ -2151,6 +2152,11 @@ "partytown": "bin/partytown.cjs" } }, + "node_modules/@chenglou/pretext": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@chenglou/pretext/-/pretext-0.0.4.tgz", + "integrity": "sha512-FnPAFMid1/p1j2V2gRPUVBarGUIb2PhkkC9YNnTOfPtTDgHKh8siO8PP9pCxpFfYlcodWPJpE1UbSHGQqt8pQQ==" + }, "node_modules/@emotion/is-prop-valid": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", diff --git a/uli-website/package.json b/uli-website/package.json index 0a50fc6b..1280514c 100644 --- a/uli-website/package.json +++ b/uli-website/package.json @@ -16,6 +16,7 @@ "deploy": "gatsby-plugin-s3 deploy --yes" }, "dependencies": { + "@chenglou/pretext": "^0.0.4", "@mdx-js/react": "3.0.0", "babel-plugin-styled-components": "2.1.4", "gatsby": "5.12.9", diff --git a/uli-website/src/components/atoms/DashedButton.jsx b/uli-website/src/components/atoms/DashedButton.jsx new file mode 100644 index 00000000..fe0e8523 --- /dev/null +++ b/uli-website/src/components/atoms/DashedButton.jsx @@ -0,0 +1,12 @@ +import React from "react"; + +export default function DashedButton({content, onClick, className=""}) { + return ( + + ); +} diff --git a/uli-website/src/components/atoms/NavLinkNew.jsx b/uli-website/src/components/atoms/NavLinkNew.jsx new file mode 100644 index 00000000..e8bf607a --- /dev/null +++ b/uli-website/src/components/atoms/NavLinkNew.jsx @@ -0,0 +1,21 @@ +import { Link } from 'gatsby'; +import { Text } from 'grommet' +import styled from "styled-components"; +import React from 'react' + +// // Navlink component for the new design +// export default function NavLink({children, className=""}) { +// return ( +// {children} + +// ) +// } + +export const NavLinkNew = styled(Link)` + text-decoration: none; + color: inherit; + &:hover { + color: #F28948; + text-decoration: underline; + } +`; diff --git a/uli-website/src/components/molecules/AnnouncementBanner.jsx b/uli-website/src/components/molecules/AnnouncementBanner.jsx deleted file mode 100644 index dc5cfc24..00000000 --- a/uli-website/src/components/molecules/AnnouncementBanner.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import { Box, Text } from "grommet"; -import React, { useState, useEffect, useContext } from "react"; - - -export default function AnnouncementBanner({ children }) { - return ( - - {children} - - - ); -} diff --git a/uli-website/src/components/molecules/Announcements.jsx b/uli-website/src/components/molecules/Announcements.jsx new file mode 100644 index 00000000..149e6c51 --- /dev/null +++ b/uli-website/src/components/molecules/Announcements.jsx @@ -0,0 +1,44 @@ +import { Box, Text } from "grommet"; +import React, { useState, useEffect, useContext } from "react"; +import DashedButton from "../atoms/DashedButton"; +import { navigate } from "gatsby"; + +function AnnouncementBanner({ children }) { + return ( + + {children} + + ); +} + +export default function Announcements() { + return ( + + + Uli joins UNICEF FemTech Cohort + + Our solution that monitors users’ social media feeds, identifies abuse and connects users to support networks has got selected to be developed further by the UNICEF FemTech Ventures. + + Read the announcement} + onClick={() => navigate("https://www.unicef.org/innovation/femtech-cohort-1")} + /> + + + ); +} diff --git a/uli-website/src/components/molecules/AppShellNew.jsx b/uli-website/src/components/molecules/AppShellNew.jsx new file mode 100644 index 00000000..b5b7504d --- /dev/null +++ b/uli-website/src/components/molecules/AppShellNew.jsx @@ -0,0 +1,67 @@ +import { Grommet, Box } from "grommet"; +import * as React from "react"; +import { Helmet } from "react-helmet"; +import { Colors, NavLink, Theme } from "../atoms/UliCore"; +import NavBarNew from "./NavBarNew"; +import i18n from "../atoms/i18n"; +import { useTranslation } from "react-i18next"; +import { useLocation } from "@reach/router"; +import FooterNew from "./FooterNew"; + +export default function AppShellNew({ children }) { + const { t, i18n } = useTranslation(); + React.useEffect(() => { + const lang = localStorage.getItem("uli-lang"); + i18n.changeLanguage(lang); + }, []); + const location = useLocation(); + + let fullPath = location.pathname; + if (fullPath.slice(-1) === "/") { + fullPath = fullPath.slice(0, -1); + } + let title = fullPath.split("/").at(-1); + + if (["hi", "en", "ta", "ma"].includes(title)) { + title = "Uli"; + } + + title = formatTitle(title); + + function formatTitle(str) { + return str + .split("-") + .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) + .join(" "); + } + return ( + +
+ + + Uli + + + + + + + + + + {children} + +
+
+ ); +} diff --git a/uli-website/src/components/molecules/ContentPageShell.jsx b/uli-website/src/components/molecules/ContentPageShell.jsx index bad0c814..7a2af7a7 100644 --- a/uli-website/src/components/molecules/ContentPageShell.jsx +++ b/uli-website/src/components/molecules/ContentPageShell.jsx @@ -5,52 +5,385 @@ import { MDXProvider } from "@mdx-js/react"; import styled from "styled-components"; import CustomCodeBlock from "./codeSnippet"; -// const HeadingOne = styled(Text)` -// font-size: 2em; -// line-height: 1em; -// `; +/** + * ===================================================================== + * Figma Design Tokens (node 388-265) — sizes reduced 20% from original + * ===================================================================== + * + * Page Title: Labrada SemiBold 51px (was 64), line-height 110%, tracking -0.05em + * Date: Labrada Regular 16px (was 20), line-height 120% + * Author: Labrada Bold 16px (was 20), line-height 120% + * + * h2 Section: Labrada ExtraBold 38px (was 48), line-height 150% + * h3 SubSec: Labrada SemiBold 32px (was 40), line-height 150% + * h4: IBM Plex Sans Bold 19px (was 24), line-height 160% + * h5: IBM Plex Sans Reg 19px (was 24), line-height 160% + * + * Body (p): IBM Plex Sans Reg 16px (was 20), line-height 175% + * Blockquote: Labrada Regular 19px (was 24), line-height 134% + * Link: IBM Plex Sans SB 16px (was 20), underline + * List Item: IBM Plex Sans 16px (was 20), line-height 175% + * Code: IBM Plex Mono Reg 16px (was 20), line-height 134% + * + * Header BG: #2d2d2d + * Header text: #fdf6ed (cream) + * Page BG: #fdf6ed + * Text: #212121 + * Accent: #de8821 + * Header pad: 80px top/bottom, 160px left/right + * Section gap: 80px + * ===================================================================== + */ -// const HeadingTwo = styled(Text)` -// font-size: 1.6em; -// `; +// ── Google Fonts ─────────────────────────────────────────────────────── -// const HeadingThree = styled(Text)` -// font-size: 1.2em; -// `; +const FontLink = () => ( + +); + +// ── Blog Header (dark background) ───────────────────────────────────── + +const HeaderWrapper = styled.div` + width: 100%; + background-color: #FFE7D9; + padding: 64px 24px; + display: flex; + flex-direction: column; + align-items: center; + margin-bottom: 48px; + box-sizing: border-box; + + @media (min-width: 768px) { + padding: 80px 160px; + } +`; + +const PageTitle = styled.h1` + font-family: "Labrada", serif; + font-weight: 600; + font-size: 38px; + line-height: 110%; + letter-spacing: -0.05em; + text-align: center; + color: #212121; + margin: 0 0 12px 0; + max-width: 800px; + + @media (min-width: 768px) { + font-size: 51px; + } +`; + +const MetaDate = styled.p` + font-family: "Labrada", serif; + font-weight: 400; + font-size: 16px; + line-height: 120%; + text-align: center; + color: #212121; + margin: 0; +`; + +const MetaAuthor = styled.p` + font-family: "Labrada", serif; + font-weight: 700; + font-size: 16px; + line-height: 120%; + text-align: center; + color: #212121; + margin: 4px 0 0 0; +`; + +// ── Simple title header (cream bg, no metadata) ─────────────────────── + +const SimpleTitleWrapper = styled.div` + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + margin-bottom: 32px; + padding-top: 16px; +`; + +const SimpleTitleText = styled.h1` + font-family: "Labrada", serif; + font-weight: 400; + font-size: 32px; + line-height: 105%; + text-align: center; + color: #212121; + margin: 0 0 16px 0; + + @media (min-width: 768px) { + font-size: 51px; + } +`; + +const DecorativeBorder = styled.div` + width: 100%; + border-bottom: 16px solid transparent; + border-image-source: url("/ResourceBorder.png"); + border-image-slice: 33%; + border-image-repeat: round; +`; + +// ── Heading components ───────────────────────────────────────────────── + +const SectionOpening = styled.h2` + font-family: "Labrada", serif; + font-weight: 800; + font-size: 24px; + line-height: 100%; + color: #212121; + margin: 48px 0 12px 0; + + @media (min-width: 768px) { + font-size: 38px; + } +`; + +const SubSectionOpening = styled.h3` + font-family: "Labrada", serif; + font-weight: 600; + font-size: 22px; + line-height: 150%; + color: #212121; + margin: 40px 0 10px 0; + + @media (min-width: 768px) { + font-size: 32px; + } +`; + +const SubSubSection = styled.h4` + font-family: "IBM Plex Sans", sans-serif; + font-weight: 700; + font-size: 16px; + line-height: 160%; + color: #212121; + margin: 32px 0 8px 0; + + @media (min-width: 768px) { + font-size: 19px; + } +`; + +const SubSubSubSection = styled.h5` + font-family: "IBM Plex Sans", sans-serif; + font-weight: 400; + font-size: 16px; + line-height: 160%; + color: #212121; + margin: 28px 0 8px 0; + + @media (min-width: 768px) { + font-size: 19px; + } +`; + +// ── Body components ──────────────────────────────────────────────────── + +const BodyText = styled.p` + font-family: "IBM Plex Sans", sans-serif; + font-weight: 400; + font-size: 14px; + line-height: 175%; + color: #212121; + margin: 0 0 16px 0; + word-break: break-word; + + @media (min-width: 768px) { + font-size: 16px; + } +`; + +const StyledLink = styled.a` + font-family: "IBM Plex Sans", sans-serif; + font-weight: 600; + font-size: inherit; + color: #de8821; + text-decoration: underline; + text-underline-offset: 2px; + word-break: break-all; + transition: color 0.15s ease; + + &:hover { + color: #212121; + } + &:visited { + color: #de8821; + } +`; + +const BlockquoteStyled = styled.blockquote` + font-family: "Labrada", serif; + font-weight: 400; + font-size: 16px; + line-height: 134%; + color: #212121; + margin: 24px 0; + padding-left: 20px; + border-left: 4px solid #de8821; + font-style: italic; + + @media (min-width: 768px) { + font-size: 19px; + } +`; + +const UnorderedList = styled.ul` + font-family: "IBM Plex Sans", sans-serif; + font-size: 14px; + line-height: 175%; + color: #212121; + margin: 0 0 16px 0; + padding-left: 24px; + list-style-type: disc; + + @media (min-width: 768px) { + font-size: 16px; + } +`; + +const OrderedList = styled.ol` + font-family: "IBM Plex Sans", sans-serif; + font-size: 14px; + line-height: 175%; + color: #212121; + margin: 0 0 16px 0; + padding-left: 24px; + list-style-type: decimal; + + @media (min-width: 768px) { + font-size: 16px; + } +`; + +const ListItem = styled.li` + font-family: "IBM Plex Sans", sans-serif; + font-weight: 400; + margin-bottom: 6px; + word-break: break-word; +`; + +const HorizontalRule = styled.hr` + border: none; + border-top: 2px solid #de8821; + margin: 40px 0; +`; + +const CodeBlock = styled.pre` + font-family: "IBM Plex Mono", monospace; + font-weight: 400; + font-size: 14px; + line-height: 134%; + background: #2d2d2d; + color: #f5f5f5; + padding: 20px; + border-radius: 6px; + overflow-x: auto; + margin: 16px 0; + + @media (min-width: 768px) { + font-size: 16px; + } +`; + +const InlineCode = styled.code` + font-family: "IBM Plex Mono", monospace; + font-size: 0.875em; + background: rgba(0, 0, 0, 0.06); + padding: 2px 6px; + border-radius: 3px; +`; + +const StrongText = styled.strong` + font-weight: 700; +`; + +const EmText = styled.em` + font-style: italic; +`; + +// ── MDX component map ────────────────────────────────────────────────── + +const mdxComponents = { + h1: (props) => , + h2: (props) => , + h3: (props) => , + h4: (props) => , + h5: (props) => , + p: (props) => , + a: (props) => ( + + ), + blockquote: (props) => , + ul: (props) => , + ol: (props) => , + li: (props) => , + hr: (props) => , + pre: (props) => , + code: (props) => { + if (props.className) { + return ; + } + return ; + }, + strong: (props) => , + em: (props) => , +}; + +// ── Date formatter ───────────────────────────────────────────────────── + +function formatDate(input) { + if (!input) return ""; + const d = new Date(input); + if (isNaN(d.getTime())) return String(input); + return d.toLocaleDateString("en-GB", { + day: "numeric", + month: "long", + year: "numeric", + }); +} + +// ── Main component ───────────────────────────────────────────────────── + +const ContentPageShell = (props) => { + const { children } = props; + const frontmatter = props.pageContext?.frontmatter || {}; + const { name, author, date, title } = frontmatter; + + const hasMetadata = !!(author || date); + const displayTitle = name || title; -const ContentPageShell = ({ children }) => { return ( - -

, - h2: (props)=>

, - // h3: HeadingThree, - p: (props) => , - li: (props) => ( -
  • - -
  • - ), - a: (props) => ( - - ), - code: (props) => , - }} - > - - {children} + + + + {/* ── Blog header with dark background ── */} + {hasMetadata && ( + + {displayTitle && {displayTitle}} + {date && {formatDate(date)}} + {author && {author}} + + )} + + {/* ── Simple title (no metadata) ── */} + {!hasMetadata && displayTitle && ( + + {displayTitle} + + + )} + + + {children} + diff --git a/uli-website/src/components/molecules/EmailSubscription_Archive.jsx b/uli-website/src/components/molecules/EmailSubscription_Archive.jsx new file mode 100644 index 00000000..89d0e4f4 --- /dev/null +++ b/uli-website/src/components/molecules/EmailSubscription_Archive.jsx @@ -0,0 +1,45 @@ +import React, { useState, useEffect, useContext } from "react"; +import { Box, Nav, Text, ResponsiveContext } from "grommet"; +import { NavLink } from "../atoms/UliCore"; +import { navigate } from "gatsby"; +import { useScrollReveal } from "../../hooks/useScrollReveal"; + +export default function EmailSubscription() { + // const size = useContext(ResponsiveContext); + const revealRef = useScrollReveal({ threshold: 0.1 }); + + return ( + + Stay Updated + + An endeavour to build safer online spaces in India by collectivizing women and gender minorities for creating representative data and tools for detection of online abuse, and supporting each other in times of need. + +
    +
    + + + +
    +
    +
    + ); +} diff --git a/uli-website/src/components/molecules/FooterNew.jsx b/uli-website/src/components/molecules/FooterNew.jsx new file mode 100644 index 00000000..ab92f6d3 --- /dev/null +++ b/uli-website/src/components/molecules/FooterNew.jsx @@ -0,0 +1,25 @@ +import React, { useState, useEffect, useContext } from "react"; +import { Box, Nav, Text, ResponsiveContext } from "grommet"; +import { NavLink } from "../atoms/UliCore"; +import { Link, navigate } from "gatsby"; + +export default function FooterNew() { + // const size = useContext(ResponsiveContext); + + return ( + + + {/* + Uli by Tattle + Email & Other contacts + + + + Github + + Link 2 + Link 3 + */} + + ); +} diff --git a/uli-website/src/components/molecules/NavBarNew.jsx b/uli-website/src/components/molecules/NavBarNew.jsx new file mode 100644 index 00000000..8345c680 --- /dev/null +++ b/uli-website/src/components/molecules/NavBarNew.jsx @@ -0,0 +1,88 @@ +import React, { useContext, useEffect, useState, useRef } from "react"; +import { Box, ResponsiveContext, Text } from "grommet"; +import { NavLink } from "../atoms/UliCore"; +import { navigate } from "gatsby"; +import { NavLinkNew } from "../atoms/NavLinkNew"; + +export default function NavBarNew() { + const [open, setOpen] = useState(false); + const size = useContext(ResponsiveContext); + const borderRef = useRef(null); + + // Scroll-driven border animation: shifts background-position-x as user scrolls + useEffect(() => { + let rafId; + const handleScroll = () => { + rafId = requestAnimationFrame(() => { + if (borderRef.current) { + const scrollY = window.scrollY || window.pageYOffset; + // Slow drift: 0.3x scroll speed + borderRef.current.style.backgroundPositionX = `${scrollY * 0.3}px`; + } + }); + }; + window.addEventListener("scroll", handleScroll, { passive: true }); + return () => { + window.removeEventListener("scroll", handleScroll); + cancelAnimationFrame(rafId); + }; + }, []); + + return ( + + + + + Tattle + + + + + Uli Logo navigate("/")} + /> + + + + + + {/* + Contact + */} + + About us + + + Blog + + + + + + + + About us + + + Blog + + + + + + + ); +} diff --git a/uli-website/src/components/molecules/Projects.jsx b/uli-website/src/components/molecules/Projects.jsx new file mode 100644 index 00000000..3d9e6697 --- /dev/null +++ b/uli-website/src/components/molecules/Projects.jsx @@ -0,0 +1,135 @@ +import { Box, Text } from "grommet"; +import { navigate } from "gatsby"; +import { + SectionBorderTop, + SectionBorderBottom, + SectionBorderSides, +} from "./SectionBorders"; +import React from "react"; +import DashedButton from "../atoms/DashedButton"; +import { useScrollReveal } from "../../hooks/useScrollReveal"; + +const projectsConfig = [ + { + title: "Datasets", + icon: "/track_icons/Database.png", + content: + "Through participatory workshops, we create datasets on abuse in Indian languages. The flagship dataset is a dataset on online misogyny. We also maintain a dataset on slurs and abusive phrases in Indian languages.", + buttons: [ + { + content: "View Dataset Snapshot", + url: "https://github.com/tattle-made/Uli/blob/main/browser-extension/plugin/scripts/slur-list.txt", + } + ], + }, + { + title: "Workshops", + icon: "/track_icons/Workshops.png", + content: + "A pedagogical track to engage with young people upwards of 14 years in interactive sessions discussing forms of OGBV with a special focus on language-based abuse rampant on social media.", + buttons: [ + { + content: "Read workshop reflection", + url: "https://tattle.co.in/blog/uli-coimbatore-workshop-retrospective/", + }, + ], + }, + { + title: "User-Facing Tools", + icon: "/track_icons/Tools.png", + content: + "Tattle builds tools to reduce the toxicity from people’s social media feeds to provide timely response. In 2022 we built a browser plugin. With support from UNICEF’s Femtech Venture Fund, we will build a tool to monitor users’ social media feeds to identify abuse and connect them to support networks.", + buttons: [ + { + content: "Browser Extension", + url: "/", + }, + // { + // content: "install", + // url: "/#", + // }, + ], + }, +]; + +export default function Projects() { + return ( + + + + + {/* CONTENT */} + + {projectsConfig.map((project, idx) => { + return ( + + ); + })} + + + ); +} + +function ProjectCard({ title, icon, content, buttons, order = 0 }) { + const revealRef = useScrollReveal({ threshold: 0.1 }); + return ( + + + {title} + {content} +
    + {buttons.map((btn, idx) => { + return ( + navigate(btn.url)} + /> + ); + })} +
    +
    + + + {title} + +
    + ); +} diff --git a/uli-website/src/components/molecules/RecentBlogs.jsx b/uli-website/src/components/molecules/RecentBlogs.jsx new file mode 100644 index 00000000..9dd6a2f0 --- /dev/null +++ b/uli-website/src/components/molecules/RecentBlogs.jsx @@ -0,0 +1,117 @@ +import { Box, Text } from "grommet"; +import React from "react"; +import { SectionBorderSides, SectionBorderTop } from "./SectionBorders"; +import { graphql, useStaticQuery, navigate } from "gatsby"; +import { useStaggerReveal } from "../../hooks/useScrollReveal"; + +function formatDate(input) { + if (!input) return ""; + + const timestamp = Number(input); + const date = new Date(timestamp); + + if (isNaN(date.getTime())) return "Invalid date"; + + return date.toLocaleDateString("en-GB", { + day: "2-digit", + month: "short", + year: "numeric", + timeZone: "Asia/Kolkata", + }); +} + +/** + * Formats the author string to show abbreviated form (e.g., "John Doe et al."). + * + * @param {string} author - Full author name string, usually comma-separated. + * @returns {string} Abbreviated author string. + */ + +function formatAuthor(author) { + if (typeof author !== "string") return ""; + let firstDividerIndex = -1; + let dividers = ["&", "and", "And", ","]; + for (let d of dividers) { + let i = author.indexOf(d); + + if (firstDividerIndex === -1) { + firstDividerIndex = Math.max(firstDividerIndex, i); + } else { + firstDividerIndex = Math.max(firstDividerIndex, i); + } + } + if (firstDividerIndex === -1) return author; + + author = author.substring(0, firstDividerIndex).trim().concat(" et al."); + + return author; +} + +export default function RecentBlogs() { + const data = useStaticQuery(graphql` + { + latestBlogs: allMdx( + limit: 5 + sort: { frontmatter: { date: DESC } } + filter: { + internal: { contentFilePath: { regex: "/.*/src/pages/blog/" } } + } + ) { + nodes { + fields { + slug + } + frontmatter { + name + excerpt + author + project + date + } + internal { + contentFilePath + } + } + } + } + `); + console.log(data); + const staggerRef = useStaggerReveal({ threshold: 0.05 }); + + return ( + + + + + + {data.latestBlogs.nodes.map((blog, idx) => { + return ( + navigate(blog.fields.slug)} + > + + {formatDate(blog.frontmatter.date)} + + + navigate(blog.fields.slug)} className="font-semibold lg:font-semibold text-[14px] lg:text-[16px]"> + {blog.frontmatter.name} + + + + {formatAuthor(blog.frontmatter.author)} + + + ); + })} + + + + ); +} diff --git a/uli-website/src/components/molecules/Resources.jsx b/uli-website/src/components/molecules/Resources.jsx new file mode 100644 index 00000000..b7262943 --- /dev/null +++ b/uli-website/src/components/molecules/Resources.jsx @@ -0,0 +1,136 @@ +import { Box, Text } from "grommet"; +import React from "react"; +import { + SectionBorderSides, + SectionBorderSidesBottom, + SectionBorderTop, +} from "./SectionBorders"; +import { graphql, useStaticQuery, navigate } from "gatsby"; +import { useScrollReveal } from "../../hooks/useScrollReveal"; + +const resourcesConfig = [ + { + category: "For Platforms", + resources: [ + { + type: "Report", + name: "Make It Real - Mapping AI-Facilitated", + url: "/#", + }, + { + type: "Report", + name: "Make It Real - Mapping AI-Facilitated", + url: "/#", + }, + { + type: "Report", + name: "Make It Real - Mapping AI-Facilitated", + url: "/#", + }, + { + type: "Report", + name: "Make It Real - Mapping AI-Facilitated", + url: "/#", + }, + ], + }, + { + category: "For Educators", + resources: [ + { + type: "Report", + name: "Make It Real - Mapping AI-Facilitated", + url: "/#", + }, + { + type: "Report", + name: "Make It Real - Mapping AI-Facilitated", + url: "/#", + }, + { + type: "Report", + name: "Make It Real - Mapping AI-Facilitated", + url: "/#", + }, + { + type: "Report", + name: "Make It Real - Mapping AI-Facilitated", + url: "/#", + }, + ], + }, + { + category: "For Technologists", + resources: [ + { + type: "Report", + name: "Make It Real - Mapping AI-Facilitated", + url: "/#", + }, + { + type: "Report", + name: "Make It Real - Mapping AI-Facilitated", + url: "/#", + }, + { + type: "Report", + name: "Make It Real - Mapping AI-Facilitated", + url: "/#", + }, + { + type: "Report", + name: "Make It Real - Mapping AI-Facilitated", + url: "/#", + }, + ], + }, +]; + +export default function Resources() { + return ( + + + + + + {resourcesConfig.map((resource, idx) => { + return ( + + + {resource.category} + + + {resource.resources.map((r, id) => { + return ( + navigate(r.url)} + > + {r.type} + navigate(r.url)} + > + {r.name} + + + ); + })} + + + ); + })} + + + + ); +} diff --git a/uli-website/src/components/molecules/SectionBorders.jsx b/uli-website/src/components/molecules/SectionBorders.jsx new file mode 100644 index 00000000..b4b0d0b7 --- /dev/null +++ b/uli-website/src/components/molecules/SectionBorders.jsx @@ -0,0 +1,132 @@ +import { Box, Text } from "grommet"; +import React from "react"; + +export function SectionBorderTop({ title }) { + return ( + /* TOP BORDER WITH TEXT */ + + + + {title} + + + + ); +} + +export function SectionBorderSidesBottom() { + return ( + <> + {/* LEFT BORDER */} + + {/* RIGHT BORDER */} + + {/* Bottom BORDER */} + + + ); +} + +export function SectionBorderSides() { + return ( + <> + {/* LEFT BORDER */} + + + {/* RIGHT BORDER */} + + + ); +} diff --git a/uli-website/src/components/molecules/SupportUs.jsx b/uli-website/src/components/molecules/SupportUs.jsx new file mode 100644 index 00000000..351e7b4e --- /dev/null +++ b/uli-website/src/components/molecules/SupportUs.jsx @@ -0,0 +1,215 @@ +import React, { useState } from "react"; +import { Box, Text } from "grommet"; +import { useScrollReveal } from "../../hooks/useScrollReveal"; +import { navigate } from "gatsby"; + +const MaskIcon = ({ url, color, size = 34, className }) => ( +
    +); + +const items = [ + { + title: "Contribute to the Dataset", + description: "You can contribute to the dataset as an individual through the Uli Community Page. You can also conduct a crowdsourcing workshop with your language/regional community. Please reach out to poorvi@tattle.co.in", + buttonText: "", + iconUrl: "/support_icons/database.svg" + }, + { + title: "Host a workshop on OGBV", + description: "If you would like us to conduct a workshop with your students or your organization on OGBV or online safety, please email poorvi@tattle.co.in", + buttonText: "Email Us", + iconUrl: "/support_icons/workshop.svg" + }, + { + title: "Sponsor a track", + description: "We are looking for funders who can help grow the three tracks: datasets, workshops and abuse response. Each track has a different roadmap. If you are a funder working on online safety, please reach out to admin@tattle.co.in", + buttonText: "", + iconUrl: "/support_icons/support.svg" + }, + { + title: "Sponsor us on Github", + description: "If you are an individual who wants to support the overall project, consider becoming a GitHub sponsor. The GitHub sponsor's money is pooled and may be used for any of the three tracks. All sponsors will be added to the Uli mailing list for periodic updates on the project.", + buttonText: "Github Sponsors", + iconUrl: "/support_icons/github.svg", + url: "https://github.com/sponsors/tattle-made" + } +]; + +const PixelatedArrow = ({ color, isOpen }) => ( + +); + +const HighlightedDescription = ({ text }) => { + const emailRegex = /([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+)/gi; + const parts = text.split(emailRegex); + + return ( + + ); +}; + +function AccordionItem({ item, isOpen, onToggle }) { + const [isHover, setIsHover] = useState(false); + + let bg = "transparent"; + let borderColor = "#FFF6E8"; + let textColor = "#FFF6E8"; + + if (isOpen) { + bg = "#FFF6E8"; + borderColor = "#000000"; + textColor = "#000000"; + } else if (isHover) { + bg = "#FFF6E8"; + borderColor = "#FFF6E8"; + textColor = "#000000"; + } + + const dashedBorderStyle = { + backgroundImage: `url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' stroke='${encodeURIComponent(borderColor)}' stroke-width='2' stroke-dasharray='8%2c 8' stroke-dashoffset='0' stroke-linecap='square'/%3e%3c/svg%3e")`, + backgroundPosition: 'center', + backgroundSize: '100% 100%', + backgroundRepeat: 'no-repeat' + }; + + return ( +
    setIsHover(true)} + onMouseLeave={() => setIsHover(false)} + onClick={onToggle} + className="w-full flex flex-col cursor-pointer transition-all duration-300 overflow-hidden" + style={{ + backgroundColor: bg, + ...dashedBorderStyle, + minHeight: '82px' + }} + > +
    +
    + +
    +
    + + {item.title} + +
    +
    + +
    +
    + + {isOpen &&
    +
    + + {item.buttonText.length!=0 && } + + + +
    +
    } +
    + ); +} + +export default function SupportUs() { + const [activeIndex, setActiveIndex] = useState(null); + const revealRef = useScrollReveal({ threshold: 0.1 }); + + return ( + +
    + + Support Our Work + + + You can support Uli's work in the following ways. + +
    + +
    + {items.map((item, idx) => ( + setActiveIndex(activeIndex === idx ? null : idx)} + /> + ))} +
    +
    + ); +} + + + + diff --git a/uli-website/src/hooks/useScrollReveal.js b/uli-website/src/hooks/useScrollReveal.js new file mode 100644 index 00000000..bd3cd98a --- /dev/null +++ b/uli-website/src/hooks/useScrollReveal.js @@ -0,0 +1,62 @@ +import { useEffect, useRef } from "react"; + +/** + * Hook that adds IntersectionObserver-based scroll reveal. + * Returns a ref to attach to the container element. + * When the element enters the viewport, it gets the "visible" class added. + * + * @param {Object} options + * @param {string} options.threshold - visibility threshold (0-1), default 0.15 + * @param {string} options.rootMargin - root margin, default "0px 0px -40px 0px" + */ +export function useScrollReveal({ threshold = 0.15, rootMargin = "0px 0px -40px 0px" } = {}) { + const ref = useRef(null); + + useEffect(() => { + const el = ref.current; + if (!el) return; + + const observer = new IntersectionObserver( + ([entry]) => { + if (entry.isIntersecting) { + el.classList.add("visible"); + observer.unobserve(el); // animate only once + } + }, + { threshold, rootMargin } + ); + + observer.observe(el); + return () => observer.disconnect(); + }, [threshold, rootMargin]); + + return ref; +} + +/** + * Hook that observes multiple child elements for staggered reveal. + * Attach to a parent container. Each direct child will animate in sequence. + */ +export function useStaggerReveal({ threshold = 0.1, rootMargin = "0px 0px -30px 0px" } = {}) { + const ref = useRef(null); + + useEffect(() => { + const el = ref.current; + if (!el) return; + + const observer = new IntersectionObserver( + ([entry]) => { + if (entry.isIntersecting) { + el.classList.add("visible"); + observer.unobserve(el); + } + }, + { threshold, rootMargin } + ); + + observer.observe(el); + return () => observer.disconnect(); + }, [threshold, rootMargin]); + + return ref; +} diff --git a/uli-website/src/pages/about.mdx b/uli-website/src/pages/about.mdx index 9fc062de..2bbcaa8e 100644 --- a/uli-website/src/pages/about.mdx +++ b/uli-website/src/pages/about.mdx @@ -1,8 +1,8 @@ import ContentPageShell from "../components/molecules/ContentPageShell.jsx" import MultiLingualAbout from "../components/atoms/MultiLingualAbout"; -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } ## About Uli diff --git a/uli-website/src/pages/blog/Uli-workshop.mdx b/uli-website/src/pages/blog/Uli-workshop.mdx index 905e60aa..b8a0a7bf 100644 --- a/uli-website/src/pages/blog/Uli-workshop.mdx +++ b/uli-website/src/pages/blog/Uli-workshop.mdx @@ -7,8 +7,8 @@ date: 2025-02-28 --- import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } ## Learnings from Students and the Indian Social Media Experience diff --git a/uli-website/src/pages/blog/approach-data-annotation.mdx b/uli-website/src/pages/blog/approach-data-annotation.mdx index 87aa3744..8385fd51 100644 --- a/uli-website/src/pages/blog/approach-data-annotation.mdx +++ b/uli-website/src/pages/blog/approach-data-annotation.mdx @@ -9,8 +9,8 @@ tags: import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } **Our Approach to Data Annotation** diff --git a/uli-website/src/pages/blog/approach.mdx b/uli-website/src/pages/blog/approach.mdx index 642f05de..6cb27924 100644 --- a/uli-website/src/pages/blog/approach.mdx +++ b/uli-website/src/pages/blog/approach.mdx @@ -8,8 +8,8 @@ date: 2021-08-01 import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } **This is one of the earliest articulations of the project vision and approach, written in the July/August 2021** diff --git a/uli-website/src/pages/blog/chisel-online-abuse.mdx b/uli-website/src/pages/blog/chisel-online-abuse.mdx index a8527f87..59a13006 100644 --- a/uli-website/src/pages/blog/chisel-online-abuse.mdx +++ b/uli-website/src/pages/blog/chisel-online-abuse.mdx @@ -9,8 +9,8 @@ tags: import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } ![](/HeroIllustration.gif) diff --git a/uli-website/src/pages/blog/collective-journey.mdx b/uli-website/src/pages/blog/collective-journey.mdx index 0adb0512..84ecf9f7 100644 --- a/uli-website/src/pages/blog/collective-journey.mdx +++ b/uli-website/src/pages/blog/collective-journey.mdx @@ -9,8 +9,8 @@ tags: import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } While hosted and led by Tattle Civic Tech, the evolution of Uli over the last 3 years has been a collective journey. diff --git a/uli-website/src/pages/blog/context-matters.mdx b/uli-website/src/pages/blog/context-matters.mdx index 3aa25e39..5270c104 100644 --- a/uli-website/src/pages/blog/context-matters.mdx +++ b/uli-website/src/pages/blog/context-matters.mdx @@ -9,8 +9,8 @@ tags: import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } ![](/Illustration-context-matters.png) diff --git a/uli-website/src/pages/blog/cross-platform-pt1.mdx b/uli-website/src/pages/blog/cross-platform-pt1.mdx index 91be3cff..f9ff2d04 100644 --- a/uli-website/src/pages/blog/cross-platform-pt1.mdx +++ b/uli-website/src/pages/blog/cross-platform-pt1.mdx @@ -7,8 +7,8 @@ date: 2024-03-13 --- import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } Online abuse persists either through posts across online platforms, or through circumvented attempts to create newer accounts and reposting previously reported content. diff --git a/uli-website/src/pages/blog/cross-platform_pt_2.mdx b/uli-website/src/pages/blog/cross-platform_pt_2.mdx index 92acc51d..ee8e88f0 100644 --- a/uli-website/src/pages/blog/cross-platform_pt_2.mdx +++ b/uli-website/src/pages/blog/cross-platform_pt_2.mdx @@ -8,8 +8,8 @@ date: 2024-04-17 import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } We're continuing by taking a look at how cross-platform abuse operates on federated and centralised platforms, and the kind of solutions they must test and implement to tackle cross-platform abuse. diff --git a/uli-website/src/pages/blog/getting-started-with-aws-copilot.mdx b/uli-website/src/pages/blog/getting-started-with-aws-copilot.mdx index afeddc50..763afcc6 100644 --- a/uli-website/src/pages/blog/getting-started-with-aws-copilot.mdx +++ b/uli-website/src/pages/blog/getting-started-with-aws-copilot.mdx @@ -8,8 +8,8 @@ date: 2022-08-28 import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } Around a few days ago, I was introduced to, what is, from the time of writing a relatively new framework for hosting containers in the cloud, known as AWS co-pilot. This blog post serves as a collection of all that I've learnt and more regarding the usage of co-pilot, a potential way to deploy and host Uli, using copilot and relevant resources which were useful to me in learning about co-pilot and its various use cases. diff --git a/uli-website/src/pages/blog/hover-feature-making.mdx b/uli-website/src/pages/blog/hover-feature-making.mdx index a5a9a1a4..d79875da 100644 --- a/uli-website/src/pages/blog/hover-feature-making.mdx +++ b/uli-website/src/pages/blog/hover-feature-making.mdx @@ -9,8 +9,8 @@ tags: import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } **Building Uli: How the hover-for-metadata feature came about.** diff --git a/uli-website/src/pages/blog/index.jsx b/uli-website/src/pages/blog/index.jsx index 631c3c46..d34d7470 100644 --- a/uli-website/src/pages/blog/index.jsx +++ b/uli-website/src/pages/blog/index.jsx @@ -21,17 +21,17 @@ const BlogIndex = ({ data }) => { {blogs.map((blog) => { return ( - + {blog.frontmatter.name}, {blog.frontmatter.author} - {/* Publish date ko yahan display kiya gaya hai */} + - Published on: {formatDate(blog.frontmatter.date)} + {formatDate(blog.frontmatter.date)} diff --git a/uli-website/src/pages/blog/making-of-August-2023.mdx b/uli-website/src/pages/blog/making-of-August-2023.mdx index 99a19d84..7f56cfa5 100644 --- a/uli-website/src/pages/blog/making-of-August-2023.mdx +++ b/uli-website/src/pages/blog/making-of-August-2023.mdx @@ -8,8 +8,8 @@ date: 2023-09-07 import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } ## The Evolution of Uli diff --git a/uli-website/src/pages/blog/making-of-dec-2021.mdx b/uli-website/src/pages/blog/making-of-dec-2021.mdx index c585ba58..faf5b219 100644 --- a/uli-website/src/pages/blog/making-of-dec-2021.mdx +++ b/uli-website/src/pages/blog/making-of-dec-2021.mdx @@ -8,8 +8,8 @@ date: 2021-12-15 import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } # The making of the ML tool to mitigate online gender based violence in three Indian languages diff --git a/uli-website/src/pages/blog/making-of-dec-2023.mdx b/uli-website/src/pages/blog/making-of-dec-2023.mdx index 28228919..84a45a35 100644 --- a/uli-website/src/pages/blog/making-of-dec-2023.mdx +++ b/uli-website/src/pages/blog/making-of-dec-2023.mdx @@ -8,8 +8,8 @@ date: 2023-12-22 import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } ## Updates from Uli: November/December 2023 diff --git a/uli-website/src/pages/blog/making-of-feb-2022.mdx b/uli-website/src/pages/blog/making-of-feb-2022.mdx index c77fa292..7fc4fab9 100644 --- a/uli-website/src/pages/blog/making-of-feb-2022.mdx +++ b/uli-website/src/pages/blog/making-of-feb-2022.mdx @@ -8,8 +8,8 @@ date: 2022-02-15 import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } Today we will dwell on the features that we have added to the beta version of the tool and while our machine continues to learn the difference between a friendly post and a post meant to harass on the basis of the ongoing annotations, these additional features will keep the tool alive. diff --git a/uli-website/src/pages/blog/making-of-jan-2022.mdx b/uli-website/src/pages/blog/making-of-jan-2022.mdx index 857f146b..e79508d4 100644 --- a/uli-website/src/pages/blog/making-of-jan-2022.mdx +++ b/uli-website/src/pages/blog/making-of-jan-2022.mdx @@ -8,8 +8,8 @@ date: 2022-01-15 import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } # The making of the ML tool to mitigate online gender based violence in three Indian languages diff --git a/uli-website/src/pages/blog/making-of-mar-2022.mdx b/uli-website/src/pages/blog/making-of-mar-2022.mdx index 7f80342c..1fc9a1c6 100644 --- a/uli-website/src/pages/blog/making-of-mar-2022.mdx +++ b/uli-website/src/pages/blog/making-of-mar-2022.mdx @@ -8,8 +8,8 @@ date: 2022-04-26 import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } **This post is adapted from the Uli newsletter updates sent in March and April 2022** diff --git a/uli-website/src/pages/blog/responsible-display.mdx b/uli-website/src/pages/blog/responsible-display.mdx index 10cdf5e5..cc3fa039 100644 --- a/uli-website/src/pages/blog/responsible-display.mdx +++ b/uli-website/src/pages/blog/responsible-display.mdx @@ -8,8 +8,8 @@ date: 2022-04-16 import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } # Responsible Way of Showcasing the Countering of OGBV diff --git a/uli-website/src/pages/blog/silencing-impact-OGBV.mdx b/uli-website/src/pages/blog/silencing-impact-OGBV.mdx index b310ee09..4737b721 100644 --- a/uli-website/src/pages/blog/silencing-impact-OGBV.mdx +++ b/uli-website/src/pages/blog/silencing-impact-OGBV.mdx @@ -8,8 +8,8 @@ date: 2024-04-24 import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } ![](/silencing-impact-illustration.png) diff --git a/uli-website/src/pages/blog/slurs-occur-every-language.mdx b/uli-website/src/pages/blog/slurs-occur-every-language.mdx index 0604a3f9..dcae975c 100644 --- a/uli-website/src/pages/blog/slurs-occur-every-language.mdx +++ b/uli-website/src/pages/blog/slurs-occur-every-language.mdx @@ -9,8 +9,8 @@ tags: import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } The majority of machine learning investment on online platforms still happens in English. diff --git a/uli-website/src/pages/blog/tech4dev-user-research-lessons.mdx b/uli-website/src/pages/blog/tech4dev-user-research-lessons.mdx index 9fb7a5b3..c2d64e59 100644 --- a/uli-website/src/pages/blog/tech4dev-user-research-lessons.mdx +++ b/uli-website/src/pages/blog/tech4dev-user-research-lessons.mdx @@ -8,8 +8,8 @@ date: 2022-04-18 import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } ## Lessons in User Research from Donald Lobo diff --git a/uli-website/src/pages/blog/uli-privacy.mdx b/uli-website/src/pages/blog/uli-privacy.mdx index cacddbb0..da46a5b8 100644 --- a/uli-website/src/pages/blog/uli-privacy.mdx +++ b/uli-website/src/pages/blog/uli-privacy.mdx @@ -8,8 +8,8 @@ date: 2022-07-15 import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } # Privacy Preserving Features of Uli diff --git a/uli-website/src/pages/blog/workshop-tech-dev.mdx b/uli-website/src/pages/blog/workshop-tech-dev.mdx index beb5eea8..0a05ec62 100644 --- a/uli-website/src/pages/blog/workshop-tech-dev.mdx +++ b/uli-website/src/pages/blog/workshop-tech-dev.mdx @@ -8,8 +8,8 @@ tags: --- import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } This year, the team has been implementing changes to Uli on the development side, and there have been many notable updates. In the process of conducting workshops with university students to explore Uli's use as a pedagogical tool for sensitization, we also created functionalities that show great potential for different use cases. This made us rethink the experience of using Uli and prioritize features differently. In this post we will go over changes we made to the browser extension and new features we built to support these workshops. diff --git a/uli-website/src/pages/faq.mdx b/uli-website/src/pages/faq.mdx index 46fd97ed..c9e2b974 100644 --- a/uli-website/src/pages/faq.mdx +++ b/uli-website/src/pages/faq.mdx @@ -1,8 +1,8 @@ import ContentPageShell from "../components/molecules/ContentPageShell.jsx" import { Box } from "grommet"; -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } # FAQ diff --git a/uli-website/src/pages/hi/about.mdx b/uli-website/src/pages/hi/about.mdx index 717f18ff..1f8a149a 100644 --- a/uli-website/src/pages/hi/about.mdx +++ b/uli-website/src/pages/hi/about.mdx @@ -1,7 +1,7 @@ import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } ## उली क्या है? diff --git a/uli-website/src/pages/hi/faq.mdx b/uli-website/src/pages/hi/faq.mdx index 35920dd4..ef79f3b4 100644 --- a/uli-website/src/pages/hi/faq.mdx +++ b/uli-website/src/pages/hi/faq.mdx @@ -1,8 +1,8 @@ import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" import { Box } from "grommet"; -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } # सामान्यतः पूछे जाने वाले प्रश्न: diff --git a/uli-website/src/pages/new-home.js b/uli-website/src/pages/new-home.js index 51339056..797acd49 100644 --- a/uli-website/src/pages/new-home.js +++ b/uli-website/src/pages/new-home.js @@ -1,28 +1,51 @@ -import * as React from "react" -import AppShell from "../components/molecules/AppShell" -import AnnouncementBanner from "../components/molecules/AnnouncementBanner" -import { Box, Text } from "grommet" - +import * as React from "react"; +import AppShellNew from "../components/molecules/AppShellNew"; +import Announcements from "../components/molecules/Announcements"; +import { Box, Text } from "grommet"; +import Projects from "../components/molecules/Projects"; +import RecentBlogs from "../components/molecules/RecentBlogs"; +import Resources from "../components/molecules/Resources"; +import SupportUs from "../components/molecules/SupportUs"; +// import Resources from "../components/molecules/Resources"; +import { NavLinkNew } from "../components/atoms/NavLinkNew"; const NewHome = () => { return ( - -
    + + + + + + Reclaim your
    online space +
    + + + An endeavour to build safer online spaces in India by collectivizing women and gender minorities. Uli creates representative data and tools for detection of online abuse and connects to support in times of need. + - - - Announcement -
    - That white background would typically be a solid fill with border radius, and using Auto Layout
    would be able to grow and shrink based on the label overrides per instance.
    - + + + Our Process + About Us +
    +
    + + + {/* */} + + - -

    New Home

    -

    This is a temporary placeholder for the new homepage design.

    -
    -
    - ) -} + + ); +}; -export default NewHome +export default NewHome; diff --git a/uli-website/src/pages/privacy-policy.mdx b/uli-website/src/pages/privacy-policy.mdx index 2c3c81f8..9f28cc38 100644 --- a/uli-website/src/pages/privacy-policy.mdx +++ b/uli-website/src/pages/privacy-policy.mdx @@ -1,7 +1,7 @@ import ContentPageShell from "../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } # Privacy Policy diff --git a/uli-website/src/pages/process.mdx b/uli-website/src/pages/process.mdx new file mode 100644 index 00000000..4ce5a6b0 --- /dev/null +++ b/uli-website/src/pages/process.mdx @@ -0,0 +1,45 @@ +import ContentPageShell from "../components/molecules/ContentPageShell.jsx" +import MultiLingualAbout from "../components/atoms/MultiLingualAbout"; +import { Box, Text } from "grommet"; + +export default function Layout(props) { + return {props.children}; +} + +## Process + +Gender-based violence now exists on an online-offline continuum. Online violence is often accompanied by offline violence. Uli (meaning chisel in Tamil) is our attempt to hand the chisel and power over to users most affected by online gender-based violence. + +Uli was born from the collective labour of journalists, activists, community influencers, and writers engaged in the struggle against the interwoven caste, religion, gender and sexuality-based violence both online and offline. They contributed towards the development of the Uli datasets and the plugin to filter out offensive words/phrases. Uli is not imagined as the final product, but rather a simple tool, a chisel, that allows people to come together, share stories, and reflect on the future we all want to see. In its second year, Uli is evolving as a user-facing tool; as well as a set of resources that researchers, Trust and Safety teams, professionals, and journalists can use in their workflows. + +## Participatory process + +The project started as an exploration of building datasets and AI aligned with [feminist principles](https://uli.tattle.co.in/blog/approach/). There are many terms- such as responsible, ethical, trustworthy, participatory, feminist- to describe better or alternative visions of AI (and technology). Core to these ideas is the principle of centering the communities who are most impacted by the technology. In our case it is women and marginalized genders at the receiving end of OGBV. + +The Uli project contributes unique insights on the nuts and bolts of participatory data and AI. This presentation describes the challenges of converting feminist principles to practice: + + + + + {" "} + Building Participatory AI + + + + + + + + +With every iteration we learn something new. The methodology of building the flagship dataset on misogyny in India languages with experts with lived experience of abuse is documented here. The paper won the outstanding paper award at the Workshop on Online Abuse and Harms at NAACL, 2024. In another paper on participation in AI we introduce the concept of horizontal and vertical translation of expertise for effective participation. When building out AI safety benchmarks for MLCommons, we learnt where lived expertise could interplay with synthetic/ at scale dataset creation. + +While we keep the values of care and radical inclusion as our north star, we recognize that in hitting diff --git a/uli-website/src/pages/research.mdx b/uli-website/src/pages/research.mdx index e38ad85f..cf61e8ac 100644 --- a/uli-website/src/pages/research.mdx +++ b/uli-website/src/pages/research.mdx @@ -1,8 +1,8 @@ import ContentPageShell from "../components/molecules/ContentPageShell.jsx"; import { Box, Text } from "grommet"; -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } # Research diff --git a/uli-website/src/pages/resources.mdx b/uli-website/src/pages/resources.mdx index 93d324ec..5d7d5de4 100644 --- a/uli-website/src/pages/resources.mdx +++ b/uli-website/src/pages/resources.mdx @@ -1,7 +1,7 @@ import ContentPageShell from "../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } # Resources diff --git a/uli-website/src/pages/ta/about.mdx b/uli-website/src/pages/ta/about.mdx index faa3a65d..c3ed5406 100644 --- a/uli-website/src/pages/ta/about.mdx +++ b/uli-website/src/pages/ta/about.mdx @@ -1,7 +1,7 @@ import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } ## உளி பற்றி diff --git a/uli-website/src/pages/ta/faq.mdx b/uli-website/src/pages/ta/faq.mdx index c8cad437..c5d28ace 100644 --- a/uli-website/src/pages/ta/faq.mdx +++ b/uli-website/src/pages/ta/faq.mdx @@ -1,8 +1,8 @@ import ContentPageShell from "../../components/molecules/ContentPageShell.jsx" import { Box } from "grommet"; -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } # அடிக்கடி கேட்கப்படும் கேள்விகள் diff --git a/uli-website/src/pages/team-2021.mdx b/uli-website/src/pages/team-2021.mdx index ba2085aa..85909087 100644 --- a/uli-website/src/pages/team-2021.mdx +++ b/uli-website/src/pages/team-2021.mdx @@ -1,8 +1,8 @@ import ContentPageShell from "../components/molecules/ContentPageShell.jsx" import MultiLingualAbout from "../components/atoms/MultiLingualAbout"; -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } ## The pilot diff --git a/uli-website/src/pages/uli-for-ts.mdx b/uli-website/src/pages/uli-for-ts.mdx index 0e4ea020..f680b2e3 100644 --- a/uli-website/src/pages/uli-for-ts.mdx +++ b/uli-website/src/pages/uli-for-ts.mdx @@ -1,7 +1,7 @@ import ContentPageShell from "../components/molecules/ContentPageShell.jsx" -export default function Layout({ children }) { - return {children}; +export default function Layout(props) { + return {props.children}; } ## Uli for Trust and Safety Teams diff --git a/uli-website/src/styles/global.css b/uli-website/src/styles/global.css index c0c7b90b..a5675f29 100644 --- a/uli-website/src/styles/global.css +++ b/uli-website/src/styles/global.css @@ -1,3 +1,4 @@ +@import url('https://fonts.googleapis.com/css2?family=Labrada:ital,wght@0,100..900;1,100..900&family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap'); @tailwind base; @tailwind components; @tailwind utilities; @@ -17,4 +18,111 @@ pre>code { padding: 1rem; display: block; overflow-x: auto; +} + +/* Keyframes for fadeUp animation used via Tailwind arbitrary animation */ +@keyframes fadeUp { + from { + opacity: 0; + transform: translateY(1.25rem); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes fadeIn { + from { opacity: 0; } + to { opacity: 1; } +} + +@keyframes fadeRight { + from { + opacity: 0; + transform: translateX(-1.5rem); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +@keyframes scaleIn { + from { + opacity: 0; + transform: scale(0.96); + } + to { + opacity: 1; + transform: scale(1); + } +} + +/* ── Scroll-reveal: hidden by default, revealed by IntersectionObserver ── */ +.reveal { + opacity: 0; + transform: translateY(24px); + transition: opacity 0.7s cubic-bezier(0.22, 1, 0.36, 1), + transform 0.7s cubic-bezier(0.22, 1, 0.36, 1); +} +.reveal.visible { + opacity: 1; + transform: translateY(0); +} + +/* Stagger children inside a reveal container */ +.reveal-stagger > * { + opacity: 0; + transform: translateY(16px); + transition: opacity 0.5s cubic-bezier(0.22, 1, 0.36, 1), + transform 0.5s cubic-bezier(0.22, 1, 0.36, 1); +} +.reveal-stagger.visible > *:nth-child(1) { transition-delay: 0.05s; } +.reveal-stagger.visible > *:nth-child(2) { transition-delay: 0.12s; } +.reveal-stagger.visible > *:nth-child(3) { transition-delay: 0.19s; } +.reveal-stagger.visible > *:nth-child(4) { transition-delay: 0.26s; } +.reveal-stagger.visible > *:nth-child(5) { transition-delay: 0.33s; } +.reveal-stagger.visible > * { + opacity: 0; + transform: translateY(16px); +} +.reveal-stagger.visible > * { + opacity: 1; + transform: translateY(0); +} + +/* ── Smooth responsive layout transitions ── */ +.smooth-layout { + transition: width 0.4s ease, padding 0.4s ease, margin 0.4s ease, + font-size 0.3s ease, gap 0.3s ease, max-width 0.4s ease; +} + +/* ── Border slide-in animations (page load) ── */ +@keyframes borderSlideX { + from { background-position-x: -200px; } + to { background-position-x: 0; } +} + +@keyframes borderSlideY { + from { background-position-y: -200px; } + to { background-position-y: 0; } +} + +/* Horizontal border — slides in from left on load */ +.border-animate-x { + animation: borderSlideX 1.2s cubic-bezier(0.22, 1, 0.36, 1) both; +} + +/* Vertical border — slides in from top on load */ +.border-animate-y { + animation: borderSlideY 1.4s cubic-bezier(0.22, 1, 0.36, 1) 0.2s both; +} + +/* Section borders get staggered delays */ +.border-animate-x-delay { + animation: borderSlideX 1s cubic-bezier(0.22, 1, 0.36, 1) 0.4s both; +} +.border-animate-y-delay { + animation: borderSlideY 1.2s cubic-bezier(0.22, 1, 0.36, 1) 0.6s both; } \ No newline at end of file diff --git a/uli-website/static/cross-icon.svg b/uli-website/static/cross-icon.svg new file mode 100644 index 00000000..472ced6b --- /dev/null +++ b/uli-website/static/cross-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/uli-website/static/dashed-btn-bg.png b/uli-website/static/dashed-btn-bg.png new file mode 100644 index 00000000..b9363461 Binary files /dev/null and b/uli-website/static/dashed-btn-bg.png differ diff --git a/uli-website/static/hamburger-icon.svg b/uli-website/static/hamburger-icon.svg new file mode 100644 index 00000000..cd50ac3a --- /dev/null +++ b/uli-website/static/hamburger-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/uli-website/static/heading.svg b/uli-website/static/heading.svg new file mode 100644 index 00000000..55304c91 --- /dev/null +++ b/uli-website/static/heading.svg @@ -0,0 +1,4 @@ + + + + diff --git a/uli-website/static/mail-logo.svg b/uli-website/static/mail-logo.svg new file mode 100644 index 00000000..89586df6 --- /dev/null +++ b/uli-website/static/mail-logo.svg @@ -0,0 +1,3 @@ + + + diff --git a/uli-website/static/project-card-bg.svg b/uli-website/static/project-card-bg.svg new file mode 100644 index 00000000..d6b9abab --- /dev/null +++ b/uli-website/static/project-card-bg.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/uli-website/static/project-card-logo.svg b/uli-website/static/project-card-logo.svg new file mode 100644 index 00000000..54027c0d --- /dev/null +++ b/uli-website/static/project-card-logo.svg @@ -0,0 +1,62 @@ + + + + + + + + + diff --git a/uli-website/static/section-border-vertical.svg b/uli-website/static/section-border-vertical.svg new file mode 100644 index 00000000..4a9ddbca --- /dev/null +++ b/uli-website/static/section-border-vertical.svg @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/uli-website/static/section-border.svg b/uli-website/static/section-border.svg new file mode 100644 index 00000000..052c1a89 --- /dev/null +++ b/uli-website/static/section-border.svg @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/uli-website/static/subscribe-bar-bg.svg b/uli-website/static/subscribe-bar-bg.svg new file mode 100644 index 00000000..20e26413 --- /dev/null +++ b/uli-website/static/subscribe-bar-bg.svg @@ -0,0 +1,4 @@ + + + + diff --git a/uli-website/static/subscribe-btn-bg.png b/uli-website/static/subscribe-btn-bg.png new file mode 100644 index 00000000..89f8a3cf Binary files /dev/null and b/uli-website/static/subscribe-btn-bg.png differ diff --git a/uli-website/static/support_icons/database.svg b/uli-website/static/support_icons/database.svg new file mode 100644 index 00000000..0b87a154 --- /dev/null +++ b/uli-website/static/support_icons/database.svg @@ -0,0 +1,3 @@ + + + diff --git a/uli-website/static/support_icons/support.svg b/uli-website/static/support_icons/support.svg new file mode 100644 index 00000000..b9cb5a71 --- /dev/null +++ b/uli-website/static/support_icons/support.svg @@ -0,0 +1,3 @@ + + + diff --git a/uli-website/static/support_icons/workshop.svg b/uli-website/static/support_icons/workshop.svg new file mode 100644 index 00000000..55b5548b --- /dev/null +++ b/uli-website/static/support_icons/workshop.svg @@ -0,0 +1,4 @@ + + + + diff --git a/uli-website/static/top-border.svg b/uli-website/static/top-border.svg new file mode 100644 index 00000000..c68db5e2 --- /dev/null +++ b/uli-website/static/top-border.svg @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + diff --git a/uli-website/static/track_icons/Database.png b/uli-website/static/track_icons/Database.png new file mode 100644 index 00000000..732640ef Binary files /dev/null and b/uli-website/static/track_icons/Database.png differ diff --git a/uli-website/static/track_icons/Slur Editor.png b/uli-website/static/track_icons/Slur Editor.png new file mode 100644 index 00000000..51623f9f Binary files /dev/null and b/uli-website/static/track_icons/Slur Editor.png differ diff --git a/uli-website/static/track_icons/Tools.png b/uli-website/static/track_icons/Tools.png new file mode 100644 index 00000000..43ae0fe7 Binary files /dev/null and b/uli-website/static/track_icons/Tools.png differ diff --git a/uli-website/static/track_icons/Workshops.png b/uli-website/static/track_icons/Workshops.png new file mode 100644 index 00000000..34c3730a Binary files /dev/null and b/uli-website/static/track_icons/Workshops.png differ diff --git a/uli-website/tailwind.config.js b/uli-website/tailwind.config.js index 13b8e34d..c3434033 100644 --- a/uli-website/tailwind.config.js +++ b/uli-website/tailwind.config.js @@ -5,7 +5,11 @@ module.exports = { "./src/components/**/*.{js,jsx,ts,tsx}", ], theme: { - extend: {}, + extend: { + fontFamily:{ + labrada: ["Labrada","monospace", "serif"] + } + }, }, important: "#app", plugins: [],