diff --git a/.vscode/settings.json b/.vscode/settings.json index ad8767b3..deefd6d4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,4 @@ { - "vsicons.presets.angular": true -} \ No newline at end of file + "vsicons.presets.angular": true, + "editor.formatOnSave": false +} diff --git a/src/app/MetaService.ts b/src/app/MetaService.ts new file mode 100644 index 00000000..b798079a --- /dev/null +++ b/src/app/MetaService.ts @@ -0,0 +1,82 @@ +import { Injectable } from '@angular/core'; +import { Meta, Title } from '@angular/platform-browser'; + +@Injectable({ + providedIn: 'root', +}) + +export class MetaService { + constructor(private title: Title, private meta: Meta) { } + + clearAllTags() { + + // Only remove og, twitter, and description meta tags to avoid removing things like the viewport tag. + + let tags = this.meta.getTags('property^="og:"'); + for (let i = 0; i < tags.length; i++) { + this.meta.removeTagElement(tags[i]) + } + + tags = this.meta.getTags('name^="twitter:"'); + for (let i = 0; i < tags.length; i++) { + this.meta.removeTagElement(tags[i]) + } + + this.meta.removeTag('name="description"'); + } + + update(name: string, value: string) { + let tag = null; + + // OG tags use the "property" attribute instead of "name" + if (/^og:/.test(name)) { + tag = this.meta.getTag(`property="${name}"`); + } else { + tag = this.meta.getTag(`name="${name}"`); + } + + if (name === 'title') { + this.title.setTitle(value); + } else if (tag) { + if (/^og:/.test(name)) { + this.meta.updateTag({ name: name, content: value }, `property="${name}"`) + } else { + this.meta.updateTag({ name: name, content: value }, `name="${name}"`) + } + } else { + if (/^og:/.test(name)) { + this.meta.addTag({ property: name, content: value }) + } else { + this.meta.addTag({ name: name, content: value }) + } + } + } + + remove(name: string, value: string) { + // OG tags use the "property" attribute instead of "name" + if (/^og:/.test(name)) { + this.meta.removeTag(`property="${name}"`); + } else { + this.meta.removeTag(`name="${name}"`); + } + } + + // The following "setGlobalX" functions refer to "global" as covering the three major meta schemas: w3c, OpenGraph, and Twitter. + setGlobalImage(image: string) { + if (!/^https:\/\//.test(image)) { + image = `https://www.orchid.com${image}`; + } + this.update('og:image', image); + this.update('twitter:image', image); + } + setGlobalDescription(description: string) { + this.update('description', description); + this.update('og:description', description); + this.update('twitter:description', description); + } + setGlobalTitle(title: string) { + this.update('title', title); + this.update('og:title', title); + this.update('twitter:title', title); + } +} \ No newline at end of file diff --git a/src/app/about-company/about-company.component.html b/src/app/about-company/about-company.component.html index 049cc5a5..ce85fb43 100644 --- a/src/app/about-company/about-company.component.html +++ b/src/app/about-company/about-company.component.html @@ -1,198 +1,89 @@ -
-
-
-
-

About us

-
-

- Orchid was founded in 2017, on the principle that the internet should be more open and more accessible, to - everyone. In 2017 and 2018, Orchid successfully raised more than $48 million, and those funds immediately went - towards building the Orchid team – now with offices in CA and Berlin – and to creating the technology and - products that will advance our mission. -

-
-
- splash image -
-
-
- -
-
-
-
-
- -
-
-
-

Can decentralized technologies preserve democracy? (Oslo Freedom Forum)

-

- Dr. Seven Waterhouse, Orchid co-founder & CEO discusses solutions to combat the global rise of centralized - surveillance states and how decentralization of the global internet architecture could be the key to - preserving democracy, privacy, and individual rights. -

-
-
-
-
-
-
-

- - Why We Need a Better VPN - -

-

- As dueling interests move to control the future of the internet, users around the globe are increasingly - turning to VPNs. But what users don't know is that many VPNs fail to provide the security and privacy that - they advertise. -

+
+
+
+
+

We can
reclaim the
internet
together

-
-
-
-
-

- - Access Denied: Restoring the Internet's Openness - -

-

- Governments and corporate interests are competing to own the future of the internet, and with it, control - information and personal data. As users, developers, and investors, how can we take back control? -

+
+ splash image
-
-
-
-
-

- - The Commodification of You - -

-

- How ISPs, apps, third parties, and websites are raking in the big bucks by tracking your clicks, emails, and - purchases—and what we can do to control our digital identities. -

-
-
-
-
+ + -
-
-

Founders

-

- Orchid’s founders bring together deep experience in the open source software community (BASH Shell, GNU Finger), - technology management (RPX IPO), blockchain investment (Bitstamp, Pantera Capital), jailbroken app package - management (Cydia) and security (Wells Fargo’s 1st Online Banking, Ethereum core security team). -

- -
-
+
+
+
-
-
-

Backed by leading investors

-
    -
  • DFJ
  • -
  • Andreessen Horowitz
  • -
  • Sequoia
  • -
-
    -
  • Yes VC
  • -
  • Danhua Capital -
  • -
  • C
  • -
  • MetaStable
  • -
-
    -
  • Blockchain Capital
  • -
  • Box Group
  • -
-
-

- “Orchid struck us as one of the first killer apps that we can see getting broad appeal. It also has an important - mission that we think is very timely in the world today.” -

-

- — Matt Huang, Former Sequoia partner and Paradigm co-founder (Business Insider, Nov. 2017) +

+

The Internet opened up an unlimited world of information. Its creators invited us to bring our curiosity and explore that world freely.

+ +

As the Internet grew, exploring freely became harder. Web 2.0 business models incentivized companies to watch and track us and sell our data. And in some places, limits were placed on the information we can see.

+ +

But that is changing. The decentralized Web 3.0 being built on Ethereum is allowing the Internet to be reclaimed by its users.

+ +

At Orchid we share in this mission. We use Web 3.0 technology to offer users better digital privacy today, so we can realize the promise of the Web 1.0 and explore freely again.

+ +

Orchid was founded in 2017 to help restore the open and accessible Internet for everyone. Since then, we have grown an incredible team based in San Francisco and Berlin that is releasing the Orchid tokenized VPN in Q4 2019.

+
+
+ +
+
+

Founders

+

+ Orchid’s founders bring together deep experience in the open source software community (BASH Shell, GNU Finger), technology management (RPX IPO), blockchain investment (Pantera Capital), jailbroken app package management (Cydia) and security (Wells Fargo’s 1st Online Banking employee, Ethereum core security team).

-
-
    -
  • Wing
  • -
  • Foundation Capital -
  • -
  • BlockChange Capital
  • -
  • Scytale Ventures -
  • -
  • Standard Kepler
  • -
  • Hack VC
  • -
  • Struck Capital
  • -
  • Moon Capital
  • -
  • Springview Capital -
  • -
  • Altair Capital
  • -
  • KittyHawk
  • -
  • Crypto Bazar
  • -
  • Day One Ventures
  • -
-
-
+ + +
-
-
-
-

Corporate info

-

Orchid is a Delaware c-corp

-
-
-
- Headquarters:
- 1288 Columbus Ave. #122,
- San Francisco, CA 94133 -
-
- Europe:
- Skalitzer Str. 85,
- 10997 Berlin, Germany -
-
-
- - -
-
-
- +
+
+
+

Corporate info

+

Orchid is a Delaware c-corp

-
-
+
+
+ Headquarters:
+ 1288 Columbus Ave. #122,
+ San Francisco, CA 94133 +
+
+ Europe:
+ Skalitzer Str. 85,
+ 10997 Berlin, Germany +
+
+
+ + +
+
+
+ +
+
+ +
+ diff --git a/src/app/about-company/about-company.component.scss b/src/app/about-company/about-company.component.scss index 907624bd..b5d40173 100644 --- a/src/app/about-company/about-company.component.scss +++ b/src/app/about-company/about-company.component.scss @@ -3,6 +3,173 @@ @import "orc_config"; @import "styles"; +.about-company__page-container { + overflow-x: hidden; +} + +.about-company__splash { + @extend .section-wide; + @extend .hpad-thin; + + padding-bottom: $pad-wide; + + pointer-events: none; + + display: flex; + justify-content: center; + align-items: flex-end; + + @include mobile { + flex-direction: column-reverse; + justify-content: center; + align-items: center; + padding-bottom: 2rem; + } +} + +.about-company__splash-text-container { + h1 { + font-size: 3rem; + @include mobile { + font-size: 2rem; + text-align: center; + } + } + .big { + font-size: 160%; + } +} + +.about-company__splash-image-container { + width: 100%; + max-width: 800px; + @include mobile { + max-width: 620px; + } + + img { + width: 100%; + height: auto; + } + grid-area: image; + display: flex; + flex-flow: column nowrap; + justify-content: center; + align-items: center; + position: relative; + + @media (min-width: 1440px) { + margin-bottom: -100px; + } + + > img { + width: 100%; + height: auto; + position: relative; + z-index: 1; + + @include mobile { + //width: auto; + max-width: 100%; + } + } +} + +.about-company__splash-image-container:before { + content: " "; + display: block; + position: absolute; + top: 0; + left: -33.3333%; + height: 100%; + width: 205%; + background-size: auto 100%; + background-repeat: no-repeat; + background-position: top left; + background-image: url(/assets/img/company/splash/splash-background.svg); + pointer-events: none; +} + +.about-company__centered-text-floating-circle-1 { + position: absolute; + left: -5rem; + left: calc(50% - 38rem); + top: -5rem; + width: 10rem; + height: 10rem; + background-image: url(/assets/img/company/dashed-circle.svg); + background-position: center; + background-size: contain; + background-repeat: no-repeat; + pointer-events: none; +} +.about-company__centered-text-floating-circle-2 { + position: absolute; + right: -2rem; + right: calc(50% - 38rem); + bottom: -2rem; + width: 4rem; + height: 4rem; + border-radius: 100%; + border: 1.33px solid #bca9ff; + pointer-events: none; +} + +.about-company__centered-text-section-container { + position: relative; + + & > p { + position: relative; + z-index: 2; + } + &:before { + content: ""; + display: block; + position: absolute; + top: 0; + left: 50%; + height: 57%; + width: 50%; + max-width: 32.5rem; + background-image: url(/assets/img/company/background-circuits.svg); + background-position: bottom right; + background-repeat: no-repeat; + pointer-events: none; + @include mobile { + background-position: bottom left; + opacity: 0.5; + } + } + + &:after { + content: ""; + display: block; + position: absolute; + top: calc(100% - 12.7rem); + right: 50%; + height: 26rem; + width: 50%; + max-width: 33.6rem; + background-image: url(/assets/img/company/background-circuits-2.svg); + background-position: bottom left; + background-repeat: no-repeat; + pointer-events: none; + @include mobile { + opacity: 0.5; + } + } +} + +.about-company__centered-text-section { + @include mobile { + padding: 2rem; + text-align: left; + } + @include not-mobile { + max-width: 58rem; + } +} + header h1 { line-height: 67px; } @@ -23,7 +190,8 @@ header h1 { } @include mobile { - &, &#news-feature { + &, + &#news-feature { grid-template-rows: auto 2rem auto; grid-template-columns: 1fr; grid-template-areas: @@ -135,7 +303,7 @@ ul.sale-icons { } } -#corporate-info { +.about-company__corporate-info-section { display: grid; grid-template-rows: auto 1rem auto; // NB: 16.5rem taken from .btn-fixed @@ -145,6 +313,8 @@ ul.sale-icons { ". . buttons" "address . buttons"; + font-size: 0.9rem; + @include mobile { grid-template-rows: auto 1rem auto 1rem auto; grid-template-columns: 1fr; @@ -258,7 +428,22 @@ section h2:first-of-type { } } -#founders { +.about-company__founders-section { + position: relative; + z-index: 1; + + background-image: url(/assets/img/company/accent-circles.svg); + background-position: 80% 2%; + background-repeat: no-repeat; + pointer-events: none; + + @include mobile { + padding: 2rem; + & > .center-text { + text-align: left; + } + } + .waterhouse img { filter: grayscale(100%); } @@ -283,7 +468,11 @@ section h2:first-of-type { } } -#corporate-info { +.about-company__corporate-info-section { + @include mobile { + padding: 2rem; + } + #corporate-header { h2 { margin-left: 0; diff --git a/src/app/about-company/about-company.component.ts b/src/app/about-company/about-company.component.ts index 16a96a1c..b78d98f2 100644 --- a/src/app/about-company/about-company.component.ts +++ b/src/app/about-company/about-company.component.ts @@ -1,30 +1,35 @@ import { Component, OnInit } from '@angular/core'; +import { MetaService } from '../MetaService'; @Component({ - selector: 'app-about-company', - templateUrl: './about-company.component.html', - styleUrls: ['./about-company.component.scss'] + selector: 'app-about-company', + templateUrl: './about-company.component.html', + styleUrls: ['./about-company.component.scss'] }) export class AboutCompanyComponent implements OnInit { - constructor() { } + constructor(private meta: MetaService) { } - ngOnInit() { } + ngOnInit() { + this.meta.setGlobalTitle('About the Open Accessible Internet | Orchid'); + this.meta.setGlobalImage('https://www.orchid.com/assets/img/company/social.png'); + this.meta.setGlobalDescription('We believe the internet should be open and accessible to everyone, which is why we\'re building a truly open source network overlay VPN.'); + } go_sec() { - window.location.href = "https://www.sec.gov/Archives/edgar/data/1721086/000172108618000001/xslFormDX01/primary_doc.xml"; + window.location.href = "https://www.sec.gov/Archives/edgar/data/1721086/000172108618000001/xslFormDX01/primary_doc.xml"; } go_press() { - let kit = ""; - - if (window && "location" in window && "protocol" in window.location && - "pathname" in window.location && "host" in window.location) { - kit = window.location.protocol + "//" + window.location.host + "/assets/press/OrchidPressKit.zip"; - } else { - kit = "https://github.com/orchidprotocol/presskit"; - } + let kit = ""; + + if (window && "location" in window && "protocol" in window.location && + "pathname" in window.location && "host" in window.location) { + kit = window.location.protocol + "//" + window.location.host + "/assets/press/OrchidPressKit.zip"; + } else { + kit = "https://github.com/orchidprotocol/presskit"; + } - window.location.href = kit; + window.location.href = kit; } } diff --git a/src/app/about-network/about-network.component.ts b/src/app/about-network/about-network.component.ts index 87c3ae7b..a1e1d859 100644 --- a/src/app/about-network/about-network.component.ts +++ b/src/app/about-network/about-network.component.ts @@ -1,5 +1,6 @@ import { Component, OnInit } from '@angular/core'; import { downloadWhitepaper } from '../whitepaper'; +import { MetaService } from '../MetaService'; @Component({ selector: 'app-about-network', @@ -8,9 +9,11 @@ import { downloadWhitepaper } from '../whitepaper'; }) export class AboutNetworkComponent implements OnInit { - constructor() { } + constructor(private meta: MetaService) { } ngOnInit() { + this.meta.setGlobalTitle('Our Vision for Restoring Privacy | Orchid'); + this.meta.setGlobalDescription('Our vision is to restore user trust on the internet by creating our private internet access vpn, built as an open source app'); } downloadWhitepaper() { downloadWhitepaper(); } diff --git a/src/app/app.component.ts b/src/app/app.component.ts index f9ef5f1b..55c48edb 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,5 +1,5 @@ import {Component, OnInit} from "@angular/core"; -import {Title} from "@angular/platform-browser"; + import { NavigationEnd, Router @@ -13,31 +13,16 @@ import { export class AppComponent implements OnInit { title = "orchid-www"; - titleMap: Map = new Map([ - ["/", "Orchid | Open Source VPN & Privacy Software"], - ["/download", "Packet Analyzer App for iOS & Android | Orchid"], - ["/about-us", "About the Open Internet | Orchid"], - ["/network", "Distributed VPN | Orchid"], - ["/vision", "Our Vision | Orchid"], - ["/faq", "FAQs | Orchid"], - ["/events", "Events | Orchid"], - ["/privacy-policy", "Privacy Policy | Orchid"], - ["/service-terms", "Terms of Service | Orchid"], - ]); - - public constructor(private router: Router, private titleService: Title) {} + public constructor(private router: Router) {} ngOnInit(): void { this.router.events.subscribe((evt) => { if (!(evt instanceof NavigationEnd)) return; - // TODO: this feels very bad - this.titleService.setTitle( - this.titleMap.get(this.router.routerState.snapshot.url)); - - const win = typeof window !== "undefined" && window; + // Scroll the user to the top of the page on load/refresh? + // const win = typeof window !== "undefined" && window; + // if (win) win.scrollTo(0, 0); - if (win) win.scrollTo(0, 0); }, (err) => {}, () => {}); } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index f254cfb5..ebe35d68 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -5,6 +5,7 @@ import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { AboutAppComponent } from './about-app/about-app.component'; import { AboutNetworkComponent } from './about-network/about-network.component'; +import { HowItWorksComponent } from './how-it-works/how-it-works.component'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { VisionComponent } from './vision/vision.component'; import { EventsComponent } from './events/events.component'; @@ -14,19 +15,23 @@ import { ServiceTermsComponent } from './service-terms/service-terms.component'; import { DownloadComponent } from './download/download.component'; import { HomeComponent } from './home/home.component'; import { NewsletterSignupComponent } from './newsletter-signup/newsletter-signup.component'; +import { NewsletterSignupHeroComponent } from './newsletter-signup-hero/newsletter-signup-hero.component'; import { PageLayoutComponent } from './page-layout/page-layout.component'; import { FaqComponent } from './faq/faq.component'; +import { ContactComponent } from './contact/contact.component'; import { AboutCompanyComponent } from './about-company/about-company.component'; import { NotFoundComponent } from './not-found/not-found.component'; import { HttpClientModule, HttpClientJsonpModule } from '@angular/common/http'; import { FormsModule } from '@angular/forms'; +import { MetaService } from './MetaService'; @NgModule({ declarations: [ AppComponent, AboutAppComponent, AboutNetworkComponent, + HowItWorksComponent, VisionComponent, EventsComponent, DownloadComponent, @@ -35,8 +40,10 @@ import { FormsModule } from '@angular/forms'; ServiceTermsComponent, HomeComponent, NewsletterSignupComponent, + NewsletterSignupHeroComponent, PageLayoutComponent, FaqComponent, + ContactComponent, AboutCompanyComponent, NotFoundComponent ], @@ -49,7 +56,7 @@ import { FormsModule } from '@angular/forms'; HttpClientJsonpModule, FormsModule ], - providers: [], + providers: [MetaService], bootstrap: [AppComponent] }) export class AppModule { } diff --git a/src/app/contact/contact.component.html b/src/app/contact/contact.component.html new file mode 100644 index 00000000..9a658dfa --- /dev/null +++ b/src/app/contact/contact.component.html @@ -0,0 +1,93 @@ +
+
+
+
+

Contact

+ +
+

We want to hear from you

+

Let's reclaim the Internet together! We are looking for partnership opportunities with infrastructure + providers and integration partners that want to build with Orchid. Contact us and we'll get back to you + shortly.

+
+
+
+ +
+
+
+ +
+
+ +
+
+ Office Address +
+
+ 1288 Columbus Ave. #122, + San Francisco, CA 94133 +
+
+ +
+ +
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ {{errorMessage}} +
+
+ {{successMessage}} +
+ + + +
+ +
+
\ No newline at end of file diff --git a/src/app/contact/contact.component.scss b/src/app/contact/contact.component.scss new file mode 100644 index 00000000..12bc38f9 --- /dev/null +++ b/src/app/contact/contact.component.scss @@ -0,0 +1,142 @@ +@import 'media_queries'; +@import 'misc_config'; +@import "orc_config"; + +.contact-section { + display: grid; + grid-template-columns: 1fr 3fr; + column-gap: 1rem; + @include mobile { + grid-template-columns: 1fr; + } +} + +.contact-page-card { + background: #fff; + border: 1px solid $orc-beige; + padding: 1rem; + margin: 1rem; + font-size: 0.82rem; +} +.contact-page-card-header { + font-size: 1rem; + font-weight: bold; +} +.contact-page-card-seperator { + border-top: 2px solid #C8C6C8; + margin: 0.5rem 0; + margin: calc(0.5rem - 1px) 0; + box-sizing: border-box; + width: 100%; +} + +.contact-page-card-list { + list-style: none; + padding: 0; + & > li > a { + width: 100%; + display: flex; + align-items: center; + padding: 0.25rem; + } +} +.contact-page-card-list > li img { + margin-right: 5px; + width: auto; + height: auto; +} + +.contact-form-container { + display: none; +} +.contact-form-disabled { + position: relative; + pointer-events: none; + &:after { + content: ' '; + display: block; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + } +} +.contact-form-container.js { + display: flex; + flex-wrap: wrap; + justify-content: flex-start; + align-items: flex-start; +} + +.contact-form-input-wrapper { + box-sizing: border-box; + position: relative; + width: 100%; + margin: 1rem; + &:nth-child(1), + &:nth-child(2) { + @include not-mobile { + width: calc(50% - 2rem); + } + } + &.invalid { + &:after { + display: block; + content: '*'; + color: red; + position: absolute; + top: 0; + right: 0; + padding: 0.5rem; + } + } +} + +.contact-form-container input[type=text], +.contact-form-container input[type=email], +.contact-form-container textarea { + border: none; + box-sizing: border-box; + box-shadow: 0px 0.25rem 0.5rem 0.1rem rgba(0,0,0,0.1), inset 0px 0rem 0rem 0rem rgba(255,0,0,0.2); + transition: box-shadow 0.25s ease; + padding: 0.8rem 0.5rem; + + &.invalid { + box-shadow: 0px 0.25rem 0.5rem 0.1rem rgba(0,0,0,0.1), inset 0px 0rem 0.1rem 0.25rem rgba(255,0,0,0.2); + } + border-radius: 8px; + min-height: 3rem; +} + +.contact-form-container textarea { + min-height: 6rem; + @include not-mobile { + min-height: 12rem; + } +} + +.contact-form-message { + width: 100%; + padding: 0.5rem; + margin: 0.5rem 1rem; + border: 1px solid $orc-beige; + + display: none; + &.active { + display: block; + } +} +.contact-form-error { + background: rgba(255,0,0,0.1); +} + +.contact-form-container button { + margin: 1rem; + @include not-mobile { + min-width: 10rem; + } +} +.contact-form-container button + button { + margin-left: 0rem; +} \ No newline at end of file diff --git a/src/app/contact/contact.component.ts b/src/app/contact/contact.component.ts new file mode 100644 index 00000000..a25e23fa --- /dev/null +++ b/src/app/contact/contact.component.ts @@ -0,0 +1,161 @@ +import { Component, OnInit } from '@angular/core'; +import { MetaService } from '../MetaService'; + +@Component({ + selector: 'app-contact', + templateUrl: './contact.component.html', + styleUrls: ['./contact.component.scss'] +}) + +export class ContactComponent implements OnInit { + js: boolean = false; + + success: boolean = false; + successMessage: string = ''; + error: boolean = false; + errorMessage: string = ''; + form_disabled: boolean = false; + + name: string = ""; + invalid_name: boolean = false; + + subject: string = ""; + invalid_subject: boolean = false; + + message: string = ""; + invalid_message: boolean = false; + + email: string = ""; + invalid_email: boolean = false; + email_test: RegExp = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; + + constructor ( private meta: MetaService ) { } + + ngOnInit() { + //this.meta.clearAllTags(); + this.meta.setGlobalTitle('Get In Touch | Orchid'); + this.meta.setGlobalImage('https://www.orchid.com/assets/img/contact/social.png'); + this.meta.setGlobalDescription('Let\'s reclaim the Internet together! We are looking for partnership opportunities with infrastructure providers and integration partners that want to build with Orchid.'); + + const doc = typeof document !== "undefined" && document; + + if (doc) { + this.js = true; + } + } + + displayError(message) { + this.error = true; + this.errorMessage = message; + } + displaySuccess(message) { + this.success = true; + this.successMessage = message; + } + clear() { + this.success = false; + this.error = false; + this.invalid_name = false; + this.invalid_subject = false; + this.invalid_message = false; + this.invalid_email = false; + this.name = ''; + this.subject = ''; + this.message = ''; + this.email = ''; + } + + async submitForm() { + this.success = false; + this.error = false; + this.form_disabled = true; + + try { + let response = null; + let data = null; + + if (window && window.location.host.match(/localhost/i) !== null) { + response = "Form disabled"; + data = "form disabled"; + } else { + let response = await fetch("https://evy3f9g1ki.execute-api.us-west-2.amazonaws.com/Production/contact", + { + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + method: "POST", + body: JSON.stringify({ + "name": this.name, + "email": this.email, + "subject": this.subject, + "message": this.message + }) + }) + let data = await response.json(); + } + this.form_disabled = false; + this.clear(); + this.displaySuccess("Your message has been sent.") + } catch (e) { + console.error(e); + this.form_disabled = false; + this.displayError("There was an unknown error, your message may not have been sent"); + } + + } + + onSubmit() { + if (this.validateForm()) { + this.error = false; + this.success = false; + this.submitForm(); + } else { + this.displayError('Required fields are missing'); + } + } + + validateForm() { + let failed_validation: boolean = false; + + if (this.validateEmail()) failed_validation = true; + if (this.validateName()) failed_validation = true; + if (this.validateSubject()) failed_validation = true; + if (this.validateMessage()) failed_validation = true; + + return !failed_validation; + } + + validateEmail() { + const validEmail: boolean = this.email_test.test(this.email.toLowerCase()); + if (!validEmail) { + this.invalid_email = true; + } else this.invalid_email = false; + + return this.invalid_email; + } + + validateName() { + if (!this.name || this.name.length === 0) { + this.invalid_name = true; + } else this.invalid_name = false; + + return this.invalid_name; + } + + validateSubject() { + if (!this.subject || this.subject.length === 0) { + this.invalid_subject = true; + } else this.invalid_subject = false; + + return this.invalid_subject; + } + + validateMessage() { + if (!this.message || this.message.length === 0) { + this.invalid_message = true; + } else this.invalid_message = false; + + return this.invalid_message; + } +} diff --git a/src/app/download/download.component.html b/src/app/download/download.component.html index c3a55579..bb452fea 100644 --- a/src/app/download/download.component.html +++ b/src/app/download/download.component.html @@ -8,21 +8,6 @@

Try the pre-release Orchid app

-
-
-

Our initial feature is a local VPN traffic analyzer.
(The complete VPN service is coming soon.)

-

We've decided to distribute an early version of the Orchid app ahead of our network launch. This pre-release version analyzes network traffic on your phone and does not include VPN service yet (your IP address will not change). We are using the software to test and audit our networking code prior to integrating the token and interfacing with the Orchid Network. Once we launch our network, we can update the Orchid App to provide complete VPN service.

-

In its initial form, this app will only be focused on one thing: analyzing and reporting the hosts that the data on your device are connecting to. For now, our app includes the following features:

-
    -
  • Local VPN service providing network flow analysis
  • -
  • Advanced filtering to drill down on the data you care about
  • -
  • IP address & port number for both source and destination
  • -
-

It's important to us that this app is both open source and localized to your device, meaning no third parties see your data and nothing leaves your phone. We believe that an Open Source approach embraces the core tenets of decentralization and provides the greatest opportunity to create a network capable of delivering the stability, capacity, and security necessary to provide users with the online experience they desire.

-

Follow the directions below to download the Orchid App.

-
-
-
@@ -51,3 +36,6 @@

Android

+ + + diff --git a/src/app/download/download.component.ts b/src/app/download/download.component.ts index acef6e76..b61ff7ad 100644 --- a/src/app/download/download.component.ts +++ b/src/app/download/download.component.ts @@ -1,5 +1,6 @@ import { Component, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; +import { MetaService } from '../MetaService'; @Component({ selector: 'app-download', @@ -8,6 +9,9 @@ import { Observable } from 'rxjs'; }) export class DownloadComponent implements OnInit { - constructor() { } - ngOnInit() { } + constructor(private meta: MetaService) { } + ngOnInit() { + this.meta.setGlobalTitle('Packet Analyzer App for iOS & Android | Orchid'); + this.meta.setGlobalDescription('Your privacy is important to us, therefore no third parties will see your data after downloading our free VPN traffic analyzer app.'); + } } diff --git a/src/app/events/events.component.html b/src/app/events/events.component.html index d283e99a..814cfb9e 100644 --- a/src/app/events/events.component.html +++ b/src/app/events/events.component.html @@ -1,5 +1,14 @@ +
+
+
+
+

Events

+
+
+
+
-
+

Find us IRL

diff --git a/src/app/events/events.component.scss b/src/app/events/events.component.scss index 52fa51fa..2ac3925d 100644 --- a/src/app/events/events.component.scss +++ b/src/app/events/events.component.scss @@ -1,5 +1,11 @@ @import 'orc_config'; +.events-page__section { + h2 { + color: #53686A; + } +} + #ev-list { margin: 3rem 0 0; } diff --git a/src/app/events/events.component.ts b/src/app/events/events.component.ts index 26a163b8..6bd9b3d6 100644 --- a/src/app/events/events.component.ts +++ b/src/app/events/events.component.ts @@ -1,8 +1,9 @@ -import {Component, OnInit} from "@angular/core"; -import {Observable} from "rxjs"; +import { Component, OnInit } from "@angular/core"; +import { Observable } from "rxjs"; +import { MetaService } from '../MetaService'; -import {CalEvent} from "./event"; -import {EventsService} from "./events.service"; +import { CalEvent } from "./event"; +import { EventsService } from "./events.service"; @Component({ selector: "app-events", @@ -12,7 +13,12 @@ import {EventsService} from "./events.service"; export class EventsComponent implements OnInit { events$: Observable; - constructor(private events: EventsService) {} + constructor(private events: EventsService, private meta: MetaService) { } - ngOnInit() { this.events$ = this.events.getEvents(); } + ngOnInit() { + this.meta.setGlobalTitle('Blockchain Industry Events | Orchid'); + this.meta.setGlobalDescription('Come and meet the Orchid team in real life by attending one of our blockchain and crypto industry events around the globe.'); + + this.events$ = this.events.getEvents(); + } } diff --git a/src/app/faq/faq.component.html b/src/app/faq/faq.component.html index 937fe798..414b1d9f 100644 --- a/src/app/faq/faq.component.html +++ b/src/app/faq/faq.component.html @@ -1,15 +1,14 @@ -
-
-
-
+
+
+
+

FAQ

-
+
-
-
-
+
+
    diff --git a/src/app/faq/faq.component.ts b/src/app/faq/faq.component.ts index eaebb366..2e0ec959 100644 --- a/src/app/faq/faq.component.ts +++ b/src/app/faq/faq.component.ts @@ -1,4 +1,5 @@ import { Component, OnInit } from '@angular/core'; +import { MetaService } from '../MetaService'; import { faqs } from './faqs.js'; @Component({ selector: 'app-faq', @@ -10,10 +11,12 @@ export class FaqComponent implements OnInit { url:string = "/assets/json/faqs.json"; faqs:any = faqs; - constructor() { + constructor(private meta: MetaService) { } ngOnInit() { + this.meta.setGlobalTitle('FAQs and Customer Support | Orchid'); + this.meta.setGlobalDescription('A guide to getting started with Orchid\'s VPN, an open-source project committed to ending surveillance and censorship on the Internet.'); } anchorParse (component: string):string { diff --git a/src/app/home/home.component.html b/src/app/home/home.component.html index 2a2dd010..45789e79 100644 --- a/src/app/home/home.component.html +++ b/src/app/home/home.component.html @@ -1,111 +1,121 @@ -
    -
    -
    -
    -

    A place where users can reclaim the internet

    -
    -

    The pre-release Orchid app now available

    -

    - Download the Orchid app today for a local traffic flow analysis of your phone's internet connection with no - external servers and no third parties. -

    -

    - As we build towards a decentralized, tokenized marketplace where users can construct their own custom VPN - configurations and privacy services (as described in our whitepaper), the first feature offers under-the-hood introspection into - your internet connection. -

    -

    - -

    -
    -
    - splash -
    -
    -
    -
    -
    -
      -
    • -
      - internet preservation -
      -
      -

      Preserving the natural internet

      -

      - Humans naturally crave space to freely express their agency. No other place on Earth has the potential for - all humans to collaborate and access opportunities than the web that connects us all. -

      -

      - Orchid is building a suite of Open Source tools and cryptographic protocols developed and run by people who - want the internet to extend our natural human freedom, not curtail it. -

      -
      -
    • -
    + +
    +
    +
    +
    +
    +

    Stay Curious, Explore Freely

    +

    Get digital privacy

    +
    +
    +

    Don't miss the launch!

    + +
    +
    + +
    +
    +
    +
    +
    +

    A next-level VPN & privacy tool

    +

    + Read the whitepaper to see what we’re building. +

    +
    +
    -
    -
    +
    +

    Our approach

    -

    We believe that by eliminating centralization, rewarding network contributors, and harnessing the power of - blockchain, we can preserve an open and accessible internet.

    +

    We believe that by eliminating centralization, rewarding network contributors, and harnessing the power of blockchain, we can preserve an open and accessible internet.

    -
      -
    • -
      - decentralized +
        +
      • +
        + decentralized
        -
        -

        Decentralization

        +
        +

        Decentralized

        - Utilizing the power of Ethereum’s ecosystem allows Orchid to operate without a central authority. The app - runs local on your device—not through a server—and no data is ever stored. + Ethereum allows Orchid to operate without a central authority, and the network is completely permissionless.

        +
      • -
      • -
        - open source +
      • +
        + open source
        -
        -

        Open Source

        +
        +

        Open Source

        - Orchid is 100% open source software, enabling the sharing of ideas, community auditing, debugging, and, of - course, contributions. + Orchid software is Open Source to enable the sharing of ideas, auditing and debugging by the community, and of course, contributions.

        +
      • -
      • -
        - peer to peer +
      • +
        + peer to peer
        -
        -

        Peer to peer

        +
        +

        Peer to peer

        - Orchid clients and network providers transact directly, with no middlemen, creating an open, transparent, - and low cost - marketplace for bandwidth and VPN connectivity. + Clients and network providers transact directly with no middlemen, creating a low-cost marketplace for bandwidth and VPN connectivity.

        +
    -
    -
    -

    As seen in

    - -
      -
    • -
    • -
    • +
      +
      +
      + +
      +

      As seen in

      +
        +
      • +
        + +

        + In a world where one assumes the Cambridge Analytica scandal is merely the tip of the iceberg when it comes to data abuse, it’s easy to see the project’s appeal." +

        + Read More +
        +
      • +
      • +
        + +

        + Orchid’s mission is to build open-source software that keeps the Internet open and accessible  —  a natural resource for everyone, everywhere.” +

        + Read More +
        +
      • +
      • +
        + +

        + Orchid is developing an open-source decentralized and surveillance-free internet protocol intending to provide anonymized internet access to the global community.” +

        + Read More +
        +
      @@ -115,8 +125,8 @@

      As seen in

      -

      Meet the Orchid team

      - See all events > +

      Meet us in person

      + See all events
      • diff --git a/src/app/home/home.component.scss b/src/app/home/home.component.scss index e573a4c6..efb966ca 100644 --- a/src/app/home/home.component.scss +++ b/src/app/home/home.component.scss @@ -3,28 +3,221 @@ @import 'misc_config'; @import 'orc_config'; -@include splash-columns(5fr, 7fr); +$hero-bp-1: 1400px; +$hero-bp-vert: 1150px; -#splash-text { - @include not-vert-splash { - z-index: 1; +// HERO SECTION +// It took a lot of magic numbers to make this work across all resolutions. +// TODO: find a less fiddly way to manage the floating islands. +.home-hero { + position: relative; + background: $orc-beige-light; + height: 810px; + + @media (max-width: $hero-bp-1) { + height: 55vw; } } -#splash-whitepaper { - display: flex; - flex-flow: row nowrap; - justify-content: flex-end; - align-items: center; - margin-top: 4rem; +.home-hero__bg { + background: url('/assets/img/index/orchid-main-combined-minus-3.svg') no-repeat top right; + position: absolute; + top: 0; + left: 0; + right: 0; + width: 100%; + max-width: 72rem; + height: calc(100% + 30px); + margin: 0 auto; - @include mobile { + & > img { + display: none; + } + + @media (max-width: $hero-bp-1) { + background-size: 66%; + background-position: right center; + } +} + +.home-hero__content { + box-sizing: border-box; + width: 642px; + + @media(min-width: 1401px) { + padding-top: 3.5rem; + } +} + +.home-hero__form { + margin-top: 143px; + + @media (max-width: $hero-bp-1) { + margin-top: 10vw; + transform: translateY(-2vw); + } +} + +@media (max-width: $hero-bp-vert) { + .home-hero { + height: unset; + } + .home-hero__bg { + background: transparent; + position: relative; + max-height: 50vh; + max-width: 100%; + display: flex; justify-content: center; + + & > img { + display: block; + max-width: 100%; + } + } + .home-hero__content { + text-align: center; + margin: 0 auto; + max-width: 100%; + } + .home-hero__form { margin-top: 1rem; } } -@include v-feature-list("#feature-list", ".ft-text", ".ft-image"); +.home-satellite-3 { + position: absolute; + transform: translate(-30px, 53px); +} + +.home-satellite-3a { + position: absolute; + background: url('/assets/img/index/orchid-satellite-03-2.svg'); + background-repeat: no-repeat; + background-position: calc(50% - 444px); + width: 100%; + height: 390px; + left: 0; + top: -223px; + z-index: 0; + @media (max-width: $hero-bp-1) { + background-size: 30vw; + background-position: calc(50% - 33vw); + top: -209px; + } + @media (max-width: 1330px) { + background-size: 26vw; + top: -16vw; + background-position: calc(50% - 33vw); + } + @media (max-width: $hero-bp-vert) { + background-size: 35vw; + background-position: calc(50% - 42vw); + top: -21vw; + } + @media (max-width: 790px) { + background-size: 303px; + background-position: calc(50% - 307px); + top: -206px; + } + @media (max-width: 580px) { + display: none; + // position: relative; + // height: 322px; + // top: 0; + // background-position: center; + } +} + +.home-satellite-4 { + position: absolute; + background: url(/assets/img/index/orchid-satellite-04-2.svg); + background-repeat: no-repeat; + background-position: 65vw top; + width: 100%; + height: 476px; + top: 155px; + right: 0; + z-index: 0; + + @media (max-width: 1550px) { + background-position: 69vw; + } + @media (max-width: 1194px) { + background-position: 71vw; + } + @media (max-width: 1092px) { + transform: scale(0.8); + transform-origin: right; + background-position: 68vw; + } + @media (max-width: 962px) { + transform: scale(0.6); + background-position: 52vw; + top: 133px; + } + @include mobile { + transform: scale(0.6); + background-position: 52vw; + top: 100px; + } + @media (max-width: 580px) { + display: none; + // position: relative; + // height: 322px; + // top: 0; + // background-position: center; + } +} + +// TODO: use variables for font sizes +.title { + font-size: 72px; + + & > span { + display: block; + } + + @include mobile { + font-size: 40px; + } + @media (max-width: 413px) { + font-size: 37px; + } + @media (max-width: 374px) { + font-size: 30px; + } +} + +// TODO: use variables for font sizes +.subtitle { + color: $orc-rock-gray; + margin: 0.5rem 0 1.5rem 0; + font-size: 36px; + + @include mobile { + font-size: 30px; + } + @media (max-width: 374px) { + font-size: 27px; + margin-bottom: 0.5rem; + } +} + + +// HOW IT WORKS SECTION + +.how-it-works { + position: relative; + + p { + margin-top: 1rem; + margin-bottom: 1.5rem; + } +} + + +// EVENTS SECTION #ev-header { display: flex; @@ -88,18 +281,77 @@ #download-orchid { margin: 4em 0 2.5em 0; } -#splash-text { - margin-left: 40px; - p { color: $orc-gray; } - @media screen and (max-width: 800px) { - margin-left: 0px; + +// OUR APPROACH SECTION + +div.our-approach { + margin-left: auto; + margin-right: auto; + margin-bottom: 3em; + text-align: center; + max-width: 80%; + + h2 { + margin-bottom: 0.75rem; + } + + & > p { + max-width: 60ch; + margin-left: auto; + margin-right: auto; } } -div.our-approach { - margin-left: auto; margin-right: auto; margin-bottom: 3em; text-align: center; max-width: 80%; - h2 { color: $orc-rock-gray; margin-bottom: 0.75rem; } +.card-list { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + grid-gap: 2rem; + justify-content: center; + + @include vert-splash { + grid-template-columns: repeat(1, minmax(200px, 600px)); + } } +.card { + background: #fff; + border-radius: 12px; + display: flex; + flex-direction: column; + + h3 { + font-size: $size-body-md; + margin: 1rem 0; + + @include mobile { + font-size: $size-body-md-mobile; + } + } + img { + max-width: 100%; + } + p { + flex: 1; + } +} + +.card__image > img { + height: 16vw; + max-height: 234px; + + @include vert-splash { + height: auto; + } +} + +.card__text { + display: flex; + flex-direction: column; + justify-content: space-between; + flex: 1; +} + + +// TODO: Do we still need this stuff and can we move it elsewhere? .background-white { background: white; } .background-gray { background: #f0f0f0; } @@ -110,27 +362,138 @@ ul.phantom-list { ul.smaller .ft-text h3 { font-size: 160%; } -h4.subtitle { color: $orc-rock-gray; margin: 0.5rem 0 1.5rem 0; font-size: 145%; } .ft-text h3 { margin-bottom: 0.5rem; } -section#as-seen-in { - margin-left: auto; margin-right: auto; text-align: center; - > h2 { - margin-right: .5em; - margin-bottom: 1rem; - } - ul.logos { - display: flex; flex-wrap: wrap; justify-content: center; - align-items: baseline; - margin-left: auto; margin-right: auto; - text-align: center; - li { - display: flex; - flex-flow: row-wrap; - margin: 0rem 2rem 2rem 0rem; - vertical-align: text-top; - } + +// PRESS SECTION + +.as-seen-in > section { + position: relative; + + &::after { + content: ""; + position: absolute; + background: url('/assets/img/index/as-seen-4-circles.svg') no-repeat center center; + width: 10px; + height: 126px; + bottom: 0; + right: 0; + transform: translateY(50%); + + @media (max-width: 1300px) { + right: 1rem; } - img { max-width: 12rem; } + } +} + +.as-seen-bg-1 { + position: absolute; + top: -163px; + left: -345px; + + @include mobile { + left: unset; + right: 65vw; + } + @media (max-width: 475px) { + transform: scale(0.8); + right: 50vw; + top: -216px; + } + @media (max-width: 374px) { + right: 41vw; + transform: scale(0.7); + top: -238px; + } +} + +.press-cards { + display: grid; + grid-gap: 2rem; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + justify-content: center; + position: relative; + + @media(max-width: 1090px) { + grid-gap: 1rem; + } + + @media(max-width: 1040px) { + grid-template-columns: minmax(300px, 420px); + } +} + +.press-card { + padding: 1rem; + position: relative; + + &, & * { + box-sizing: border-box; + } + + &::before { + content: ""; + top: 56px; + height: calc(100% - 88px); + width: calc(100% - 2rem); + position: absolute; + z-index: 0; + box-shadow: 0 0 16px rgba(0, 0, 0, 0.1); + } + + & > .wrapper { + padding: 0 2rem 2rem; + position: relative; + display: flex; + flex-direction: column; + height: 100%; + background: #fff; + } +} + +.press-card__logo { + display: flex; + justify-content: center; + align-items: center; + max-width: 90%; + height: 76px; + border: 1px solid $orc-beige; + border-radius: 3px; + padding: 0 1rem; + position: relative; + z-index: 1; + margin: 0 auto; + + & > img { + max-width: 100%; + display: block; + } +} + +.press-card__quote { + + position: relative; + font-style: italic; + margin-top: 1.5rem; + margin-bottom: 1.5rem; + + &::before { + content: ""; + background: url('/assets/img/shared/quotes.svg'); + position: absolute; + z-index: 1; + width: 35px; + height: 33px; + left: calc(-37px - 1rem); + top: -12px; + } +} + +.press-card__more { + text-decoration: none; + display: block; + text-align: right; + font-weight: bold; + margin-top: auto; } diff --git a/src/app/home/home.component.ts b/src/app/home/home.component.ts index b184f35a..d1b04e7e 100644 --- a/src/app/home/home.component.ts +++ b/src/app/home/home.component.ts @@ -3,6 +3,7 @@ import { CalEvent } from '../events/event'; import { EventsService } from '../events/events.service'; import { Observable } from 'rxjs'; import { downloadWhitepaper, downloadOrchid } from '../whitepaper'; +import { MetaService } from '../MetaService'; @Component({ selector: 'app-home', @@ -13,9 +14,13 @@ import { downloadWhitepaper, downloadOrchid } from '../whitepaper'; export class HomeComponent implements OnInit { events$: Observable; - constructor(private events: EventsService) { } + constructor(private events: EventsService, private meta: MetaService) { } ngOnInit() { + this.meta.setGlobalTitle('Orchid | Open Source VPN & Privacy Software'); + this.meta.setGlobalDescription('Your VPN should be secure, which is why Orchid is building with open source tools for custom VPN configurations and privacy services.'); + this.meta.update('og:url', 'https://www.orchid.com/'); + this.events$ = this.events.getEvents(); } diff --git a/src/app/how-it-works/how-it-works.component.html b/src/app/how-it-works/how-it-works.component.html new file mode 100644 index 00000000..12ad25a8 --- /dev/null +++ b/src/app/how-it-works/how-it-works.component.html @@ -0,0 +1,211 @@ +
        +
        +
        +

        How Orchid delivers digital privacy

        +

        The Orchid network enables a decentralized virtual private network (VPN), allowing users to buy bandwidth from a global pool of service providers.

        +

        To do this, Orchid uses an ERC-20 utility token called OXT, a new VPN protocol for token-incentivized bandwidth proxying, and smart-contracts with algorithmic advertising and payment functions. Orchid's users connect to bandwidth sellers using a provider directory, and they pay using probabilistic nanopayments so Ethereum transaction fees on packets are acceptably low.

        +
        +
        + +
        + +
        +
        +

        Core components of the Orchid network

        + +
        +
        +
        + +
        +
        + +
        +
        +
        + + + + + + +
        +
        +

        The Orchid app

        +

        Users of Orchid run a client similar to a typical VPN client for protocols such as OpenVPN, but which speaks the Orchid protocol. The Orchid network client goes past the basic functionality offered by most VPN clients, with features such as the ability to run traffic through an integrated personal firewall. The Orchid client is accessible via iOS, Android, macOS, Linux, and (soon) Windows.

        +

        Get the pre-release version of the app today!

        +
        +
        + +
        +
        + back to top +
        +
        +
        +
        +
        + +
        +
        + + + + + + +
        +
        +

        The Orchid cryptocurrency (OXT)

        +

        OXT’s primary and fundamental purpose is to keep track of who has used computing services, who has provided computing services, and whether the average user is fairly compensating the average provider.

        +

        The OXT token provides value in the Orchid network in a number of ways:

        +
          +
        • A Bandwidth Provider - Anyone can operate an Orchid Node, but must first stake OXT, with the more OXT that is staked, the greater the chances of reward in the Network.
        • +
        • A Bandwidth User- For the first time, users can pay-on-the-fly for a private, secure internet connection. To power up the client, a user installs the Orchid VPN, adds OXT to a wallet, and then can access the internet through a user-chosen path to ensure a secure connection anywhere in the world. Users only pay for the bandwidth they consume.
        • +
        +

        The bandwidth marketplace is peer-to-peer and run in a completely decentralized manner without reliance on any central party. The primary reasons for a native token are:

        +
          +
        1. To have a token that is specifically tied to consumption of bandwidth on the Orchid network
        2. +
        3. To align operator incentives towards the benefit of the Orchid Network.
        4. +
        +

        Accordingly, in addition to facilitating bandwidth transactions on the Network, the Orchid Token is used to prove a stake within the Orchid network that is intended to demonstrate a commitment for bandwidth providers, as well as to mitigate certain risks.

        +
        +
        + +
        +
        + back to top +
        +
        +
        +
        +
        + +
        +
        + + + + + + +
        +
        +

        The Orchid Protocol

        +

        The Orchid software is designed to use a custom VPN protocol, similar in scope to OpenVPN or WireGuard. The Orchid protocol is designed for high-performance networking and runs on top of WebRTC, a common web standard, widely used to transmit video and audio from inside browsers. Our protocol is intended to allow users to request access to remote network resources and pay for these resources using OXT via a nanopayments system.

        +
        +
        + +
        +
        + back to top +
        +
        +
        +
        +
        + +
        +
        + + + + + + +
        +
        +

        Nanopayments

        +

        Orchid uses a new probabilistic nanopayment system to scale payment throughput.

        +

        This nanopayment system is the foundation of the Orchid peer to peer bandwidth marketplace where clients pay Node operators OXT “tickets” for proxy bandwidth. The system is designed to lower the transaction fees on small payments by amortizing transaction fees across many transactions and even across multiple parties.

        +

        For more information, see our recent article: Introducing Nanopayments

        +
        +
        + +
        +
        + back to top +
        +
        +
        +
        +
        + +
        +
        + + + + + + +
        +
        +

        Nodes

        +

        Service providers on Orchid run software similar to a typical VPN daemon for protocols such as OpenVPN, but which speaks the Orchid protocol.

        +

        Orchid nodes maintain registration information in a stake registry and provider directory on Ethereum. The stake registry is optimized for enabling the Orchid app to automatically discover random servers in a decentralized environment, while the provider directory allows Orchid nodes to register metadata such as geolocation or additional services offered.

        +
        +
        + +
        +
        + back to top +
        +
        +
        +
        +
        + +
        +
        + + + + + + +
        +
        +

        Staking

        +

        A provider stakes some number of OXT tokens to create a stake deposit.

        +
          +
        • Anyone can stake OXT on nodes using the smart contract.
        • +
        • Clients select new nodes in proportion to their relative OXT deposit size.
        • +
        • Larger stake deposits thus lead to proportionally more users, bandwidth, and revenue.
        • +
        • If the node is already at max bandwidth capacity additional stake is effectively wasted.
        • +
        +

        Once tokens have been locked into a stake deposit they can be used immediately for bandwidth provisioning. If the provider wants to withdraw tokens from the staking contract, they have to start an ‘unlocking’ process period, which involves a three month cooldown where their funds cannot be used as a stake deposit or transferred elsewhere by the provider.

        +

        Whatever the amount of value that is exchanged in the Orchid ecosystem, a given seller’s relative stake amount, as a percentage of the total stake, provides them that same percentage of user traffic and dealflow. Assuming typical and honest selling behavior (no users drop them for bad service) this dealflow will translate into a similar portion of the total revenue. The staking decisions of sellers is left to their own choices.

        +
        +
        + +
        +
        + back to top +
        +
        +
        +
        + +
        + +
        +
        +
        +
        +
        + + +
        +
        +
        +
        + + diff --git a/src/app/how-it-works/how-it-works.component.scss b/src/app/how-it-works/how-it-works.component.scss new file mode 100644 index 00000000..d825e46c --- /dev/null +++ b/src/app/how-it-works/how-it-works.component.scss @@ -0,0 +1,518 @@ +@import 'orc_config'; +@import 'media_queries'; +@import 'misc_config'; + +// PAGE VARIABLES +$section-sm: 54rem; + +// HERO SECTION + +.how-hero { + .content { + max-width: 39rem; + padding-bottom: 200px; + + @include mobile { + padding-bottom: 2rem; + padding: 2rem + } + + & > p { + max-width: 30rem; + margin-left: auto; + margin-right: auto; + } + } + .satellite-1 { + & > img { + display: none; + } + background-image: url('/assets/img/how-it-works/satellite-1.svg'); + background-repeat: no-repeat; + background-position: 72vw center; + width: 100%; + height: 446px; + position: absolute; + top: 0; + left: 0; + + @media (min-width: 1570px) { + background-position: calc(50% + 658px); + } + + @media (max-width: 1269px) and (min-width: 1096px + 1) { + background-position: 74vw; + } + + @media (max-width: 1096px) and (min-width: $mobile-width + 1) { + background-size: 62%; + background-position: 77vw; + } + + @include mobile { + background: none; + position: relative; + height: unset; + max-height: 50vh; + & > img { + display: block; + max-width: 90%; + margin: 0 auto; + } + } + } + +} + + +// CORE COMPONENTS SECTION + +.core { + & > * { + box-sizing: border-box; + } + .satellite-2 { + background-image: url('/assets/img/how-it-works/satellite-2.svg'); + background-repeat: no-repeat; + background-position: -21vw center; + width: 100%; + height: 674px; + position: absolute; + top: -469px; + left: 0; + + & > img { + display: none; + max-width: 100%; + } + } + .content { + max-width: $section-sm; + } + h2 > span { + display: block; + } + .buttons { + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-gap: 1rem; + justify-content: center; + } + .button { + text-decoration: none; + display: block; + border-radius: 12px; + padding: 1rem 2rem; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); + font-size: $size-body-md; + color: $orc-rock-gray; + } +} + +@media (min-width: 1570px) { + .core { + .satellite-2 { + background-position: calc(50% - 608px); + } + } +} + +@media (max-width: 1376px) and (min-width: $mobile-width + 1) { + .core { + .satellite-2 { + background-size: 56%; + top: -404px; + } + } +} + +@include mobile { + .core { + padding-top: 2rem; + + .satellite-2 { + display: none; + max-height: 50vh; + position: relative; + top: 0; + margin-bottom: -40px; + background: transparent; + height: unset; + padding: 0 2rem; + + & > img { + display: block; + } + } + .buttons { + grid-template-columns: 1fr; + } + .button { + font-size: $size-body-md-mobile; + } + } +} + + + +// EXPLAINER SECTIONS + +$exp-outer-width: 1440px; +$exp-text-width: 750px; +$exp-progress-1-width: 146px; +$exp-progress-2-width: 130px; +$exp-image-delta: 136px; +$exp-image-width: 412px; +$exp-image-gap: 30px; +$exp-dash-height: 4px; +$exp-bottom-1-height: $exp-dash-height; +$exp-bottom-2-height: 60px; +$exp-to-top-size: 30px; +$exp-dot-size: 18px; +$exp-start-height: 170px; + +$exp-vert-bp: 960px; + +.anchor { + top: 60px; + position: relative; + display: block; +} + +.explainers { + counter-reset: section; +} +.explainer > * { + box-sizing: border-box; +} +.explainer { + --section-bg: #{$bkgd-faint-gray}; + --section-bg-alt: #fff; + min-height: 800px; + display: flex; + justify-content: center; + align-items: stretch; + overflow-x: hidden; + background-color: var(--section-bg); + position: relative; + counter-increment: section; +} +.explainer__container { + max-width: $exp-outer-width; + display: grid; + grid-template-areas: ". progress-2 text image image image" + ". bottom bottom bottom bottom ." + ". . . . connector ."; + grid-template-columns: $exp-progress-1-width $exp-progress-2-width 1fr $exp-image-delta $exp-progress-2-width $exp-progress-1-width; + grid-template-rows: 1fr $exp-bottom-1-height $exp-bottom-2-height; + justify-content: center; + position: relative; +} + +// Even # rows +.explainer:nth-child(2n) { + --section-bg: #fff; + --section-bg-alt: #{$bkgd-faint-gray}; + .explainer__container { + direction: rtl; + } + .explainer__progress { + background-position: right 3px; + } + .explainer__dot { + transform: translateX(50%); + } + .explainer__text { + direction: ltr; + } + .explainer__image { + padding-right: 60px; + padding-left: 0; + } + .explainer__connector { + background-position: left; + } +} + +.explainer:first-child { + padding-top: 20px; + .explainer__container { + grid-template-areas: ". start start start start ." + ". progress-2 text image image image" + ". bottom bottom bottom bottom ." + ". . . . connector ."; + grid-template-columns: $exp-progress-1-width $exp-progress-2-width 1fr $exp-image-delta $exp-progress-2-width $exp-progress-1-width; + grid-template-rows: 100px 1fr $exp-bottom-1-height $exp-bottom-2-height; + } + .explainer__progress { + justify-content: flex-start; + } +} +.explainer__start { + grid-area: start; + background-image: url('/assets/img/how-it-works/dash-x.svg'); + background-repeat: repeat-x; + background-position: bottom; + margin-bottom: -50px; + width: 50%; + position: relative; + + &::after { + content: ""; + position: absolute; + width: 4px; + height: 100%; + background-image: url('/assets/img/how-it-works/dash-y.svg'); + background-repeat: repeat-y; + right: 0; + top: 0; + } +} +.explainer__start-cap { + position: absolute; + z-index: 1; + left: calc(50% - 18px); + transform: translateY(20px); + + &::after { + content: ""; + position: absolute; + background-image: url('/assets/img/how-it-works/start-shine.svg'); + background-repeat: no-repeat; + width: 148px; + height: 148px; + top: -58px; + left: -58px; + } + + & > div { + width: 32px; + height: 32px; + border-radius: 32px; + background: $orc-purple; + } +} + +.explainer:last-child { + .explainer__bottom::after { + content: ""; + position: absolute; + background: var(--section-bg); + width: 50%; + height: 100%; + transform: translate(100%); + z-index: 0; + } + &:nth-child(2n) .explainer__bottom::after { + transform: translate(0); + left: 0; + } + .explainer__connector { + background: transparent; + } +} +.explainer__progress { + grid-area: progress-2; + background-image: url('/assets/img/how-it-works/dash-y.svg'); + background-repeat: repeat-y; + background-position: left 3px; + display: flex; + flex-direction: column; + justify-content: center; +} +.explainer__dot { + background-color: var(--section-bg); + width: $exp-dot-size; + height: $exp-dot-size; + transform: translateX(-50%); + display: block; + & + & { + margin-top: 70px; + } + & > img { + display: block; + } +} +.explainer__dot.active { + & > img { + display: none; + } + background-color: $orc-light-purple; + font-family: $orc-tf-primary; + font-size: 40px; + line-height: 60px;; + text-align: center; + width: 60px; + height: 60px; + border-radius: 60px; + text-decoration: none; + color: #fff; + transform: translateX(calc(-50% + 2px)); + position: relative; + border: 22px solid var(--section-bg); + z-index: 3; + &:nth-child(2n) { + transform: translateX(calc(50% - 2px)); + } + &::before { + content: counter(section); + } + &::after { + content: ""; + position: absolute; + background-image: url(/assets/img/how-it-works/shine.svg); + background-repeat: no-repeat; + background-position: center; + width: 104px; + height: 104px; + top: -22px; + left: -22px; + } +} + +.explainer__text { + grid-area: text; + max-width: $exp-text-width; + display: flex; + flex-direction: column; + justify-content: center; + padding: 4rem 0; + + & > h3 { + font-size: 34px; + color: $orc-rock-gray; + margin-bottom: 1rem; + } + & > h4 { + font-size: $size-body-md; + } +} +.explainer__image { + grid-area: image; + display: flex; + padding-left: $exp-image-gap; +} +.explainer__bottom { + grid-area: bottom; + background-image: url('/assets/img/how-it-works/dash-x.svg'); + background-repeat: repeat-x; + background-position: top; + position: relative; +} +.explainer__to-top { + position: absolute; + margin: 0 auto; + transform: translateY(-50%); + left: calc(50% - #{$exp-to-top-size}); + background-color: var(--section-bg); + z-index: 1; + & > img { + display: block; + } +} +.explainer__connector { + grid-area: connector; + background-image: url('/assets/img/how-it-works/dash-y.svg'); + background-repeat: repeat-y; + background-position: right; +} +.explainer__finish { + position: absolute; + background-image: url('/assets/img/how-it-works/dash-y.svg'); + width: $exp-dash-height; + height: 110px; + left: calc(50% - 2px); + top: -60px; + + & > img { + position: absolute; + z-index: 1; + bottom: 0; + left: -10px; + } +} + +@media (max-width: $exp-vert-bp) { + .explainer { + overflow: visible; + padding: 1rem; + min-height: unset; + } + .explainer__container, + .explainer:first-child .explainer__container { + max-width: 100%; + grid-template-areas: "image" + "text" + "bottom"; + grid-template-columns: 1fr; + grid-template-rows: auto 1fr auto; + justify-content: center; + position: relative; + } + .explainer__text { + padding: 0; + justify-content: flex-start; + max-width: 60ch; + margin-left: auto; + margin-right: auto; + } + .explainer .explainer__container .explainer__image { // Need the specificity + padding: 1rem; + justify-content: center; + max-height: 50vh; + & > img { + max-width: 100%; + } + } + .explainer__progress { + display: none; + } + .explainer__bottom { + background: none; + text-align: center; + padding: 1rem 0 0; + } + .explainer__to-top { + position: static; + transform: none; + display: inline-block; + } + .explainer__connector { + background: none; + } + .explainer:last-child { + .explainer__bottom::after { + display: none + } + } + .explainer__start-cap, + .explainer__finish { + display: none; + } +} + +// WHITE PAPER SECTION + +.whitepaper-section { + position: relative; + padding: 3em 0; + text-align: center; +} +#read-whitepaper { + display: flex; + flex-flow: row nowrap; + justify-content: center; + align-items: center; + margin: auto; + + @include mobile { + justify-content: center; + margin: 1rem 0 1rem; + } +} + +#read-whitepaper-adorner { + position: absolute; + left: -2rem; + top: -5rem; +} diff --git a/src/app/how-it-works/how-it-works.component.ts b/src/app/how-it-works/how-it-works.component.ts new file mode 100644 index 00000000..2592c442 --- /dev/null +++ b/src/app/how-it-works/how-it-works.component.ts @@ -0,0 +1,21 @@ +import { Component, OnInit } from '@angular/core'; +import { downloadWhitepaper } from '../whitepaper'; +import { MetaService } from '../MetaService'; + +@Component({ + selector: 'how-it-works', + templateUrl: './how-it-works.component.html', + styleUrls: ['./how-it-works.component.scss'] +}) +export class HowItWorksComponent implements OnInit { + + constructor(private meta: MetaService) { } + + ngOnInit() { + this.meta.setGlobalTitle('How It Works | Orchid'); + this.meta.setGlobalDescription('The Orchid network enables a decentralized virtual private network (VPN), allowing users to buy bandwidth from a global pool of service providers.'); + this.meta.setGlobalImage('/assets/img/how-it-works/social.png'); + } + + downloadWhitepaper() { downloadWhitepaper(); } +} diff --git a/src/app/newsletter-signup-hero/newsletter-signup-hero.component.html b/src/app/newsletter-signup-hero/newsletter-signup-hero.component.html new file mode 100644 index 00000000..c913d732 --- /dev/null +++ b/src/app/newsletter-signup-hero/newsletter-signup-hero.component.html @@ -0,0 +1,19 @@ + diff --git a/src/app/newsletter-signup-hero/newsletter-signup-hero.component.scss b/src/app/newsletter-signup-hero/newsletter-signup-hero.component.scss new file mode 100644 index 00000000..11e59f34 --- /dev/null +++ b/src/app/newsletter-signup-hero/newsletter-signup-hero.component.scss @@ -0,0 +1,42 @@ +@import 'misc_config'; +@import 'orc_config'; +@import 'media_queries'; + +#hero-error, #hero-success { + max-width: 60ch; + padding: 3rem 0 0; + font-size: 1.25em; +} + +#hero-error { + color: $color-error; +} + +.newsletter-signup-hero { + + // Putting this inside for specificity + .newsletter-signup-hero__input { + background: #fff; + max-width: 20rem; + } + .newsletter-signup-hero__button { + max-width: 15rem; + } + +} + +label.gdpr-consent { + margin-top: 0; + input[type="checkbox"] { + margin-right: 8px; + } + &.blink_box { padding: 4px; border: 2px solid red; } +} + +.gdpr-consent-wrap { + max-width: 20rem; + @media (max-width: 1150px) { + margin-left: auto; + margin-right: auto; + } +} diff --git a/src/app/newsletter-signup-hero/newsletter-signup-hero.component.ts b/src/app/newsletter-signup-hero/newsletter-signup-hero.component.ts new file mode 100644 index 00000000..cf35e6a5 --- /dev/null +++ b/src/app/newsletter-signup-hero/newsletter-signup-hero.component.ts @@ -0,0 +1,58 @@ +import { HttpClient } from "@angular/common/http"; +import { Component, OnInit } from "@angular/core"; + +@Component({ + selector: "app-newsletter-signup-hero", + templateUrl: "./newsletter-signup-hero.component.html", + styleUrls: ["./newsletter-signup-hero.component.scss"], +}) + +export class NewsletterSignupHeroComponent implements OnInit { + _email: string = ""; + consented: boolean = false; + error: string = ""; + success: string = ""; + submitted: boolean = false; + blink_box: boolean = false; + showFull: boolean = false; + + get email() { return this._email; } + + set email(val: string) { + this._email = val; + this.showFull = !!this._email; + if (!this.showFull) this.consented = false; + } + + constructor(private http: HttpClient) {} + + submit() { + const mailchimp_add = "https://ik396c7x0k.execute-api.us-west-2.amazonaws.com/default/mailchimp?email="; + const mailchimp_url = mailchimp_add + encodeURIComponent(this.email || ""); + + if (!this.consented) { + this.blink_box = true; + return false; + } else { + this.blink_box = false; + } + + this.error = ""; + + this.http.get(mailchimp_url) + .subscribe( + response => { + if (response["status"] == "pending") { + this.submitted = true; + this.success = "Great! Now please check your email and confirm." + } else if (response["detail"]) { + this.error = response["detail"]; + } + }, + error => { + this.error = "Sorry, an error occurred."; + }); + } + + ngOnInit() {} +} diff --git a/src/app/newsletter-signup/newsletter-signup.component.html b/src/app/newsletter-signup/newsletter-signup.component.html index e32bdf78..db4b8eaa 100644 --- a/src/app/newsletter-signup/newsletter-signup.component.html +++ b/src/app/newsletter-signup/newsletter-signup.component.html @@ -1,17 +1,17 @@
        -

        Stay connected as we grow Orchid.

        +

        Let's stay connected

        -

        Subscribe to our newsletter.

        +

        Get the newsletter for updates and privacy news

        -
        + class="input-large center-block vgap-thin" /> +
        + + I consent to receiving further instructions at the email address I submitted above. +
        diff --git a/src/app/newsletter-signup/newsletter-signup.component.scss b/src/app/newsletter-signup/newsletter-signup.component.scss index af2e1be9..8cb74e8a 100644 --- a/src/app/newsletter-signup/newsletter-signup.component.scss +++ b/src/app/newsletter-signup/newsletter-signup.component.scss @@ -1,5 +1,6 @@ @import 'misc_config'; @import 'orc_config'; +@import 'media_queries'; #error, #success { margin: 0 auto 0 auto; @@ -12,7 +13,9 @@ color: $color-error; } -header h2 { color: $orc-rock-gray; } +header h2 { + margin-bottom: 1rem; +} label.gdpr-consent { margin-top: 0; diff --git a/src/app/newsletter-signup/newsletter-signup.component.ts b/src/app/newsletter-signup/newsletter-signup.component.ts index b8d1486a..c6d8c782 100644 --- a/src/app/newsletter-signup/newsletter-signup.component.ts +++ b/src/app/newsletter-signup/newsletter-signup.component.ts @@ -36,7 +36,7 @@ export class NewsletterSignupComponent implements OnInit { } else { this.blink_box = false; } - + this.error = ""; this.http.get(mailchimp_url) diff --git a/src/app/page-layout/page-layout.component.html b/src/app/page-layout/page-layout.component.html index 63718d91..5cc8c0f4 100644 --- a/src/app/page-layout/page-layout.component.html +++ b/src/app/page-layout/page-layout.component.html @@ -2,23 +2,27 @@