Working site/webapp v1.0

master
Skylar Ittner 3 years ago
commit ea22e16775

@ -0,0 +1,6 @@
[Dolphin]
Timestamp=2019,10,20,19,16,41
Version=4
[Settings]
HiddenFilesShown=true

4
.gitignore vendored

@ -0,0 +1,4 @@
web
nbproject/private
vendor
source/static/settings.php

@ -0,0 +1,91 @@
<?php
require __DIR__ . "/../vendor/autoload.php";
require "lib/settings.php";
require "lib/mustache.php";
require "lib/markdown.php";
function toHtml($file, $stache = null): string {
global $_SETTINGS, $STACHECONTEXT;
if ($file->getExtension() != "php") {
if ($stache == null) {
$stache = $STACHECONTEXT;
}
$contents = file_get_contents($file->getPathname());
$cleancontents = "";
foreach (preg_split("/((\r?\n)|(\r\n?))/", $contents) as $line) {
if (strpos($line, "// ") === 0) {
$keyval = explode(" ", str_replace("// ", "", $line), 2);
$stache[$keyval[0]] = $keyval[1];
} else {
$cleancontents .= $line . "\n";
}
}
$contents = stacheify($cleancontents, "", $stache);
}
switch ($file->getExtension()) {
case "md":
$html = md2html($contents);
return stacheify($html, $_SETTINGS["md_template"], $stache);
case "htm": // .htm for HTML files that should be templated
return stacheify($contents, $_SETTINGS["md_template"], $stache);
case "html":
return $contents;
case "php":
ob_start();
include $file->getPathname();
$contents = ob_get_clean();
return stacheify($contents, "", $stache);
default:
return "";
}
}
echo "Compiling templates and included snippets...\n";
$STACHECONTEXT = getstachecontext();
echo "Cleaning old files in $_SETTINGS[output_folder]...\n";
$outputdir = __DIR__ . '/../' . $_SETTINGS["output_folder"];
$di = new RecursiveDirectoryIterator($outputdir, FilesystemIterator::SKIP_DOTS);
$ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($ri as $file) {
$file->isDir() ? rmdir($file) : unlink($file);
}
$it = new RecursiveDirectoryIterator(__DIR__ . "/../" . $_SETTINGS["source_folder"] . "/pages", \RecursiveDirectoryIterator::SKIP_DOTS);
echo "Compiling pages...\n";
foreach (new RecursiveIteratorIterator($it) as $file) {
if ($file->isDir()) {
continue;
}
$html = toHtml($file);
if ($html == "") {
continue;
}
$indenter = new \Gajus\Dindent\Indenter();
$html = $indenter->indent($html);
$outpath = str_replace($_SETTINGS["source_folder"] . "/pages", $_SETTINGS["output_folder"], $file->getPath());
if (!file_exists($outpath)) {
mkdir($outpath, 0777, true);
}
$outfile = $outpath . "/" . $file->getBasename("." . $file->getExtension()) . ".html";
echo " " . explode("../$_SETTINGS[output_folder]", $outfile, 2)[1] . "\n";
file_put_contents($outfile, $html);
}
echo "Copying static content...\n";
$source = __DIR__ . "/../" . $_SETTINGS["source_folder"] . "/static";
$dest = __DIR__ . "/../" . $_SETTINGS["output_folder"];
foreach ($iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($source, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST) as $item) {
echo " " . explode("../$_SETTINGS[source_folder]/static", $item, 2)[1] . "\n";
if ($item->isDir()) {
mkdir($dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName());
} else {
copy($item, $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName());
}
}

@ -0,0 +1,21 @@
<?php
use League\CommonMark\CommonMarkConverter;
use League\CommonMark\Environment;
use League\CommonMark\Extras\CommonMarkExtrasExtension;
//use Webuni\CommonMark\TableExtension\TableExtension;
use Evirma\CommonMark\Extension\AttributesExtension;
$mdenvironment = Environment::createCommonMarkEnvironment();
$mdenvironment->addExtension(new CommonMarkExtrasExtension());
//$mdenvironment->addExtension(new TableExtension());
$mdenvironment->addExtension(new AttributesExtension());
$mdconverter = new CommonMarkConverter([], $mdenvironment);
function md2html($markdown) {
global $mdconverter;
return $mdconverter->convertToHtml($markdown);
}

@ -0,0 +1,33 @@
<?php
/**
* Generate the global context for Mustache.
*/
function getstachecontext(): array {
global $_SETTINGS;
$context = [];
foreach ($_SETTINGS["context"] as $key => $val) {
$context[$key] = $val;
}
return $context;
}
function stacheify(string $content, $template = "", $context = null): string {
global $_SETTINGS, $STACHECONTEXT;
if (!is_array($context)) {
$context = $STACHECONTEXT;
}
$options = ['extension' => '.html'];
$m = new Mustache_Engine([
'partials_loader' => new Mustache_Loader_FilesystemLoader(__DIR__ . "/../../" . $_SETTINGS["source_folder"] . "/includes", $options)
]);
if (!empty($template)) {
$template = file_get_contents(__DIR__ . "/../../" . $_SETTINGS["source_folder"] . "/template/" . $template . ".html");
$context["page_content"] = $content;
return $m->render($template, $context);
}
return $m->render($content, $context);
}

@ -0,0 +1,23 @@
<?php
/**
* Load settings from settings.json
*/
$_SETTINGS = [
"md_template" => "generic",
"source_folder" => "source",
"output_folder" => "public",
"folder_permission" => 775,
"context" => [
// Global variables for Mustache templates
]
];
$customsettings = json_decode(file_get_contents(__DIR__ . "/../../settings.json"), true);
foreach ($customsettings as $key => $val) {
$_SETTINGS[$key] = $val;
}
unset($customsettings);

@ -0,0 +1,5 @@
#!/bin/bash
sass source/static/assets/sass/main.scss source/static/assets/css/main.css
php bin/compile.php

@ -0,0 +1,18 @@
{
"name": "netsyms/stuff2static",
"type": "project",
"require": {
"mustache/mustache": "^2.12",
"league/commonmark": "^1.0",
"gajus/dindent": "^2.0",
"evirma/commonmark-ext-attributes": "^1.0",
"league/commonmark-extras": "^1.0"
},
"license": "MPL-2.0",
"authors": [
{
"name": "Skylar Ittner",
"email": "admin@netsyms.com"
}
]
}

179
composer.lock generated

@ -0,0 +1,179 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "3478c14a7813f09b795d80397ff5e74c",
"packages": [
{
"name": "gajus/dindent",
"version": "2.0.2",
"source": {
"type": "git",
"url": "https://github.com/gajus/dindent.git",
"reference": "d81c3a6f78fbe1ab26f5e753098bbbef6b6a9f3c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/gajus/dindent/zipball/d81c3a6f78fbe1ab26f5e753098bbbef6b6a9f3c",
"reference": "d81c3a6f78fbe1ab26f5e753098bbbef6b6a9f3c",
"shasum": ""
},
"require": {
"php": ">=5.3"
},
"require-dev": {
"satooshi/php-coveralls": "dev-master"
},
"type": "library",
"autoload": {
"psr-4": {
"Gajus\\Dindent\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Gajus Kuizinas",
"email": "gk@anuary.com"
}
],
"description": "HTML indentation library for development and testing.",
"homepage": "https://github.com/gajus/dindent",
"keywords": [
"format",
"html",
"indent"
],
"time": "2014-10-08T10:03:04+00:00"
},
{
"name": "league/commonmark",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/commonmark.git",
"reference": "7a40f2b0931602c504c2a9692d9f1e33635fd5ef"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/7a40f2b0931602c504c2a9692d9f1e33635fd5ef",
"reference": "7a40f2b0931602c504c2a9692d9f1e33635fd5ef",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"php": "^7.1"
},
"replace": {
"colinodell/commonmark-php": "*"
},
"require-dev": {
"cebe/markdown": "~1.0",
"commonmark/commonmark.js": "0.29.0",
"erusev/parsedown": "~1.0",
"michelf/php-markdown": "~1.4",
"mikehaertl/php-shellcommand": "^1.4",
"phpstan/phpstan-shim": "^0.11.5",
"phpunit/phpunit": "^7.5",
"scrutinizer/ocular": "^1.5",
"symfony/finder": "^4.2"
},
"suggest": {
"league/commonmark-extras": "Library of useful extensions including smart punctuation"
},
"bin": [
"bin/commonmark"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1-dev"
}
},
"autoload": {
"psr-4": {
"League\\CommonMark\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Colin O'Dell",
"email": "colinodell@gmail.com",
"homepage": "https://www.colinodell.com",
"role": "Lead Developer"
}
],
"description": "PHP Markdown parser based on the CommonMark spec",
"homepage": "https://commonmark.thephpleague.com",
"keywords": [
"commonmark",
"markdown",
"parser"
],
"time": "2019-06-29T11:19:01+00:00"
},
{
"name": "mustache/mustache",
"version": "v2.12.0",
"source": {
"type": "git",
"url": "https://github.com/bobthecow/mustache.php.git",
"reference": "fe8fe72e9d580591854de404cc59a1b83ca4d19e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/fe8fe72e9d580591854de404cc59a1b83ca4d19e",
"reference": "fe8fe72e9d580591854de404cc59a1b83ca4d19e",
"shasum": ""
},
"require": {
"php": ">=5.2.4"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "~1.11",
"phpunit/phpunit": "~3.7|~4.0|~5.0"
},
"type": "library",
"autoload": {
"psr-0": {
"Mustache": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Justin Hileman",
"email": "justin@justinhileman.info",
"homepage": "http://justinhileman.com"
}
],
"description": "A Mustache implementation in PHP.",
"homepage": "https://github.com/bobthecow/mustache.php",
"keywords": [
"mustache",
"templating"
],
"time": "2017-07-11T12:54:05+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": []
}

@ -0,0 +1,25 @@
auxiliary.org-netbeans-modules-css-prep.less_2e_compiler_2e_options=
auxiliary.org-netbeans-modules-css-prep.less_2e_enabled=false
auxiliary.org-netbeans-modules-css-prep.less_2e_mappings=/less:/css
auxiliary.org-netbeans-modules-css-prep.sass_2e_compiler_2e_options=
auxiliary.org-netbeans-modules-css-prep.sass_2e_configured=true
auxiliary.org-netbeans-modules-css-prep.sass_2e_enabled=true
auxiliary.org-netbeans-modules-css-prep.sass_2e_mappings=/source/static/assets/sass:/source/static/assets/css,/assets/sass:/assets/css
auxiliary.org-netbeans-modules-javascript-nodejs.enabled=false
auxiliary.org-netbeans-modules-javascript-nodejs.node_2e_default=true
auxiliary.org-netbeans-modules-javascript-nodejs.run_2e_enabled=false
auxiliary.org-netbeans-modules-javascript-nodejs.sync_2e_enabled=true
browser.run=true
file.reference.helena.express-source=source
file.reference.helena.express-web=web
file.reference.new.ship.netsyms.com-public_html=public_html
file.reference.new.ship.netsyms.com-source=source
file.reference.new.ship.netsyms.com-test=test
file.reference.new.ship.netsyms.com-web=web
file.reference.ship.netsyms.com-source=source
file.reference.ship.netsyms.com-web=web
files.encoding=UTF-8
site.root.folder=${file.reference.helena.express-web}
source.folder=${file.reference.helena.express-source}
start.file=index.html
web.context.root=/

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.web.clientproject</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/clientside-project/1">
<name>certifiedfromhome.com</name>
</data>
</configuration>
</project>

@ -0,0 +1,5 @@
sass source/static/assets/sass/main.scss source/static/assets/css/main.css
php bin/compile.php
rsync -rv web 192.168.122.10:/var/www/certifiedfromhome.com/

@ -0,0 +1,14 @@
{
"context": {
"site_title": "Certified from Home",
"site_root": "https://certifiedfromhome.com/",
"stripe_pk": "pk_live_RgpadCo1LIIkfyUsY47VhUq6",
"navigation": [
{
"title": "Home",
"url": "/"
}
]
},
"output_folder": "web"
}

@ -0,0 +1,8 @@
<!-- Footer -->
<footer id="footer">
<div class="copyright">
&copy; 2021 <a href="https://netsyms.com">Netsyms Technologies</a> and <a href="https://helena.express">Helena Express</a>.
<br />
<a href="https://netsyms.com/#contact">Contact Us</a>
</div>
</footer>

