new homepage

master
alice 3 years ago
parent bbe4e12d56
commit 7cd9a7a230

@ -15,6 +15,7 @@ from django.utils.translation import (
)
from django.template.loader import TemplateDoesNotExist, get_template
from django.template import Template
import django_lcore
from constance import config
import frontmatter
@ -22,11 +23,28 @@ from downloads.models import Version
from .common import get_price_float
@django_lcore.APICache(initial=[])
def get_gateway_locations():
gateways = django_lcore.api.get("gateways/", enabled=True)
locations = set()
for gw in gateways.list_iter():
if not gw["tags"]:
continue
loc = gw["tags"].get("location")
if not loc:
continue
locations.add((loc["lat"], loc["lon"]))
return list(locations)
def index(request):
eur = '%.2f' % get_price_float()
return render(request, 'ccvpn/index.html', dict(eur_price=eur, motd=config.MOTD))
return render(request, 'ccvpn/index.html', {
"eur_price": '%.2f' % get_price_float(),
"motd": config.MOTD,
"gateway_locations": get_gateway_locations(),
})
def chat(request):

@ -496,83 +496,107 @@ ul.errorlist {
/***************************************************/
/********************* Home Page */
.home-content {
width: 75%;
margin: 3em auto;
.home-signup {
text-align: center;
}
.home-item{
float: left;
a.home-signup-button {
padding: 0.75em 2em;
}
@media screen and (max-width: 48em) {
.home-signup-button {
min-width: 50%;
}
}
.homepage h2 {
font-weight: 400;
text-align: center;
font-family: 'Arvo', serif;
font-size: 1.6em;
margin: 3em;
}
.home-item img{
width: 60%;
margin: auto;
.homepage .title {
color: #1c619a
}
.home-item h2{
color: #1c619a;
text-transform: uppercase;
font-weight: normal;
font-size: 1.5em;
margin: 0.80em 0 0.60em 0;
.homepage .title h3 {
width: 50%;
margin: auto;
border-bottom: 3px solid #1c619a;
border-radius: 5px;
}
.home-item p{
margin: 0px;
padding: 0.2em;
.homepage .inner {
width: 50%;
margin: auto;
}
.home-item b{ color: #1c619a; }
.home-item ul{
margin: 0;
padding: 0 1.5em;
.homepage .features {
margin: 2em 0;
}
.home-item ul li{
margin: 0px;
padding: 0px;
list-style: none;
.homepage .right h3 {
text-align: right;
}
.home-signup {
text-align: center;
.homepage h3 {
font-family: 'Arvo', serif;
font-weight: normal;
font-size: 1.2em;
}
a.home-signup-button {
padding: 0.75em 2em;
.homepage ul {
list-style-type: circle;
margin: 1em;
padding-left: 1em;
}
.homepage p {
margin: 0.75em;
}
.home-secondary > div {
padding: 0.5em 2em;
.homepage .home-signup {
margin: 3em 1em;
}
.home-secondary b:first-child {
.homepage .locations {
width: 70%;
margin: 4em auto;
}
.homepage .more {
text-align: right;
}
.homepage .map {
display: block;
}
#worldmap svg {
stroke-width: 0.5;
}
@media screen and (max-width: 80em) {
.home-content {
width: 100%;
}
#map {
display: block;
width: 100%;
margin: auto;
}
@media screen and (max-width: 48em) {
.home-content {
width: 100%;
margin-top: 0;
.homepage .features {
margin: 0;
}
.home-item-content {
margin-left: 20%;
.homepage .title h3 {
margin-top: 2em;
}
.home-item h2 {
margin: 1em 0 0.20em 0;
}
.home-item img {
width: 20%;
float: left;
margin-top: 3em;
.homepage .title h3, .homepage .inner {
width: 90%;
}
.home-signup-button {
min-width: 50%;
.homepage .locations {
width: 100%;
}
}
/***************************************************/
/********************* Account */
@ -1023,6 +1047,22 @@ div.ticket-message-private {
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
@font-face {
font-family: 'Arvo';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('../fonts/arvo-0.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: 'Arvo';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('../fonts/arvo-1.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/***************************************************/

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

@ -0,0 +1,104 @@
(function() {
function createSvgEl(tag) {
return document.createElementNS("http://www.w3.org/2000/svg", tag);
}
function lerp(datax, datay, x) {
for (let i=0; i<datax.length; i++) {
const lo = datax[i];
const hi = datax[i + 1];
if (lo > x || hi < x)
continue;
const loy = datay[i];
const hiy = datay[i + 1];
return loy + (hiy-loy) * ((x - lo) / (hi - lo));
}
}
function robinson(lat, lon, radius, centerMeridian, adjX, adjY) {
const table = [
// lat a b
[0, 1.0000, 0.0000],
[5, 0.9986, 0.0314],
[10, 0.9954, 0.0629],
[15, 0.9900, 0.0943],
[20, 0.9822, 0.1258],
[25, 0.9730, 0.1572],
[30, 0.9600, 0.1887],
[35, 0.9427, 0.2201],
[40, 0.9216, 0.2515],
[45, 0.8962, 0.2826],
[50, 0.8679, 0.3132],
[55, 0.8350, 0.3433],
[60, 0.7986, 0.3726],
[65, 0.7597, 0.4008],
[70, 0.7186, 0.4278],
[75, 0.6732, 0.4532],
[80, 0.6213, 0.4765],
[85, 0.5722, 0.4951],
[90, 0.5322, 0.5072],
];
const a = lerp(table.map(r => r[0]), table.map(r => r[1]), Math.abs(lat));
const b = lerp(table.map(r => r[0]), table.map(r => r[2]), Math.abs(lat));
const x = 0.8487 * radius * a * ((lon * Math.PI/180) - centerMeridian) * adjX;
const y = (1.3523 * radius * b * adjY) * (lat < 0 ? -1 : 1);
return [x, y];
}
function hexbyte(n) {
return Math.round(n).toString(16).padStart(2, '0')
}
function ring(x, y, radius, strokeWid, trans) {
const circle = createSvgEl("circle");
circle.setAttribute("cx", x);
circle.setAttribute("cy", y);
circle.setAttribute("r", radius);
circle.setAttribute("stroke", "#1c619a" + hexbyte(80 + trans * 5));
circle.setAttribute("stroke-width", strokeWid);
circle.setAttribute("fill", "#1c619a" + hexbyte(trans));
return circle;
}
function drawServerLocation(e, data) {
if (!e || !data) return;
const svg = e.contentDocument.querySelector("svg");
const height = svg.height.baseVal.value;
const width = svg.width.baseVal.value;
const earthRadius = width / 2.666269758 / 2;
const center = 0;
const adjX = 1.02;
const adjY = 2;
const offX = -12;
const offY = 75;
for (point of data) {
const xy = robinson(point[0], point[1], earthRadius, center, adjX, adjY);
const realX = (width / 2) + xy[0] + offX;
const realY = (height / 2) - (xy[1]) + offY;
const dot = createSvgEl("circle");
dot.setAttribute("cx", realX);
dot.setAttribute("cy", realY);
dot.setAttribute("r", 5);
dot.setAttribute("fill", "#1c619a");
svg.appendChild(dot);
const rf = 5;
const rs = 15;
svg.appendChild(ring(realX, realY, rf + rs * 1, 2, 20));
svg.appendChild(ring(realX, realY, rf + rs * 2, 1, 15));
svg.appendChild(ring(realX, realY, rf + rs * 3, 0.5, 10));
}
}
window.addEventListener("load", function() {
drawServerLocation(
document.getElementById("map"),
JSON.parse(document.getElementById('locations-data').textContent)
);
});
})();

@ -3,95 +3,64 @@
{% load static %}
{% block headers %}
<meta name="description" content="{% trans 'CCrypto VPN is a cheap, fast, anonymous and secure VPN service' %}" />
<meta name="description" content="{% trans 'CCrypto VPN is an affordable, fast, anonymous and secure VPN service' %}" />
{% endblock %}
{% block content %}
<div class="content">
<div class="pure-g home-content">
<div class="home-item pure-u-1 pure-u-md-1-5">
<img src="{% static 'img/unlimited.svg' %}" alt="" />
<div class="home-item-content">
<h2>{% trans 'Unlimited' %}</h2>
<p><b>{% trans 'Unlimited bandwidth' %}</b>.<br />
<b>{% trans 'Uncensored' %}</b>.<br />
{% trans 'The data must flow.' %}</p>
</div>
<div class="homepage">
<h2>Secure your browsing with a VPN</h2>
<div class="features left">
<div class="title">
<h3>Hide your IP Address</h3>
</div>
<div class="inner">
<p>From corporations and attackers tracking you for advertising, marketing, geo-blocking, extorsion, ...
and irresponsibly storing personal data that can leak to malicious parties and be used against you.</p>
</div>
<div class="home-item pure-u-1 pure-u-md-1-5">
<img src="{% static 'img/cheap.svg' %}" alt="" />
<div class="home-item-content">
<h2>{% trans 'Affordable' %}</h2>
<p><b>{{eur_price}}&euro;</b> {% trans 'per month!' %}<br/>
{% trans 'Pay by card, PayPal, or 40+ cryptocurrencies.' %}</p>
</div>
</div>
<div class="features right">
<div class="title">
<h3>through a Secure Tunnel to the Internet</h3>
</div>
<div class="home-item pure-u-1 pure-u-md-1-5">
<img src="{% static 'img/anon.svg' %}" alt="" />
<div class="home-item-content">
<h2>{% trans 'Secure' %}</h2>
<p><b>{% trans 'Encrypted tunnel' %}</b>
{% trans 'with an <b>anonymous address</b>.' %}<br />
{% trans 'Supports DNSSEC and PFS.' %}</p>
</div>
<div class="inner">
<p>
‣ Defend against eavesdropping & tampering, from compromised WiFi access points to intrusive corporate monitoring and Deep Packet Inspection.</p>
<p>
‣ Avoid network limitations (IPv6 unavailable, bad peering, misconfigured firewalls, ...)
and circumvent interception attempts (lying DNS, DNS blocking, ...)
</p>
</div>
<div class="home-item pure-u-1 pure-u-md-1-5">
<img src="{% static 'img/openvpn.svg' %}" alt="" />
<div class="home-item-content">
<h2>{% trans 'OpenVPN' %}</h2>
<p>
<ul>
<li><b>Windows, OSX</b></li>
<li><b>GNU/Linux, BSD</b></li>
<li><b>Android, iOS</b></li>
</ul>
</p>
</div>
</div>
<div class="features center">
<div class="title">
<h3>CCrypto VPN is a simple solution for only 3€/month</h3>
</div>
<div class="home-item pure-u-1 pure-u-md-1-5">
<img src="{% static 'img/fast.svg' %}" alt="" />
<div class="home-item-content">
<h2>{% trans 'Fast' %}</h2>
<p>{% trans 'Up to 1Gbps.' %}<br/>
<b>{% trans 'With WireGuard compatibility' %}</b>
{% trans 'for the best performances.' %}
</p>
</div>
<div class="inner">
<ul>
<li>Access to fast & secure servers around the world with no data cap.</li>
<li>Powered by OpenVPN or WireGuard, freely available on Windows, Linux, macOS, Android, iOS, and many more.</li>
<li>With the best encryption available, IPv4 & IPv6, private DNS resolvers, and DDoS protection.</li>
<li>Subscribe with PayPal, credit card, or any of 40+ cryptocurrencies</li>
</ul>
</div>
<div style="clear: both"></div>
</div>
<p class="home-signup">
<a href="/account/signup" class="home-signup-button pure-button pure-button-primary">
{% trans 'Sign up and get your free trial' %}
{% trans 'Sign up & try for a week for free' %}
</a>
</p>
<div class="pure-g home-secondary">
<div class="pure-u-1 pure-u-md-1-2">
<p>{% trans '<b>Hide your IP address</b> to disrupt tracking and geolocation.' %}</p>
</div>
<div class="pure-u-1 pure-u-md-1-2">
<p>{% trans '<b>Protect your privacy</b> on insecure networks with AES GCM 256 bits, RSA 4096 bits.' %}</p>
</div>
<div class="pure-u-1 pure-u-md-1-2">
<p>{% trans '<b>Get a clean and neutral access</b> without censorship, interception, or manipulation.' %}</p>
</div>
<div class="pure-u-1 pure-u-md-1-2">
<p>{% trans '<b>Bypass firewalls</b> in restricted network environments.' %}</p>
</div>
<div class="pure-u-1 pure-u-md-1-2">
<p>{% trans '<b>Transparently compress your traffic</b> to save data and gain speed on slow connections.' %}</p>
</div>
<div class="pure-u-1 pure-u-md-1-2">
<p>{% trans '<b>Get IPv6 connectivity</b> on IPv4-only networks or where IPv6 is not equally supported.' %}</p>
</div>
<div class="locations">
<object id="map" data="{% static 'img/world.svg' %}" type="image/svg+xml"></object>
{{gateway_locations|json_script:"locations-data"}}
<script type="text/javascript" src="{% static 'js/map.js' %}"></script>
<p class="more">
<a href="/servers">more on our infrastructure</a>
</p>
</div>
</div>
{% endblock %}

Loading…
Cancel
Save