Visibility jam landing page

This commit is contained in:
Ben Visness 2024-07-04 16:45:37 -05:00
parent b591e5f6bd
commit bcc27b06d9
33 changed files with 605 additions and 230 deletions

33
public/js/countdown.js Normal file
View File

@ -0,0 +1,33 @@
document.addEventListener("DOMContentLoaded", () => {
for (const countdown of document.querySelectorAll(".countdown")) {
const deadline = countdown.getAttribute("data-deadline");
const deadlineDate = new Date(parseInt(deadline, 10) * 1000);
function updateCountdown() {
const remainingMs = deadlineDate.getTime() - new Date().getTime();
const remainingMinutes = remainingMs / 1000 / 60;
const remainingHours = remainingMinutes / 60;
const remainingDays = remainingHours / 24; // no daylight savings transitions during the jam mmkay
let str = "imminently";
if (remainingMinutes < 60) {
str = `in ${Math.ceil(remainingMinutes)} ${
remainingMinutes === 1 ? "minute" : "minutes"
}`;
} else if (remainingHours < 24) {
str = `in ${Math.ceil(remainingHours)} ${
remainingHours === 1 ? "hour" : "hours"
}`;
} else {
str = `in ${Math.ceil(remainingDays)} ${
remainingDays === 1 ? "day" : "days"
}`;
}
countdown.innerText = str;
}
updateCountdown();
setInterval(updateCountdown, 1000 * 60);
}
});

View File