@ -0,0 +1,46 @@
<head>
<meta charset="utf-8" />
<title>{{#title}}{{title}} :: {{/title}}{{site_title}}</title>
<link rel="stylesheet" href="{{site_root}}assets/css/main.css" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="{{site_root}}/assets/favicon.png">
<meta property="og:title" content="{{#title}}{{title}} :: {{/title}}{{site_title}}" />
<meta property="og:url" content="{{site_root}}" />
<meta property="og:type" content="website" />
{{#meta_description}}
<meta name="description" content="{{meta_description}}" />
<meta name="og:description" content="{{meta_description}}" />
{{/meta_description}}
{{^meta_description}}
{{#description}}
<meta name="description" content="{{description}}" />
<meta name="og:description" content="{{description}}" />
{{/description}}
{{^description}}
<meta name="description" content="Send Certified Mail letters without going to the Post Office. All you need is a printer, a sheet of paper, and some tape." />
<meta property="og:description" content="Send Certified Mail letters without going to the Post Office. All you need is a printer, a sheet of paper, and some tape." />
{{/description}}
{{/meta_description}}
<!-- Opt out by enabling Do-Not-Track in your browser -->
<script type="text/javascript">
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function () {
var u = "https://analytics.netsyms.net/";
_paq.push(['setTrackerUrl', u + 'matomo.php']);
_paq.push(['setSiteId', '34']);
var d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];
g.type = 'text/javascript';
g.async = true;
g.src = u + 'matomo.js';
s.parentNode.insertBefore(g, s);
})();
</script>
</head>
<noscript><img src="https://analytics.netsyms.net/matomo.php?idsite=33&amp;rec=1" style="border:0;" alt="" /></noscript>

@ -0,0 +1,4 @@
<header id="header"{{#headeralt}} class="alt"{{/headeralt}}>
<span class="logo"><a href="{{site_root}}">Certified from Home</a></span>
<!-- <a href="#menu">Menu</a> -->
</header>

@ -0,0 +1,11 @@
<nav id="menu">
<div class="inner">
<h2>Menu</h2>
<ul class="links">
{{#navigation}}
<li><a href="{{url}}">{{title}}</a></li>
{{/navigation}}
</ul>
<a class="close">Close</a>
</div>
</nav>

@ -0,0 +1,12 @@
<script src="https://static.netsyms.net/jquery/jquery.min.js"></script>
<script src="{{site_root}}assets/js/browser.min.js"></script>
<script src="{{site_root}}assets/js/breakpoints.min.js"></script>
<script src="{{site_root}}assets/js/util.js"></script>
<script src="{{site_root}}assets/js/jquery.scrollex.min.js"></script>
<script src="{{site_root}}assets/js/jquery.scrolly.min.js"></script>
<script src="{{site_root}}assets/js/main.js"></script>
<script src="https://js.stripe.com/v3/"></script>
<script>
var stripe = Stripe("{{stripe_pk}}");
</script>
<script src="{{site_root}}assets/js/shipment.js"></script>

@ -0,0 +1,51 @@
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option>
<option value="AR">Arkansas</option>
<option value="CA">California</option>
<option value="CO">Colorado</option>
<option value="CT">Connecticut</option>
<option value="DE">Delaware</option>
<option value="DC">District Of Columbia</option>
<option value="FL">Florida</option>
<option value="GA">Georgia</option>
<option value="HI">Hawaii</option>
<option value="ID">Idaho</option>
<option value="IL">Illinois</option>
<option value="IN">Indiana</option>
<option value="IA">Iowa</option>
<option value="KS">Kansas</option>
<option value="KY">Kentucky</option>
<option value="LA">Louisiana</option>
<option value="ME">Maine</option>
<option value="MD">Maryland</option>
<option value="MA">Massachusetts</option>
<option value="MI">Michigan</option>
<option value="MN">Minnesota</option>
<option value="MS">Mississippi</option>
<option value="MO">Missouri</option>
<option value="MT">Montana</option>
<option value="NE">Nebraska</option>
<option value="NV">Nevada</option>
<option value="NH">New Hampshire</option>
<option value="NJ">New Jersey</option>
<option value="NM">New Mexico</option>
<option value="NY">New York</option>
<option value="NC">North Carolina</option>
<option value="ND">North Dakota</option>
<option value="OH">Ohio</option>
<option value="OK">Oklahoma</option>
<option value="OR">Oregon</option>
<option value="PA">Pennsylvania</option>
<option value="RI">Rhode Island</option>
<option value="SC">South Carolina</option>
<option value="SD">South Dakota</option>
<option value="TN">Tennessee</option>
<option value="TX">Texas</option>
<option value="UT">Utah</option>
<option value="VT">Vermont</option>
<option value="VA">Virginia</option>
<option value="WA">Washington</option>
<option value="WV">West Virginia</option>
<option value="WI">Wisconsin</option>
<option value="WY">Wyoming</option>

@ -0,0 +1,2 @@
// title Page not found
// description The page you're looking for has been moved, deleted, or never existed (spooky!).

@ -0,0 +1,219 @@
// headeralt true
<!DOCTYPE HTML>
<html>
{{> head}}
<body class="is-preload">
<div id="page-wrapper">
{{> header}}
{{> nav}}
<!-- Banner -->
<section id="banner">
<div class="inner">
<p>Send Certified Mail from home in minutes with just a printer.<br>No envelopes, forms, labels, stamps, waiting in line, or account required!</p>
<ul class="actions special">
<li><a href="#info" class="button large primary scrolly">How it Works</a></li>
<li><a href="#label" class="button large primary scrolly">Get Started</a></li>
</ul>
</div>
</section>
<!-- One -->
<!--<section id="one" class="wrapper style2">
<div class="inner">
<section class="spotlights">
<article>
<header class="major">
<p>Magna</p>
<h2>Dolor sit amet vivamus</h2>
</header>
<p>Phasellus in ante vitae nibh porttitor tempus vitae ut ante. Vestibulum blandit ex a elementum viverra. Sed quat diam, aliquet tempus felis nisl at lacus.</p>
<ul class="actions">
<li><a href="#" class="button">More</a></li>
</ul>
</article>
<article>
<header class="major">
<p>Lorem</p>
<h2>Ipsum dolor sit amet</h2>
</header>
<p>Phasellus in ante vitae nibh porttitor tempus vitae ut ante. Vestibulum blandit ex a elementum viverra. Sed quat diam, aliquet tempus felis nisl at lacus.</p>
<ul class="actions">
<li><a href="#" class="button">More</a></li>
</ul>
</article>
</section>
</div>
</section>-->
<!-- Two -->
<section id="info" class="wrapper style2 special">
<div class="inner">
<header class="major" style="text-align: left;">
<h2>How it Works</h2>
</header>
<ul class="features">
<li>
<span class="icon major regular fa-edit"></span>
<h4>Add Info</h4>
<p>Tell us where your letter is going and your return address.</p>
</li>
<li>
<span class="icon major regular fa-credit-card"></span>
<h4>Pay</h4>
<p>We'll charge your card for the price of postage plus a $1 service fee.</p>
</li>
<li>
<span class="icon major regular fa-print"></span>
<h4>Print and Fold</h4>
<p>Print the PDF we give you, fold it around your letter, and tape the edges to make a postage-paid envelope.</p>
</li>
<li>
<span class="icon major regular fa-mailbox"></span>
<h4>Send</h4>
<p>Put your letter in your mailbox like any other outgoing mail; it'll be picked up by your mail carrier.</p>
</li>
</ul>
</div>
</section>
<!-- Three -->
<section id="label" class="wrapper style1">
<div class="inner">
<header class="major">
<p id="header-small-text">Get Started</p>
<h2 id="header-big-text">Send a Certified Mail letter</h2>
</header>
<form id="addressform">
<h3>To:</h3>
<input type="text" name="to_name" placeholder="Recipient Name" />
<input type="text" name="to_company" placeholder="Company Name" />
<input type="text" name="to_street" placeholder="456 Destination Street" required />
<input type="text" name="to_street2" placeholder="Second Line of Address (optional)" />
<input type="text" name="to_city" placeholder="City" />
<select name="to_state">
<option value="">State</option>
{{> statelist}}
</select>
<input type="text" name="to_zip" placeholder="ZIP Code" />
<br />
<h3>From:</h3>
<input type="text" name="from_name" placeholder="Your Name" required />
<input type="text" name="from_street" placeholder="1234 Your Street" required />
<input type="text" name="from_street2" placeholder="Second Line" />
<input type="text" name="from_city" placeholder="Your City" />
<select name="from_state">
<option value="">Your State</option>
{{> statelist}}
</select>
<input type="text" name="from_zip" placeholder="Your ZIP Code" required />
<br />
<h3>Options:</h3>
<div class="row gtr-uniform">
<div class="col-4 col-12-small">
<input id="postagetype_certified" type="radio" name="postagetype" value="certified" checked="" />
<label for="postagetype_certified"><b>Certified Mail</b>
<br />
Trackable via USPS.com to follow its progress and see the
date and time of delivery. The recipient will need to sign for
it or pick it up from their local post office.
</label>
</div>
<div class="col-4 col-12-small">
<input id="postagetype_certified_receipt" type="radio" name="postagetype" value="certified_receipt" />
<label for="postagetype_certified_receipt"><b>Certified Mail + Electronic Return Receipt</b>
<br />
With this extra service, after the letter is delivered,
you can visit USPS.com and use the tracking code to have the
return receipt, including date, time, and a copy of the signature,
emailed to you.
</label>
</div>
<div class="col-4 col-12-small">
<input id="postagetype_first" type="radio" name="postagetype" value="first" />
<label for="postagetype_first"><b>First Class letter</b>
<br />
Make a regular First Class envelope with no tracking, signatures,
or special features. Must weigh no more than 3.5 ounces and be at most 1/4
inch thick. If the contents aren't flexible, it must weigh no more
than 3 ounces.
</label>
</div>
</div>
<br />
<div id="addresserror"></div>
<br />
<ul class="actions">
<li><a id="getRateAndValidateAddressButton" class="button large primary"><i class="far fa-chevron-right"></i> Next</a></li>
</ul>
</form>
<div id="paymentform" style="display: none;">
<div class="row gtr-uniform">
<div class="col-4 col-12-xsmall">
<i class="far fa-share"></i> To:
<br />
<span id="toaddr"></span>
</div>
<div class="col-4 col-12-xsmall">
From:
<br />
<span id="fromaddr"></span>
</div>
</div>
<br />
<h3>Total: <span id="paymentamount"></span></h3>
<div id="card-element" style="width: 500px; max-width: 100%; background-color: white; padding: 1em; border-radius: 4px;"></div>
<br />
<div id="paymenterror"></div>
<br />
<ul class="actions">
<li><a id="cancelPaymentButton" class="button large"><i class="far fa-chevron-left"></i> Edit Address</a></li>
<li><a id="submitPaymentButton" class="button large primary"><i class="far fa-chevron-right"></i> Purchase</a></li>
</ul>
</div>
<div id="printform" style="display: none;">
<p>
You're all set! Print the PDF below on a sheet of 8.5x11 letter-sized paper.
Make sure your printer is set to print at 100% or actual size and not shrink to fit.
Then just fold on the dashed lines, put your letter inside, tape the edges,
and tape the flap to seal. Put the letter in your mailbox with the signal flag up,
or slide it into your cluster mailbox's outgoing mail slot.
</p>
<p id="trackingnumberparagraph">Tracking Number: <a target="_BLANK" id="trackingnumber"></a>
<br>You should write this number down or bookmark the tracking link,
we won't show it again after you leave the page.</p>
<p><i class="fal fa-badge-sheriff"></i> Warning: Do not print and mail
multiple copies of the same PDF.
It's fraud, forgery, theft, and a violation of multiple federal laws,
such as 18 U.S. Code § 501, 1001, 1341, 1720, 1725, and 3802.
If two letters with the same barcode are detected by the mail sorting system,
they will be automatically reported to USPIS, the federal postal police.
If your PDF doesn't print correctly, first cancel the misprinted postage by drawing
an X through all the barcodes or destroying the paper, then try printing again.
</p>
<br />
<ul class="actions">
<li><a id="printButton" class="button large primary icon regular fa-print">Print</a></li>
<li><a id="startOverButton" class="button large icon regular fa-redo">Send Another Letter</a></li>
</ul>
<iframe style="width: 100%; height: 1200px; max-height:80vh;" src="about:blank" id="pdfframe"></iframe>
<a id="pdfbackuplink">Can't see the file and/or print it? Click here.</a>
</div>
</div>
</section>
{{> footer}}
</div>
{{> scripts}}
</body>
</html>

@ -0,0 +1,6 @@
[Dolphin]
Timestamp=2020,9,1,11,26,48
Version=4
[Settings]
HiddenFilesShown=true

@ -0,0 +1,33 @@
Options -Indexes
ErrorDocument 404 /404.html
RewriteEngine On
RewriteBase /
RewriteRule ^data/uploads/(.*)$ /files/$1 [R=301,NC,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ /$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\.]+)$ $1.html [NC,L]
# O P T I M I Z E
<If "%{REQUEST_URI} =~ m#(assets|files|images)/(.+)$#">
<IfModule mod_expires.c>
ExpiresActive on
ExpiresByType image/jpg “access plus 7 days”
ExpiresByType image/png “access plus 7 days”
ExpiresByType application/javascript “access plus 1 days”
ExpiresByType text/javascript “access plus 1 days”
ExpiresByType text/css “access plus 1 days”
</IfModule>
</If>
<Else>
<IfModule mod_http2.c>
H2PushResource /assets/css/main.css
H2PushResource /assets/css/media.css
H2PushResource /images/happy-map-helena.jpg
H2PushResource /images/house-porch-signal.jpg
</IfModule>
</Else>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="32"
height="32"
viewBox="0 0 8.4666665 8.4666669"
version="1.1"
id="svg8"
inkscape:version="0.92.3 (2405546, 2018-03-11)"
sodipodi:docname="favicon.svg"
inkscape:export-filename="/home/skylar/Documents/Projects/Websites/certifiedfromhome.com/source/static/assets/favicon.png"
inkscape:export-xdpi="192"
inkscape:export-ydpi="192">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.98994949"
inkscape:cx="-177.33349"
inkscape:cy="57.84457"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
inkscape:window-width="1920"
inkscape:window-height="1013"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-288.53332)">
<g
id="g877"
transform="translate(0,-0.14642665)">
<path
id="path2-5"
d="m 6.7789145,293.28342 c 0.040307,-0.0321 0.1002521,-0.002 0.1002521,0.0486 v 2.11357 c 0,0.27388 -0.2222087,0.49609 -0.4960934,0.49609 H 2.0835939 c -0.2738854,0 -0.4960941,-0.22221 -0.4960941,-0.49609 v -2.11254 c 0,-0.0517 0.058913,-0.0806 0.100252,-0.0486 0.2315101,0.17984 0.5384687,0.40825 1.5926683,1.17409 0.218074,0.15917 0.58601,0.49403 0.9529128,0.49196 0.36897,0.003 0.7441407,-0.33899 0.9539474,-0.49196 1.0541995,-0.76584 1.3601235,-0.99529 1.5916342,-1.17512 z m -2.5455816,1.33532 c 0.2397787,0.004 0.5849774,-0.30179 0.7586101,-0.42788 1.3714928,-0.99529 1.4758795,-1.08211 1.7921389,-1.33015 0.059947,-0.0465 0.095085,-0.11886 0.095085,-0.19534 V 292.469 c 0,-0.27389 -0.2222087,-0.49609 -0.4960934,-0.49609 H 2.0835939 c -0.2738854,0 -0.4960941,0.2222 -0.4960941,0.49609 v 0.19637 c 0,0.0765 0.03514,0.1478 0.095085,0.19534 0.3162594,0.24701 0.420646,0.33486 1.7921389,1.33015 0.1736327,0.12609 0.5188308,0.43201 0.7586092,0.42788 z"
style="fill:#388e3c;stroke-width:0.26458335"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="ccssssccccccccccccc"
style="fill:currentColor;stroke-width:0.26458335"
inkscape:connector-curvature="0"
id="path2"
d="m 7.856301,292.68764 -1.0680101,-0.88035 v -1.7695 c 0,-0.0847 -0.068636,-0.15331 -0.153303,-0.15331 H 5.919574 c -0.084667,0 -0.153303,0.0687 -0.153303,0.15331 v 0.92761 l -1.1437677,-0.94103 c -0.2263678,-0.18627 -0.552922,-0.18627 -0.7792902,0 l -3.23379801,2.66327 c -0.065288,0.054 -0.074441,0.15064 -0.020441,0.21588 l 0.3257685,0.39604 c 0.053859,0.0655 0.15065251,0.0748 0.21602951,0.0208 l 3.0049934,-2.47509 c 0.057042,-0.0459 0.1384197,-0.0459 0.1954614,0 l 3.0051212,2.47508 c 0.065256,0.054 0.1619394,0.0449 0.2159018,-0.0205 l 0.3257693,-0.39602 c 0.053959,-0.0657 0.044216,-0.16267 -0.02172,-0.21629 z" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

@ -0,0 +1,2 @@
/* breakpoints.js v1.0 | @ajlkn | MIT licensed */
var breakpoints=function(){"use strict";function e(e){t.init(e)}var t={list:null,media:{},events:[],init:function(e){t.list=e,window.addEventListener("resize",t.poll),window.addEventListener("orientationchange",t.poll),window.addEventListener("load",t.poll),window.addEventListener("fullscreenchange",t.poll)},active:function(e){var n,a,s,i,r,d,c;if(!(e in t.media)){if(">="==e.substr(0,2)?(a="gte",n=e.substr(2)):"<="==e.substr(0,2)?(a="lte",n=e.substr(2)):">"==e.substr(0,1)?(a="gt",n=e.substr(1)):"<"==e.substr(0,1)?(a="lt",n=e.substr(1)):"!"==e.substr(0,1)?(a="not",n=e.substr(1)):(a="eq",n=e),n&&n in t.list)if(i=t.list[n],Array.isArray(i)){if(r=parseInt(i[0]),d=parseInt(i[1]),isNaN(r)){if(isNaN(d))return;c=i[1].substr(String(d).length)}else c=i[0].substr(String(r).length);if(isNaN(r))switch(a){case"gte":s="screen";break;case"lte":s="screen and (max-width: "+d+c+")";break;case"gt":s="screen and (min-width: "+(d+1)+c+")";break;case"lt":s="screen and (max-width: -1px)";break;case"not":s="screen and (min-width: "+(d+1)+c+")";break;default:s="screen and (max-width: "+d+c+")"}else if(isNaN(d))switch(a){case"gte":s="screen and (min-width: "+r+c+")";break;case"lte":s="screen";break;case"gt":s="screen and (max-width: -1px)";break;case"lt":s="screen and (max-width: "+(r-1)+c+")";break;case"not":s="screen and (max-width: "+(r-1)+c+")";break;default:s="screen and (min-width: "+r+c+")"}else switch(a){case"gte":s="screen and (min-width: "+r+c+")";break;case"lte":s="screen and (max-width: "+d+c+")";break;case"gt":s="screen and (min-width: "+(d+1)+c+")";break;case"lt":s="screen and (max-width: "+(r-1)+c+")";break;case"not":s="screen and (max-width: "+(r-1)+c+"), screen and (min-width: "+(d+1)+c+")";break;default:s="screen and (min-width: "+r+c+") and (max-width: "+d+c+")"}}else s="("==i.charAt(0)?"screen and "+i:i;t.media[e]=!!s&&s}return t.media[e]!==!1&&window.matchMedia(t.media[e]).matches},on:function(e,n){t.events.push({query:e,handler:n,state:!1}),t.active(e)&&n()},poll:function(){var e,n;for(e=0;e<t.events.length;e++)n=t.events[e],t.active(n.query)?n.state||(n.state=!0,n.handler()):n.state&&(n.state=!1)}};return e._=t,e.on=function(e,n){t.on(e,n)},e.active=function(e){return t.active(e)},e}();!function(e,t){"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?module.exports=t():e.breakpoints=t()}(this,function(){return breakpoints});

@ -0,0 +1,2 @@
/* browser.js v1.0 | @ajlkn | MIT licensed */
var browser=function(){"use strict";var e={name:null,version:null,os:null,osVersion:null,touch:null,mobile:null,_canUse:null,canUse:function(n){e._canUse||(e._canUse=document.createElement("div"));var o=e._canUse.style,r=n.charAt(0).toUpperCase()+n.slice(1);return n in o||"Moz"+r in o||"Webkit"+r in o||"O"+r in o||"ms"+r in o},init:function(){var n,o,r,i,t=navigator.userAgent;for(n="other",o=0,r=[["firefox",/Firefox\/([0-9\.]+)/],["bb",/BlackBerry.+Version\/([0-9\.]+)/],["bb",/BB[0-9]+.+Version\/([0-9\.]+)/],["opera",/OPR\/([0-9\.]+)/],["opera",/Opera\/([0-9\.]+)/],["edge",/Edge\/([0-9\.]+)/],["safari",/Version\/([0-9\.]+).+Safari/],["chrome",/Chrome\/([0-9\.]+)/],["ie",/MSIE ([0-9]+)/],["ie",/Trident\/.+rv:([0-9]+)/]],i=0;i<r.length;i++)if(t.match(r[i][1])){n=r[i][0],o=parseFloat(RegExp.$1);break}for(e.name=n,e.version=o,n="other",o=0,r=[["ios",/([0-9_]+) like Mac OS X/,function(e){return e.replace("_",".").replace("_","")}],["ios",/CPU like Mac OS X/,function(e){return 0}],["wp",/Windows Phone ([0-9\.]+)/,null],["android",/Android ([0-9\.]+)/,null],["mac",/Macintosh.+Mac OS X ([0-9_]+)/,function(e){return e.replace("_",".").replace("_","")}],["windows",/Windows NT ([0-9\.]+)/,null],["bb",/BlackBerry.+Version\/([0-9\.]+)/,null],["bb",/BB[0-9]+.+Version\/([0-9\.]+)/,null],["linux",/Linux/,null],["bsd",/BSD/,null],["unix",/X11/,null]],i=0;i<r.length;i++)if(t.match(r[i][1])){n=r[i][0],o=parseFloat(r[i][2]?r[i][2](RegExp.$1):RegExp.$1);break}e.os=n,e.osVersion=o,e.touch="wp"==e.os?navigator.msMaxTouchPoints>0:!!("ontouchstart"in window),e.mobile="wp"==e.os||"android"==e.os||"ios"==e.os||"bb"==e.os}};return e.init(),e}();!function(e,n){"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?module.exports=n():e.browser=n()}(this,function(){return browser});

File diff suppressed because one or more lines are too long

@ -0,0 +1,2 @@
/* jquery.scrollex v0.2.1 | (c) @ajlkn | github.com/ajlkn/jquery.scrollex | MIT licensed */
!function(t){function e(t,e,n){return"string"==typeof t&&("%"==t.slice(-1)?t=parseInt(t.substring(0,t.length-1))/100*e:"vh"==t.slice(-2)?t=parseInt(t.substring(0,t.length-2))/100*n:"px"==t.slice(-2)&&(t=parseInt(t.substring(0,t.length-2)))),t}var n=t(window),i=1,o={};n.on("scroll",function(){var e=n.scrollTop();t.map(o,function(t){window.clearTimeout(t.timeoutId),t.timeoutId=window.setTimeout(function(){t.handler(e)},t.options.delay)})}).on("load",function(){n.trigger("scroll")}),jQuery.fn.scrollex=function(l){var s=t(this);if(0==this.length)return s;if(this.length>1){for(var r=0;r<this.length;r++)t(this[r]).scrollex(l);return s}if(s.data("_scrollexId"))return s;var a,u,h,c,p;switch(a=i++,u=jQuery.extend({top:0,bottom:0,delay:0,mode:"default",enter:null,leave:null,initialize:null,terminate:null,scroll:null},l),u.mode){case"top":h=function(t,e,n,i,o){return t>=i&&o>=t};break;case"bottom":h=function(t,e,n,i,o){return n>=i&&o>=n};break;case"middle":h=function(t,e,n,i,o){return e>=i&&o>=e};break;case"top-only":h=function(t,e,n,i,o){return i>=t&&n>=i};break;case"bottom-only":h=function(t,e,n,i,o){return n>=o&&o>=t};break;default:case"default":h=function(t,e,n,i,o){return n>=i&&o>=t}}return c=function(t){var i,o,l,s,r,a,u=this.state,h=!1,c=this.$element.offset();i=n.height(),o=t+i/2,l=t+i,s=this.$element.outerHeight(),r=c.top+e(this.options.top,s,i),a=c.top+s-e(this.options.bottom,s,i),h=this.test(t,o,l,r,a),h!=u&&(this.state=h,h?this.options.enter&&this.options.enter.apply(this.element):this.options.leave&&this.options.leave.apply(this.element)),this.options.scroll&&this.options.scroll.apply(this.element,[(o-r)/(a-r)])},p={id:a,options:u,test:h,handler:c,state:null,element:this,$element:s,timeoutId:null},o[a]=p,s.data("_scrollexId",p.id),p.options.initialize&&p.options.initialize.apply(this),s},jQuery.fn.unscrollex=function(){var e=t(this);if(0==this.length)return e;if(this.length>1){for(var n=0;n<this.length;n++)t(this[n]).unscrollex();return e}var i,l;return(i=e.data("_scrollexId"))?(l=o[i],window.clearTimeout(l.timeoutId),delete o[i],e.removeData("_scrollexId"),l.options.terminate&&l.options.terminate.apply(this),e):e}}(jQuery);

@ -0,0 +1,2 @@
/* jquery.scrolly v1.0.0-dev | (c) @ajlkn | MIT licensed */
(function(e){function u(s,o){var u,a,f;if((u=e(s))[t]==0)return n;a=u[i]()[r];switch(o.anchor){case"middle":f=a-(e(window).height()-u.outerHeight())/2;break;default:case r:f=Math.max(a,0)}return typeof o[i]=="function"?f-=o[i]():f-=o[i],f}var t="length",n=null,r="top",i="offset",s="click.scrolly",o=e(window);e.fn.scrolly=function(i){var o,a,f,l,c=e(this);if(this[t]==0)return c;if(this[t]>1){for(o=0;o<this[t];o++)e(this[o]).scrolly(i);return c}l=n,f=c.attr("href");if(f.charAt(0)!="#"||f[t]<2)return c;a=jQuery.extend({anchor:r,easing:"swing",offset:0,parent:e("body,html"),pollOnce:!1,speed:1e3},i),a.pollOnce&&(l=u(f,a)),c.off(s).on(s,function(e){var t=l!==n?l:u(f,a);t!==n&&(e.preventDefault(),a.parent.stop().animate({scrollTop:t},a.speed,a.easing))})}})(jQuery);

@ -0,0 +1,154 @@
/*
Atmosphere by Pixelarity
pixelarity.com | hello@pixelarity.com
License: pixelarity.com/license
*/
(function($) {
var $window = $(window),
$body = $('body'),
$header = $('#header'),
$banner = $('#banner');
// Breakpoints.
breakpoints({
xlarge: [ '1281px', '1680px' ],
large: [ '981px', '1280px' ],
medium: [ '737px', '980px' ],
small: [ '481px', '736px' ],
xsmall: [ '361px', '480px' ],
xxsmall: [ null, '360px' ]
});
// Play initial animations on page load.
$window.on('load', function() {
window.setTimeout(function() {
$body.removeClass('is-preload');
}, 100);
});
// Scrolly.
$('.scrolly').scrolly({
offset: function() {
return $header.height();
}
});
// Header.
if ($banner.length > 0
&& $header.hasClass('alt')) {
$window.on('resize', function() { $window.trigger('scroll'); });
$banner.scrollex({
bottom: $header.outerHeight(),
terminate: function() { $header.removeClass('alt'); },
enter: function() { $header.addClass('alt'); },
leave: function() { $header.removeClass('alt'); }
});
}
// Menu.
var $menu = $('#menu');
$menu._locked = false;
$menu._lock = function() {
if ($menu._locked)
return false;
$menu._locked = true;
window.setTimeout(function() {
$menu._locked = false;
}, 350);
return true;
};
$menu._show = function() {
if ($menu._lock())
$body.addClass('is-menu-visible');
};
$menu._hide = function() {
if ($menu._lock())
$body.removeClass('is-menu-visible');
};
$menu._toggle = function() {
if ($menu._lock())
$body.toggleClass('is-menu-visible');
};
$menu
.appendTo($body)
.on('click', function(event) {
event.stopPropagation();
// Hide.
$menu._hide();
})
.find('.inner')
.on('click', '.close', function(event) {
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
// Hide.
$menu._hide();
})
.on('click', function(event) {
event.stopPropagation();
})
.on('click', 'a', function(event) {
var href = $(this).attr('href');
event.preventDefault();
event.stopPropagation();
// Hide.
$menu._hide();
// Redirect.
window.setTimeout(function() {
window.location.href = href;
}, 350);
});
$body
.on('click', 'a[href="#menu"]', function(event) {
event.stopPropagation();
event.preventDefault();
// Toggle.
$menu._toggle();
})
.on('keydown', function(event) {
// Hide on escape.
if (event.keyCode == 27)
$menu._hide();
});
})(jQuery);

@ -0,0 +1,191 @@
var rateid = null;
var shipmentid = null;
var price = null;
var cardElement = null;
var disableGetRateButton = false;
var disablePayButton = true;
var printed = false;
function getRateAndValidateAddress() {
$("#getRateAndValidateAddressButton").html('<i class="far fa-spinner fa-spin"></i> Working...</a>');
disableGetRateButton = true;
$.post("makeshipment.php",
$("#addressform").serialize(),
function (resp) {
if (resp.status == "OK") {
$("input[name=to_name]").val(resp.address.name);
$("input[name=to_company]").val(resp.address.company);
$("input[name=to_street]").val(resp.address.street1);
$("input[name=to_street2]").val(resp.address.street2);
$("input[name=to_city]").val(resp.address.city);
$("input[name=to_state]").val(resp.address.state);
$("input[name=to_zip]").val(resp.address.zip);
$("input[name=from_name]").val(resp.fromaddress.name);
$("input[name=from_street]").val(resp.fromaddress.street1);
$("input[name=from_street2]").val(resp.fromaddress.street2);
$("input[name=from_city]").val(resp.fromaddress.city);
$("input[name=from_state]").val(resp.fromaddress.state);
$("input[name=from_zip]").val(resp.fromaddress.zip);
$("#toaddr").html(
resp.address.name
+ (resp.address.name != "" && resp.address.company != "" ? "<br>" : "")
+ resp.address.company
+ "<br>" + resp.address.street1
+ (resp.address.street2 == "" ? "" : "<br>" + resp.address.street2)
+ "<br>" + resp.address.city + " " + resp.address.state + " " + resp.address.zip
);
$("#fromaddr").html(
resp.fromaddress.name
+ "<br>" + resp.fromaddress.street1
+ (resp.fromaddress.street2 == "" ? "" : "<br>" + resp.fromaddress.street2)
+ "<br>" + resp.fromaddress.city + " " + resp.fromaddress.state + " " + resp.fromaddress.zip
);
rateid = resp.rate.id;
shipmentid = resp.shipmentid;
price = resp.rate.price;
$("#paymentamount").text("$" + price.toFixed(2));
var elements = stripe.elements();
cardElement = elements.create('card', {});
cardElement.mount('#card-element');
cardElement.addEventListener('change', function (event) {
var displayError = document.getElementById('paymenterror');
if (event.error) {
displayError.textContent = event.error.message;
} else {
displayError.textContent = '';
}
});
$("#paymentform").css("display", "");
$("#addressform").css("display", "none");
$("#getRateAndValidateAddressButton").html('<i class="far fa-chevron-right"></i> Next</a>');
$("#header-small-text").text("Confirm and Pay");
document.getElementById("label").scrollIntoView();
disablePayButton = false;
} else {
$("#addresserror").text(resp.message);
$("#getRateAndValidateAddressButton").html('<i class="far fa-chevron-right"></i> Next</a>');
disableGetRateButton = false;
}
}
);
}
function submitPayment() {
disablePayButton = true;
$("#submitPaymentButton").html('<i class="far fa-spinner fa-spin"></i> Purchasing...</a>');
stripe.createPaymentMethod(
{
type: 'card',
card: cardElement
}
).then(function (result) {
if (result.error) {
// Inform the customer that there was an error.
disablePayButton = false;
$("#paymenterror").text(result.error.message);
$("#submitPaymentButton").html('<i class="far fa-chevron-right"></i> Purchase</a>');
} else {
$.post("payshipment.php",
{
"shipmentid": shipmentid,
"rateid": rateid,
"stripeid": result.paymentMethod.id,
"price": price
},
function (resp) {
if (resp.status == "OK") {
// load PDF to print
$("#pdfframe").attr("src", resp.pdf + "#toolbar=0&navpanes=0&pagemode=none");
$("#pdfbackuplink").attr("src", resp.pdf);
//$("#pdfframe").attr("src", "assets/pdfjs/web/viewer.html?file=" + encodeURIComponent(resp.pdf) + "#zoom=page-fit&page=1&pagemode=none");
$("#printform").css("display", "");
$("#paymentform").css("display", "none");
$("#trackingnumber").html(resp.trackingcode + " <i class='far fa-external-link'></i>");
$("#trackingnumber").attr("href", "https://tools.usps.com/go/TrackConfirmAction?qtc_tLabels1=" + resp.trackingcode);
$("#header-small-text").text("Print and Finish");
document.getElementById("label").scrollIntoView();
// hide tracking info for non-tracked letters
if (resp.trackingcode.startsWith("00")) {
$("#trackingnumberparagraph").css("display", "none");
}
_paq.push(['addEcommerceItem',
"letter",
price * 1.0,
1
]);
_paq.push(['trackEcommerceOrder',
shipmentid,
price * 1.0
]);
} else {
$("#paymenterror").text(resp.message);
$("#submitPaymentButton").html('<i class="far fa-chevron-right"></i> Purchase</a>');
disablePayButton = false;
}
}
);
}
});
}
$("#getRateAndValidateAddressButton").on("click", function () {
if (disableGetRateButton == false) {
getRateAndValidateAddress();
}
}
);
$("#submitPaymentButton").on("click", function () {
if (disablePayButton == false) {
submitPayment();
}
});
$("#cancelPaymentButton").on("click", function () {
if (disablePayButton == false) {
rateid = null;
shipmentid = null;
price = null;
cardElement = null;
disableGetRateButton = false;
$("#paymentform").css("display", "none");
$("#paymenterror").text("");
$("#addressform").css("display", "");
$("#header-small-text").text("Get Started");
document.getElementById("label").scrollIntoView();
}
});
$("#printButton").on("click", function () {
if (printed) {
if (confirm("You seem to be reprinting the same file. By continuing, you agree that only one copy is to be mailed, under penalty of federal law.")) {
document.getElementById("pdfframe").contentWindow.print();
}
} else {
document.getElementById("pdfframe").contentWindow.print();
printed = true;
}
});
$("#pdfbackuplink").on("click", function () {
printed = true;
if (confirm("By continuing, you agree that only one copy of the file is to be mailed, under penalty of federal law.")) {
window.open($("#pdfbackuplink").attr("src"), "_blank");
}
});
$("#startOverButton").on("click", function () {
if (printed || (!printed && confirm("Heads up! If you haven't printed this label yet, press cancel and do that first. You won't be able to get it back once you start over."))) {
location.hash = 'label';
location.reload();
}
});

@ -0,0 +1,587 @@
(function($) {
/**
* Generate an indented list of links from a nav. Meant for use with panel().
* @return {jQuery} jQuery object.
*/
$.fn.navList = function() {
var $this = $(this);
$a = $this.find('a'),
b = [];
$a.each(function() {
var $this = $(this),
indent = Math.max(0, $this.parents('li').length - 1),
href = $this.attr('href'),
target = $this.attr('target');
b.push(
'<a ' +
'class="link depth-' + indent + '"' +
( (typeof target !== 'undefined' && target != '') ? ' target="' + target + '"' : '') +
( (typeof href !== 'undefined' && href != '') ? ' href="' + href + '"' : '') +
'>' +
'<span class="indent-' + indent + '"></span>' +
$this.text() +
'</a>'
);
});
return b.join('');
};
/**
* Panel-ify an element.
* @param {object} userConfig User config.
* @return {jQuery} jQuery object.
*/
$.fn.panel = function(userConfig) {
// No elements?
if (this.length == 0)
return $this;
// Multiple elements?
if (this.length > 1) {
for (var i=0; i < this.length; i++)
$(this[i]).panel(userConfig);
return $this;
}
// Vars.
var $this = $(this),
$body = $('body'),
$window = $(window),
id = $this.attr('id'),
config;
// Config.
config = $.extend({
// Delay.
delay: 0,
// Hide panel on link click.
hideOnClick: false,
// Hide panel on escape keypress.
hideOnEscape: false,
// Hide panel on swipe.
hideOnSwipe: false,
// Reset scroll position on hide.
resetScroll: false,
// Reset forms on hide.
resetForms: false,
// Side of viewport the panel will appear.
side: null,
// Target element for "class".
target: $this,
// Class to toggle.
visibleClass: 'visible'
}, userConfig);
// Expand "target" if it's not a jQuery object already.
if (typeof config.target != 'jQuery')
config.target = $(config.target);
// Panel.
// Methods.
$this._hide = function(event) {
// Already hidden? Bail.
if (!config.target.hasClass(config.visibleClass))
return;
// If an event was provided, cancel it.
if (event) {
event.preventDefault();
event.stopPropagation();
}
// Hide.
config.target.removeClass(config.visibleClass);
// Post-hide stuff.
window.setTimeout(function() {
// Reset scroll position.
if (config.resetScroll)
$this.scrollTop(0);
// Reset forms.
if (config.resetForms)
$this.find('form').each(function() {
this.reset();
});
}, config.delay);
};
// Vendor fixes.
$this
.css('-ms-overflow-style', '-ms-autohiding-scrollbar')
.css('-webkit-overflow-scrolling', 'touch');
// Hide on click.
if (config.hideOnClick) {
$this.find('a')
.css('-webkit-tap-highlight-color', 'rgba(0,0,0,0)');
$this
.on('click', 'a', function(event) {
var $a = $(this),
href = $a.attr('href'),
target = $a.attr('target');
if (!href || href == '#' || href == '' || href == '#' + id)
return;
// Cancel original event.
event.preventDefault();
event.stopPropagation();
// Hide panel.
$this._hide();
// Redirect to href.
window.setTimeout(function() {
if (target == '_blank')
window.open(href);
else
window.location.href = href;
}, config.delay + 10);
});
}
// Event: Touch stuff.
$this.on('touchstart', function(event) {
$this.touchPosX = event.originalEvent.touches[0].pageX;
$this.touchPosY = event.originalEvent.touches[0].pageY;
})
$this.on('touchmove', function(event) {
if ($this.touchPosX === null
|| $this.touchPosY === null)
return;
var diffX = $this.touchPosX - event.originalEvent.touches[0].pageX,
diffY = $this.touchPosY - event.originalEvent.touches[0].pageY,
th = $this.outerHeight(),
ts = ($this.get(0).scrollHeight - $this.scrollTop());
// Hide on swipe?
if (config.hideOnSwipe) {
var result = false,
boundary = 20,
delta = 50;
switch (config.side) {
case 'left':
result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX > delta);
break;
case 'right':
result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX < (-1 * delta));
break;
case 'top':
result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY > delta);
break;
case 'bottom':
result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY < (-1 * delta));
break;
default:
break;
}
if (result) {
$this.touchPosX = null;
$this.touchPosY = null;
$this._hide();
return false;
}
}
// Prevent vertical scrolling past the top or bottom.
if (($this.scrollTop() < 0 && diffY < 0)
|| (ts > (th - 2) && ts < (th + 2) && diffY > 0)) {
event.preventDefault();
event.stopPropagation();
}
});
// Event: Prevent certain events inside the panel from bubbling.
$this.on('click touchend touchstart touchmove', function(event) {
event.stopPropagation();
});
// Event: Hide panel if a child anchor tag pointing to its ID is clicked.
$this.on('click', 'a[href="#' + id + '"]', function(event) {
event.preventDefault();
event.stopPropagation();
config.target.removeClass(config.visibleClass);
});
// Body.
// Event: Hide panel on body click/tap.
$body.on('click touchend', function(event) {
$this._hide(event);
});
// Event: Toggle.
$body.on('click', 'a[href="#' + id + '"]', function(event) {
event.preventDefault();
event.stopPropagation();
config.target.toggleClass(config.visibleClass);
});
// Window.
// Event: Hide on ESC.
if (config.hideOnEscape)
$window.on('keydown', function(event) {
if (event.keyCode == 27)
$this._hide(event);
});
return $this;
};
/**
* Apply "placeholder" attribute polyfill to one or more forms.
* @return {jQuery} jQuery object.
*/
$.fn.placeholder = function() {
// Browser natively supports placeholders? Bail.
if (typeof (document.createElement('input')).placeholder != 'undefined')
return $(this);
// No elements?
if (this.length == 0)
return $this;
// Multiple elements?
if (this.length > 1) {
for (var i=0; i < this.length; i++)
$(this[i]).placeholder();
return $this;
}
// Vars.
var $this = $(this);
// Text, TextArea.
$this.find('input[type=text],textarea')
.each(function() {
var i = $(this);
if (i.val() == ''
|| i.val() == i.attr('placeholder'))
i
.addClass('polyfill-placeholder')
.val(i.attr('placeholder'));
})
.on('blur', function() {
var i = $(this);
if (i.attr('name').match(/-polyfill-field$/))
return;
if (i.val() == '')
i
.addClass('polyfill-placeholder')
.val(i.attr('placeholder'));
})
.on('focus', function() {
var i = $(this);
if (i.attr('name').match(/-polyfill-field$/))
return;
if (i.val() == i.attr('placeholder'))
i
.removeClass('polyfill-placeholder')
.val('');
});
// Password.
$this.find('input[type=password]')
.each(function() {
var i = $(this);
var x = $(
$('<div>')
.append(i.clone())
.remove()
.html()
.replace(/type="password"/i, 'type="text"')
.replace(/type=password/i, 'type=text')
);
if (i.attr('id') != '')
x.attr('id', i.attr('id') + '-polyfill-field');
if (i.attr('name') != '')
x.attr('name', i.attr('name') + '-polyfill-field');
x.addClass('polyfill-placeholder')
.val(x.attr('placeholder')).insertAfter(i);
if (i.val() == '')
i.hide();
else
x.hide();
i
.on('blur', function(event) {
event.preventDefault();
var x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');
if (i.val() == '') {
i.hide();
x.show();
}
});
x
.on('focus', function(event) {
event.preventDefault();
var i = x.parent().find('input[name=' + x.attr('name').replace('-polyfill-field', '') + ']');
x.hide();
i
.show()
.focus();
})
.on('keypress', function(event) {
event.preventDefault();
x.val('');
});
});
// Events.
$this
.on('submit', function() {
$this.find('input[type=text],input[type=password],textarea')
.each(function(event) {
var i = $(this);
if (i.attr('name').match(/-polyfill-field$/))
i.attr('name', '');
if (i.val() == i.attr('placeholder')) {
i.removeClass('polyfill-placeholder');
i.val('');
}
});
})
.on('reset', function(event) {
event.preventDefault();
$this.find('select')
.val($('option:first').val());
$this.find('input,textarea')
.each(function() {
var i = $(this),
x;
i.removeClass('polyfill-placeholder');
switch (this.type) {
case 'submit':
case 'reset':
break;
case 'password':
i.val(i.attr('defaultValue'));
x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');
if (i.val() == '') {
i.hide();
x.show();
}
else {
i.show();
x.hide();
}
break;
case 'checkbox':
case 'radio':
i.attr('checked', i.attr('defaultValue'));
break;
case 'text':
case 'textarea':
i.val(i.attr('defaultValue'));
if (i.val() == '') {
i.addClass('polyfill-placeholder');
i.val(i.attr('placeholder'));
}
break;
default:
i.val(i.attr('defaultValue'));
break;
}
});
});
return $this;
};
/**
* Moves elements to/from the first positions of their respective parents.
* @param {jQuery} $elements Elements (or selector) to move.
* @param {bool} condition If true, moves elements to the top. Otherwise, moves elements back to their original locations.
*/
$.prioritize = function($elements, condition) {
var key = '__prioritize';
// Expand $elements if it's not already a jQuery object.
if (typeof $elements != 'jQuery')
$elements = $($elements);
// Step through elements.
$elements.each(function() {
var $e = $(this), $p,
$parent = $e.parent();
// No parent? Bail.
if ($parent.length == 0)
return;
// Not moved? Move it.
if (!$e.data(key)) {
// Condition is false? Bail.
if (!condition)
return;
// Get placeholder (which will serve as our point of reference for when this element needs to move back).
$p = $e.prev();
// Couldn't find anything? Means this element's already at the top, so bail.
if ($p.length == 0)
return;
// Move element to top of parent.
$e.prependTo($parent);
// Mark element as moved.
$e.data(key, $p);
}
// Moved already?
else {
// Condition is true? Bail.
if (condition)
return;
$p = $e.data(key);
// Move element back to its original location (using our placeholder).
$e.insertAfter($p);
// Unmark element as moved.
$e.removeData(key);
}
});
};
})(jQuery);

@ -0,0 +1,177 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -0,0 +1,47 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* Basic */
// MSIE: Required for IEMobile.
@-ms-viewport {
width: device-width;
}
// MSIE: Prevents scrollbar from overlapping content.
body {
-ms-overflow-style: scrollbar;
}
// Ensures page width is always >=320px.
@include breakpoint('<=xsmall') {
html, body {
min-width: 320px;
}
}
// Set box model to border-box.
// Based on css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
background: _palette(bg);
// Stops initial animations until page loads.
&.is-preload {
*, *:before, *:after {
@include vendor('animation', 'none !important');
@include vendor('transition', 'none !important');
}
}
}

@ -0,0 +1,76 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
// Reset.
// Based on meyerweb.com/eric/tools/css/reset (v2.0 | 20110126 | License: public domain)
html, body, div, span, applet, object,
iframe, h1, h2, h3, h4, h5, h6, p, blockquote,
pre, a, abbr, acronym, address, big, cite,
code, del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var, b,
u, i, center, dl, dt, dd, ol, ul, li, fieldset,
form, label, legend, table, caption, tbody,
tfoot, thead, tr, th, td, article, aside,
canvas, details, embed, figure, figcaption,
footer, header, hgroup, menu, nav, output, ruby,
section, summary, time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
&:before,
&:after {
content: '';
content: none;
}
}
table {
border-collapse: collapse;
border-spacing: 0;
}
body {
-webkit-text-size-adjust: none;
}
mark {
background-color: transparent;
color: inherit;
}
input::-moz-focus-inner {
border: 0;
padding: 0;
}
input, select, textarea {
-moz-appearance: none;
-webkit-appearance: none;
-ms-appearance: none;
appearance: none;
}

@ -0,0 +1,220 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* Type */
body {
background-color: _palette(bg);
color: _palette(fg);
}
body, input, select, textarea {
font-family: _font(family);
font-size: 14pt;
font-weight: _font(weight);
line-height: 1.625;
@include breakpoint('<=xlarge') {
font-size: 12pt;
}
@include breakpoint('<=large') {
font-size: 12pt;
}
@include breakpoint('<=medium') {
font-size: 12pt;
}
@include breakpoint('<=small') {
font-size: 12pt;
}
@include breakpoint('<=xsmall') {
font-size: 12pt;
}
@include breakpoint('<=xxsmall') {
font-size: 11pt;
}
}
a {
text-decoration: underline;
&:hover {
text-decoration: none;
}
}
strong, b {
font-weight: _font(weight-bold);
}
em, i {
font-style: italic;
}
p {
margin: 0 0 _size(element-margin) 0;
}
h1, h2, h3, h4, h5, h6 {
line-height: 1.3;
margin: 0 0 (_size(element-margin) * 0.5) 0;
a {
color: inherit;
text-decoration: none;
}
}
h1 {
font-size: 2em;
}
h2 {
font-size: 1.75em;
}
h3 {
font-size: 1.35em;
}
h4 {
font-size: 1em;
}
h5 {
font-size: 0.9em;
}
h6 {
font-size: 0.7em;
}
sub {
font-size: 0.8em;
position: relative;
top: 0.5em;
}
sup {
font-size: 0.8em;
position: relative;
top: -0.5em;
}
blockquote {
border-left: solid (_size(border-width) * 4);
font-style: italic;
margin: 0 0 _size(element-margin) 0;
padding: (_size(element-margin) / 4) 0 (_size(element-margin) / 4) _size(element-margin);
}
code {
border-radius: _size(border-radius);
border: solid _size(border-width);
font-family: _font(family-fixed);
font-size: 0.9em;
margin: 0 0.25em;
padding: 0.25em 0.65em;
}
pre {
-webkit-overflow-scrolling: touch;
font-family: _font(family-fixed);
font-size: 0.9em;
margin: 0 0 _size(element-margin) 0;
code {
display: block;
line-height: 1.75;
padding: 1em 1.5em;
overflow-x: auto;
}
}
hr {
border: 0;
border-bottom: solid _size(border-width);
margin: _size(element-margin) 0;
&.major {
margin: (_size(element-margin) * 1.5) 0;
}
}
.align-left {
text-align: left;
}
.align-center {
text-align: center;
}
.align-right {
text-align: right;
}
@include breakpoint('<=small') {
h1 {
font-size: 1.75em;
}
h2 {
font-size: 1.5em;
}
h3 {
font-size: 1.25em;
}
}
@mixin color-typography($p: null) {
$highlight: _palette($p, highlight);
@if $p != null {
background-color: _palette($p, bg);
color: _palette($p, fg);
}
input, select, textarea {
color: _palette($p, fg-bold);
}
a {
@if $p == $highlight {
color: _palette($p, fg-bold);
}
@else {
color: _palette(accent1, bg);
}
}
strong, b {
color: _palette($p, fg-bold);
}
h1, h2, h3, h4, h5, h6 {
color: _palette($p, fg-bold);
}
blockquote {
border-left-color: _palette($p, border);
}
code {
background: _palette($p, border-bg);
border-color: _palette($p, border);
}
hr {
border-bottom-color: _palette($p, border);
}
}
@include color-typography;

@ -0,0 +1,101 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* Actions */
ul.actions {
@include vendor('display', 'flex');
cursor: default;
list-style: none;
margin-left: (_size(element-margin) * -0.5);
padding-left: 0;
li {
padding: 0 0 0 (_size(element-margin) * 0.5);
vertical-align: middle;
}
&.special {
@include vendor('justify-content', 'center');
width: 100%;
margin-left: 0;
li {
&:first-child {
padding-left: 0;
}
}
}
&.stacked {
@include vendor('flex-direction', 'column');
margin-left: 0;
li {
padding: (_size(element-margin) * 0.65) 0 0 0;
&:first-child {
padding-top: 0;
}
}
}
&.fit {
width: calc(100% + #{_size(element-margin) * 0.5});
li {
@include vendor('flex-grow', '1');
@include vendor('flex-shrink', '1');
width: 100%;
> * {
width: 100%;
}
}
&.stacked {
width: 100%;
}
}
@include breakpoint('<=xsmall') {
&:not(.fixed) {
@include vendor('flex-direction', 'column');
margin-left: 0;
width: 100% !important;
li {
@include vendor('flex-grow', '1');
@include vendor('flex-shrink', '1');
padding: (_size(element-margin) * 0.5) 0 0 0;
text-align: center;
width: 100%;
> * {
width: 100%;
}
&:first-child {
padding-top: 0;
}
input[type="submit"],
input[type="reset"],
input[type="button"],
button,
.button {
width: 100%;
&.icon {
&:before {
margin-left: -0.5em;
}
}
}
}
}
}
}

@ -0,0 +1,34 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* Box */
.box {
border-radius: _size(border-radius);
border: solid _size(border-width);
margin-bottom: _size(element-margin);
padding: 1.5em;
> :last-child,
> :last-child > :last-child,
> :last-child > :last-child > :last-child {
margin-bottom: 0;
}
&.alt {
border: 0;
border-radius: 0;
padding: 0;
}
}
@mixin color-box($p: null) {
.box {
border-color: _palette($p, border);
}
}
@include color-box;

@ -0,0 +1,123 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* Button */
input[type="submit"],
input[type="reset"],
input[type="button"],
button,
.button {
@include vendor('appearance', 'none');
@include vendor('transition', 'background-color #{_duration(transition)} ease-in-out, color #{_duration(transition)} ease-in-out');
border-radius: _size(border-radius);
border: 0;
cursor: pointer;
display: inline-block;
font-size: 0.8em;
font-weight: _font(weight-bold);
height: 3.5em;
line-height: 3.5em;
padding: 0 2.25em;
text-align: center;
text-decoration: none;
text-transform: uppercase;
white-space: nowrap;
&.icon {
padding-left: 1.35em;
&:before {
font-size: 0.95em;
margin-right: 0.5em;
}
}
&.fit {
width: 100%;
}
&.small {
font-size: 0.6em;
}
&.large {
font-size: 0.95em;
}
&.disabled,
&:disabled {
@include vendor('pointer-events', 'none');
opacity: 0.25;
}
@include breakpoint('<=xsmall') {
padding: 0;
}
}
@mixin color-button($p: null) {
$highlight: _palette($p, highlight);
input[type="submit"],
input[type="reset"],
input[type="button"],
button,
.button {
background-color: transparent;
box-shadow: inset 0 0 0 _size(border-width) _palette($p, border);
color: _palette($p, fg-bold) !important;
&:hover, &:focus {
background-color: _palette($p, border-bg);
}
&:active {
background-color: opacify(_palette($p, border-bg), 0.1);
}
&.icon {
&:before {
color: _palette($p, fg-light);
}
}
&.primary {
box-shadow: none;
@if $p == $highlight {
background-color: _palette($p, fg-bold);
color: _palette($p, bg) !important;
&.icon {
&:before {
color: _palette($p, bg) !important;
}
}
}
@else {
background-color: _palette($highlight, bg);
color: _palette($highlight, fg-bold) !important;
&.icon {
&:before {
color: _palette($highlight, fg-bold) !important;
}
}
&:hover, &:focus {
background-color: lighten(_palette($highlight, bg), 5);
}
&:active {
background-color: darken(_palette($highlight, bg), 5);
}
}
}
}
}
@include color-button;

@ -0,0 +1,58 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* Features */
.features {
@include vendor('display', 'flex');
@include vendor('flex-wrap', 'wrap');
@include vendor('justify-content', 'center');
list-style-type: none;
padding-left: 0;
li {
margin-bottom: _size(element-margin);
padding: 0 1em;
width: 25%;
}
.icon {
border-radius: 100%;
box-shadow: -0.5em 0.5em 1em rgba(#000, 0.05);
display: block;
font-size: 2.75em;
height: 3.75em;
line-height: 3.75em;
margin: 0 auto (_size(element-margin) * 0.35);
text-align: center;
width: 3.75em;
}
h4 {
font-weight: _font(weight-bold);
margin-bottom: 0.5em;
text-transform: uppercase;
}
@include breakpoint('<=medium') {
li {
width: 50%;
}
}
@include breakpoint('<=small') {
.icon {
font-size: 2em;
}
}
@include breakpoint('<=xsmall') {
li {
margin-bottom: (_size(element-margin) * 0.5);
width: 100%;
}
}
}

@ -0,0 +1,300 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* Form */
form {
margin: 0 0 _size(element-margin) 0;
> :last-child {
margin-bottom: 0;
}
> .fields {
$gutter: (_size(element-margin) * 0.75);
@include vendor('display', 'flex');
@include vendor('flex-wrap', 'wrap');
width: calc(100% + #{$gutter * 2});
margin: ($gutter * -1) 0 _size(element-margin) ($gutter * -1);
> .field {
@include vendor('flex-grow', '0');
@include vendor('flex-shrink', '0');
padding: $gutter 0 0 $gutter;
width: calc(100% - #{$gutter * 1});
&.half {
width: calc(50% - #{$gutter * 0.5});
}
&.third {
width: calc(#{100% / 3} - #{$gutter * (1 / 3)});
}
&.quarter {
width: calc(25% - #{$gutter * 0.25});
}
}
}
@include breakpoint('<=xsmall') {
> .fields {
$gutter: (_size(element-margin) * 0.75);
width: calc(100% + #{$gutter * 2});
margin: ($gutter * -1) 0 _size(element-margin) ($gutter * -1);
> .field {
padding: $gutter 0 0 $gutter;
width: calc(100% - #{$gutter * 1});
&.half {
width: calc(100% - #{$gutter * 1});
}
&.third {
width: calc(100% - #{$gutter * 1});
}
&.quarter {
width: calc(100% - #{$gutter * 1});
}
}
}
}
}
label {
display: block;
font-size: 0.9em;
font-weight: _font(weight-bold);
margin: 0 0 (_size(element-margin) * 0.5) 0;
}
input[type="text"],
input[type="password"],
input[type="email"],
select,
textarea {
@include vendor('appearance', 'none');
border: none;
border: solid _size(border-width);
color: inherit;
display: block;
outline: 0;
padding: 0 1em;
text-decoration: none;
width: 100%;
&:invalid {
box-shadow: none;
}
}
select {
background-size: 1.25rem;
background-repeat: no-repeat;
background-position: calc(100% - 1rem) center;
height: _size(element-height);
padding-right: _size(element-height);
text-overflow: ellipsis;
&:focus {
&::-ms-value {
background-color: transparent;
}
}
&::-ms-expand {
display: none;
}
}
input[type="text"],
input[type="password"],
input[type="email"],
select {
height: _size(element-height);
}
textarea {
padding: 0.75em 1em;
}
input[type="checkbox"],
input[type="radio"], {
@include vendor('appearance', 'none');
display: block;
float: left;
margin-right: -2em;
opacity: 0;
width: 1em;
z-index: -1;
& + label {
@include icon(false, solid);
cursor: pointer;
display: inline-block;
font-size: 1em;
font-weight: _font(weight);
padding-left: (_size(element-height) * 0.6) + 0.75em;
padding-right: 0.75em;
position: relative;
&:before {
border-radius: _size(border-radius);
border: solid _size(border-width);
content: '';
display: inline-block;
font-size: 0.8em;
height: (_size(element-height) * 0.6);
left: 0;
line-height: (_size(element-height) * 0.575);
position: absolute;
text-align: center;
top: 0;
width: (_size(element-height) * 0.6);
}
}
&:checked + label {
&:before {
content: '\f00c';
}
}
}
input[type="checkbox"] {
& + label {
&:before {
border-radius: _size(border-radius);
}
}
}
input[type="radio"] {
& + label {
&:before {
border-radius: 100%;
}
}
}
::-webkit-input-placeholder {
opacity: 1.0;
}
:-moz-placeholder {
opacity: 1.0;
}
::-moz-placeholder {
opacity: 1.0;
}
:-ms-input-placeholder {
opacity: 1.0;
}
@mixin color-form($p: null) {
$highlight: _palette($p, highlight);
label {
color: _palette($p, fg-bold);
}
input[type="text"],
input[type="password"],
input[type="email"],
select,
textarea {
background-color: _palette($p, border2-bg);
border-color: transparent;
&:focus {
@if $p == $highlight {
border-color: _palette($p, fg-bold);
box-shadow: 0 0 0 _size(border-width) _palette($p, fg-bold);
}
@else {
border-color: _palette(accent1, bg);
box-shadow: 0 0 0 _size(border-width) _palette(accent1, bg);
}
}
}
select {
background-image: svg-url("<svg xmlns='http://www.w3.org/2000/svg' width='40' height='40' preserveAspectRatio='none' viewBox='0 0 40 40'><path d='M9.4,12.3l10.4,10.4l10.4-10.4c0.2-0.2,0.5-0.4,0.9-0.4c0.3,0,0.6,0.1,0.9,0.4l3.3,3.3c0.2,0.2,0.4,0.5,0.4,0.9 c0,0.4-0.1,0.6-0.4,0.9L20.7,31.9c-0.2,0.2-0.5,0.4-0.9,0.4c-0.3,0-0.6-0.1-0.9-0.4L4.3,17.3c-0.2-0.2-0.4-0.5-0.4-0.9 c0-0.4,0.1-0.6,0.4-0.9l3.3-3.3c0.2-0.2,0.5-0.4,0.9-0.4S9.1,12.1,9.4,12.3z' fill='#{_palette($p, border)}' /></svg>");
option {
color: _palette($p, fg-bold);
background: _palette($p, bg);
}
}
input[type="checkbox"],
input[type="radio"], {
& + label {
color: _palette($p, fg);
&:before {
background: _palette($p, border2-bg);
border-color: _palette($p, border);
}
}
&:checked + label {
&:before {
@if $p == $highlight {
background-color: _palette($p, fg-bold);
border-color: _palette($p, fg-bold);
color: _palette($p, bg);
}
@else {
background-color: _palette(accent1, bg);
border-color: _palette(accent1, bg);
color: _palette(accent1, fg-bold);
}
}
}
&:focus + label {
&:before {
@if $p == $highlight {
border-color: _palette($p, fg-bold);
box-shadow: 0 0 0 _size(border-width) _palette($p, fg-bold);
}
@else {
border-color: _palette(accent1, bg);
box-shadow: 0 0 0 _size(border-width) _palette(accent1, bg);
}
}
}
}
::-webkit-input-placeholder {
color: _palette($p, fg-light) !important;
}
:-moz-placeholder {
color: _palette($p, fg-light) !important;
}
::-moz-placeholder {
color: _palette($p, fg-light) !important;
}
:-ms-input-placeholder {
color: _palette($p, fg-light) !important;
}
.formerize-placeholder {
color: _palette($p, fg-light) !important;
}
}
@include color-form;

@ -0,0 +1,66 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* Icon */
.icon {
@include icon;
border-bottom: none;
position: relative;
&.solid {
&:before {
font-weight: 900;
}
}
&.regular {
&:before {
font-weight: 400;
}
}
&.light {
&:before {
font-weight: 300;
}
}
&.brands {
&:before {
font-family: 'Font Awesome 5 Brands';
}
}
&.duotone {
position: relative;
padding-left: 1.25em; /* make space for the width of the absolutely positioned icon */
&:before,
&:after {
font-family: 'Font Awesome 5 Duotone';
font-weight: 900;
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 1.25em;
text-align: center;
}
&:before {
opacity: 1;
opacity: var(--fa-primary-opacity, 1.0);
}
&:after {
opacity: var(--fa-primary-opacity, 0.4);
}
}
> .label {
display: none;
}
}

@ -0,0 +1,28 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* Icons */
ul.icons {
cursor: default;
list-style: none;
padding-left: 0;
li {
display: inline-block;
padding: 0 1em 0 0;
&:last-child {
padding-right: 0;
}
.icon {
&:before {
font-size: 2em;
}
}
}
}

@ -0,0 +1,64 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* Image */
.image {
border: 0;
display: inline-block;
position: relative;
img {
display: block;
}
&.left,
&.right {
max-width: 40%;
img {
width: 100%;
}
}
&.left {
float: left;
margin: 0 1.5em 1em 0;
top: 0.25em;
}
&.right {
float: right;
margin: 0 0 1em 1.5em;
top: 0.25em;
}
&.fit {
display: block;
margin: 0 0 _size(element-margin) 0;
width: 100%;
img {
width: 100%;
}
}
&.main {
display: block;
margin: 0 0 (_size(element-margin) * 1.5) 0;
width: 100%;
img {
width: 100%;
}
}
@include breakpoint('<=small') {
&.main {
margin: 0 0 _size(element-margin) 0;
}
}
}

@ -0,0 +1,68 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* List */
ol {
list-style: decimal;
margin: 0 0 _size(element-margin) 0;
padding-left: 1.25em;
li {
padding-left: 0.25em;
}
}
ul {
list-style: disc;
margin: 0 0 _size(element-margin) 0;
padding-left: 1em;
li {
padding-left: 0.5em;
}
&.alt {
list-style: none;
padding-left: 0;
li {
border-top: solid _size(border-width);
padding: 0.5em 0;
&:first-child {
border-top: 0;
padding-top: 0;
}
}
}
}
dl {
margin: 0 0 _size(element-margin) 0;
dt {
display: block;
font-weight: _font(weight-bold);
margin: 0 0 (_size(element-margin) * 0.5) 0;
}
dd {
margin-left: _size(element-margin);
}
}
@mixin color-list($p: null) {
ul {
&.alt {
li {
border-top-color: _palette($p, border);
}
}
}
}
@include color-list;

@ -0,0 +1,68 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* Posts */
.posts {
margin-bottom: (_size(element-margin) * 2);
article {
@include vendor('display', 'flex');
@include vendor('align-items', 'center');
margin-bottom: _size(element-margin);
width: 100%;
.content {
-ms-flex: 1;
}
.image {
@include vendor('order', '99');
margin: 0 0 _size(element-margin) _size(element-margin);
}
&.alt {
.image {
@include vendor('order', '-1');
margin: 0 _size(element-margin) _size(element-margin) 0;
}
}
}
@include breakpoint('<=large') {
.content {
@include vendor('flex-shrink', '0');
width: 33%;
}
.image {
img {
max-width: 100%;
}
}
}
@include breakpoint('<=medium') {
article {
@include vendor('flex-wrap', 'wrap');
.content {
width: 100%;
}
.image {
@include vendor('order', '-1');
margin-left: 0;
margin-right: 0;
width: 100%;
}
}
}
@include breakpoint('<=small') {
margin-bottom: _size(element-margin);
}
}

@ -0,0 +1,31 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* Row */
.row {
@include html-grid(2em);
@include breakpoint('<=xlarge') {
@include html-grid(2em, 'xlarge');
}
@include breakpoint('<=large') {
@include html-grid(1.5em, 'large');
}
@include breakpoint('<=medium') {
@include html-grid(1.5em, 'medium');
}
@include breakpoint('<=small') {
@include html-grid(1.25em, 'small');
}
@include breakpoint('<=xsmall') {
@include html-grid(1.25em, 'xsmall');
}
}

@ -0,0 +1,114 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* Section/Article */
section, article {
&.special {
text-align: center;
}
}
header {
p {
position: relative;
margin: 0 0 (_size(element-margin) * 0.75) 0;
}
h2 + p {
font-size: 1.25em;
margin-top: (_size(element-margin) * -0.5);
}
h3 + p {
font-size: 1.1em;
margin-top: (_size(element-margin) * -0.4);
}
h4 + p,
h5 + p,
h6 + p {
font-size: 0.9em;
margin-top: (_size(element-margin) * -0.3);
}
&.major {
margin-bottom: (_size(element-margin) * 1.35);
padding-bottom: (_size(element-margin) * 1.35);
position: relative;
h1, h2, h3 {
margin-bottom: 0;
}
p {
font-weight: _font(weight-bold);
margin-bottom: 0.25em;
text-transform: uppercase;
}
&:after {
bottom: 0;
content: '';
height: 1px;
left: 0;
position: absolute;
width: 7em;
}
&.alt {
margin-bottom: 0;
}
}
@include breakpoint('<=large') {
&.major {
&.alt {
margin-bottom: (_size(element-margin) * 1.35);
}
}
}
@include breakpoint('<=small') {
&.major {
margin-bottom: (_size(element-margin) * 0.9);
padding-bottom: (_size(element-margin) * 0.65);
&.alt {
margin-bottom: (_size(element-margin) * 0.9);
}
}
}
}
@mixin color-section($p: null) {
$highlight: _palette($p, highlight);
header {
p {
color: _palette($p, fg-light);
}
&.major {
@if $p == $highlight {
p {
color: _palette($p, fg-bold);
}
}
@else {
p {
color: _palette($highlight, bg);
}
}
&:after {
background-color: _palette($p, border);
}
}
}
}
@include color-section;

@ -0,0 +1,81 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* Spotlights */
.spotlights {
@include vendor('display', 'flex');
@include vendor('flex-wrap', 'wrap');
@include vendor('justify-content', 'center');
margin-bottom: (_size(element-margin) * 2);
article {
@include padding(3.5em, 4em);
box-shadow: 0 1em 5em rgba(#000, 0.05);
margin-bottom: (_size(element-margin) * 1.5);
width: 48%;
&:nth-child(even) {
margin-left: 4%;
}
header.major {
&:after {
margin-left: -4em;
}
}
}
@include breakpoint('<=medium') {
article {
@include padding(2em, 2em);
width: 100%;
&:nth-child(even) {
margin-left: 0;
}
header.major {
&:after {
margin-left: -2em;
}
}
}
}
@include breakpoint('<=small') {
margin-bottom: _size(element-margin);
}
@include breakpoint('<=xsmall') {
article {
@include padding(1.5em, 1.5em);
header.major {
&:after {
margin-left: -1.5em;
}
}
}
}
}
@mixin color-spotlights($p: null) {
$highlight: _palette($p, highlight);
.spotlights {
article {
@if $p == $highlight {
background-color: _palette($p, border-bg);
}
@else {
background-color: _palette($highlight, fg-bold);
}
}
}
}
@include color-spotlights;

@ -0,0 +1,114 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* Table */
.table-wrapper {
-webkit-overflow-scrolling: touch;
overflow-x: auto;
}
table {
margin: 0 0 _size(element-margin) 0;
width: 100%;
tbody {
tr {
border: solid _size(border-width);
border-left: 0;
border-right: 0;
}
}
td {
padding: 0.75em 0.75em;
}
th {
font-size: 0.9em;
font-weight: _font(weight-bold);
padding: 0 0.75em 0.75em 0.75em;
text-align: left;
}
thead {
border-bottom: solid (_size(border-width) * 2);
}
tfoot {
border-top: solid (_size(border-width) * 2);
}
&.alt {
border-collapse: separate;
tbody {
tr {
td {
border: solid _size(border-width);
border-left-width: 0;
border-top-width: 0;
&:first-child {
border-left-width: _size(border-width);
}
}
&:first-child {
td {
border-top-width: _size(border-width);
}
}
}
}
thead {
border-bottom: 0;
}
tfoot {
border-top: 0;
}
}
}
@mixin color-table($p: null) {
table {
tbody {
tr {
border-color: _palette($p, border);
&:nth-child(2n + 1) {
background-color: _palette($p, border-bg);
}
}
}
th {
color: _palette($p, fg-bold);
}
thead {
border-bottom-color: _palette($p, border);
}
tfoot {
border-top-color: _palette($p, border);
}
&.alt {
tbody {
tr {
td {
border-color: _palette($p, border);
}
}
}
}
}
}
@include color-table;

@ -0,0 +1,109 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* Timeline */
.timeline {
> section {
@include vendor('display', 'flex');
border-left: solid _size(border-width);
position: relative;
&:before {
position: absolute;
content: '';
border-radius: 100%;
width: 1em;
height: 1em;
left: -0.5em;
top: 0;
}
&:last-child {
border-left: 0;
}
}
header {
@include vendor('flex-shrink', '0');
margin-bottom: _size(element-margin);
padding: 0 2.5em;
width: 25%;
h4 {
font-weight: _font(weight-bold);
text-transform: uppercase;
}
p {
margin-bottom: 0.5em;
font-weight: _font(weight-bold);
}
}
.image {
margin-bottom: _size(element-margin);
margin-right: 2.5em;
}
.content {
margin-bottom: _size(element-margin);
-ms-flex: 1;
p {
margin-bottom: (_size(element-margin) * 0.5);
}
}
@include breakpoint('<=medium') {
> section {
@include vendor('flex-wrap', 'wrap');
padding-left: 2em;
}
header {
margin-bottom: 1em;
padding: 0;
width: 100%;
}
}
@include breakpoint('<=xsmall') {
> section {
padding-left: 1.5em;
}
}
}
@mixin color-timeline($p: null) {
$highlight: _palette($p, highlight);
.timeline {
> section {
border-color: _palette($p, fg-light);
&:before {
background-color: _palette($p, fg-light);
}
}
header {
@if $p == $highlight {
p {
color: _palette($p, fg-bold);
}
}
@else {
p {
color: _palette($highlight, bg);
}
}
}
}
}
@include color-timeline;

@ -0,0 +1,94 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* Wrapper */
/// Sets the colors of the wrapper's top/bottom edges.
/// @param {string} $color Color.
@mixin wrapper-edges-color($color: black) {
&:before, &:after {
background-image: svg-url('<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100" preserveAspectRatio="none"><polygon points="0,0 0,100 100,100" style="fill:#{$color};" /></svg>');
}
}
.wrapper {
@include padding(6em, 0);
@include wrapper-edges-color(_palette(bg));
position: relative;
> .inner {
margin: 0 auto;
max-width: 75em;
width: calc(100% - 4em);
}
&:before, &:after {
background-repeat: no-repeat;
background-size: 100% 100%;
height: 6em;
left: 0;
position: absolute;
width: 100%;
}
&:before {
@include vendor('transform', 'translateY(-100%)');
content: '';
top: 0;
}
&.alt {
padding-bottom: 1em;
&:after {
@include vendor('transform', 'translateY(100%) rotate(180deg)');
bottom: 0;
content: '';
}
}
&.style1 {
@include color(accent1);
@include wrapper-edges-color(_palette(accent1, bg));
}
&.style2 {
@include color(accent2);
@include wrapper-edges-color(_palette(accent2, bg));
}
@include breakpoint('<=large') {
@include padding(5em, 0);
&:before, &:after {
height: 4em;
}
}
@include breakpoint('<=medium') {
@include padding(4em, 0);
&:before, &:after {
height: 3em;
}
}
@include breakpoint('<=small') {
@include padding(3em, 0);
> .inner {
width: calc(100% - 3em);
}
&:before, &:after {
height: 2em;
}
&.alt {
padding-bottom: 0;
}
}
}

@ -0,0 +1,100 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* Banner */
#banner {
@include vendor('background-image', (
'linear-gradient(to top, #{transparentize(_palette(bg-alt), 0.1)}, #{transparentize(_palette(bg-alt), 0.1)})',
'url("../../images/banner.jpg")'
));
background-attachment: fixed;
background-position: center center;
background-size: cover;
color: #fff;
padding: 16em 3em;
position: relative;
text-align: center;
h1 {
color: inherit;
font-size: 3.2em;
margin: 0 0 0.65em 0;
padding: 0;
text-transform: uppercase;
}
p {
font-size: 1.75em;
margin-bottom: 0.75em;
}
.button {
min-width: 14em;
}
> .inner {
@include vendor('transition', (
'opacity 1s ease-in-out',
'transform 1s ease-in-out'
));
opacity: 1;
position: relative;
z-index: 1;
}
&:after {
@include vendor('transition', 'opacity 1s ease-in-out');
@include vendor('pointer-events', 'none');
content: '';
display: block;
background-color: desaturate(darken(_palette(bg-alt), 10), 5);
opacity: 0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
body.is-preload & {
.inner {
@include vendor('transform', 'translateY(1em)');
opacity: 0;
}
&:after {
opacity: 1;
}
}
@include breakpoint('<=large') {
background-attachment: scroll;
padding: 16em 3em;
}
@include breakpoint('<=medium') {
h1 {
font-size: 2.8em;
}
}
@include breakpoint('<=small') {
padding: 8em 2em;
h1 {
font-size: 2.25em;
}
p {
font-size: 1.25em;
}
}
@include breakpoint('<=xxsmall') {
padding: 6em 2em;
}
}

@ -0,0 +1,201 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* Footer */
#footer {
@include vendor('background-image', (
'linear-gradient(to top, #{transparentize(_palette(bg-alt), 0.1)}, #{transparentize(_palette(bg-alt), 0.1)})',
'url("../../images/banner.jpg")'
));
background-attachment: fixed;
background-position: center center;
background-size: cover;
padding: 12em 0 2em;
> .inner {
@include vendor('display', 'flex');
margin: 0 auto (_size(element-margin) * 1.5);
max-width: 75em;
width: calc(100% - 4em);
}
.contact {
@include padding(4em, 2.5em);
background-color: #fff;
list-style-type: none;
margin-bottom: 0;
width: 35%;
li {
margin-bottom: _size(element-margin);
padding-bottom: _size(element-margin);
padding-left: 4em;
position: relative;
strong {
color: _palette(accent1, bg);
display: block;
margin-bottom: 0.5em;
text-transform: uppercase;
}
&.icon:before {
color: _palette(border);
position: absolute;
left: 0;
top: 0.25em;
font-size: 1.25em;
}
&:after {
background-color: _palette(border);
bottom: 0;
content: '';
height: 1px;
left: -4em;
position: absolute;
width: 8em;
}
&:last-child {
margin-bottom: 0;
&:after {
display: none;
}
}
}
}
form {
@include color(accent1);
@include vendor('flex-grow', '1');
margin-bottom: 0;
padding: 4em 3.5em;
h4 {
font-weight: _font(weight-bold);
margin-bottom: _size(element-margin);
text-transform: uppercase;
}
label {
@include sr-only;
}
@include breakpoint('<=medium') {
> .fields {
$gutter: (_size(element-margin) * 0.75);
width: calc(100% + #{$gutter * 2});
margin: ($gutter * -1) 0 _size(element-margin) ($gutter * -1);
> .field {
padding: $gutter 0 0 $gutter;
width: calc(100% - #{$gutter * 1});
&.half {
width: calc(100% - #{$gutter * 1});
}
&.third {
width: calc(100% - #{$gutter * 1});
}
&.quarter {
width: calc(100% - #{$gutter * 1});
}
}
}
}
}
.copyright {
color: _palette(fg-light);
margin-bottom: (_size(element-margin) * 1.5);
padding: 0;
text-align: center;
li {
border-left: solid _size(border-width) _palette(border);
display: inline-block;
list-style: none;
margin-left: 1.5em;
padding-left: 1.5em;
&:first-child {
border-left: 0;
margin-left: 0;
padding-left: 0;
}
}
}
@include breakpoint('<=large') {
background-attachment: scroll;
}
@include breakpoint('<=medium') {
padding-top: 10em;
.contact {
@include padding(2em, 2em);
width: 45%;
li {
padding-left: 3em;
}
}
form {
padding: 2em 2em;
width: 55%;
}
}
@include breakpoint('<=small') {
padding-top: 7em;
> .inner {
@include vendor('flex-wrap', 'wrap');
width: calc(100% - 3em);
}
.contact {
width: 100%;
}
form {
width: 100%;
}
.copyright {
margin-bottom: _size(element-margin);
li {
display: block;
border-left: 0;
margin-left: 0;
padding-left: 0;
}
}
}
@include breakpoint('<=xsmall') {
.contact {
@include padding(2em, 1.5em);
li {
padding-left: 2.5em;
}
}
form {
padding: 2em 1.5em;
}
}
}

@ -0,0 +1,125 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* Header */
#header {
@include vendor('align-items', 'center');
@include vendor('display', 'flex');
@include vendor('justify-content', 'flex-end');
@include vendor('transition-duration', '#{_duration(transition)}');
@include vendor('transition-property', 'background-color padding');
@include vendor('transition-timing-function', 'ease-in-out');
background: desaturate(darken(_palette(fg-bold), 20), 5);
color: _palette(accent1, fg-bold);
left: 0;
padding: 1em;
position: fixed;
text-transform: uppercase;
top: 0;
width: 100%;
z-index: _misc(z-index-base) + 1;
> .logo {
@include vendor('flex', '1');
display: block;
cursor: default;
white-space: nowrap;
a {
@include vendor('transition', 'color #{_duration(transition)} ease-in-out');
color: inherit;
text-decoration: none;
font-weight: _font(weight-bold);
}
}
> a {
@include vendor('transition', 'color #{_duration(transition)} ease-in-out');
padding: 0 0.75em;
color: inherit;
font-weight: _font(weight-bold);
text-decoration: none;
display: block;
&:hover, &:focus {
color: _palette(accent1, fg-bold);
}
&[href="#menu"] {
@include vendor('transition', 'background-color #{_duration(transition)} ease-in-out, color #{_duration(transition)} ease-in-out');
@include icon(false, solid);
-webkit-tap-highlight-color: rgba(0,0,0,0);
border-radius: _size(border-radius);
box-shadow: 0 0 0 _size(border-width) _palette(accent1, border);
font-weight: _font(weight-bold);
margin-left: 0.5em;
padding: 0.5em 1.25em;
&:before {
content: '\f0c9';
float: right;
line-height: inherit;
margin-left: 0.5em;
}
&:hover {
background-color: _palette(accent1, border-bg);
}
}
}
&.alt {
background-color: transparent;
padding: 1.5em 2em;
}
@include breakpoint('<=small') {
@include vendor('align-items', 'flex-start');
padding: 0 0 0 1em;
> .logo {
padding: 0.5em 0;
span {
display: none;
}
}
> a {
&[href="#menu"] {
box-shadow: none;
position: relative;
text-indent: 8em;
white-space: nowrap;
width: 3.5em;
&:before {
left: 0;
margin-left: 0;
padding: 0.5em 0;
position: absolute;
text-align: center;
text-indent: 0;
top: 0;
width: inherit;
}
&:hover {
background-color: transparent;
}
}
}
&.alt {
padding: 0.5em 0 0.5em 1em;
}
}
@include breakpoint('<=xsmall') {
min-width: 320px;
}
}

@ -0,0 +1,15 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* Main */
#main {
padding: 10em 0 4em;
@include breakpoint('<=small') {
padding: 5em 0 2em;
}
}

@ -0,0 +1,143 @@
///
/// Atmosphere by Pixelarity
/// pixelarity.com | hello@pixelarity.com
/// License: pixelarity.com/license
///
/* Menu */
#page-wrapper {
@include vendor('transition', 'filter 0.25s ease');
}
#menu {
@include vendor('align-items', 'center');
@include vendor('display', 'flex');
@include vendor('justify-content', 'center');
@include vendor('pointer-events', 'none');
@include vendor('transition', ('opacity #{_duration(menu)} ease', 'visibility #{_duration(menu)}'));
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-tap-highlight-color: rgba(0,0,0,0);
background-color: transparentize(desaturate(darken(_palette(bg-alt), 10), 5), 0.1);
cursor: default;
height: 100%;
left: 0;
opacity: 0;
position: fixed;
text-align: center;
top: 0;
visibility: hidden;
width: 100%;
padding: 1.5em;
z-index: _misc(z-index-base) + 2;
.inner {
@include padding(2.5em, 1.5em);
@include vendor('transform', 'translateY(0.5em)');
@include vendor('transition', ('opacity #{_duration(menu)} ease','transform #{_duration(menu)} ease'));
-webkit-overflow-scrolling: touch;
background: _palette(accent1, bg);
border-radius: _size(border-radius);
color: _palette(accent1, fg);
display: block;
max-width: 100%;
opacity: 0;
position: relative;
text-transform: uppercase;
width: 24em;
}
h2 {
color: inherit;
border-bottom: solid 2px _palette(accent1, border);
padding-bottom: 1em;
}
.close {
@include icon(false, solid);
content: '';
cursor: pointer;
display: block;
height: 4em;
overflow: hidden;
position: absolute;
right: 0;
text-align: center;
text-indent: 4em;
top: 0;
width: 4em;
color: _palette(accent1, fg-bold);
&:before {
content: '\f00d';
position: absolute;
top: 0.75em;
right: 0.75em;
font-size: 1.25em;
width: 1em;
height: 1em;
line-height: 1em;
display: block;
text-indent: 0;
}
}
.links {
list-style: none;
margin-bottom: (_size(element-margin) - 0.5em);
padding: 0;
li {
padding: 0;
a {
background-color: transparent;
border-radius: _size(border-radius);
border: 0;
color: inherit;
display: block;
font-weight: _font(weight);
line-height: 1.85em;
padding: 0.75em 0;
text-decoration: none;
&:hover {
color: _palette(accent1, bg);
background-color: _palette(accent1, fg-bold);
}
}
}
}
@include breakpoint('<=small') {
.inner {
max-height: 100%;
overflow-y: auto;
overflow-x: hidden;
.close {
background-size: 1.5em 1.5em;
}
}
}
}
body.is-menu-visible {
#page-wrapper {
@include vendor('filter', 'blur(1.5px)');
}
#menu {
@include vendor('pointer-events', 'auto');
opacity: 1;
visibility: visible;
.inner {
@include vendor('transform', 'translateY(0)');
opacity: 1;
}
}
}

@ -0,0 +1,223 @@
// breakpoints.scss v1.0 | @ajlkn | MIT licensed */
// Vars.
/// Breakpoints.
/// @var {list}
$breakpoints: () !global;
// Mixins.
/// Sets breakpoints.
/// @param {map} $x Breakpoints.
@mixin breakpoints($x: ()) {
$breakpoints: $x !global;
}
/// Wraps @content in a @media block targeting a specific orientation.
/// @param {string} $orientation Orientation.
@mixin orientation($orientation) {
@media screen and (orientation: #{$orientation}) {
@content;
}
}
/// Wraps @content in a @media block using a given query.
/// @param {string} $query Query.
@mixin breakpoint($query: null) {
$breakpoint: null;
$op: null;
$media: null;
// Determine operator, breakpoint.
// Greater than or equal.
@if (str-slice($query, 0, 2) == '>=') {
$op: 'gte';
$breakpoint: str-slice($query, 3);
}
// Less than or equal.
@elseif (str-slice($query, 0, 2) == '<=') {
$op: 'lte';
$breakpoint: str-slice($query, 3);
}
// Greater than.
@elseif (str-slice($query, 0, 1) == '>') {
$op: 'gt';
$breakpoint: str-slice($query, 2);
}
// Less than.
@elseif (str-slice($query, 0, 1) == '<') {
$op: 'lt';
$breakpoint: str-slice($query, 2);
}
// Not.
@elseif (str-slice($query, 0, 1) == '!') {
$op: 'not';
$breakpoint: str-slice($query, 2);
}
// Equal.
@else {
$op: 'eq';
$breakpoint: $query;
}
// Build media.
@if ($breakpoint and map-has-key($breakpoints, $breakpoint)) {
$a: map-get($breakpoints, $breakpoint);
// Range.
@if (type-of($a) == 'list') {
$x: nth($a, 1);
$y: nth($a, 2);
// Max only.
@if ($x == null) {
// Greater than or equal (>= 0 / anything)
@if ($op == 'gte') {
$media: 'screen';
}
// Less than or equal (<= y)
@elseif ($op == 'lte') {
$media: 'screen and (max-width: ' + $y + ')';
}
// Greater than (> y)
@elseif ($op == 'gt') {
$media: 'screen and (min-width: ' + ($y + 1) + ')';
}
// Less than (< 0 / invalid)
@elseif ($op == 'lt') {
$media: 'screen and (max-width: -1px)';
}
// Not (> y)
@elseif ($op == 'not') {
$media: 'screen and (min-width: ' + ($y + 1) + ')';
}
// Equal (<= y)
@else {
$media: 'screen and (max-width: ' + $y + ')';
}
}
// Min only.
@else if ($y == null) {
// Greater than or equal (>= x)
@if ($op == 'gte') {
$media: 'screen and (min-width: ' + $x + ')';
}
// Less than or equal (<= inf / anything)
@elseif ($op == 'lte') {
$media: 'screen';
}
// Greater than (> inf / invalid)
@elseif ($op == 'gt') {
$media: 'screen and (max-width: -1px)';
}
// Less than (< x)
@elseif ($op == 'lt') {
$media: 'screen and (max-width: ' + ($x - 1) + ')';
}
// Not (< x)
@elseif ($op == 'not') {
$media: 'screen and (max-width: ' + ($x - 1) + ')';
}
// Equal (>= x)
@else {
$media: 'screen and (min-width: ' + $x + ')';
}
}
// Min and max.
@else {
// Greater than or equal (>= x)
@if ($op == 'gte') {
$media: 'screen and (min-width: ' + $x + ')';
}
// Less than or equal (<= y)
@elseif ($op == 'lte') {
$media: 'screen and (max-width: ' + $y + ')';
}
// Greater than (> y)
@elseif ($op == 'gt') {
$media: 'screen and (min-width: ' + ($y + 1) + ')';
}
// Less than (< x)
@elseif ($op == 'lt') {
$media: 'screen and (max-width: ' + ($x - 1) + ')';
}
// Not (< x and > y)
@elseif ($op == 'not') {
$media: 'screen and (max-width: ' + ($x - 1) + '), screen and (min-width: ' + ($y + 1) + ')';
}
// Equal (>= x and <= y)
@else {
$media: 'screen and (min-width: ' + $x + ') and (max-width: ' + $y + ')';
}
}
}
// String.
@else {
// Missing a media type? Prefix with "screen".
@if (str-slice($a, 0, 1) == '(') {
$media: 'screen and ' + $a;
}
// Otherwise, use as-is.
@else {
$media: $a;
}
}
}
// Output.
@media #{$media} {
@content;
}
}

@ -0,0 +1,90 @@
/// Removes a specific item from a list.
/// @author Hugo Giraudel
/// @param {list} $list List.
/// @param {integer} $index Index.
/// @return {list} Updated list.
@function remove-nth($list, $index) {
$result: null;
@if type-of($index) != number {
@warn "$index: #{quote($index)} is not a number for `remove-nth`.";
}
@else if $index == 0 {
@warn "List index 0 must be a non-zero integer for `remove-nth`.";
}
@else if abs($index) > length($list) {
@warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`.";
}
@else {
$result: ();
$index: if($index < 0, length($list) + $index + 1, $index);
@for $i from 1 through length($list) {
@if $i != $index {
$result: append($result, nth($list, $i));
}
}
}
@return $result;
}
/// Gets a value from a map.
/// @author Hugo Giraudel
/// @param {map} $map Map.
/// @param {string} $keys Key(s).
/// @return {string} Value.
@function val($map, $keys...) {
@if nth($keys, 1) == null {
$keys: remove-nth($keys, 1);
}
@each $key in $keys {
$map: map-get($map, $key);
}
@return $map;
}
/// Gets a duration value.
/// @param {string} $keys Key(s).
/// @return {string} Value.
@function _duration($keys...) {
@return val($duration, $keys...);
}
/// Gets a font value.
/// @param {string} $keys Key(s).
/// @return {string} Value.
@function _font($keys...) {
@return val($font, $keys...);
}
/// Gets a misc value.
/// @param {string} $keys Key(s).
/// @return {string} Value.
@function _misc($keys...) {
@return val($misc, $keys...);
}
/// Gets a palette value.
/// @param {string} $keys Key(s).
/// @return {string} Value.
@function _palette($keys...) {
@return val($palette, $keys...);
}
/// Gets a size value.
/// @param {string} $keys Key(s).
/// @return {string} Value.
@function _size($keys...) {
@return val($size, $keys...);
}

@ -0,0 +1,149 @@
// html-grid.scss v1.0 | @ajlkn | MIT licensed */
// Mixins.
/// Initializes the current element as an HTML grid.
/// @param {mixed} $gutters Gutters (either a single number to set both column/row gutters, or a list to set them individually).
/// @param {mixed} $suffix Column class suffix (optional; either a single suffix or a list).
@mixin html-grid($gutters: 1.5em, $suffix: '') {
// Initialize.
$cols: 12;
$multipliers: 0, 0.25, 0.5, 1, 1.50, 2.00;
$unit: 100% / $cols;
// Suffixes.
$suffixes: null;
@if (type-of($suffix) == 'list') {
$suffixes: $suffix;
}
@else {
$suffixes: ($suffix);
}
// Gutters.
$guttersCols: null;
$guttersRows: null;
@if (type-of($gutters) == 'list') {
$guttersCols: nth($gutters, 1);
$guttersRows: nth($gutters, 2);
}
@else {
$guttersCols: $gutters;
$guttersRows: 0;
}
// Row.
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
align-items: stretch;
// Columns.
> * {
box-sizing: border-box;
}
// Gutters.
&.gtr-uniform {
> * {
> :last-child {
margin-bottom: 0;
}
}
}
// Alignment.
&.aln-left {
justify-content: flex-start;
}
&.aln-center {
justify-content: center;
}
&.aln-right {
justify-content: flex-end;
}
&.aln-top {
align-items: flex-start;
}
&.aln-middle {
align-items: center;
}
&.aln-bottom {
align-items: flex-end;
}
// Step through suffixes.
@each $suffix in $suffixes {
// Suffix.
@if ($suffix != '') {
$suffix: '-' + $suffix;
}
@else {
$suffix: '';
}
// Row.
// Important.
> .imp#{$suffix} {
order: -1;
}
// Columns, offsets.
@for $i from 1 through $cols {
> .col-#{$i}#{$suffix} {
width: $unit * $i;
}
> .off-#{$i}#{$suffix} {
margin-left: $unit * $i;
}
}
// Step through multipliers.
@each $multiplier in $multipliers {
// Gutters.
$class: null;
@if ($multiplier != 1) {
$class: '.gtr-' + ($multiplier * 100);
}
&#{$class} {
margin-top: ($guttersRows * $multiplier * -1);
margin-left: ($guttersCols * $multiplier * -1);
> * {
padding: ($guttersRows * $multiplier) 0 0 ($guttersCols * $multiplier);
}
// Uniform.
&.gtr-uniform {
margin-top: $guttersCols * $multiplier * -1;
> * {
padding-top: $guttersCols * $multiplier;
}
}
}
}
}
}

@ -0,0 +1,86 @@
/// Makes an element's :before pseudoelement a FontAwesome icon.
/// @param {string} $content Optional content value to use.
/// @param {string} $category Optional category to use.
/// @param {string} $where Optional pseudoelement to target (before or after).
@mixin icon($content: false, $category: regular, $where: before) {
text-decoration: none;
&:#{$where} {
@if $content {
content: $content;
}
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
display: inline-block;
font-style: normal;
font-variant: normal;
text-rendering: auto;
line-height: 1;
text-transform: none !important;
@if ($category == brands) {
font-family: 'Font Awesome 5 Brands';
}
@elseif ($category == solid) {
font-family: 'Font Awesome 5 Pro';
font-weight: 900;
}
@elseif ($category == light) {
font-family: 'Font Awesome 5 Pro';
font-weight: 300;
}
@elseif ($category == duotone) {
font-family: 'Font Awesome 5 Duotone';
font-weight: 900;
}
@else {
font-family: 'Font Awesome 5 Pro';
font-weight: 400;
}
}
}
/// Applies padding to an element, taking the current element-margin value into account.
/// @param {mixed} $tb Top/bottom padding.
/// @param {mixed} $lr Left/right padding.
/// @param {list} $pad Optional extra padding (in the following order top, right, bottom, left)
/// @param {bool} $important If true, adds !important.
@mixin padding($tb, $lr, $pad: (0,0,0,0), $important: null) {
@if $important {
$important: '!important';
}
$x: 0.1em;
@if unit(_size(element-margin)) == 'rem' {
$x: 0.1rem;
}
padding: ($tb + nth($pad,1)) ($lr + nth($pad,2)) max($x, $tb - _size(element-margin) + nth($pad,3)) ($lr + nth($pad,4)) #{$important};
}
/// Encodes a SVG data URL so IE doesn't choke (via codepen.io/jakob-e/pen/YXXBrp).
/// @param {string} $svg SVG data URL.
/// @return {string} Encoded SVG data URL.
@function svg-url($svg) {
$svg: str-replace($svg, '"', '\'');
$svg: str-replace($svg, '%', '%25');
$svg: str-replace($svg, '<', '%3C');
$svg: str-replace($svg, '>', '%3E');
$svg: str-replace($svg, '&', '%26');
$svg: str-replace($svg, '#', '%23');
$svg: str-replace($svg, '{', '%7B');
$svg: str-replace($svg, '}', '%7D');
$svg: str-replace($svg, ';', '%3B');
@return url("data:image/svg+xml;charset=utf8,#{$svg}");
}

@ -0,0 +1,64 @@
// Misc.
$misc: (
z-index-base: 10000
);
// Duration.
$duration: (
menu: 0.5s,
transition: 0.2s
);
// Size.
$size: (
border-radius: 4px,
border-width: 1px,
element-height: 3em,
element-margin: 2em
);
// Font.
$font: (
family: ('Ubuntu', Arial, sans-serif),
family-fixed: ('Courier New', monospace),
weight: 400,
weight-bold: 700,
);
// Palette.
$palette: (
bg: #fff,
bg-alt: #2b5a96,
fg: #637485,
fg-bold: #637485,
fg-light: #bbb,
border: rgba(#637485,0.25),
border-bg: rgba(#637485,0.075),
border2: rgba(#637485,0.4),
border2-bg: rgba(#637485,0.075),
highlight: accent1,
accent1: (
bg: #39a288,
fg: #ffffff,
fg-bold: #ffffff,
fg-light: rgba(#ffffff, 0.75),
border: rgba(255,255,255,0.25),
border-bg: rgba(255,255,255,0.065),
border2: rgba(0,0,0,0.25),
border2-bg: rgba(0,0,0,0.065),
highlight: accent1
),
accent2: (
bg: #f5f8fa,
fg: #637485,
fg-bold: #637485,
fg-light: #bbb,
border: rgba(#637485,0.25),
border-bg: rgba(#637485,0.075),
border2: rgba(#637485,0.4),
border2-bg: rgba(#637485,0.075),
highlight: accent1
)
);

@ -0,0 +1,376 @@
// vendor.scss v1.0 | @ajlkn | MIT licensed */
// Vars.
/// Vendor prefixes.
/// @var {list}
$vendor-prefixes: (
'-moz-',
'-webkit-',
'-ms-',
''
);
/// Properties that should be vendorized.
/// Data via caniuse.com, github.com/postcss/autoprefixer, and developer.mozilla.org
/// @var {list}
$vendor-properties: (
// Animation.
'animation',
'animation-delay',
'animation-direction',
'animation-duration',
'animation-fill-mode',
'animation-iteration-count',
'animation-name',
'animation-play-state',
'animation-timing-function',
// Appearance.
'appearance',
// Backdrop filter.
'backdrop-filter',
// Background image options.
'background-clip',
'background-origin',
'background-size',
// Box sizing.
'box-sizing',
// Clip path.
'clip-path',
// Filter effects.
'filter',
// Flexbox.
'align-content',
'align-items',
'align-self',
'flex',
'flex-basis',
'flex-direction',
'flex-flow',
'flex-grow',
'flex-shrink',
'flex-wrap',
'justify-content',
'order',
// Font feature.
'font-feature-settings',
'font-language-override',
'font-variant-ligatures',
// Font kerning.
'font-kerning',
// Fragmented borders and backgrounds.
'box-decoration-break',
// Grid layout.
'grid-column',
'grid-column-align',
'grid-column-end',
'grid-column-start',
'grid-row',
'grid-row-align',
'grid-row-end',
'grid-row-start',
'grid-template-columns',
'grid-template-rows',
// Hyphens.
'hyphens',
'word-break',
// Masks.
'mask',
'mask-border',
'mask-border-outset',
'mask-border-repeat',
'mask-border-slice',
'mask-border-source',
'mask-border-width',
'mask-clip',
'mask-composite',
'mask-image',
'mask-origin',
'mask-position',
'mask-repeat',
'mask-size',
// Multicolumn.
'break-after',
'break-before',
'break-inside',
'column-count',
'column-fill',
'column-gap',
'column-rule',
'column-rule-color',
'column-rule-style',
'column-rule-width',
'column-span',
'column-width',
'columns',
// Object fit.
'object-fit',
'object-position',
// Regions.
'flow-from',
'flow-into',
'region-fragment',
// Scroll snap points.
'scroll-snap-coordinate',
'scroll-snap-destination',
'scroll-snap-points-x',
'scroll-snap-points-y',
'scroll-snap-type',
// Shapes.
'shape-image-threshold',
'shape-margin',
'shape-outside',
// Tab size.
'tab-size',
// Text align last.
'text-align-last',
// Text decoration.
'text-decoration-color',
'text-decoration-line',
'text-decoration-skip',
'text-decoration-style',
// Text emphasis.
'text-emphasis',
'text-emphasis-color',
'text-emphasis-position',
'text-emphasis-style',
// Text size adjust.
'text-size-adjust',
// Text spacing.
'text-spacing',
// Transform.
'transform',
'transform-origin',
// Transform 3D.
'backface-visibility',
'perspective',
'perspective-origin',
'transform-style',
// Transition.
'transition',
'transition-delay',
'transition-duration',
'transition-property',
'transition-timing-function',
// Unicode bidi.
'unicode-bidi',
// User select.
'user-select',
// Writing mode.
'writing-mode',
);
/// Values that should be vendorized.
/// Data via caniuse.com, github.com/postcss/autoprefixer, and developer.mozilla.org
/// @var {list}
$vendor-values: (
// Cross fade.
'cross-fade',
// Element function.
'element',
// Filter function.
'filter',
// Flexbox.
'flex',
'inline-flex',
// Grab cursors.
'grab',
'grabbing',
// Gradients.
'linear-gradient',
'repeating-linear-gradient',
'radial-gradient',
'repeating-radial-gradient',
// Grid layout.
'grid',
'inline-grid',
// Image set.
'image-set',
// Intrinsic width.
'max-content',
'min-content',
'fit-content',
'fill',
'fill-available',
'stretch',
// Sticky position.
'sticky',
// Transform.
'transform',
// Zoom cursors.
'zoom-in',
'zoom-out',
);
// Functions.
/// Removes a specific item from a list.
/// @author Hugo Giraudel
/// @param {list} $list List.
/// @param {integer} $index Index.
/// @return {list} Updated list.
@function remove-nth($list, $index) {
$result: null;
@if type-of($index) != number {
@warn "$index: #{quote($index)} is not a number for `remove-nth`.";
}
@else if $index == 0 {
@warn "List index 0 must be a non-zero integer for `remove-nth`.";
}
@else if abs($index) > length($list) {
@warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`.";
}
@else {
$result: ();
$index: if($index < 0, length($list) + $index + 1, $index);
@for $i from 1 through length($list) {
@if $i != $index {
$result: append($result, nth($list, $i));
}
}
}
@return $result;
}
/// Replaces a substring within another string.
/// @author Hugo Giraudel
/// @param {string} $string String.
/// @param {string} $search Substring.
/// @param {string} $replace Replacement.
/// @return {string} Updated string.
@function str-replace($string, $search, $replace: '') {
$index: str-index($string, $search);
@if $index {
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
}
@return $string;
}
/// Replaces a substring within each string in a list.
/// @param {list} $strings List of strings.
/// @param {string} $search Substring.
/// @param {string} $replace Replacement.
/// @return {list} Updated list of strings.
@function str-replace-all($strings, $search, $replace: '') {
@each $string in $strings {
$strings: set-nth($strings, index($strings, $string), str-replace($string, $search, $replace));
}
@return $strings;
}
// Mixins.
/// Wraps @content in vendorized keyframe blocks.
/// @param {string} $name Name.
@mixin keyframes($name) {
@-moz-keyframes #{$name} { @content; }
@-webkit-keyframes #{$name} { @content; }
@-ms-keyframes #{$name} { @content; }
@keyframes #{$name} { @content; }
}
/// Vendorizes a declaration's property and/or value(s).
/// @param {string} $property Property.
/// @param {mixed} $value String/list of value(s).
@mixin vendor($property, $value) {
// Determine if property should expand.
$expandProperty: index($vendor-properties, $property);
// Determine if value should expand (and if so, add '-prefix-' placeholder).
$expandValue: false;
@each $x in $value {
@each $y in $vendor-values {
@if $y == str-slice($x, 1, str-length($y)) {
$value: set-nth($value, index($value, $x), '-prefix-' + $x);
$expandValue: true;
}
}
}
// Expand property?
@if $expandProperty {
@each $vendor in $vendor-prefixes {
#{$vendor}#{$property}: #{str-replace-all($value, '-prefix-', $vendor)};
}
}
// Expand just the value?
@elseif $expandValue {
@each $vendor in $vendor-prefixes {
#{$property}: #{str-replace-all($value, '-prefix-', $vendor)};
}
}
// Neither? Treat them as a normal declaration.
@else {
#{$property}: #{$value};
}
}

@ -0,0 +1,84 @@
@import 'libs/vars';
@import 'libs/functions';
@import 'libs/mixins';
@import 'libs/vendor';
@import 'libs/breakpoints';
@import 'libs/html-grid';
@import url('https://static.netsyms.net/fontawesome-pro/5/css/all.min.css');
@import url('https://static.netsyms.net/fonts/ubuntu/Ubuntu.css');
/*
Atmosphere by Pixelarity
pixelarity.com | hello@pixelarity.com
License: pixelarity.com/license
*/
// Breakpoints.
@include breakpoints((
xlarge: ( 1281px, 1680px ),
large: ( 981px, 1280px ),
medium: ( 737px, 980px ),
small: ( 481px, 736px ),
xsmall: ( 361px, 480px ),
xxsmall: ( null, 360px )
));
// Mixins.
@mixin color($p) {
@include color-typography($p);
@include color-box($p);
@include color-button($p);
@include color-form($p);
@include color-list($p);
@include color-section($p);
@include color-table($p);
@include color-spotlights($p);
@include color-timeline($p);
}
@mixin sr-only {
border: 0;
clip: rect(0,0,0,0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
// Base.
@import 'base/reset';
@import 'base/page';
@import 'base/typography';
// Component.
@import 'components/row';
@import 'components/box';
@import 'components/button';
@import 'components/form';
@import 'components/icon';
@import 'components/image';
@import 'components/list';
@import 'components/actions';
@import 'components/icons';
@import 'components/section';
@import 'components/table';
@import 'components/spotlights';
@import 'components/features';
@import 'components/posts';
@import 'components/timeline';
@import 'components/wrapper';
// Layout.
@import 'layout/header';
@import 'layout/menu';
@import 'layout/banner';
@import 'layout/main';
@import 'layout/footer';

@ -0,0 +1,15 @@
{
"name": "netsyms/www",
"require": {
"phpmailer/phpmailer": "^6.0",
"stripe/stripe-php": "^7.71",
"catfan/medoo": "^1.7",
"easypost/easypost-php": "^3.4"
},
"authors": [
{
"name": "Skylar Ittner",
"email": "admin@netsyms.com"
}
]
}

@ -0,0 +1,252 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "7a941c6f682b3194cfb9e60d6455d254",
"packages": [
{
"name": "catfan/medoo",
"version": "v1.7.10",
"source": {
"type": "git",
"url": "https://github.com/catfan/Medoo.git",
"reference": "2d675f73e23f63bbaeb9a8aa33318659a3d3c32f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/catfan/Medoo/zipball/2d675f73e23f63bbaeb9a8aa33318659a3d3c32f",
"reference": "2d675f73e23f63bbaeb9a8aa33318659a3d3c32f",
"shasum": ""
},
"require": {
"ext-pdo": "*",
"php": ">=5.4"
},
"suggest": {
"ext-pdo_dblib": "For MSSQL or Sybase database on Linux/UNIX platform",
"ext-pdo_mysql": "For MySQL or MariaDB database",
"ext-pdo_oci": "For Oracle database",
"ext-pdo_oci8": "For Oracle version 8 database",
"ext-pdo_pqsql": "For PostgreSQL database",
"ext-pdo_sqlite": "For SQLite database",
"ext-pdo_sqlsrv": "For MSSQL database on both Window/Liunx platform"
},
"type": "framework",
"autoload": {
"psr-4": {
"Medoo\\": "/src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Angel Lai",
"email": "angel@catfan.me"
}
],
"description": "The lightweight PHP database framework to accelerate development",
"homepage": "https://medoo.in",
"keywords": [
"database",
"database library",
"lightweight",
"mariadb",
"mssql",
"mysql",
"oracle",
"php framework",
"postgresql",
"sql",
"sqlite"
],
"time": "2020-02-11T08:20:42+00:00"
},
{
"name": "easypost/easypost-php",
"version": "3.4.5",
"source": {
"type": "git",
"url": "https://github.com/EasyPost/easypost-php.git",
"reference": "c1aaa1baf82c8f5b330ec4da80d084da458765a5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/EasyPost/easypost-php/zipball/c1aaa1baf82c8f5b330ec4da80d084da458765a5",
"reference": "c1aaa1baf82c8f5b330ec4da80d084da458765a5",
"shasum": ""
},
"require": {
"ext-curl": "*",
"ext-json": "*",
"php": ">=5.3.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.16",
"overtrue/phplint": "^1.2",
"phpunit/phpunit": "^8"
},
"type": "library",
"autoload": {
"psr-0": {
"EasyPost": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "EasyPost Developers",
"email": "oss@easypost.com",
"homepage": "https://www.easypost.com"
}
],
"description": "EasyPost Shipping API Client Library for PHP",
"homepage": "https://github.com/EasyPost/easypost-php",
"keywords": [
"api",
"easypost",
"shipping"
],
"time": "2020-05-07T20:37:59+00:00"
},
{
"name": "phpmailer/phpmailer",
"version": "v6.0.7",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "0c41a36d4508d470e376498c1c0c527aa36a2d59"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/0c41a36d4508d470e376498c1c0c527aa36a2d59",
"reference": "0c41a36d4508d470e376498c1c0c527aa36a2d59",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"ext-filter": "*",
"php": ">=5.5.0"
},
"require-dev": {
"doctrine/annotations": "1.2.*",
"friendsofphp/php-cs-fixer": "^2.2",
"phpdocumentor/phpdocumentor": "2.*",
"phpunit/phpunit": "^4.8 || ^5.7",
"zendframework/zend-eventmanager": "3.0.*",
"zendframework/zend-i18n": "2.7.3",
"zendframework/zend-serializer": "2.7.*"
},
"suggest": {
"ext-mbstring": "Needed to send email in multibyte encoding charset",
"hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
"league/oauth2-google": "Needed for Google XOAUTH2 authentication",
"psr/log": "For optional PSR-3 debug logging",
"stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication",
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)"
},
"type": "library",
"autoload": {
"psr-4": {
"PHPMailer\\PHPMailer\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-2.1"
],
"authors": [
{
"name": "Jim Jagielski",
"email": "jimjag@gmail.com"
},
{
"name": "Marcus Bointon",
"email": "phpmailer@synchromedia.co.uk"
},
{
"name": "Andy Prevost",
"email": "codeworxtech@users.sourceforge.net"
},
{
"name": "Brent R. Matzelle"
}
],
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"time": "2019-02-01T15:04:28+00:00"
},
{
"name": "stripe/stripe-php",
"version": "v7.71.0",
"source": {
"type": "git",
"url": "git@github.com:stripe/stripe-php.git",
"reference": "5ebe39d814411594b1ff9d79f0598a0de7faa30b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/stripe/stripe-php/zipball/5ebe39d814411594b1ff9d79f0598a0de7faa30b",
"reference": "5ebe39d814411594b1ff9d79f0598a0de7faa30b",
"shasum": ""
},
"require": {
"ext-curl": "*",
"ext-json": "*",
"ext-mbstring": "*",
"php": ">=5.6.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "2.17.1",
"php-coveralls/php-coveralls": "^2.1",
"phpunit/phpunit": "^5.7",
"squizlabs/php_codesniffer": "^3.3",
"symfony/process": "~3.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0-dev"
}
},
"autoload": {
"psr-4": {
"Stripe\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Stripe and contributors",
"homepage": "https://github.com/stripe/stripe-php/contributors"
}
],
"description": "Stripe PHP Library",
"homepage": "https://stripe.com/",
"keywords": [
"api",
"payment processing",
"stripe"
],
"time": "2021-02-05T21:29:10+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.0.0"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 325 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

@ -0,0 +1,96 @@
<?php
/*
* Copyright 2020 Netsyms Technologies.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
class MergeLabels {
private $keys = [];
private $rows = [[]];
private $labelpath = "";
private $title = "label";
/**
*
* @param string $labelpath Path to the glabels 3 label template.
*/
public function __construct(string $labelpath, string $labeltitle = "label") {
if (file_exists($labelpath)) {
$this->labelpath = $labelpath;
} else {
throw new InvalidArgumentException("Label $labelpath does not exist.");
}
$this->title = $labeltitle;
}
/**
* Set multiple merge fields at once.
* @param array $fields key => value string array
*/
public function setColumnKeys(array $titles) {
$this->keys = $titles;
}
/**
* Set multiple merge fields at once, allowing for multiple labels at once.
* @param array $fields key => value string array
*/
public function setMergeFields(array $rows) {
$this->rows = $rows;
}
public function setTitle(string $title) {
$this->title = $title;
}
private function writeCSVFileAndReturnFilePath(): string {
$csvfile = tempnam(sys_get_temp_dir(), "GLABELS_MERGE_CSV");
$fp = fopen($csvfile, 'w');
fputcsv($fp, array_values($this->keys));
foreach ($this->rows as $row) {
fputcsv($fp, $row);
}
fclose($fp);
return $csvfile;
}
private function toPDFFilePath() {
$csvfile = $this->writeCSVFileAndReturnFilePath();
$pdffile = tempnam(sys_get_temp_dir(), "GLABELS_MERGE_PDF");
shell_exec("glabels-3-batch --input=$csvfile --output=$pdffile " . $this->labelpath);
unlink($csvfile);
return $pdffile;
}
public function servePDF() {
$pdfpath = $this->toPDFFilePath();
$pdfsize = filesize($pdfpath);
header('Content-Type: application/pdf');
header("Content-Length: $pdfsize");
header("Content-Disposition: inline; filename=\"$this->title\"");
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
echo file_get_contents($pdfpath);
unlink($pdfpath);
}
public function getPDFDataURI(): string {
$pdfpath = $this->toPDFFilePath();
$pdfString = file_get_contents($pdfpath);
unlink($pdfpath);
$pdfBase64 = base64_encode($pdfString);
return 'data:application/pdf;base64,' . $pdfBase64;
}
}

@ -0,0 +1,104 @@
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
class Email {
private $subject = "";
private $body = "";
private $attachments = [];
private $to = [];
private $fromaddress = "";
private $fromname = "";
private $smtphost = "";
private $smtpport = "";
private $smtpauth = "";
private $smtpusername = "";
private $smtppassword = "";
private $smtpsecurity = "";
public function setFrom(string $address, string $name = "") {
$this->fromaddress = $address;
if (empty($name)) {
$this->fromname = $address;
} else {
$this->fromname = $name;
}
}
public function setSubject(string $subj) {
$this->subject = $subj;
}
public function setBody(string $body) {
$this->body = $body;
}
public function addAttachment(string $filename, string $name = "") {
$this->attachments[$filename] = $name;
}
public function addTo(string $email) {
$this->to[] = $email;
}
public function rmTo() {
$this->to = [];
}
/**
* Set the SMTP configuration.
*
* @param string $host smtp.example.com
* @param int $port 587
* @param bool $auth true
* @param string $user
* @param string $pass
* @param string $security tls
*/
public function setSMTP(string $host = "smtp.example.com", int $port = 587, bool $auth = true, string $user = "", string $pass = "", string $security = "tls") {
$this->smtphost = $host;
$this->smtpport = $port;
$this->smtpauth = $auth;
$this->smtpusername = $user;
$this->smtppassword = $pass;
$this->smtpsecurity = $security;
}
public function send() {
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = $this->smtphost;
$mail->SMTPAuth = $this->smtpauth;
if ($this->smtpauth) {
$mail->Username = $this->smtpusername;
$mail->Password = $this->smtppassword;
}
if ($this->smtpsecurity != "none") {
$mail->SMTPSecure = $this->smtpsecurity;
}
$mail->Port = $this->smtpport;
$mail->isHTML(false);
$mail->setFrom($this->fromaddress, $this->fromname);
foreach ($this->to as $to) {
$mail->addAddress($to);
}
$mail->Subject = $this->subject;
$mail->Body = $this->body;
foreach ($this->attachments as $file => $name) {
if (empty($name)) {
$mail->addAttachment($file);
} else {
$mail->addAttachment($file, $name);
}
}
$mail->send();
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,121 @@
<?php
require_once __DIR__ . "/required.php";
$shipmentinfo = [];
try {
if (empty($_REQUEST["to_street"])) {
throw new Exception("Please enter the delivery address.");
}
if (empty($_REQUEST["to_name"]) && empty($_REQUEST["to_company"])) {
throw new Exception("Please enter the recipient's name and/or a company name.");
}
if (empty($_REQUEST["to_zip"]) && (empty($_REQUEST["to_city"]) || empty($_REQUEST["to_state"]))) {
throw new Exception("Please enter the delivery ZIP code, or if you don't know, enter the city and state and we'll find the ZIP code for you.");
}
if (empty($_REQUEST["from_name"]) || empty($_REQUEST["from_street"])) {
throw new Exception("Please enter your return address.");
}
if (empty($_REQUEST["from_zip"]) && (empty($_REQUEST["from_city"]) || empty($_REQUEST["from_state"]))) {
throw new Exception("Please enter your ZIP code, or if you don't know, enter your city and state and we'll find the ZIP code for you.");
}
$shipmentinfo["from_address"] = \EasyPost\Address::create([
"verify" => array("delivery"),
"name" => $_REQUEST["from_name"],
"street1" => $_REQUEST["from_street"],
"street2" => $_REQUEST["from_street2"],
"city" => $_REQUEST["from_city"],
"state" => $_REQUEST["from_state"],
"zip" => $_REQUEST["from_zip"],
"country" => "US"
]);
$shipmentinfo["to_address"] = \EasyPost\Address::create([
"verify" => array("delivery"),
"name" => $_REQUEST["to_name"],
"company" => $_REQUEST["to_company"],
"street1" => $_REQUEST["to_street"],
"street2" => $_REQUEST["to_street2"],
"city" => $_REQUEST["to_city"],
"state" => $_REQUEST["to_state"],
"zip" => $_REQUEST["to_zip"],
"country" => "US"
]);
$shipmentinfo["parcel"] = \EasyPost\Parcel::create([
"predefined_package" => "Letter",
"weight" => 3.5
]);
if ($_REQUEST["postagetype"] == "certified") {
$shipmentinfo["options"]["certified_mail"] = true;
} else if ($_REQUEST["postagetype"] == "certified_receipt") {
$shipmentinfo["options"]["certified_mail"] = true;
$shipmentinfo["options"]["return_receipt"] = true;
}
$shipmentinfo["options"]["label_format"] = "PNG";
$shipmentinfo["options"]["label_size"] = "7x3";
$shipmentinfo["options"]["label_date"] = date("c", strtotime("tomorrow"));
$shipment = \EasyPost\Shipment::create($shipmentinfo);
$selectedrate = [];
for ($i = 0; $i < count($shipment->rates); $i++) {
$rate = $shipment->rates[$i];
$retail_rate = $rate->retail_rate ?? ($rate->list_rate ?? $rate->rate);
if ($rate->service != "First") {
continue;
}
$selectedrate = [
"id" => $rate->id,
"cost" => $retail_rate,
"price" => $retail_rate + 1.00
];
}
if (empty($selectedrate)) {
throw new Exception("Unable to find price. Check your destination address and try again.");
}
$address = $shipment->to_address;
$fromaddress = $shipment->from_address;
header("Content-Type: application/json");
exit(json_encode([
"status" => "OK",
"rate" => $selectedrate,
"shipmentid" => $shipment->id,
"address" => [
"name" => $address->name ?? "",
"company" => $address->company ?? "",
"street1" => $address->street1 ?? "",
"street2" => $address->street2 ?? "",
"city" => $address->city ?? "",
"state" => $address->state ?? "",
"zip" => $address->zip ?? ""
],
"fromaddress" => [
"name" => $fromaddress->name ?? "",
"street1" => $fromaddress->street1 ?? "",
"street2" => $fromaddress->street2 ?? "",
"city" => $fromaddress->city ?? "",
"state" => $fromaddress->state ?? "",
"zip" => $fromaddress->zip ?? ""
]]
));
} catch (Exception $ex) {
header("Content-Type: application/json");
exit(json_encode(["status" => "ERROR", "message" => $ex->getMessage()]));
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 97 KiB

@ -0,0 +1,97 @@
<?php
require_once __DIR__ . "/required.php";
$shipmentinfo = [];
try {
$shipment = \EasyPost\Shipment::retrieve($_REQUEST["shipmentid"]);
$price = 0;
foreach ($shipment->rates as $rate) {
if ($rate->id == $_REQUEST["rateid"]) {
$retail_rate = $rate->retail_rate ?? ($rate->list_rate ?? $rate->rate);
$price = $retail_rate + 1.00;
}
}
if ($price == 0) {
throw new Exception("Invalid rate selection. Refresh the page and try again. Your card was not charged.");
}
if ($price != $_REQUEST["price"]) {
throw new Exception("Price mismatch detected. Refresh the page and try again. Your card was not charged.");
}
// make the payment intent but don't capture it yet, in case something goes wrong.
$intent = \Stripe\PaymentIntent::create([
'amount' => $price * 100,
'currency' => 'usd',
'payment_method' => $_REQUEST["stripeid"],
'description' => "CertifiedFromHome.com",
'statement_descriptor' => "CrtfdFrmHome",
'payment_method_types' => ['card'],
'capture_method' => 'manual',
'confirm' => true
]);
if ($intent->status == 'requires_capture') {
// Payment will go through, proceed to spend money on postage
if (empty($shipment->postage_label)) {
// Do this conditionally in case label got purchased but payment somehow failed,
// allowing a retry of the payment.
$shipment->buy(['rate' => ['id' => $_REQUEST["rateid"]]]);
}
$labelurl = $shipment->postage_label->label_url;
// load postage image
$labelimage = imagecreatefrompng($labelurl);
if (!empty($shipment->options->certified_mail)) {
// load page template
$paperimage = imagecreatefrompng(__DIR__ . "/papertemplate.png");
// copy postage label image into page template
imagecopyresampled($paperimage, $labelimage, 225, 750, 0, 0, 2100, 900, 2100, 900);
} else {
// load page template
$paperimage = imagecreatefrompng(__DIR__ . "/papertemplate_notracking.png");
// copy postage label image into page template
imagecopyresampled($paperimage, $labelimage, 225, 600, 0, 0, 2100, 900, 2100, 900);
}
// save generated image to temp file
$tmpfile = tempnam(sys_get_temp_dir(), "certifiedlabel");
imagepng($paperimage, $tmpfile);
// Generate PDF from image
$pdf = new FPDF('P', 'in', 'Letter');
$pdf->AddPage();
$pdf->Image($tmpfile, 0, 0, -300, -300, "PNG");
$pdffile = date("Ymd") . "_" . hash("sha256", $_REQUEST["shipmentid"]) . ".pdf";
$pdf->Output("F", __DIR__ . "/pdf/" . $pdffile);
// cleanup temp file
unlink($tmpfile);
// get paid
$intent->capture();
header("Content-Type: application/json");
exit(json_encode([
"status" => "OK",
"pdf" => "https://certifiedfromhome.com/pdf/" . $pdffile,
"trackingcode" => $shipment->tracking_code
]));
} else {
throw new Exception("Payment didn't go through. Please try again or try a different card.");
}
} catch (Exception $ex) {
header("Content-Type: application/json");
exit(json_encode(["status" => "ERROR", "message" => $ex->getMessage()]));
}

@ -0,0 +1,24 @@
<?php
require_once __DIR__ . "/vendor/autoload.php";
require_once __DIR__ . "/settings.php";
if ($_SETTINGS["debug"]) {
error_reporting(E_ALL);
ini_set('display_errors', 'On');
} else {
error_reporting(0);
ini_set('display_errors', 'off');
ini_set('display_startup_errors', 'off');
ini_set('html_errors', 'off');
}
$libs = glob(__DIR__ . "/lib/*.lib.php");
foreach ($libs as $lib) {
require_once $lib;
}
\EasyPost\EasyPost::setApiKey($_SETTINGS["easypost_key"]);
\Stripe\Stripe::setApiKey($_SETTINGS["stripe_sk"]);
header("Access-Control-Allow-Origin: *");

@ -0,0 +1,7 @@
<?php
$_SETTINGS = [
"debug" => false,
"easypost_key" => "",
"stripe_sk" => "",
];

@ -0,0 +1,28 @@
<!DOCTYPE HTML>
<html>
{{> head}}
<body class="is-preload">
<div id="page-wrapper">
{{> header}}
{{> nav}}
<section id="main" class="wrapper alt">
<div class="inner">
{{#title}}
<header class="major">
<h1>{{title}}</h1>
{{#description}}
<p>{{description}}</p>
{{/description}}
</header>
{{/title}}
{{&page_content}}
</div>
</section>
{{> footer}}
</div>
{{> scripts}}
</body>
</html>

@ -0,0 +1,107 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<link rel="stylesheet" href="assets/css/main.css" />
</head>
<body class="is-preload">
<!-- Page wrapper -->
<div id="page-wrapper">
<!-- Header -->
<header id="header">
<span class="logo"><a href="index.html">Atmosphere</a> <span>by Pixelarity</span></span>
<a href="#menu">Menu</a>
</header>
<!-- Nav -->
<nav id="menu">
<div class="inner">
<h2>Menu</h2>
<ul class="links">
<li><a href="index.html">Home</a></li>
<li><a href="generic.html">Generic</a></li>
<li><a href="elements.html">Elements</a></li>
<li><a href="#">Log In</a></li>
<li><a href="#">Sign Up</a></li>
</ul>
<a class="close">Close</a>
</div>
</nav>
<!-- Main -->
<section id="main" class="wrapper alt">
<div class="inner">
<header class="major special">
<p>Lorem Ipsum Dolor</p>
<h1>Just a Generic Page</h1>
</header>
<a href="#" class="image main"><img src="images/pic01.jpg" alt="" /></a>
<p>Vis accumsan feugiat adipiscing nisl amet adipiscing accumsan blandit accumsan sapien blandit ac amet faucibus aliquet placerat commodo. Interdum ante aliquet commodo accumsan vis phasellus adipiscing. Ornare a in lacinia. Vestibulum accumsan ac metus massa tempor. Accumsan in lacinia ornare massa amet. Ac interdum ac non praesent. Cubilia lacinia interdum massa faucibus blandit nullam. Accumsan phasellus nunc integer. Accumsan euismod nunc adipiscing lacinia erat ut sit. Arcu amet. Id massa aliquet arcu accumsan lorem amet accumsan.</p>
<p>Amet nibh adipiscing adipiscing. Commodo ante vis placerat interdum massa massa primis. Tempus condimentum tempus non ac varius cubilia adipiscing placerat lorem turpis at. Aliquet lorem porttitor interdum. Amet lacus. Aliquam lobortis faucibus blandit ac phasellus. In amet magna non interdum volutpat porttitor metus a ante ac neque. Nisi turpis. Commodo col. Interdum adipiscing mollis ut aliquam id ante adipiscing commodo integer arcu amet Ac interdum ac non praesent. Cubilia lacinia interdum massa faucibus blandit nullam. Accumsan phasellus nunc integer. Accumsan euismod nunc adipiscing lacinia erat ut sit. Arcu amet. Id massa aliquet arcu accumsan lorem amet accumsan commodo odio cubilia ac eu interdum placerat placerat arcu commodo lobortis adipiscing semper ornare pellentesque.</p>
<p>Amet nibh adipiscing adipiscing. Commodo ante vis placerat interdum massa massa primis. Tempus condimentum tempus non ac varius cubilia adipiscing placerat lorem turpis at. Aliquet lorem porttitor interdum. Amet lacus. Aliquam lobortis faucibus blandit ac phasellus. In amet magna non interdum volutpat porttitor metus a ante ac neque. Nisi turpis. Commodo col. Interdum adipiscing mollis ut aliquam id ante adipiscing commodo integer arcu amet blandit adipiscing arcu ante.</p>
</div>
</section>
<!-- Footer -->
<footer id="footer">
<div class="inner">
<ul class="contact">
<li class="icon solid fa-home">
<strong>Address</strong>
1234 Fictional Avenue<br>Nashville, TN 00000
</li>
<li class="icon solid fa-phone">
<strong>Phone</strong>
(000) 000-0000
</li>
<li class="icon solid fa-envelope">
<strong>Email</strong>
information@untitled.tld
</li>
</ul>
<form action="#" method="post">
<h4>Get in touch</h4>
<div class="fields">
<div class="field half">
<label for="name">Name</label>
<input name="name" id="name" type="text" placeholder="Name">
</div>
<div class="field half">
<label for="email">Email</label>
<input name="email" id="email" type="email" placeholder="Email">
</div>
<div class="field">
<label for="message">Message</label>
<textarea name="message" id="message" rows="6" placeholder="Message"></textarea>
</div>
</div>
<ul class="actions">
<li><input value="Send Message" class="button large" type="submit"></li>
</ul>
</form>
</div>
<div class="copyright">
&copy; Untitled. All rights reserved.
</div>
</footer>
</div>
<!-- Scripts -->
<script src="assets/js/jquery.min.js"></script>
<script src="assets/js/browser.min.js"></script>
<script src="assets/js/breakpoints.min.js"></script>
<script src="assets/js/util.js"></script>
<script src="assets/js/jquery.scrollex.min.js"></script>
<script src="assets/js/jquery.scrolly.min.js"></script>
<script src="assets/js/main.js"></script>
</body>
</html>
Loading…
Cancel
Save