From fdc4839703ac877c5a0c855b8ee6de3f0e98921c Mon Sep 17 00:00:00 2001 From: Aaron DeRuvo Date: Thu, 5 Dec 2019 11:45:50 -0800 Subject: [PATCH] Experience Brand Kit 1.0 (#1948) * Static version of Menu us looking good * Brand kit general layout * Add base pages and other fun stuff * Wip * Section nav * Redo pages * Steal this from other branch * Sane scroll behavior * Use constants for all paths * Mobile * WIP fetching from air table * Logo page basic content first pass * Add in words (WIP) * Better white spacing * Move some files around and other things * Ensure long menu would be scrollable * Colors true * no message * Typeography Page A * Fetching icons from airtbale and and displaying on page nice * Usage Example * Fix ilocal keys * Right on * Type overhaul w han * Judement * Improve Logo page on mobile * LOGOGOSOGOOGOS * Change URI to be /experience/brand/* * LINT this and add brand redirect * Icons view change and fix * Create download button, fix up nav and make font page great * Remove board and left alignment on colors * Better gap * Alignment of top * Color Page Content * Create Inline Anchor for using inline button in the trans Remove hash hoc Update general cleanup * Brand home page is a ok * Logo page content and better fit on tablet * Logo page content Some sizing stuff Ensure there is a minimum size for sidebar * Add web deps * Tyopgraphy page * ICONS text * Beautiful icons * Sweet Jesus its downloading season * Self review * Fix import * Dont show border on last type example Add margin to subtitles Make name Celo White Fix monochrome logo * Glphs on backgrounds should be square on mobile Icons make square small enough for 2x2 on mobile Keep squares square and variable size Add logo downloads Thicken stroke on download icon Remove buttons example Converte minimums to be sag not png for better crispy scale Better mobile spacing in general Add new uiSmall first class type style * Lint * Lint * Cleanup from PR * Ensure the sidebar is not ever covered by the footer * Add License * Super duper with Laurance * Lint --- packages/web/package.json | 5 +- packages/web/pages/_app.tsx | 12 +- packages/web/pages/_document.tsx | 11 +- packages/web/pages/experience/brand/color.tsx | 3 + packages/web/pages/experience/brand/icons.tsx | 3 + packages/web/pages/experience/brand/index.tsx | 3 + .../pages/experience/brand/key-imagery.tsx | 2 + packages/web/pages/experience/brand/logo.tsx | 3 + .../web/pages/experience/brand/typography.tsx | 3 + packages/web/server-env-config.js.enc | Bin 2321 -> 2448 bytes packages/web/server/AssetBase.ts | 66 ++++ packages/web/server/index.ts | 15 + packages/web/src/brandkit/Color.tsx | 150 ++++++++ packages/web/src/brandkit/IconsPage.tsx | 90 +++++ packages/web/src/brandkit/Intro.tsx | 37 ++ packages/web/src/brandkit/KeyImagery.tsx | 37 ++ packages/web/src/brandkit/Logo.tsx | 347 ++++++++++++++++++ packages/web/src/brandkit/Typography.tsx | 172 +++++++++ packages/web/src/brandkit/color/Palette.tsx | 36 ++ packages/web/src/brandkit/color/Pigment.tsx | 164 +++++++++ .../src/brandkit/common/DownloadButton.tsx | 25 ++ packages/web/src/brandkit/common/Fetch.tsx | 44 +++ .../web/src/brandkit/common/MobileMenu.tsx | 95 +++++ packages/web/src/brandkit/common/Page.tsx | 281 ++++++++++++++ .../web/src/brandkit/common/PageHeadline.tsx | 20 + .../web/src/brandkit/common/SectionTitle.tsx | 23 ++ packages/web/src/brandkit/common/Showcase.tsx | 64 ++++ packages/web/src/brandkit/common/Sidebar.tsx | 172 +++++++++ packages/web/src/brandkit/common/TopBar.tsx | 52 +++ .../src/brandkit/common/TripplePairing.tsx | 37 ++ .../web/src/brandkit/common/constants.tsx | 28 ++ packages/web/src/brandkit/common/data.ts | 29 ++ packages/web/src/brandkit/images/Check.png | Bin 0 -> 199 bytes .../src/brandkit/images/ClearspaceImage.png | Bin 0 -> 43497 bytes packages/web/src/brandkit/images/X.png | Bin 0 -> 240 bytes packages/web/src/brandkit/images/lilah.jpg | Bin 0 -> 11088 bytes .../web/src/brandkit/images/lilahOverlay.jpg | Bin 0 -> 8760 bytes packages/web/src/brandkit/logo/Judgement.tsx | 42 +++ .../web/src/brandkit/logo/LogoExample.tsx | 68 ++++ .../src/brandkit/logo/LogoWithBackground.tsx | 69 ++++ packages/web/src/brandkit/logo/Minimums.tsx | 77 ++++ .../src/brandkit/typography/UseageExample.tsx | 46 +++ packages/web/src/community/EcoFund.tsx | 2 +- packages/web/src/dev/DeveloperUpdates.tsx | 2 +- packages/web/src/dev/FaucetPage.tsx | 9 +- .../web/src/fauceting/MicroComponents.tsx | 2 +- packages/web/src/header/CookieConsent.tsx | 1 - packages/web/src/i18n.ts | 1 + packages/web/src/icons/CopyIcon.tsx | 20 + packages/web/src/icons/Download.tsx | 18 + packages/web/src/layout/ScreenSize.tsx | 2 +- packages/web/src/logos/LogoLightBg.tsx | 11 +- .../logos/{RingsLight.tsx => RingsGlyph.tsx} | 5 +- packages/web/src/react-native-aug.d.ts | 3 + packages/web/src/shared/DropDownGroup.tsx | 1 - packages/web/src/shared/Footer.3.tsx | 12 +- packages/web/src/shared/Hoverable.tsx | 26 +- packages/web/src/shared/InlineAnchor.tsx | 11 + packages/web/src/shared/menu-items.ts | 60 +-- packages/web/src/styles.ts | 62 +++- packages/web/src/terms/Agreement.tsx | 8 +- packages/web/static/assets/CeloColorLogo.zip | Bin 0 -> 70331 bytes .../static/assets/CeloColorLogoReverse.zip | Bin 0 -> 67966 bytes packages/web/static/assets/CeloGlyphs.zip | Bin 0 -> 129800 bytes .../web/static/assets/CeloLogoPackage.zip | Bin 0 -> 390811 bytes .../web/static/assets/CeloMonochromeLogo.zip | Bin 0 -> 61677 bytes .../assets/CeloMonochromeLogoReverse.zip | Bin 0 -> 57414 bytes packages/web/static/locales/en/brand.json | 102 +++++ yarn.lock | 15 + 69 files changed, 2625 insertions(+), 79 deletions(-) create mode 100644 packages/web/pages/experience/brand/color.tsx create mode 100644 packages/web/pages/experience/brand/icons.tsx create mode 100644 packages/web/pages/experience/brand/index.tsx create mode 100644 packages/web/pages/experience/brand/key-imagery.tsx create mode 100644 packages/web/pages/experience/brand/logo.tsx create mode 100644 packages/web/pages/experience/brand/typography.tsx create mode 100644 packages/web/server/AssetBase.ts create mode 100644 packages/web/src/brandkit/Color.tsx create mode 100644 packages/web/src/brandkit/IconsPage.tsx create mode 100644 packages/web/src/brandkit/Intro.tsx create mode 100644 packages/web/src/brandkit/KeyImagery.tsx create mode 100644 packages/web/src/brandkit/Logo.tsx create mode 100644 packages/web/src/brandkit/Typography.tsx create mode 100644 packages/web/src/brandkit/color/Palette.tsx create mode 100644 packages/web/src/brandkit/color/Pigment.tsx create mode 100644 packages/web/src/brandkit/common/DownloadButton.tsx create mode 100644 packages/web/src/brandkit/common/Fetch.tsx create mode 100644 packages/web/src/brandkit/common/MobileMenu.tsx create mode 100644 packages/web/src/brandkit/common/Page.tsx create mode 100644 packages/web/src/brandkit/common/PageHeadline.tsx create mode 100644 packages/web/src/brandkit/common/SectionTitle.tsx create mode 100644 packages/web/src/brandkit/common/Showcase.tsx create mode 100644 packages/web/src/brandkit/common/Sidebar.tsx create mode 100644 packages/web/src/brandkit/common/TopBar.tsx create mode 100644 packages/web/src/brandkit/common/TripplePairing.tsx create mode 100644 packages/web/src/brandkit/common/constants.tsx create mode 100644 packages/web/src/brandkit/common/data.ts create mode 100644 packages/web/src/brandkit/images/Check.png create mode 100644 packages/web/src/brandkit/images/ClearspaceImage.png create mode 100644 packages/web/src/brandkit/images/X.png create mode 100644 packages/web/src/brandkit/images/lilah.jpg create mode 100644 packages/web/src/brandkit/images/lilahOverlay.jpg create mode 100644 packages/web/src/brandkit/logo/Judgement.tsx create mode 100644 packages/web/src/brandkit/logo/LogoExample.tsx create mode 100644 packages/web/src/brandkit/logo/LogoWithBackground.tsx create mode 100644 packages/web/src/brandkit/logo/Minimums.tsx create mode 100644 packages/web/src/brandkit/typography/UseageExample.tsx create mode 100644 packages/web/src/icons/CopyIcon.tsx create mode 100644 packages/web/src/icons/Download.tsx rename packages/web/src/logos/{RingsLight.tsx => RingsGlyph.tsx} (91%) create mode 100644 packages/web/src/shared/InlineAnchor.tsx create mode 100644 packages/web/static/assets/CeloColorLogo.zip create mode 100644 packages/web/static/assets/CeloColorLogoReverse.zip create mode 100644 packages/web/static/assets/CeloGlyphs.zip create mode 100644 packages/web/static/assets/CeloLogoPackage.zip create mode 100644 packages/web/static/assets/CeloMonochromeLogo.zip create mode 100644 packages/web/static/assets/CeloMonochromeLogoReverse.zip create mode 100644 packages/web/static/locales/en/brand.json diff --git a/packages/web/package.json b/packages/web/package.json index 4ac7e0f3994..02c0d442b6e 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -28,6 +28,7 @@ "apollo-boost": "^0.3.1", "big-integer": "^1.6.31", "body-parser": "^1.18.3", + "colortranslator": "^1.1.1", "compression": "^1.7.4", "connect-slashes": "^1.4.0", "cross-fetch": "^3.0.2", @@ -74,12 +75,14 @@ "shuffle-seed": "^1.1.6", "stickyfilljs": "^2.0.5", "svgs": "^4.1.0", - "tls": "^0.0.1" + "tls": "^0.0.1", + "yiq": "^3.0.1" }, "devDependencies": { "@firebase/app-types": "^0.4.6", "@sentry/types": "^5.6.1", "@types/airtable": "^0.5.6", + "@types/hex-rgba": "^1.0.0", "@types/i18next": "^12.1.0", "@types/mailgun-js": "^0.16.3", "@types/next": "^8.0.3", diff --git a/packages/web/pages/_app.tsx b/packages/web/pages/_app.tsx index c4ae3afe993..80bb4b03ead 100644 --- a/packages/web/pages/_app.tsx +++ b/packages/web/pages/_app.tsx @@ -29,10 +29,14 @@ class MyApp extends App { } } - // there are a few pages we dont want the header on for artistic reasons - // currently this is just the animation demo pages + // there are a few pages we dont want the header on + // currently this is just the animation demo pages and brand kit skipHeader() { - return this.props.router.asPath.startsWith('/animation') + return this.props.router.asPath.startsWith('/animation') || this.isBrand() + } + + isBrand = () => { + return this.props.router.asPath.startsWith('/experience') } componentDidCatch = (error: Error, info: object) => { @@ -76,5 +80,5 @@ function checkH1Count() { function hashScroller(id: string) { const element = document.getElementById(id.replace('#', '')) - scrollIntoView(element, { time: 200, align: { top: 0.2, topOffset: HEADER_HEIGHT } }) + scrollIntoView(element, { time: 100, align: { top: 0, topOffset: HEADER_HEIGHT + 100 } }) } diff --git a/packages/web/pages/_document.tsx b/packages/web/pages/_document.tsx index c2289bd533f..1a8f17c96f8 100644 --- a/packages/web/pages/_document.tsx +++ b/packages/web/pages/_document.tsx @@ -54,8 +54,15 @@ export default class MyDocument extends Document { - - + + diff --git a/packages/web/pages/experience/brand/color.tsx b/packages/web/pages/experience/brand/color.tsx new file mode 100644 index 00000000000..2c352349b78 --- /dev/null +++ b/packages/web/pages/experience/brand/color.tsx @@ -0,0 +1,3 @@ +import Color from 'src/brandkit/Color' + +export default Color diff --git a/packages/web/pages/experience/brand/icons.tsx b/packages/web/pages/experience/brand/icons.tsx new file mode 100644 index 00000000000..66c81bc4f56 --- /dev/null +++ b/packages/web/pages/experience/brand/icons.tsx @@ -0,0 +1,3 @@ +import IconsPage from 'src/brandkit/IconsPage' + +export default IconsPage diff --git a/packages/web/pages/experience/brand/index.tsx b/packages/web/pages/experience/brand/index.tsx new file mode 100644 index 00000000000..7b748332055 --- /dev/null +++ b/packages/web/pages/experience/brand/index.tsx @@ -0,0 +1,3 @@ +import Intro from 'src/brandkit/Intro' + +export default Intro diff --git a/packages/web/pages/experience/brand/key-imagery.tsx b/packages/web/pages/experience/brand/key-imagery.tsx new file mode 100644 index 00000000000..1e21eea5208 --- /dev/null +++ b/packages/web/pages/experience/brand/key-imagery.tsx @@ -0,0 +1,2 @@ +import KeyImagery from 'src/brandkit/KeyImagery' +export default KeyImagery diff --git a/packages/web/pages/experience/brand/logo.tsx b/packages/web/pages/experience/brand/logo.tsx new file mode 100644 index 00000000000..62ba9759399 --- /dev/null +++ b/packages/web/pages/experience/brand/logo.tsx @@ -0,0 +1,3 @@ +import Logo from 'src/brandkit/Logo' + +export default Logo diff --git a/packages/web/pages/experience/brand/typography.tsx b/packages/web/pages/experience/brand/typography.tsx new file mode 100644 index 00000000000..0d0412358f7 --- /dev/null +++ b/packages/web/pages/experience/brand/typography.tsx @@ -0,0 +1,3 @@ +import Typography from 'src/brandkit/Typography' + +export default Typography diff --git a/packages/web/server-env-config.js.enc b/packages/web/server-env-config.js.enc index f9609e7f7519567802b242cddbbbdd6a6d1f802e..bcbed698e0b718e357c5f362343e40d4a8e6e0ba 100644 GIT binary patch literal 2448 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 Om^8ZaF2Xa)NOnHHySbJC literal 2321 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 diff --git a/packages/web/server/AssetBase.ts b/packages/web/server/AssetBase.ts new file mode 100644 index 00000000000..aece66473b6 --- /dev/null +++ b/packages/web/server/AssetBase.ts @@ -0,0 +1,66 @@ +import { Attachment, FieldSet, Table } from 'airtable' +import getConfig from 'next/config' +import airtableInit from './airtable' + +const ASSSET_FIELD_LIGHT = 'Assets (on light bg)' +const ASSSET_FIELD_DARK = 'Assets (on dark bg)' + +interface Fields extends FieldSet { + Name: string + Description: string + [ASSSET_FIELD_LIGHT]: Attachment[] + [ASSSET_FIELD_DARK]: Attachment[] + Zip: Attachment[] + Terms: boolean + Tags: string[] +} + +enum AssetSheet { + Icons = 'Icons', + Illustrations = 'Illustrations', + AbstractGraphics = 'Abstract Graphics', +} + +export default function getAssets(sheet: AssetSheet) { + return getAirtable(sheet) + .select({ + filterByFormula: `AND(${IS_APROVED}, ${TERMS_SIGNED})`, + sort: [{ field: 'Name', direction: 'desc' }], + }) + .all() + .then((records) => { + return records.map((r) => normalize(r.fields)) + }) +} + +function getAirtable(sheet: AssetSheet): Table { + return airtableInit(getConfig().serverRuntimeConfig.AIRTABLE_BRANDKIT_ID)(sheet) +} + +const IS_APROVED = 'Approved=1' +const TERMS_SIGNED = 'Terms=1' + +function normalize(asset: Fields) { + return { + name: asset.Name, + description: asset.Description, + preview: getPreview(asset), + uri: getURI(asset), + } +} + +function getPreview(asset: Fields) { + const previewField = asset[ASSSET_FIELD_LIGHT] + + return ( + (previewField && + previewField[0] && + previewField[0].thumbnails && + previewField[0].thumbnails.large.url) || + '' + ) +} + +function getURI(asset: Fields) { + return (asset.Zip && asset.Zip[0] && asset.Zip[0].url) || '' +} diff --git a/packages/web/server/index.ts b/packages/web/server/index.ts index f7bf748bca4..7b2b3fd12a4 100644 --- a/packages/web/server/index.ts +++ b/packages/web/server/index.ts @@ -13,6 +13,7 @@ import ecoFundSubmission from '../server/EcoFundApp' import { RequestType } from '../src/fauceting/FaucetInterfaces' import nextI18next from '../src/i18n' import latestAnnouncements from './Announcement' +import getAssets from './AssetBase' import { faucetOrInviteController } from './controllers' import getFormattedEvents from './EventHelpers' import { submitFellowApp } from './FellowshipApp' @@ -74,9 +75,14 @@ function wwwRedirect(req, res, nextAction) { }) }) + server.get('/brand', (_, res) => { + res.redirect('/experience/brand') + }) + server.get('/connect', (_, res) => { res.redirect('/community') }) + server.get('/tos', (_, res) => { res.redirect('/user-agreement') }) @@ -141,6 +147,15 @@ function wwwRedirect(req, res, nextAction) { } }) + server.get('/brand/api/assets/:asset', async (req, res) => { + try { + const assets = await getAssets(req.params.asset) + res.json(assets) + } catch (e) { + res.status(e.statusCode || 500).json({ message: e.message || 'unknownError' }) + } + }) + server.post('/partnerships-email', async (req, res) => { const { email } = req.body await mailer({ diff --git a/packages/web/src/brandkit/Color.tsx b/packages/web/src/brandkit/Color.tsx new file mode 100644 index 00000000000..2c251a04658 --- /dev/null +++ b/packages/web/src/brandkit/Color.tsx @@ -0,0 +1,150 @@ +import * as React from 'react' +import { withNamespaces } from 'react-i18next' +import { ImageBackground, ImageRequireSource, StyleSheet, Text, View } from 'react-native' +import Palette from 'src/brandkit/color/Palette' +import { brandStyles } from 'src/brandkit/common/constants' +import { + ACCENT_PALETTE, + BACKGROUND_PALETTE, + GRAY_PALETTE, + PRIMARY_PALETTE, +} from 'src/brandkit/common/data' +import Page from 'src/brandkit/common/Page' +import PageHeadline from 'src/brandkit/common/PageHeadline' +import SectionTitle from 'src/brandkit/common/SectionTitle' +import Judgement, { Value } from 'src/brandkit/logo/Judgement' +import { I18nProps, NameSpaces } from 'src/i18n' +import { ScreenProps, ScreenSizes, withScreenSize } from 'src/layout/ScreenSize' +import { hashNav } from 'src/shared/menu-items' +import { colors, fonts, standardStyles } from 'src/styles' +const { brandColor } = hashNav + +export default React.memo(function Color() { + return ( + }, + { id: brandColor.backgrounds, children: }, + ]} + /> + ) +}) + +const Overview = withNamespaces(NameSpaces.brand)(function _Overview({ t }: I18nProps) { + return ( + + + + + + + ) +}) + +const Backgrounds = withNamespaces(NameSpaces.brand)( + withScreenSize(function _Backgrounds({ t, screen }: I18nProps & ScreenProps) { + const stylesForJudgemnt = screen === ScreenSizes.DESKTOP ? styles.column : [standardStyles.row] + + return ( + + {t('color.backgroundTitle')} + + + {t('color.contrast')} + + {t('color.contrastText')} + + + + + {t('color.contrastText2')} + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + }) +) + +interface LoremProps { + backgroundColor: colors + color: colors + withGap?: boolean + hasBorder?: boolean + image?: ImageRequireSource +} + +function Lorem({ backgroundColor, color, withGap, hasBorder, image }: LoremProps) { + const Component = image ? ImageBackground : View + + return ( + // @ts-ignore : component does not have call signature? + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras ac dignissim purus. + + + ) +} + +const styles = StyleSheet.create({ + container: { padding: 10 }, + lorem: { + flex: 1, + paddingVertical: 20, + paddingHorizontal: 20, + minHeight: 200, + }, + column: { + flex: 1, + }, +}) diff --git a/packages/web/src/brandkit/IconsPage.tsx b/packages/web/src/brandkit/IconsPage.tsx new file mode 100644 index 00000000000..201236f417b --- /dev/null +++ b/packages/web/src/brandkit/IconsPage.tsx @@ -0,0 +1,90 @@ +import * as React from 'react' +import { withNamespaces } from 'react-i18next' +import { StyleSheet, Text, View } from 'react-native' + +import { brandStyles, GAP } from 'src/brandkit/common/constants' +import Page from 'src/brandkit/common/Page' +import PageHeadline from 'src/brandkit/common/PageHeadline' +import { I18nProps, NameSpaces, Trans } from 'src/i18n' + +import Fetch from 'src/brandkit/common/Fetch' +import IconShowcase from 'src/brandkit/common/Showcase' +import InlineAnchor from 'src/shared/InlineAnchor' +import { CeloLinks, hashNav } from 'src/shared/menu-items' +import { fonts, standardStyles } from 'src/styles' + +export default React.memo(function IconsPage() { + return ( + , + }, + ]} + /> + ) +}) + +interface IconData { + description: string + name: string + preview: string + uri: string +} + +const LOADING = new Array(12) + +const Overview = withNamespaces(NameSpaces.brand)(function _Overview({ t }: I18nProps) { + return ( + + + + {t('licenseTitle')} + + + + + Creative Commons Attribution-NoDerivatives 4.0 International License + + + + + + {({ loading, data }: { loading: boolean; data: IconData[] }) => { + if (loading) { + return LOADING.map((_, i) => { + return ( + + ) + }) + } + + return data.map((icon) => ( + + )) + }} + + + + ) +}) + +const styles = StyleSheet.create({ + container: { paddingHorizontal: GAP }, +}) diff --git a/packages/web/src/brandkit/Intro.tsx b/packages/web/src/brandkit/Intro.tsx new file mode 100644 index 00000000000..849daddda19 --- /dev/null +++ b/packages/web/src/brandkit/Intro.tsx @@ -0,0 +1,37 @@ +import * as React from 'react' +import { Text, View } from 'react-native' +import { brandStyles } from 'src/brandkit/common/constants' +import Page from 'src/brandkit/common/Page' +import { H1, H4 } from 'src/fonts/Fonts' +import { I18nProps, NameSpaces, Trans, withNamespaces } from 'src/i18n' +import InlineAnchor from 'src/shared/InlineAnchor' +import menuItems from 'src/shared/menu-items' +import { fonts, standardStyles } from 'src/styles' + +export default React.memo(function Intro() { + return ( + , + }, + ]} + /> + ) +}) + +const Overview = withNamespaces(NameSpaces.brand)(function _Overview({ t }: I18nProps) { + return ( + +

{t('home.title')}

+

{t('home.introduction')}

+ {t('home.useageTitle')} + + + Code Of Conduct + + +
+ ) +}) diff --git a/packages/web/src/brandkit/KeyImagery.tsx b/packages/web/src/brandkit/KeyImagery.tsx new file mode 100644 index 00000000000..0ff63410a57 --- /dev/null +++ b/packages/web/src/brandkit/KeyImagery.tsx @@ -0,0 +1,37 @@ +import * as React from 'react' +import { withNamespaces } from 'react-i18next' +import { StyleSheet, Text, View } from 'react-native' +import Page from 'src/brandkit/common/Page' +import { hashNav } from 'src/shared/menu-items' + +const { brandImagery } = hashNav + +// TODO in v 1.1 +const KeyImageryWrapped = withNamespaces()( + React.memo(function KeyImagery() { + return ( + overview, + }, + { + id: brandImagery.illustrations, + children: illustrations, + }, + { + id: brandImagery.graphics, + children: graphics, + }, + ]} + /> + ) + }) +) + +export default KeyImageryWrapped + +// const styles = StyleSheet.create({ +// container: { padding: 10 }, +// }) diff --git a/packages/web/src/brandkit/Logo.tsx b/packages/web/src/brandkit/Logo.tsx new file mode 100644 index 00000000000..8b485c1ad32 --- /dev/null +++ b/packages/web/src/brandkit/Logo.tsx @@ -0,0 +1,347 @@ +import * as React from 'react' +import { Image, StyleSheet, Text, View } from 'react-native' +import Palette from 'src/brandkit/color/Palette' +import { brandStyles, GAP } from 'src/brandkit/common/constants' +import { BACKGROUND_PALETTE } from 'src/brandkit/common/data' +import DownloadButton from 'src/brandkit/common/DownloadButton' +import Page from 'src/brandkit/common/Page' +import SectionTitle from 'src/brandkit/common/SectionTitle' +import TripplePairing from 'src/brandkit/common/TripplePairing' +import Judgement, { Value } from 'src/brandkit/logo/Judgement' +import LogoExample, { Logos } from 'src/brandkit/logo/LogoExample' +import LogoWithBackground from 'src/brandkit/logo/LogoWithBackground' +import { Digital, Print } from 'src/brandkit/logo/Minimums' +import { H1, H3 } from 'src/fonts/Fonts' +import { I18nProps, NameSpaces, Trans, withNamespaces } from 'src/i18n' +import { ScreenProps, ScreenSizes, withScreenSize } from 'src/layout/ScreenSize' +import LogoLightBg from 'src/logos/LogoLightBg' +import RingsGlyph from 'src/logos/RingsGlyph' +import AspectRatio from 'src/shared/AspectRatio' +import Button, { BTN } from 'src/shared/Button.3' +import InlineAnchor from 'src/shared/InlineAnchor' +import menuItems, { hashNav } from 'src/shared/menu-items' +import { colors, fonts, standardStyles } from 'src/styles' + +export default React.memo(function Logo() { + return ( + , + }, + { + id: hashNav.brandLogo.space, + children: , + }, + { + id: hashNav.brandLogo.backgrounds, + children: , + }, + ]} + /> + ) +}) + +const Overview = withNamespaces(NameSpaces.brand)( + withScreenSize(function _Overview({ t, screen }: I18nProps & ScreenProps) { + const glyphAreaStyle = screen === ScreenSizes.DESKTOP ? styles.pilar : styles.square + return ( + + +

{t('logo.title')}

+ + {t('logo.overviewCopy')} + +