@ -7157,8 +7157,8 @@ code {
:root {
--c1: #fafafa;
--c2: #f3f3f3;
--c3: #cbcbcb;
--c4: #595959;
--c3: #dbdbdb;
--c4: #c1c1c1;
--c-transparent-background: #fffffff3;
--red: #c61d24;
--color: #000;
@ -7167,6 +7167,7 @@ code {
--border-color: var(--c4);
--border-color-focused: #4e55ff;
--border-color-error: #ff3a3a;
--button-color: var(--c3);
--button-color-primary: #ee84ff;
--notice-hiatus-color: #aa7d30;
--notice-dead-color: #b42222;
@ -7272,9 +7273,13 @@ br {
border-style: none;
}
hr {
margin: 0;
border: none;
border-bottom: 1px solid var(--border-color);
}
video {
max-width: 100%;
}
.m-center {
margin-left: auto;
margin-right: auto;
@ -7307,11 +7312,14 @@ hr {
.c-normal {
color: var(--color);
}
.c--inherit {
.c-white {
--color: #fff;
}
.c-inherit {
color: inherit;
}
.c--inherit:hover,
.c--inherit:active {
.c-inherit:hover,
.c-inherit:active {
color: inherit;
}
.bg1 {
@ -7995,23 +8003,6 @@ hr {
.hmn-form textarea {
resize: vertical;
}
.hmn-form button,
.hmn-form input[type=submit] {
color: var(--color);
background-color: var(--c3);
cursor: pointer;
font-weight: 500;
line-height: 1.5rem;
border: none;
}
.hmn-form button.btn-primary,
.hmn-form input[type=submit].btn-primary {
background-color: var(--button-color-primary);
}
.hmn-form button:not(.no-padding),
.hmn-form input[type=submit]:not(.no-padding) {
padding: 0.5rem 1.5rem;
}
.hmn-form label {
font-weight: 600;
}
@ -8041,6 +8032,26 @@ hr {
.hmn-form legend:not(:last-child) {
border-bottom: 1px solid var(--border-color);
}
button,
input[type=submit],
.btn {
color: var(--color);
background-color: var(--button-color);
cursor: pointer;
font-weight: 500;
line-height: 1.5rem;
border: none;
}
button.btn-primary,
input[type=submit].btn-primary,
.btn.btn-primary {
background-color: var(--button-color-primary);
}
button:not(.no-padding),
input[type=submit]:not(.no-padding),
.btn:not(.no-padding) {
padding: 0.5rem 1.5rem;
}
/* src/rawdata/scss/forum.css */
.thread-list-item .latestpost {
@ -8274,9 +8285,11 @@ header.old .submenu > a {
}
}
header {
background-color: var(--c3);
--bg-header: var(--c3);
--border-header: 1px;
background-color: var(--bg-header);
border-bottom-style: solid;
border-bottom-width: 1px;
border-bottom-width: var(--border-header);
}
header .hmn-logo {
font-family: "MohaveHMN", sans-serif;
@ -8298,16 +8311,20 @@ header .header-nav > .root-item > a {
display: block;
padding: var(--spacing-3);
}
header .root-item {
position: relative;
}
header .submenu {
display: flex;
flex-direction: column;
position: absolute;
z-index: 100;
min-width: 8rem;
background-color: var(--c3);
background-color: var(--bg-header);
border-style: solid;
border-width: 1px;
border-width: var(--border-header);
border-top-width: 0;
top: 100%;
}
header .submenu > a {
padding: var(--spacing-2) var(--spacing-3);
@ -8325,6 +8342,11 @@ header:not(.clicked) .root-item:not(:hover) > .submenu,
header.clicked .root-item:not(.clicked) > .submenu {
display: none;
}
.header-transparent header {
--bg-header: rgba(0, 0, 0, 0.4);
--border-header: 0;
--color: #fff;
}
/* src/rawdata/scss/icons.css */
@font-face {

Binary file not shown.

After

Width:  |  Height:  |  Size: 814 KiB

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 461 280" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;">
<g id="Layer1">
</g>
<circle cx="56.5" cy="200.5" r="22.5" style="fill:white;"/>
<circle cx="101.5" cy="147.5" r="22.5" style="fill:white;"/>
<circle cx="183.5" cy="188.5" r="22.5" style="fill:white;"/>
<circle cx="183.5" cy="97.5" r="22.5" style="fill:white;"/>
<circle cx="83.5" cy="52.5" r="22.5" style="fill:white;"/>
<path d="M83.948,51.442L101.948,146.442" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:6px;"/>
<path d="M53.713,198.058L98.713,145.058" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:6px;"/>
<path d="M183.59,99.544L103.59,149.544" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:6px;"/>
<path d="M181.645,190.677L100.645,149.677" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:6px;"/>
<g transform="matrix(-3.82857e-16,1,-1,-3.82857e-16,457,-385)">
<path d="M442,41C442,38.24 439.76,36 437,36L426,36C423.24,36 421,38.24 421,41L421,85C421,87.76 423.24,90 426,90L437,90C439.76,90 442,87.76 442,85L442,41Z" style="fill:white;"/>
</g>
<g transform="matrix(-3.82857e-16,1,-1,-3.82857e-16,426,-296)">
<path d="M382,70C382,67.24 379.76,65 377,65L366,65C363.24,65 361,67.24 361,70L361,114C361,116.76 363.24,119 366,119L377,119C379.76,119 382,116.76 382,114L382,70Z" style="fill:white;"/>
</g>
<g transform="matrix(-3.82857e-16,1,-1,-3.82857e-16,486,-356)">
<path d="M442,70C442,67.24 439.76,65 437,65L426,65C423.24,65 421,67.24 421,70L421,159C421,161.76 423.24,164 426,164L437,164C439.76,164 442,161.76 442,159L442,70Z" style="fill:white;"/>
</g>
<g transform="matrix(-3.82857e-16,1,-1,-3.82857e-16,455,-267)">
<path d="M382,99C382,96.24 379.76,94 377,94L366,94C363.24,94 361,96.24 361,99L361,188C361,190.76 363.24,193 366,193L377,193C379.76,193 382,190.76 382,188L382,99Z" style="fill:white;"/>
</g>
<g transform="matrix(-3.82857e-16,1,-1,-3.82857e-16,515,-327)">
<path d="M442,99C442,96.24 439.76,94 437,94L426,94C423.24,94 421,96.24 421,99L421,158C421,160.76 423.24,163 426,163L437,163C439.76,163 442,160.76 442,158L442,99Z" style="fill:white;"/>
</g>
<g transform="matrix(-3.82857e-16,1,-1,-3.82857e-16,484,-238)">
<path d="M382,128C382,125.24 379.76,123 377,123L366,123C363.24,123 361,125.24 361,128L361,187C361,189.76 363.24,192 366,192L377,192C379.76,192 382,189.76 382,187L382,128Z" style="fill:white;"/>
</g>
<g transform="matrix(-3.82857e-16,1,-1,-3.82857e-16,544,-298)">
<path d="M442,128C442,125.24 439.76,123 437,123L426,123C423.24,123 421,125.24 421,128L421,238C421,240.76 423.24,243 426,243L437,243C439.76,243 442,240.76 442,238L442,128Z" style="fill:white;"/>
</g>
<g transform="matrix(-3.82857e-16,1,-1,-3.82857e-16,513,-209)">
<path d="M382,157C382,154.24 379.76,152 377,152L366,152C363.24,152 361,154.24 361,157L361,267C361,269.76 363.24,272 366,272L377,272C379.76,272 382,269.76 382,267L382,157Z" style="fill:white;"/>
</g>
<g transform="matrix(-3.82857e-16,1,-1,-3.82857e-16,573,-269)">
<path d="M442,157C442,154.24 439.76,152 437,152L426,152C423.24,152 421,154.24 421,157L421,187C421,189.76 423.24,192 426,192L437,192C439.76,192 442,189.76 442,187L442,157Z" style="fill:white;"/>
</g>
<g transform="matrix(-3.82857e-16,1,-1,-3.82857e-16,542,-180)">
<path d="M382,186C382,183.24 379.76,181 377,181L366,181C363.24,181 361,183.24 361,186L361,216C361,218.76 363.24,221 366,221L377,221C379.76,221 382,218.76 382,216L382,186Z" style="fill:white;"/>
</g>
<path d="M461,21.739C461,9.741 451.259,0 439.261,0L21.739,0C9.741,0 0,9.741 0,21.739L0,258.261C0,270.259 9.741,280 21.739,280L439.261,280C451.259,280 461,270.259 461,258.261L461,21.739ZM447,21.739L447,258.261C447,262.532 443.532,266 439.261,266C439.261,266 21.739,266 21.739,266C17.468,266 14,262.532 14,258.261L14,21.739C14,17.468 17.468,14 21.739,14L439.261,14C443.532,14 447,17.468 447,21.739Z" style="fill:white;"/>
<g transform="matrix(2.90789,0,0,1.65,-31.7105,-153.4)">
<rect x="14" y="236" width="152" height="20" style="fill:white;"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

View File

@ -64,14 +64,27 @@ var WRJ2023 = Jam{
var LJ2024 = Jam{
Event: Event{
StartTime: time.Date(2024, 3, 15, 17, 0, 0, 0, time.UTC),
EndTime: time.Date(2024, 3, 25, 0, 0, 0, 0, time.UTC),
StartTime: time.Date(2024, 8, 15, 17, 0, 0, 0, time.UTC),
EndTime: time.Date(2024, 8, 25, 0, 0, 0, 0, time.UTC),
},
Name: "Learning Jam 2024",
Slug: "LJ2024",
UrlSlug: "learning-2024",
}
var VJ2024 = Jam{
// Trying looser times this year.
// Start: 6am Seattle / 8am Minneapolis / 1pm UTC / 2pm London / 4pm Jerusalem
// End: 10pm Seattle / 12am Minneapolis / 5am UTC / 6am London / 8am Jerusalem
Event: Event{
StartTime: time.Date(2024, 7, 19, 13, 0, 0, 0, time.UTC),
EndTime: time.Date(2024, 7, 22, 5, 0, 0, 0, time.UTC),
},
Name: "Visibility Jam 2024",
Slug: "VJ2024",
UrlSlug: "visibility-2024",
}
// Conferences
var HMS2022 = Event{
StartTime: time.Date(2022, 11, 16, 0, 0, 0, 0, utils.Must1(time.LoadLocation("America/Los_Angeles"))),
@ -98,7 +111,7 @@ var HMBoston2024 = Event{
EndTime: time.Date(2024, 8, 10, 0, 0, 0, 0, utils.Must1(time.LoadLocation("America/Los_Angeles"))),
}
var AllJams = []Jam{WRJ2021, WRJ2022, VJ2023, WRJ2023, LJ2024}
var AllJams = []Jam{WRJ2021, WRJ2022, VJ2023, WRJ2023, LJ2024, VJ2024}
func CurrentJam() *Jam {
now := time.Now()

View File

@ -119,6 +119,13 @@ func BuildJamGuidelines2024_Learning() string {
return Url("/jam/learning-2024/guidelines", nil)
}
var RegexJamIndex2024_Visibility = regexp.MustCompile("^/jam/visibility-2024$")
func BuildJamIndex2024_Visibility() string {
defer CatchPanic()
return Url("/jam/visibility-2024", nil)
}
var RegexJamSaveTheDate = regexp.MustCompile("^/jam/upcoming$")
func BuildJamSaveTheDate() string {

View File

@ -60,10 +60,15 @@ br {
}
hr {
margin: 0;
border: none;
border-bottom: 1px solid var(--border-color);
}
video {
max-width: 100%;
}
/* Utility */
.m-center {
@ -105,7 +110,11 @@ hr {
color: var(--color);
}
.c--inherit {
.c-white {
--color: #fff;
}
.c-inherit {
color: inherit;
&:hover,

View File

@ -37,24 +37,6 @@
resize: vertical;
}
button,
input[type=submit] {
color: var(--color);
background-color: var(--c3);
cursor: pointer;
font-weight: 500;
line-height: 1.5rem;
border: none;
&.btn-primary {
background-color: var(--button-color-primary);
}
&:not(.no-padding) {
padding: 0.5rem 1.5rem;
}
}
label {
font-weight: 600;
}
@ -89,4 +71,23 @@
border-bottom: 1px solid var(--border-color);
}
}
}
button,
input[type=submit],
.btn {
color: var(--color);
background-color: var(--button-color);
cursor: pointer;
font-weight: 500;
line-height: 1.5rem;
border: none;
&.btn-primary {
background-color: var(--button-color-primary);
}
&:not(.no-padding) {
padding: 0.5rem 1.5rem;
}
}

View File

@ -114,9 +114,12 @@ header.old {
}
header {
background-color: var(--c3);
--bg-header: var(--c3);
--border-header: 1px;
background-color: var(--bg-header);
border-bottom-style: solid;
border-bottom-width: 1px;
border-bottom-width: var(--border-header);
.hmn-logo {
font-family: 'MohaveHMN', sans-serif;
@ -146,16 +149,21 @@ header {
}
}
.root-item {
position: relative;
}
.submenu {
display: flex;
flex-direction: column;
position: absolute;
z-index: 100;
min-width: 8rem;
background-color: var(--c3);
background-color: var(--bg-header);
border-style: solid;
border-width: 1px;
border-width: var(--border-header);
border-top-width: 0;
top: 100%;
>a {
padding: var(--spacing-2) var(--spacing-3);
@ -181,4 +189,12 @@ header {
display: none;
}
}
}
.header-transparent {
header {
--bg-header: rgba(0, 0, 0, 0.4);
--border-header: 0;
--color: #fff;
}
}

View File

@ -26,9 +26,8 @@ $breakpoint-large: screen and (min-width: 60em)
/* TODO(redesign): Probably not the right color for Soft Gray. Check with Jes. */
--c1: #fafafa;
--c2: #f3f3f3;
--c3: #cbcbcb;
/* TODO(redesign): Probably way too dark. Check with Jes. */
--c4: #595959;
--c3: #dbdbdb;
--c4: #c1c1c1;
/* TODO(redesign): Need a --c5. */
--c-transparent-background: #fffffff3;
@ -44,6 +43,7 @@ $breakpoint-large: screen and (min-width: 60em)
--border-color-focused: #4e55ff;
--border-color-error: #ff3a3a;
--button-color: var(--c3);
--button-color-primary: #ee84ff;
/* TODO(redesign): Audit these colors. */

View File

@ -7,7 +7,7 @@
<p>Dive into one of these topics and start learning.</p>
<div class="flex flex-column flex-row-ns g3 mt3 mb4">
<a href="#compilers" class="edu-topic db flex-fair-ns bg2 br3 overflow-hidden c--inherit flex flex-column">
<a href="#compilers" class="edu-topic db flex-fair-ns bg2 br3 overflow-hidden c-inherit flex flex-column">
<img src="{{ static "education/compilers.jpg" }}">
<div class="pa3">
<h2>Compilers</h2>
@ -16,7 +16,7 @@
</div>
</div>
</a>
<a href="#networking" class="edu-topic db flex-fair-ns bg2 br3 overflow-hidden c--inherit flex flex-column">
<a href="#networking" class="edu-topic db flex-fair-ns bg2 br3 overflow-hidden c-inherit flex flex-column">
<img src="{{ static "education/networking.jpg" }}">
<div class="pa3">
<h2>Networking</h2>
@ -25,7 +25,7 @@
</div>
</div>
</a>
<a href="#time" class="edu-topic db flex-fair-ns bg2 br3 overflow-hidden c--inherit flex flex-column">
<a href="#time" class="edu-topic db flex-fair-ns bg2 br3 overflow-hidden c-inherit flex flex-column">
<img src="{{ static "education/time.jpg" }}">
<div class="pa3">
<h2>Time</h2>

View File

@ -1,4 +1,4 @@
<header id="site-header" class="flex flex-row items-center link-normal">
<header id="site-header" class="flex flex-row items-stretch link-normal">
<a href="{{ .Header.HMNHomepageUrl }}" class="hmn-logo flex-shrink-0">
Handmade
</a>

View File

@ -1,4 +1,4 @@
<div class="ph3 pv4 bb b--rich-gray">
<div class="ph3 pv4 bb b--rich-gray post-content">
<h2 class="dib c--theme-gradient-light">What is a Learning Jam?</h2>
<div class="post-content">
<p>

View File

@ -9,9 +9,9 @@
--mask-url: url("{{ static "learningjam2024/presentation.svg" }}");
}
</style>
<div class="ph3 pv4 bb b--rich-gray">
<div class="ph3 pv4 bb b--rich-gray post-content">
<h2 class="dib c--theme-gradient-light">What is a Learning Jam?</h2>
<div class="post-content">
<div>
<p>
The <b class="c--theme-gradient-light">Learning Jam</b> is an opportunity for you to learn something new.
</p>
@ -23,7 +23,7 @@
</p>
</div>
</div>
<div class="ph3 pv4 bb b--rich-gray">
<div class="ph3 pv4 bb b--rich-gray post-content">
<h2 class="mb3 dib c--theme-gradient-light">How to participate</h2>
<div class="flex flex-column g2">
<div class="pa3 flex flex-column flex-row-ns g3 items-center bg--rich-gray">
@ -84,9 +84,9 @@
</div>
</div>
</div>
<div class="ph3 pv4 bb b--rich-gray">
<div class="ph3 pv4 bb b--rich-gray post-content">
<h2 class="dib c--theme-gradient-light">Why?</h2>
<div class="post-content">
<div>
<p>
The Handmade Network's goal is to change the software industry by building back up from new foundations. But in order to do that, we need to understand those foundations.
</p>

View File

@ -0,0 +1,37 @@
<div class="mw-site-narrow m-center tc link-normal c-white c-normal">
<div class="flex flex-column pv4 tc">
<img class="jam-logo m-center" src="{{ static "visjam2024/logo.svg" }}">
<div class="m-center mt3 mt4-ns">
<a class="db" href="{{ .JamUrl }}">
<h1 class="jam-title mb2">Visibility Jam</h1>
</a>
<div class="fw5 f3 mb1">
July 19-21, 2024.
{{ if gt .DaysUntilEnd 0 }}
{{ if eq .DaysUntilStart 0 }}
<span class="fw7">Happening now.</span>
{{ else if eq .DaysUntilStart 1 }}
<span class="fw7">Starting tomorrow.</span>
{{ else }}
<span class="fw7">In {{ .DaysUntilStart }} days.</span>
{{ end }}
{{ end }}
</div>
</div>
{{ if gt .DaysUntilEnd 0 }}
<div class="flex g3 justify-center mt4">
<a href="https://discord.gg/hmn" class="btn">Join the Discord</a>
</div>
{{ end }}
</div>
</div>
<style>
.jam-logo {
width: 26rem;
}
.jam-title {
font-size: 4rem;
font-weight: 700;
}
</style>

View File

@ -0,0 +1,31 @@
<div class="mw7 center link-normal c-white c-normal">
<div class="flex flex-column flex-row-ns justify-center items-center pv4 g3 tc tl-ns">
<img class="jam-logo" src="{{ static "visjam2024/logo.svg" }}">
<div class="flex flex-column justify-between">
<div>
<a class="db small" href="{{ .JamUrl }}">
<h1 class="jam-title">Visibility Jam</h1>
</a>
<div class="fw6 f5 mb3">July 19 - 21, 2024</div>
</div>
<div class="flex items-center g2">
{{ if and (not .SubmittedProject) (gt .DaysUntilEnd 0) }}
<a href="{{ .NewProjectUrl }}" class="btn">Create your project</a>
{{ else }}
<a href="https://discord.gg/hmn" class="btn">Join the Discord</a>
{{ end }}
<a href="{{ .GuidelinesUrl }}" class="flex items-baseline pv2 ph3">Guidelines <div class="dib svgicon f8 ml1">{{ svg "chevron-right" }}</div></a>
</div>
</div>
</div>
</div>
<style>
.jam-logo {
width: 11.6rem;
}
.jam-title {
font-size: 2.25rem;
font-weight: 700;
}
</style>

View File

@ -5,7 +5,7 @@
{{ end }}
{{ define "content" }}
<div class="mw7 center flex flex-column">
<div class="mw7 center flex flex-column post-content">
<div class="ph3 pv4 bb b--rich-gray">
<h2 class="c--theme-gradient-light mb3">Projects</h2>
{{ template "jam_2024_lj_projects.html" .Projects }}
@ -28,4 +28,3 @@
</div>
</div>
{{ end }}

View File

@ -58,7 +58,7 @@
{{ define "after-jam" }}
{{ template "jam_2024_lj_description.html" . }}
<div class="ph3 pv4 bb b--rich-gray">
<div class="ph3 pv4 bb b--rich-gray post-content">
<h2 class="dib c--theme-gradient-light">Recap show</h2>
<p>
Watch the recap show celebrating all the submissions:

View File

@ -0,0 +1,198 @@
{{ template "base-2024.html" . }}
{{ define "extrahead" }}
<script src="{{ static "js/countdown.js" }}"></script>
<style>
:root {
--c-jam-gradient-darker-start: #087d7d;
--c-jam-gradient-darker-end: #002e31;
--jam-gradient-darker: linear-gradient(to bottom right, var(--c-jam-gradient-darker-start), var(--c-jam-gradient-darker-end));
--c-jam-gradient-dark-start: #24e2e2;
--c-jam-gradient-dark-end: #007178;
--jam-gradient-dark: linear-gradient(to bottom right, var(--c-jam-gradient-dark-start), var(--c-jam-gradient-dark-end));
--c-jam-gradient-light-start: #90eeee;
--c-jam-gradient-light-end: #00c8d5;
--jam-gradient-light: linear-gradient(to bottom right, var(--c-jam-gradient-light-start), var(--c-jam-gradient-light-end));
--text-gradient: var(--jam-gradient-darker);
}
@media (prefers-color-scheme: dark) {
:root {
--text-gradient: var(--jam-gradient-light);
}
}
.content-top {
background: var(--jam-gradient-dark);
--link-color: var(--color);
--button-color: transparent;
}
.btn {
border: 1px solid white;
}
.link-bold a {
font-weight: 700;
}
.c--jam-gradient,
.link-gradient a,
.jam-guidelines.jam-emphasized h3 {
color: transparent;
background: var(--text-gradient);
background-clip: text;
-webkit-background-clip: text;
}
.jam-guidelines {
background-color: var(--c3);
}
.jam-guidelines.jam-emphasized {
background-color: var(--c4);
}
.jam-inspiration {
max-height: 34rem;
}
.jam-inspiration .pic {
max-width: 18rem;
}
@media screen and (min-width: 35em) {
.jam-inspiration {
max-height: 42rem;
}
.jam-inspiration .pic {
max-width: 22rem;
}
}
.jam-inspiration .pic .caption {
font-size: 0.75rem;
line-height: 1.2;
padding-top: var(--spacing-1);
}
</style>
{{ end }}
{{ define "content-top" }}
{{ if or (gt .DaysUntilStart 0) (eq .DaysUntilEnd 0) }}
{{ template "jam_2024_vj_bannerbig.html" . }}
{{ else }}
{{ template "jam_2024_vj_bannersmall.html" . }}
{{ end }}
{{ end }}
{{ define "content" }}
<div class="link-bold">
<div class="flex justify-center link-gradient">
<div class="mw-site-narrow">
<div class="ph3 pv4">
<h2 class="dib f3 pb3 c--jam-gradient">What does "visibility" mean?</h2>
<div class="post-content">
<p>Too many things in computing are <b class="c--jam-gradient">invisible</b>.</p>
<p>We run arcane command line tools just to find out what port a program is using. We imagine complicated data structures instead of drawing them out. Bugs linger for years because nobody can see their effects.</p>
<p>Your computer is full of information, but no one has <b class="c--jam-gradient">made it visible</b>.</p>
<p>So for this jam, make it visible. Maybe it's a data structure in your program. Maybe it's some obscure metrics from your operating system. Maybe it's your sleep schedule. Whatever you choose, you have a weekend to make it happen.</p>
</div>
</div>
<hr>
<div class="ph3 pv4">
<h2 class="dib f3 pb3 c--jam-gradient">How to participate</h2>
<div class="flex flex-column g2">
<div class="jam-guidelines pa3 {{ if gt .DaysUntilStart 0 }}jam-emphasized{{ end }}">
<h3 class="f4 mb3">Choose a project.</h3>
<div class="post-content">
<p>Pick something to visualize! You can brainstorm ideas in #wishlist on Discord. You can also use this time to form a team, or choose to work solo.</p>
</div>
</div>
<div class="jam-guidelines pa3 {{ if and (eq .DaysUntilStart 0) (gt .DaysUntilEnd 1) }}jam-emphasized{{ end }}">
<h3 class="f4 mb3">Jam.</h3>
<div class="post-content">
<p>
{{ if and (eq .DaysUntilStart 0) (not .SubmittedProject) }}
<a href="{{ .NewProjectUrl }}" target="_blank">
<b>Create a Handmade Network project.</b>
</a>
{{ else }}
After the jam starts, create a Handmade Network project.
{{ end }}
This project will act as your submission and can be used to share your work in progress.
</p>
<p>Then get started! Share screenshots and videos in #project-showcase on Discord, or directly from your project page.</p>
</div>
</div>
<div class="jam-guidelines pa3">
<h3 class="f4 mb3">Submit your work!</h3>
<div class="post-content">
<p><b>Your Handmade Network project is your submission.</b> Fill out the project description, making sure to explain the goals of the project and what inspired you to visualize it. Include plenty of pictures and videos!</p>
{{ if and (eq .DaysUntilStart 0) (gt .DaysUntilEnd 0) }}
<p>
Submissions close <b><span class="countdown" data-deadline="{{ .EndTimeUnix }}"></span></b>.
</p>
{{ else if eq .DaysUntilEnd 0 }}
<p>
<b>Submissions are now closed.</b>
</p>
{{ end }}
</div>
</div>
</div>
</div>
</div>
</div>
<div class="bg1 pt4 link-gradient">
<div class="mw-site-narrow m-center ph3">
<h2 class="dib pb3 f3 c--jam-gradient">Inspiration</h2>
<div class="post-content">
<p>The following projects are amazing examples of visibility. For more inspiration, check out the #wishlist channel on <a href="https://discord.gg/hmn">Discord</a>.</p>
</div>
</div>
<div class="jam-inspiration flex flex-column flex-wrap g3 ph3 ph4-l pt3 pt4-ns pb4 overflow-x-scroll">
<div class="pic">
<video
preload="metadata" controls
src="https://hmn-assets-2.ams3.cdn.digitaloceanspaces.com/ec99f8e9-4fd4-4d96-a49e-a09287a06e77/rede_demo.mp4"
poster="{{ static "visjam2023/rede.jpg" }}"
></video>
<div class="caption"><a href="https://handmade.network/p/369/rede/">REDE</a> shows you the internal structure of a regex engine as you execute it.</div>
</div>
<div class="pic">
<img src="{{ static "visjam2024/escapeartist.png" }}">
<div class="caption"><a href="https://handmade.network/p/379/escape-artist/">Escape Artist</a> shows all the invisible ASCII escape codes in terminal output.</div>
</div>
<div class="pic">
<img src="{{ static "visjam2023/graphviz.jpeg" }}">
<div class="caption"><a href="https://graphviz.org/">Graphviz</a> can be used to make debug visuals for almost any data structure.</div>
</div>
<div class="pic">
<img src="{{ static "visjam2023/wireshark.jpg" }}">
<div class="caption"><a href="https://www.wireshark.org/">Wireshark</a> exposes all activity on your network devices.</div>
</div>
<div class="pic">
<img src="{{ static "visjam2023/spall.png" }}">
<div class="caption"><a href="https://spall.handmade.network/">Spall</a> allows you to explore your program's execution at terrifying speeds.</div>
</div>
<div class="pic">
<img src="{{ static "visjam2023/v8.png" }}">
<div class="caption">Bugs can be very obvious when you render out the data. (Example: a random number generator.)</div>
</div>
<div class="pic">
<img src="{{ static "visjam2023/vmmap.png" }}">
<div class="caption"><a href="https://learn.microsoft.com/en-us/sysinternals/downloads/vmmap">vmmap</a> allows you to see exactly how your address space is allocated.</div>
</div>
<div class="pic">
<img src="{{ static "visjam2024/npmgraph.png" }}">
<div class="caption"><a href="https://npmgraph.js.org/">npmgraph</a> shows you the full dependency graph of a JavaScript package, including its size on disk.</div>
</div>
</div>
</div>
</div>
{{ end }}

View File

@ -16,6 +16,11 @@
<p>Since 2020, we have been running programming jams to encourage community members to explore new ideas and start projects. You can view all the past submissions and results here.</p>
<div class="jam-grid g3">
<a href="{{ .VJ2024Url }}">
<div class="overflow-hidden flex">
<img src="{{ static "visjam2024/2024VJTwitterCard.png" }}">
</div>
</a>
<a href="{{ .LJ2024Url }}">
<div class="overflow-hidden flex">
<img src="{{ static "learningjam2024/2024LJTwitterCard.png" }}">

View File

@ -60,8 +60,11 @@
{{ template "extrahead" . }}
</head>
<body class="flex flex-column">
{{ template "header-2024.html" . }}
<body class="flex flex-column {{ join " " .BodyClasses }}">
<div class="content-top">
{{ template "header-2024.html" . }}
{{ block "content-top" . }}{{ end }}
</div>
<!-- TODO: Notices -->
<div class="c-white flex-grow-1">
{{ block "content" . }}{{ end }}

View File

@ -1,7 +1,7 @@
{{/*
This is a copy-paste from base.html because we want to preserve the unique
style of this page no matter what future changes we make to the base.
*/}}
*/}}
<!DOCTYPE html>
<html lang="en-US" {{ if .OpenGraphItems }} prefix="og: http://ogp.me/ns#"{{ end }}>
<head>

View File

@ -1,19 +0,0 @@
{{ template "base.html" . }}
{{ define "content" }}
<div class="post-content mw7 ph3 ph0-ns m-center">
<h1>{{ .Role.Name }}</h1>
{{ block "role content" . }}{{ end }}
<div class="mt4">
<h2>Other roles</h2>
<div class="flex flex-column flex-row-ns g3">
{{ range .OtherRoles }}
<div class="flex-fair">
{{ template "role_card.html" . }}
</div>
{{ end }}
</div>
</div>
</div>
{{ end }}

View File

@ -60,7 +60,7 @@
</div>
<div class="input-group">
<label>Short Description*</label>
<label>Summary*</label>
<textarea
required
id="description" name="shortdesc"
@ -69,7 +69,7 @@
>
{{- .ProjectSettings.Blurb -}}
</textarea>
<div class="f6">Plaintext only. No links or markdown.</div>
<div class="f6">Plain text only. No links or markdown.</div>
</div>
<div class="input-group">
@ -184,6 +184,11 @@
</fieldset>
{{ end }}
{{/*
TODO(redesign): Two problems with the link editor:
1. It doesn't start out with a valid "empty" state, i.e. one set of empty fields
2. When it is in its empty state, it still renders one link in the live preview.
*/}}
{{ template "link_editor.html" .ProjectSettings.LinksJSON }}
{{ if and .Editing .User.IsStaff }}

View File

@ -1,43 +0,0 @@
{{ template "role_base.html" . }}
{{ define "role content" }}
<p>
We need to tell the outside world what we're all about. We want to convince programmers and users alike that software is bad and needs to be better. We want to do more than just complain - we want to advocate for better software development practices and better software, period.
</p>
<p>
To do this, we want someone with great communication skills who can communicate our vision to the outside world. As Advocacy Lead, you can shape the public face of the Handmade Network and Handmade Software Foundation and push for real change in the world of software.
</p>
<p>
To give you an idea of what we're looking for, here are some of our advocacy ideas:
</p>
<ul>
<li>
Take popular software that people hate (e.g. Adobe Premiere or New Reddit), reverse engineer it to find what's going on, and publish the results to put pressure on those companies to do better
</li>
<li>
Take an old computer and walk it through years of software updates, cataloguing the bloat and slowdown along the way
</li>
<li>
Organize the community to report bugs or build times and make a report detailing how much our software is dragging us down
</li>
</ul>
<p>
With your help, we can show people that there is a better way to build software. <strong>If this excites you, please get in touch!</strong> See the <b>How to apply</b> section below.
</p>
<h2>Commitment</h2>
<p>
We would like to produce a few key reports per year - big pieces that can make a splash on Hacker News or other tech media. In addition, we'd like to maintain a consistent public presence through e.g. social media.
</p>
<p>
How you achieve this is up to you - this position is flexible and many details are up in the air. Overall, we would expect ongoing communication with the leadership team and commitment to publishing the major pieces described above.
</p>
<h2>How to apply</h2>
<p>
Send us an email at <a href="mailto:team@handmade.network">team@handmade.network</a> or contact @bvisness on Discord. Please share with us:
</p>
<p>
Like all Handmade Network positions, this is a volunteer role. Thank you for your interest!
</p>
{{ end }}

View File

@ -1,46 +0,0 @@
{{ template "role_base.html" . }}
{{ define "role content" }}
<p>
We are looking for someone with visual design and UX skills to set the visual direction for everything the Network and Foundation does. Whether that's making promotional art for events or making infographics for education, we need a consistent visual voice and appealing presentation.
</p>
<p>
Here are some examples of what you might do:
<ul>
<li>
Redesign our <a target="_blank" href="https://handmade.network/projects">project gallery</a> to better highlight personal work without burying our flagship projects
</li>
<li>
Design layouts, logos, key art, and <a target="_blank" href="https://nextcloud.handmade.network/s/gMJ3Eb8e7wD3CkN">assets</a> for events like the <a target="_blank" href="https://handmade.network/jam/2022">Wheel Reinvention Jam</a>
</li>
<li>
Create cover art and infographics for <a target="_blank" href="https://handmade.network/education/http">educational articles</a>
</li>
<li>
Redesign this very website, and design reusable styles and UI components
</li>
<li>
Make sure our home page engages prospective community members and gets people excited about our mission
</li>
</ul>
</p>
<p>
<strong>If any of this excites you, please get in touch!</strong> See the <b>How to apply</b> section below.
</p>
<h2>Commitment</h2>
<p>
Our design needs fluctuate over time, but we always have a long list of things to improve.
</p>
<p>
At a minimum, we would expect you to be on call for design needs and to produce mockups or assets within a week of the request. (Timing may vary depending on the scope of work requested.) However, we would be thrilled with any other design work you choose to contribute - we want our stuff to look and feel good!
</p>
<h2>How to apply</h2>
<p>
Send us an email at <a href="mailto:team@handmade.network">team@handmade.network</a> or contact @bvisness on Discord. Please share a portfolio or other examples of your work.
</p>
<p>
Like all Handmade Network positions, this is a volunteer role. Thank you for your interest!
</p>
{{ end }}

View File

@ -1,45 +0,0 @@
{{ template "role_base.html" . }}
{{ define "role content" }}
<p>
<a target="_blank" href="https://handmade.network/education">Education</a> is one of the Foundation's flagship initiatives. We want to provide serious educational material for programmers that goes deeper than anything else on the internet, and equips programmers to learn directly from real sources.
</p>
<p>
We are looking for someone to head up our educational activities. This includes:
<ul>
<li>
Seeking out experts in various domains and working with them to produce educational content
</li>
<li>
Choosing educational topics and <a target="_blank" href="{{ static "roles/network_brainstorming.png" }}">structuring our curriculum</a>
</li>
<li>
Organizing beta tests and gathering community feedback on educational content
</li>
</ul>
</p>
<p>
<strong>If this sounds interesting to you, please get in touch!</strong> See the <b>How to apply</b> section below.
</p>
<h2>Commitment</h2>
<p>
As one of our flagship initiatives, our educational content needs ongoing attention. You would be expected to spend at least a few hours a week on Handmade education and to stay in frequent communication with external contributors. You would also be expected to lead any education-related meetings and to be the point of contact for any education-related inquiries.
</p>
<p>
In general, we want new and updated educational material to be released on a regular basis, and it would be your job to make that happen!
</p>
<h2>How to apply</h2>
<p>
Send us an email at <a href="mailto:team@handmade.network">team@handmade.network</a> or contact @bvisness on Discord. Please share with us:
<ul>
<li>Any background you have in education</li>
<li>Your personal domains of expertise in programming</li>
<li>What topics you'd love to see us cover!</li>
</ul>
</p>
<p>
Like all Handmade Network positions, this is a volunteer role. Thank you for your interest!
</p>
{{ end }}

View File

@ -8,7 +8,7 @@ import (
"io"
"io/fs"
"net/http"
"path/filepath"
"path"
"regexp"
"sort"
"strings"
@ -144,7 +144,7 @@ func GetImg(file string) []byte {
imgs = utils.DirFS("src/templates/img")
} else {
imgs = Imgs
file = filepath.Join("img/", file)
file = path.Join("img/", file)
}
img, err := imgs.Open(file)
@ -161,7 +161,7 @@ func ListImgsDir(dir string) []fs.DirEntry {
imgs = utils.DirFS("src/templates/img").(fs.ReadDirFS)
} else {
imgs = Imgs
dir = filepath.Join("img/", dir)
dir = path.Join("img/", dir)
}
entries, err := imgs.ReadDir(dir)

View File

@ -118,3 +118,8 @@ func Assert[T comparable](value T, msg ...any) {
panic(finalMsg)
}
}
// Because sometimes you just want a pointer to the thing.
func P[T any](value T) *T {
return &value
}

View File

@ -28,6 +28,7 @@ func JamsIndex(c *RequestContext) ResponseData {
VJ2023Url string
WRJ2023Url string
LJ2024Url string
VJ2024Url string
}
res.MustWriteTemplate("jams_index.html", TemplateData{
@ -39,6 +40,7 @@ func JamsIndex(c *RequestContext) ResponseData {
VJ2023Url: hmnurl.BuildJamIndex2023_Visibility(),
WRJ2023Url: hmnurl.BuildJamIndex2023(),
LJ2024Url: hmnurl.BuildJamIndex2024_Learning(),
VJ2024Url: hmnurl.BuildJamIndex2024_Visibility(),
}, c.Perf)
return res
}
@ -76,6 +78,98 @@ func JamSaveTheDate(c *RequestContext) ResponseData {
return res
}
type JamBaseDataVJ2024 struct {
DaysUntilStart, DaysUntilEnd int
StartTimeUnix, EndTimeUnix int64
JamUrl string
JamFeedUrl string
NewProjectUrl string
GuidelinesUrl string
SubmittedProject *templates.Project
}
func JamIndex2024_Visibility(c *RequestContext) ResponseData {
var res ResponseData
jam := hmndata.VJ2024
jamBaseData, err := getVJ2024BaseData(c)
if err != nil {
return c.ErrorResponse(http.StatusInternalServerError, err)
}
baseData := getBaseDataAutocrumb(c, jam.Name)
baseData.OpenGraphItems = []templates.OpenGraphItem{
{Property: "og:title", Value: "Visibility Jam"},
{Property: "og:site_name", Value: "Handmade Network"},
{Property: "og:type", Value: "website"},
{Property: "og:image", Value: hmnurl.BuildPublic("visjam2024/opengraph.png", true)},
{Property: "og:description", Value: "See things in a new way. July 19 - 21."},
{Property: "og:url", Value: hmnurl.BuildJamIndex2024_Visibility()},
{Name: "twitter:card", Value: "summary_large_image"},
{Name: "twitter:image", Value: hmnurl.BuildPublic("visjam2024/TwitterCard.png", true)},
}
baseData.BodyClasses = append(baseData.BodyClasses, "header-transparent")
type JamPageData struct {
templates.BaseData
JamBaseDataVJ2024
JamProjects []templates.Project
}
jamProjects, err := hmndata.FetchProjects(c, c.Conn, c.CurrentUser, hmndata.ProjectsQuery{
JamSlugs: []string{jam.Slug},
})
if err != nil {
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch jam projects for current user"))
}
pageProjects := make([]templates.Project, 0, len(jamProjects))
for _, p := range jamProjects {
pageProjects = append(pageProjects, templates.ProjectAndStuffToTemplate(&p))
}
res.MustWriteTemplate("jam_2024_vj_index.html", JamPageData{
BaseData: baseData,
JamBaseDataVJ2024: jamBaseData,
JamProjects: pageProjects,
}, c.Perf)
return res
}
func getVJ2024BaseData(c *RequestContext) (JamBaseDataVJ2024, error) {
jam := hmndata.VJ2024
var submittedProject *templates.Project
if c.CurrentUser != nil {
projects, err := hmndata.FetchProjects(c, c.Conn, c.CurrentUser, hmndata.ProjectsQuery{
OwnerIDs: []int{c.CurrentUser.ID},
JamSlugs: []string{jam.Slug},
Limit: 1,
})
if err != nil {
return JamBaseDataVJ2024{}, oops.New(err, "failed to fetch jam projects for current user")
}
if len(projects) > 0 {
submittedProject = utils.P(templates.ProjectAndStuffToTemplate(&projects[0]))
}
}
return JamBaseDataVJ2024{
DaysUntilStart: daysUntil(jam.StartTime),
DaysUntilEnd: daysUntil(jam.EndTime),
StartTimeUnix: jam.StartTime.Unix(),
EndTimeUnix: jam.EndTime.Unix(),
JamUrl: hmnurl.BuildJamIndex2024_Visibility(),
// JamFeedUrl: hmnurl.BuildJamFeed2024_Visibility(),
NewProjectUrl: hmnurl.BuildProjectNewJam(),
// GuidelinesUrl: hmnurl.BuildJamGuidelines2024_Visibility(),
SubmittedProject: submittedProject,
}, nil
}
func JamIndex2024_Learning(c *RequestContext) ResponseData {
var res ResponseData

View File

@ -121,6 +121,7 @@ func NewWebsiteRoutes(conn *pgxpool.Pool) http.Handler {
hmnOnly.GET(hmnurl.RegexJamIndex2024_Learning, JamIndex2024_Learning)
hmnOnly.GET(hmnurl.RegexJamFeed2024_Learning, JamFeed2024_Learning)
hmnOnly.GET(hmnurl.RegexJamGuidelines2024_Learning, JamGuidelines2024_Learning)
hmnOnly.GET(hmnurl.RegexJamIndex2024_Visibility, JamIndex2024_Visibility)
hmnOnly.GET(hmnurl.RegexJamSaveTheDate, JamSaveTheDate)
hmnOnly.GET(hmnurl.RegexTimeMachine, TimeMachine)

View File

@ -64,7 +64,7 @@
- [ ] Resolve TODO(redesign) comments
- [ ] Audit all project lifecycles on HMN - probably remove "complete", replace with stuff like "alpha", "beta", maybe other stuff that makes sense for other types of projects.
- [ ] Afterward, re-enable badges
- [ ] Add logout / settings menu on avatar
- [x] Add logout / settings menu on avatar
- [ ] Delete all the scss :D
stack!