diff --git a/components/BottomShare/index.js b/components/BottomShare/index.js
new file mode 100644
index 0000000..6662a13
--- /dev/null
+++ b/components/BottomShare/index.js
@@ -0,0 +1,21 @@
+// @flow
+import React from 'react';
+import Card from '../Card';
+import ShareButtons from '../ShareButtons';
+import { CardContent, TopBorder } from './style';
+import { SmallHeading, SmallSubheading } from '../Page/style';
+
+const BottomShare = () => (
+
+
+
+ Feeling more secure?
+
+ Spread the word about improving online privacy and security
+
+
+
+
+);
+
+export default BottomShare;
diff --git a/components/BottomShare/style.js b/components/BottomShare/style.js
new file mode 100644
index 0000000..aa08645
--- /dev/null
+++ b/components/BottomShare/style.js
@@ -0,0 +1,23 @@
+// @flow
+import styled from 'styled-components';
+
+export const CardContent = styled.div`
+ padding: 24px;
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-direction: column;
+ text-align: center;
+
+ @media (max-width: 768px) {
+ padding-top: 40px;
+ }
+`;
+
+export const TopBorder = styled.div`
+ width: 100%;
+ height: 4px;
+ background-image: linear-gradient(to left, #a913de, #6ac9ff);
+ border-radius: 6px 6px 0 0;
+`;
diff --git a/components/Checklist/style.js b/components/Checklist/style.js
index 535ac4f..342e70a 100644
--- a/components/Checklist/style.js
+++ b/components/Checklist/style.js
@@ -4,6 +4,6 @@ import styled from 'styled-components';
export const Grid = styled.div`
display: grid;
grid-template-columns: 1fr;
- margin-top: 32px;
+ margin-top: 48px;
width: 100%;
`;
diff --git a/components/ChecklistItem/Heading.js b/components/ChecklistItem/Heading.js
index 2e9936e..77c9fb5 100644
--- a/components/ChecklistItem/Heading.js
+++ b/components/ChecklistItem/Heading.js
@@ -1,15 +1,22 @@
// @flow
import React from 'react';
-import { Title, Description } from './style';
+import { Title, Description, Uncollapse } from './style';
import type { ChecklistResource } from '../../types';
type Props = {
resource: ChecklistResource,
+ isCollapsed: boolean,
+ handleCollapse: Function,
};
-export const Heading = ({ resource }: Props) => (
+export const Heading = ({ resource, isCollapsed, handleCollapse }: Props) => (
- {resource.title}
-
+
+ {resource.title}
+
+ {isCollapsed ? 'Show details' : 'Hide details'}
+
+
+ {!isCollapsed && }
);
diff --git a/components/ChecklistItem/index.js b/components/ChecklistItem/index.js
index 5c74a60..c9fbeb1 100644
--- a/components/ChecklistItem/index.js
+++ b/components/ChecklistItem/index.js
@@ -23,26 +23,34 @@ type Props = {
type State = {
isChecked: boolean,
isLoading: boolean,
+ isCollapsed: boolean,
};
class ChecklistItem extends React.Component {
- state = { isChecked: false, isLoading: true };
+ state = { isChecked: false, isLoading: true, isCollapsed: true };
componentDidMount() {
const { resource } = this.props;
const isChecked = getCheckedStatusById(resource.id);
- return this.setState({ isChecked, isLoading: false });
+ return this.setState({
+ isChecked,
+ isLoading: false,
+ isCollapsed: isChecked,
+ });
}
handleSetChecked = () => {
const { isChecked } = this.state;
const { resource } = this.props;
setCheckedStatusById(resource.id, !isChecked);
- return this.setState({ isChecked: !isChecked });
+ return this.setState({ isChecked: !isChecked, isCollapsed: !isChecked });
};
+ uncollapse = () =>
+ this.setState(state => ({ isCollapsed: !state.isCollapsed }));
+
render() {
- const { isChecked, isLoading } = this.state;
+ const { isChecked, isLoading, isCollapsed } = this.state;
const { resource } = this.props;
if (isLoading) return ;
@@ -50,21 +58,26 @@ class ChecklistItem extends React.Component {
return (
-
+
-
-
- {resource.apps && (
+
+
+
+ {!isCollapsed && resource.apps && (
)}
- {resource.resources && (
+ {!isCollapsed && resource.resources && (
diff --git a/components/ChecklistItem/style.js b/components/ChecklistItem/style.js
index ddc17ff..cacc8e6 100644
--- a/components/ChecklistItem/style.js
+++ b/components/ChecklistItem/style.js
@@ -14,7 +14,7 @@ export const CardContent = styled.div`
width: 100%;
@media (max-width: 768px) {
- flex-direction: column;
+ flex-direction: ${props => (props.isCollapsed ? 'row' : 'column')};
}
`;
@@ -22,6 +22,10 @@ export const Title = styled.h3`
font-size: 18px;
font-weight: 500;
color: ${theme.text.default};
+ display: flex;
+ line-height: 1.2;
+ justify-content: space-between;
+ align-items: center;
`;
export const Description = styled(Markdown)`
@@ -72,16 +76,25 @@ export const Checkbox = styled.span`
height: 32px;
border-radius: 4px;
border: 1px solid
- ${props => (props.isChecked ? theme.brand.default : theme.border.default)};
+ ${props => (props.isChecked ? theme.bg.default : theme.border.default)};
background: ${props =>
- props.isChecked ? theme.brand.default : theme.bg.wash};
+ props.isChecked ? theme.success.default : theme.bg.wash};
cursor: pointer;
position: relative;
+ background-image: ${props =>
+ props.isChecked
+ ? 'radial-gradient(circle at top right, #a913de, #6ac9ff)'
+ : 'none'};
+ box-shadow: ${props =>
+ props.isChecked ? 'inset 0 0 1px rgba(0,0,0,0.4)' : 'none'};
&:hover {
- ${Shadows.default};
- border: 1px solid
- ${props => (props.isChecked ? theme.brand.default : theme.border.active)};
+ ${props => !props.isChecked && Shadows.default};
+ background: ${theme.bg.default};
+ background-image: ${props =>
+ props.isChecked
+ ? 'radial-gradient(circle at top right, #a913de, #6ac9ff)'
+ : 'none'};
}
&:after {
@@ -102,12 +115,15 @@ export const Checkbox = styled.span`
export const ResourceContent = styled.div`
display: flex;
flex-direction: column;
+ margin-top: 2px;
padding-left: 16px;
width: 100%;
+ justify-content: ${props => (props.isCollapsed ? 'center' : 'flex-start')};
@media (max-width: 768px) {
- padding-left: 8px;
- margin-top: 24px;
+ padding-left: ${props => (props.isCollapsed ? '16px' : '8px')};
+ margin-top: ${props => (props.isCollapsed ? '0px' : '24px')};
+ justify-content: ${props => (props.isCollapsed ? 'center' : 'flex-start')};
}
`;
@@ -302,3 +318,26 @@ export const Divider = styled.div`
display: none;
}
`;
+
+export const Uncollapse = styled.span`
+ background: ${theme.bg.wash};
+ border-radius: 20px;
+ padding: 8px 16px;
+ font-size: 15px;
+ color: ${theme.text.tertiary};
+ cursor: pointer;
+ line-height: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-right: 8px;
+
+ @media (max-width: 768px) {
+ display: none;
+ }
+
+ &:hover {
+ color: ${theme.text.default};
+ background: ${tint(theme.bg.wash, -4)};
+ }
+`;
diff --git a/components/Header/Logo.js b/components/Header/Logo.js
index 211599b..310bfec 100644
--- a/components/Header/Logo.js
+++ b/components/Header/Logo.js
@@ -9,22 +9,26 @@ const Logo = () => (
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
-
-
+
+
+
+
+
+
@@ -33,9 +37,9 @@ const Logo = () => (
diff --git a/components/LoadingChecklistItem/index.js b/components/LoadingChecklistItem/index.js
index ca79e8e..1065f72 100644
--- a/components/LoadingChecklistItem/index.js
+++ b/components/LoadingChecklistItem/index.js
@@ -4,7 +4,7 @@ import { ShimmerInboxThread, ShimmerBase, ShimmerLine, Cover } from './style';
import Card from '../Card';
const LoadingChecklistItem = () => (
-
+
diff --git a/components/Page/index.js b/components/Page/index.js
index 83612f1..c3075cc 100644
--- a/components/Page/index.js
+++ b/components/Page/index.js
@@ -13,14 +13,12 @@ import {
SectionHeading,
Heading,
Subheading,
- LargeHeading,
- LargeSubheading,
InnerContainer,
ScrollToTop,
} from './style';
import * as gtag from '../../lib/gtag';
-export { SectionHeading, Heading, Subheading, LargeHeading, LargeSubheading };
+export { SectionHeading, Heading, Subheading };
type Props = {
children: Node,
diff --git a/components/Page/style.js b/components/Page/style.js
index 903f6f7..20b4973 100644
--- a/components/Page/style.js
+++ b/components/Page/style.js
@@ -75,12 +75,16 @@ export const Subheading = styled.h4`
}
`;
-export const LargeHeading = styled(Heading)`
- font-size: 32px;
+export const SmallHeading = styled(Heading)`
+ font-size: 30px;
+ margin-bottom: 4px;
+ margin-top: 8px;
`;
-export const LargeSubheading = styled(Subheading)`
+export const SmallSubheading = styled(Subheading)`
font-size: 20px;
+ margin-top: 4px;
+ margin-bottom: 32px;
`;
export const ScrollToTop = styled.button`
@@ -97,6 +101,7 @@ export const ScrollToTop = styled.button`
transition: all 0.2s ease-in-out;
opacity: ${props => (props.isVisible ? '1' : '0')};
background: ${theme.text.default};
+ background-image: radial-gradient(circle at top right, #a913de, #6ac9ff);
color: ${theme.bg.default};
transform: translateY(${props => (props.isVisible ? '0' : '80px')});
cursor: pointer;
diff --git a/components/ShareButtons/style.js b/components/ShareButtons/style.js
index 5946ddd..45e9a2a 100644
--- a/components/ShareButtons/style.js
+++ b/components/ShareButtons/style.js
@@ -5,8 +5,6 @@ export const Container = styled.div`
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 16px;
- margin-top: 40px;
- margin-bottom: 16px;
width: 100%;
button {
diff --git a/config/browsers.js b/config/browsers.js
index aa7257a..3174673 100644
--- a/config/browsers.js
+++ b/config/browsers.js
@@ -30,6 +30,15 @@ export default {
android: 'https://www.mozilla.org/en-US/firefox/mobile/',
},
},
+ {
+ name: 'Safari',
+ image: '/static/img/safari.jpg',
+ url: 'https://www.apple.com/safari/',
+ sources: {
+ windows: 'https://www.apple.com/safari/',
+ macos: 'https://www.apple.com/safari/',
+ },
+ },
{
name: 'Tor',
image: '/static/img/tor.png',
diff --git a/config/data.js b/config/data.js
index 38b7676..e544ed6 100644
--- a/config/data.js
+++ b/config/data.js
@@ -19,15 +19,15 @@ export default {
strongDevicePasscode,
twoFactor,
carrierPin,
- creditFreeze,
encryptedHardware,
+ creditFreeze,
dns,
vpn,
+ webcam,
browsers,
searchEngine,
email,
appPermissions,
- webcam,
socialMedia,
phishing,
};
diff --git a/cypress/integration/home_spec.js b/cypress/integration/home_spec.js
index fbe5eec..4213161 100644
--- a/cypress/integration/home_spec.js
+++ b/cypress/integration/home_spec.js
@@ -1,3 +1,5 @@
+import data from '../../config/data';
+
describe('Home', () => {
before(() => {
cy.visit('/');
@@ -23,4 +25,11 @@ describe('Home', () => {
'be.visible'
);
});
+
+ it('should render content', () => {
+ const dataKeys = Object.keys(data);
+ dataKeys.map(key => {
+ cy.contains(data[key].title);
+ });
+ });
});
diff --git a/pages/index.js b/pages/index.js
index dce05c1..625a04c 100644
--- a/pages/index.js
+++ b/pages/index.js
@@ -4,6 +4,7 @@ import Page, { SectionHeading, Heading, Subheading } from '../components/Page';
import type { GetInitialProps } from '../types';
import Checklist from '../components/Checklist';
import ShareButtons from '../components/ShareButtons';
+import BottomShare from '../components/BottomShare';
class Index extends React.Component<{}> {
static async getInitialProps({ res }: GetInitialProps) {
@@ -22,14 +23,19 @@ class Index extends React.Component<{}> {
Be safe on the internet.
- An open source collection of resources designed to improve your
- online privacy and security.
+ An open source checklist of resources designed to improve your
+ online privacy and security. Check things off to keep track as you
+ go.
+
+
+
+
);
}
diff --git a/static/android-icon-144x144.png b/static/android-icon-144x144.png
index f3594a0..266176c 100644
Binary files a/static/android-icon-144x144.png and b/static/android-icon-144x144.png differ
diff --git a/static/android-icon-192x192.png b/static/android-icon-192x192.png
index a3300c5..16b7a57 100644
Binary files a/static/android-icon-192x192.png and b/static/android-icon-192x192.png differ
diff --git a/static/android-icon-36x36.png b/static/android-icon-36x36.png
index f7848c3..9b83f81 100644
Binary files a/static/android-icon-36x36.png and b/static/android-icon-36x36.png differ
diff --git a/static/android-icon-48x48.png b/static/android-icon-48x48.png
index 708bbe5..c91694d 100644
Binary files a/static/android-icon-48x48.png and b/static/android-icon-48x48.png differ
diff --git a/static/android-icon-72x72.png b/static/android-icon-72x72.png
index 7ceb0b6..9c4f4c0 100644
Binary files a/static/android-icon-72x72.png and b/static/android-icon-72x72.png differ
diff --git a/static/android-icon-96x96.png b/static/android-icon-96x96.png
index 2dac94b..a089eab 100644
Binary files a/static/android-icon-96x96.png and b/static/android-icon-96x96.png differ
diff --git a/static/apple-icon-114x114.png b/static/apple-icon-114x114.png
index dcaedba..53947f2 100644
Binary files a/static/apple-icon-114x114.png and b/static/apple-icon-114x114.png differ
diff --git a/static/apple-icon-120x120.png b/static/apple-icon-120x120.png
index fc595f3..f0abcb9 100644
Binary files a/static/apple-icon-120x120.png and b/static/apple-icon-120x120.png differ
diff --git a/static/apple-icon-144x144.png b/static/apple-icon-144x144.png
index f3594a0..266176c 100644
Binary files a/static/apple-icon-144x144.png and b/static/apple-icon-144x144.png differ
diff --git a/static/apple-icon-152x152.png b/static/apple-icon-152x152.png
index dc0e378..e97cbbf 100644
Binary files a/static/apple-icon-152x152.png and b/static/apple-icon-152x152.png differ
diff --git a/static/apple-icon-180x180.png b/static/apple-icon-180x180.png
index e903fad..6634e95 100644
Binary files a/static/apple-icon-180x180.png and b/static/apple-icon-180x180.png differ
diff --git a/static/apple-icon-57x57.png b/static/apple-icon-57x57.png
index 3272046..22f72c5 100644
Binary files a/static/apple-icon-57x57.png and b/static/apple-icon-57x57.png differ
diff --git a/static/apple-icon-60x60.png b/static/apple-icon-60x60.png
index f45ae31..669b3b8 100644
Binary files a/static/apple-icon-60x60.png and b/static/apple-icon-60x60.png differ
diff --git a/static/apple-icon-72x72.png b/static/apple-icon-72x72.png
index 7ceb0b6..9c4f4c0 100644
Binary files a/static/apple-icon-72x72.png and b/static/apple-icon-72x72.png differ
diff --git a/static/apple-icon-76x76.png b/static/apple-icon-76x76.png
index 59fcc93..3de1155 100644
Binary files a/static/apple-icon-76x76.png and b/static/apple-icon-76x76.png differ
diff --git a/static/apple-icon-precomposed.png b/static/apple-icon-precomposed.png
index 5897c1f..2d5d9cf 100644
Binary files a/static/apple-icon-precomposed.png and b/static/apple-icon-precomposed.png differ
diff --git a/static/apple-icon.png b/static/apple-icon.png
index 5897c1f..2d5d9cf 100644
Binary files a/static/apple-icon.png and b/static/apple-icon.png differ
diff --git a/static/favicon-16x16.png b/static/favicon-16x16.png
index 628ee61..7c5db09 100644
Binary files a/static/favicon-16x16.png and b/static/favicon-16x16.png differ
diff --git a/static/favicon-32x32.png b/static/favicon-32x32.png
index f74f51b..5de2630 100644
Binary files a/static/favicon-32x32.png and b/static/favicon-32x32.png differ
diff --git a/static/favicon-96x96.png b/static/favicon-96x96.png
index 2dac94b..a089eab 100644
Binary files a/static/favicon-96x96.png and b/static/favicon-96x96.png differ
diff --git a/static/favicon.ico b/static/favicon.ico
index 0c2b0d4..5ac692e 100644
Binary files a/static/favicon.ico and b/static/favicon.ico differ
diff --git a/static/img/safari.jpg b/static/img/safari.jpg
new file mode 100644
index 0000000..20d19c3
Binary files /dev/null and b/static/img/safari.jpg differ
diff --git a/static/ms-icon-144x144.png b/static/ms-icon-144x144.png
index f3594a0..266176c 100644
Binary files a/static/ms-icon-144x144.png and b/static/ms-icon-144x144.png differ
diff --git a/static/ms-icon-150x150.png b/static/ms-icon-150x150.png
index 3230170..f7c13ff 100644
Binary files a/static/ms-icon-150x150.png and b/static/ms-icon-150x150.png differ
diff --git a/static/ms-icon-310x310.png b/static/ms-icon-310x310.png
index af428ac..e45b34e 100644
Binary files a/static/ms-icon-310x310.png and b/static/ms-icon-310x310.png differ
diff --git a/static/ms-icon-70x70.png b/static/ms-icon-70x70.png
index 71b103e..4afbe6d 100644
Binary files a/static/ms-icon-70x70.png and b/static/ms-icon-70x70.png differ
diff --git a/static/og-image.png b/static/og-image.png
index fe224b3..5880c87 100644
Binary files a/static/og-image.png and b/static/og-image.png differ