~singpolyma/post-part

033b92e46df2951558a8af7e37a8a934bb89bcae — Stephen Paul Weber 3 years ago 36308ad
Move interactive back to home
7 files changed, 342 insertions(+), 789 deletions(-)

D Home.purs
R interactive/Interactive.purs => Interactive.purs
M Makefile
M index.scss
M index.slim
D interactive/index.scss
D interactive/index.slim
D Home.purs => Home.purs +0 -66
@@ 1,66 0,0 @@
-- Full source may be found at: https://git.singpolyma.net/post-part
-- Copyright 2020 Stephen Paul Weber <singpolyma.net>
--
-- Permission to use, copy, modify, and/or distribute this software for any
-- purpose with or without fee is hereby granted, provided that the above
-- copyright notice and this permission notice appear in all copies.
--
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-- SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
-- RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
-- CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-- CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

module Home where

import Prelude
import Effect
import Effect.Class
import Data.Maybe
import Data.Either
import Data.Array
import Debug.Trace
import Data.Traversable
import Math as Math
import Data.Tuple (Tuple(..))
import Data.Int as Int
import Effect.Timer as Timer
import Effect.Ref as Ref
import Effect.Aff (Aff, Canceler(..), makeAff, launchAff_)
import Web.DOM.ParentNode (querySelector, querySelectorAll, QuerySelector(..), ParentNode)
import Web.DOM.Document as DOMDocument
import Web.HTML.HTMLDocument as HTMLDocument
import Web.HTML.HTMLElement as HTMLElement
import Web.HTML.HTMLMediaElement as HTMLMediaElement
import Web.HTML (window, HTMLElement, HTMLMediaElement)
import Web.HTML.Event.EventTypes (load)
import Web.UIEvent.MouseEvent as MouseEvent
import Web.UIEvent.MouseEvent.EventTypes (mousemove, mouseout, click)
import Web.HTML.Window as Window
import Web.DOM.Element as Element
import Web.DOM.NodeList as NodeList
import Web.DOM.DOMTokenList as DOMTokenList
import Web.Event.EventTarget (addEventListener, eventListener)
import Partial.Unsafe (unsafePartial)
import Web.CSSOM.ElementCSSInlineStyle as Style
import Web.CSSOM.CSSStyleDeclaration as Style

data TickTock = Tick | Tock

tick Tick = Tock
tick Tock = Tick

main = unsafePartial $ do
  win <- window
  doc <- HTMLDocument.toParentNode <$> Window.document win
  tickTockRef <- Ref.new Tick
  Timer.setInterval 7500 $ do
    Just slideshow <- (HTMLElement.fromElement =<< _) <$>
      querySelector (QuerySelector "#slideshow img") doc
    slideshowStyle <- Style.style (Style.fromHTMLElement slideshow)
    tickTock <- Ref.modify tick tickTockRef
    case tickTock of
      Tick -> Style.setProperty slideshowStyle "opacity" "0"
      Tock -> Style.setProperty slideshowStyle "opacity" "1"

R interactive/Interactive.purs => Interactive.purs +0 -0
M Makefile => Makefile +7 -17
@@ 3,7 3,6 @@
all: \
	index.html index.css index.js \
	QVtq/index.html \
	interactive/index.html interactive/index.css interactive/index.js \
	window/NsD0/index.html \
	window/Vfqb/index.html \
	window/m39N/index.html \


@@ 13,26 12,17 @@ all: \
entr:
	( echo Makefile; find -name '*.slim' -o -name '*.scss' -o -name '*.purs' -o -name '*.dhall'; find assets/ ) | entr make

index.html: index.slim assets/paras.txt
	/usr/share/doc/ruby-slim/examples/slimrb -p index.slim > $@

index.css: index.scss _font-face.scss
	sassc -Mt expanded index.scss $@

index.js: Home.purs packages.dhall spago.dhall
	spago bundle-app -u-c --main Home --to index.js

QVtq/index.html: QVtq/index.slim assets/paras.txt assets/img/map.svg
	/usr/share/doc/ruby-slim/examples/slimrb -p QVtq/index.slim > $@

interactive/index.html: interactive/index.slim assets/paras.txt assets/audio/transcripts.txt
	/usr/share/doc/ruby-slim/examples/slimrb -p interactive/index.slim > $@
index.html: index.slim assets/paras.txt assets/audio/transcripts.txt
	/usr/share/doc/ruby-slim/examples/slimrb -p index.slim > $@

interactive/index.css: interactive/index.scss _font-face.scss
	sassc -Mt expanded interactive/index.scss $@
index.css: index.scss _font-face.scss
	sassc -Mt expanded index.scss $@

interactive/index.js: interactive/Interactive.purs packages.dhall spago.dhall
	spago bundle-app -u-c --main Interactive --to interactive/index.js
index.js: Interactive.purs packages.dhall spago.dhall
	spago bundle-app -u-c --main Interactive --to index.js

credits/index.html: credits/index.slim assets/paras.txt
	/usr/share/doc/ruby-slim/examples/slimrb -p credits/index.slim > $@


@@ 58,4 48,4 @@ window.js: Window.purs packages.dhall spago.dhall
	spago bundle-app -u-c --main Window --to window.js

clean:
	$(RM) -r window.js index.html index.css index.js interactive/index.html interactive/index.css interactive/index.js output/ window/ credits/index.html QVtq/index.html
	$(RM) -r window.js index.html index.css index.js output/ window/ credits/index.html QVtq/index.html

M index.scss => index.scss +270 -166
@@ 38,241 38,345 @@ html, body {
	}
}

body > a[href="#wallpaper"] {
	&, &:visited, {
		position: fixed;
		top: 2em;
		left: 2em;
		color: $fg-alt;
		text-decoration: none;
	}

	&:before {
		content: "﹀";
		background: $fg;
		border-radius: 100%;
		display: inline-block;
		width: 1.5em;
		height: 1.5em;
		line-height: 2.1em;
		vertical-align: middle;
		margin-right: 0.5em;
	}
}

#bgmusic {
	display: none;
	position: fixed;
	bottom: 0;
	left: 0;
	width: 100%;
}

body > hgroup {
	position: relative;
	margin-bottom: 3em;
	font-family: druk, sans-serif;
	margin-bottom: 60vh;

	h1 {
		display: block;
		width: 100%;
		height: 50vh;
		margin-top: 2em;
		margin-top: 20vh;
		background: url(assets/img/POST-PART-TITLE.png) no-repeat center;
		background-size: contain;
		color: rgba(0, 0, 0, 0);
	}
}

a, a:visited, a:link {
	color: #0bf;
	&:hover {
		color: #fb0;
	&:after {
		content: "scroll";
		display: block;
		margin-top: 20vh;
		font-family: cardo, sans-serif;
		font-size: 0.9em;
	}

	&[href^="https://gofund.me"],
	&[href^="https://www.eventbrite.ca"],
	&[href="assets/map.pdf"] {
		font-family: druk, sans-serif;
		display: inline-block;
		text-decoration: none;
		background: $fg-alt;
		color: $fg;
		font-size: 2em;
		padding: 0.5em;
		margin: 1em;
	&:before {
		content: "";
		display: block;
		width: 1px;
		height: 10vh;
		background: $fg;
		position: absolute;
		bottom: calc(-10vh - 1em);
		left: 50%;
	}
}

	&[href^="https://www.eventbrite.ca"] {
		color: $fg-alt;
		background: $fg;
h1, h2 { font-weight: normal; }

body > p {
	max-width: $column-width;
	margin: 1em auto;
	font-size: 1.5em;

	&:nth-of-type(1) {
		font-family: druk, sans-serif;
		font-size: 1.75em;
		background: url(assets/img/BREAST-PATTERN.png) no-repeat center top;
		background-size: contain;
		padding-top: 25%;
		margin-bottom: 17em;
	}

	&[href="assets/map.pdf"] {
		color: $bg;
		background: transparent;
		border: 0.2em solid $fg-alt;
		font-size: 1em;
	&:nth-of-type(2) {
// TODO: what should happen on small screens where text won't fit in circle?
		position: relative;
		z-index: 0;

		&:hover {
			background: $fg-alt;
			border-color: $bg;
		span {
			position: relative;
			display: block;
			background: $fg;
			color: $fg-alt;
			border-radius: 100%;
			height: $column-width;
			padding: 3em;
			padding-top: calc(#{$column-width/2} - 5em);

			&:before {
				display: block;
				background: url(assets/img/WOMAN-OVAL.png) no-repeat top;
				background-size: contain;
				height: #{$column-width/2};
				width: 10vw;
				content: "";
				position: absolute;
				top: -2vw;
				left: -3vw;
				z-index: -1;
				transform: scaleX(-1);
			}

			&:after {
				display: block;
				background: url(assets/img/WOMAN-OVAL.png) no-repeat center;
				background-size: contain;
				height: #{$column-width/3};
				width: 10vw;
				content: "";
				position: absolute;
				bottom: 0;
				right: 0;
			}
		}
	}
}

h1, h2 {
	font-weight: normal;
	font-family: druk, sans-serif;
}
	&:nth-of-type(3) {
		background: url(assets/img/DETAIL-HAIR.png) no-repeat center top;
		background-size: 30%;
		padding-top: 45%;
		margin-top: 30vh;
		font-size: 1.5em;
	}

p {
	max-width: $column-width;
	margin: 5em auto;
	font-size: 1.5em;
}
	&:nth-of-type(5) {
		background: url(assets/img/WOMAN-MIRRORED.png) no-repeat center top;
		background-size: 60%;
		padding-top: 50%;
		margin-top: 20vh;
		font-family: druk, sans-serif;
		font-size: 1.75em;
	}

img {
	max-width: 90%;
}
	&:nth-of-type(6) {
		background: url(assets/img/DETAIL-LEGS.png) no-repeat center top;
		background-size: 50%;
		padding-top: 30%;
		margin-top: 30vh;
		margin-bottom: 7em;
	}

#slideshow {
	position: relative;
	overflow: hidden;
	margin-bottom: 5em;
	&:nth-of-type(7) {
		margin-bottom: 7em;
	}

	img:first-of-type {
		position: absolute;
		opacity: 1;
		transition: opacity 5s;
	&.fin {
		margin-top: 7em;
		font-size: 2em;
		font-family: druk, sans-serif;
		color: $fg-alt;
	}
}

	small {
body > small {
	display: block;
	margin-top: 20vh;

	&:after {
		content: "";
		display: block;
		width: 1px;
		height: 30vh;
		background: $fg;
		margin: auto;
		margin-top: 3em;
	}
}

body > section {
#story {
	background: $fg;
	color: $fg-alt;
	padding-top: 5em;
	padding-bottom: 5em;
	margin-top: 50vh;
	margin-bottom: 35vh;

	small {
		display: block;
		margin: auto;
	> h1 {
		background: $bg;
		color: $fg-alt;
		font-family: druk, sans-serif;
		font-size: 3em;
		padding-bottom: 0.75em;
	}

	p {
		font-size: 1.25em;
		max-width: $column-width;
		margin: 1em auto;
		background: url(assets/img/DETAIL-WOMB.png) no-repeat center top;
		background-size: 30%;
		padding-top: 23%;
		margin-top: 10vh;
		padding-bottom: 35vh;
	}
}

#location {
	ol { counter-reset: ol; }
#wallpaper {
	position: relative;
	background: url(assets/img/BROCADE.png);
	background-size: 50%;
	img {
		pointer-events: none;
		width: 100%;
	}

	li {
		list-style-type: none;
		margin: 2em 0;
		font-size: 1.5em;
	figure {
		background: black;
		border-radius: 2em;
		padding: 3em;
		text-align: left;
		h1 {
			font-size: 1.25em;
			font-weight: normal;
			font-family: druk, sans-serif;
			color: $fg-alt;

		&:before {
			display: inline-block;
			counter-increment: ol;
			content: counter(ol);
			background: $bg;
			color: $fg;
			border-radius: 100%;
			width: 1.6em;
			height: 1.6em;
			margin-right: 0.3em;
			&:before { content: "“"; }
		}
		p:after { content: "”"; }
		&:last-of-type p:after { content: ""; }

		img {
			max-width: $column-width/2;
			max-height: 7em;
		cite {
			display: block;
			margin: 1em auto;
			font-style: normal;
			color: $fg-alt;
			font-size: 0.9em;
			margin-top: 1.5em;
		}
	}

	> p > a > img {
		display: block;
		margin: 0.5em auto;
	}
	&.js figure {
		opacity: 0;
		transition: opacity 0.75s;
		pointer-events: none;
		position: absolute;
		width: 45%;

	&:before {
		content: "";
		display: block;
		margin: auto;
		background: url("assets/img/womb-pattern.svg") no-repeat center center;
		background-size: contain;
		height: $column-width/2;
		max-width: $column-width;
	}
		&:nth-of-type(1) {
			top: 1em;
			right: 1em;
		}

	&:after {
		content: "";
		display: block;
		margin: auto;
		background: url("assets/img/WOMAN-MIRRORED.png") no-repeat center center;
		background-size: contain;
		height: $column-width/2;
		max-width: $column-width;
	}
}
		&:nth-of-type(2) {
			top: 1em;
			left: 1em;
		}

a[href="interactive"], a[href="../../interactive"], a[href="credits"], a[href="../"] {
	display: block;
	font-size: 1.5em;
	margin-bottom: 5em;
}
		&:nth-of-type(3) {
			top: 33%;
			right: 1em;
		}

#sponsors, #window-sponsors, .sponsor {
	li { font-size: 1.5em; }
		&:nth-of-type(4) {
			top: 33%;
			left: 1em;
		}

	> p:first-of-type {
		margin-top: 0;
		margin-bottom: 2em;
		&:nth-of-type(5) {
			bottom: 1em;
			right: 1em;
		}

		audio { display: none; }
	}
}

	img {
		display: inline-block;
		margin: 2em;
		max-width: $column-width/4.5;
		vertical-align: middle;
#credits {
	position: relative;
	margin: auto;
	max-width: $column-width;
// TODO: what should happen on small screens where text won't fit in circle?
	background: $fg;
	color: $fg-alt;
	border-radius: 100%;
	padding: 3em;
	padding-top: calc(#{$column-width/2} - 4em);
	margin-top: calc(15vw + 30vh);
	height: $column-width;

		&[src$="breastfeeding-buddies.png"],
		&[src$="ambrosia.png"] {
			max-width: $column-width/1.5;
		}
	h1 {
		font-family: druk, sans-serif;
	}
}

.sponsor img {
	margin-top: -3em;
	margin-bottom: 5em;
}
	p { font-size: 1.5em; }

body > small {
	display: block;
	margin-bottom: 2em;
}
	&:before {
		display: block;
		background: url(assets/img/WOMAN-ARMS.png) no-repeat center;
		background-size: contain;
		width: 16vw;
		height: 40vw;
		content: "";

#window-sponsors {
	color: $bg;
		position: absolute;
		top: -15vw;
		left: calc(50% - 8vw);
	}
}

section#locations {
	background: $bg;
	color: $fg;
footer {
	background: $fg;
	color: $fg-alt;
	padding-top: 2em;
	padding-bottom: 0.5in;
	overflow: hidden;

	section { font-size: 1.5em; }
}
	p {
		max-width: $column-width;
		margin: 3em auto;

#locations {
	a[href="../../"] {
		&, &:visited {
			display: block;
			margin: auto;
			background: $fg;
			color: $fg-alt;
			height: 5em;
			width: 5em;
			line-height: 5em;
			text-align: center;
			border-radius: 100%;
			text-decoration: none;
			margin-bottom: 3em;
		&:nth-of-type(1) {
			margin-top: 7em;
		}

		&:hover {
			background: darken($fg, 10%);
		&:last-of-type {
			margin-bottom: 7em;
		}
	}

	a img {
		background: white;
		border-radius: 100%;
	address {
		display: inline-block;
		font-style: normal;
		color: $bg;
	}

	&:after {
		content: "";
		display: block;
		margin: 3em auto;
		background: url("assets/img/WOMAN-MIRRORED.png") no-repeat center center;
		background-size: contain;
		height: $column-width/2;
		max-width: $column-width;
	}
}
	img {
		display: inline-block;
		vertical-align: middle;
		max-height: 5em;

.instagram {
	font-family: druk, sans-serif;
		&[alt="Ontario Arts Council"] {
			padding-left: 0.5in;
			padding-right: 0.5in;
		}
	}
}

M index.slim => index.slim +65 -56
@@ 14,6 14,7 @@
  CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

- paras = File.read('assets/paras.txt').lines
- transcripts = File.read('assets/audio/transcripts.txt').lines.map { |x| x.chomp.split('/') }
doctype html
html
	head


@@ 23,71 24,79 @@ html
		script type="text/javascript" src="index.js"
		base target="_blank"
	body
		a href="#wallpaper" target="_self" skip to wallpaper
		audio#bgmusic controls="controls" autoplay="autoplay" loop="loop"
			source src="assets/audio/bg.opus" type="audio/ogg; codecs=opus"
			source src="assets/audio/bg.mp3" type="audio/mpeg"
			a href="assets/audio/bg.opus" background music

		hgroup
			h1 Post-Part
			h2 The Yellow Wallpaper

		p= paras[0]
		p: span= paras[1]
		p= paras[2]

		section#story
			h1 The Story
			p= paras[3]

		p= paras[4]

		p= paras[5]
		small Click to activate the wallpaper

		#wallpaper
			img src="assets/img/WALLPAPER-HIDDEN.png" alt="Wallpaper"

			- (1..5).each do |n|
				figure
					figcaption
						h1= transcripts[n - 1].shift
						p
							- transcripts[n - 1].each_with_index do |t, i|
								- if t[0] == '*'
									cite= t
								- else
									- if i.positive?
									  br
									= t
					audio controls="controls"
						source src="assets/audio/#{n}.opus" type="audio/ogg; codecs=opus"
						source src="assets/audio/#{n}.mp3" type="audio/mpeg"
						a href="assets/audio/#{n}.opus" listen

		section#credits
			h1= paras[6]
			p= paras[7]

		p= paras[8]
		p= paras[9]
		p= paras[13]

		#slideshow
			img src="assets/img/wallpaper-normal.png" alt="Wallpaper in natural light"
			img src="assets/img/wallpaper-blue.jpg" alt="Wallpaper in blue light"
			small
				' Photograph by
				a href="http://www.melaniegordon.com" Melanie Gordon

		p== paras[14]
		a.sponsor href="https://cotdwaterlooregion.org/": img alt="Climb Out of the Darkness" src="assets/img/cotd.jpg"
		a.sponsor href="https://www.cafka.org/cafka21/everything-not-saved-will-be-lost": img alt="CAFKA" src="assets/img/cafka.jpg"
		p= paras[10]

		section#location
			h1 Exhibition Location &amp; Partners

			a href="assets/map.pdf" Printable Exhibition Map

			markdown:
				1. [![Abrosia Corner Bakery](assets/img/ambrosia.png)](https://ambrosiacornerbakery.com/)
				1. [![Encompass Health](assets/img/encompass.png)](https://www.encompasshealth.ca/)
				1. ![Benton Street Parking Garage, at the corer of Charles Street](assets/img/CityofKitchener.png)
				1. [![Schneider Haus National Historic Site](assets/img/schneiderhaus.png)](https://www.schneiderhaus.ca)

			small * we acknowledge that the Post-Part exhibition will be situated on land that is the traditional home of the Neutral, Haudenosaunee (Ho-deh-no-show-nee) and Anishinaabe (Ah-nish-nah-bay) Peoples. We extend our respect to all First Nations, Métis and Inuit peoples for their past and present contributions to this land.

			p.instagram
				== paras[15]
				a href="https://www.instagram.com/post_part/"
					img src="assets/img/INSTAGRAM.png" alt="Instagram"

		section#sponsors
			h1 Thank you to the following sponsors for their support of the Kitchener exhibition of Post-Part

			a href="https://awesomewithoutborders.org/": img alt="Awesome Without Borders" src="assets/img/AWB.png"
			a href="https://www.shorecentre.ca/": img alt="SHORE Centre" src="assets/img/shore.png"
			a href="https://doula.sette.ca": img alt="Lisette Weber, Postpartum Doula" src="assets/img/lisette.png"
			img alt="City of Kitchener" src="assets/img/CityofKitchener.png"
			a href="https://www.canadianperinatalmentalhealthtrainings.com/"
				img alt="Canadian Perinatal Mental Health Trainings" src="assets/img/cpmt.png"
			a href="https://www.breastfeedingbuddies.com/"
				img alt="Breastfeeding Buddies" src="assets/img/breastfeeding-buddies.png"
			a href="https://mboa.dev"
				img alt="MBOA" src="assets/img/mboa.svg"

			section
				h1 Further Thanks

				ul
					li Laverne and Ella Brubacher
					li: a href="https://www.estherslevinsky.com/" Esther Slevinsky
					li Elanor Waslander &amp; Carole Culhane
					li: a href="https://www.reeveandcompany.com" Reeve and Company Printing
					li Franco Pang

		section
			a href="credits" Credits
		p.fin Thank you

		footer
			markdown:
				This website was designed by [Nat Janin](https://natjanin.com/) and
				[Catherine Mellinger](http://www.cargocollective.com/catherinemellinger),
				developed by [Stephen Paul Weber](https://git.singpolyma.net/post-part).

				Music: Frédéric Chopin, Prelude in B minor, Op 28, No. 6 —
				performed on piano by [Marketa Ornova](http://www.marketaornova.com/).
				Used with permission from artist.

				Music originally adapted for [Cutting Paper](https://vimeo.com/250175258)
				by Jennifer Dallas and Melanie Gordon.

			p= paras[11]
			p= paras[12]

			a href="https://www.instagram.com/longernin_collective/"
				img src="assets/img/INSTAGRAM.png" alt="Instagram"

			img src="assets/img/OAC.svg" alt="Ontario Arts Council"

			a href="https://workmanarts.com/"
				img src="assets/img/WORKMAN_ARTS.png" alt="Workman Arts"

D interactive/index.scss => interactive/index.scss +0 -382
@@ 1,382 0,0 @@
/*
* Full source may be found at: https://git.singpolyma.net/post-part
* Copyright 2020 Stephen Paul Weber <singpolyma.net>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

@import "../font-face";

@include font-face(cardo, "../assets/fonts/cardo-v12-latin-regular");
@include font-face(druk, "../assets/fonts/Druk Wide Web Medium Regular", null, null, woff2 woff ttf otf);

$bg: black;
$fg: #fff9e4;
$fg-alt: #887a00;
$column-width: 50vw;

html, body {
	margin: 0;
	font-family: cardo, sans-serif;
	background: $bg;
	color: $fg;
	text-align: center;
	line-height: 1.7;

  * {
		box-sizing: border-box;
	}
}

body > a[href="#wallpaper"] {
	&, &:visited, {
		position: fixed;
		top: 2em;
		left: 2em;
		color: $fg-alt;
		text-decoration: none;
	}

	&:before {
		content: "﹀";
		background: $fg;
		border-radius: 100%;
		display: inline-block;
		width: 1.5em;
		height: 1.5em;
		line-height: 2.1em;
		vertical-align: middle;
		margin-right: 0.5em;
	}
}

#bgmusic {
	display: none;
	position: fixed;
	bottom: 0;
	left: 0;
	width: 100%;
}

body > hgroup {
	position: relative;
	font-family: druk, sans-serif;
	margin-bottom: 60vh;

	h1 {
		display: block;
		width: 100%;
		height: 50vh;
		margin-top: 20vh;
		background: url(../assets/img/POST-PART-TITLE.png) no-repeat center;
		background-size: contain;
		color: rgba(0, 0, 0, 0);
	}

	&:after {
		content: "scroll";
		display: block;
		margin-top: 20vh;
		font-family: cardo, sans-serif;
		font-size: 0.9em;
	}

	&:before {
		content: "";
		display: block;
		width: 1px;
		height: 10vh;
		background: $fg;
		position: absolute;
		bottom: calc(-10vh - 1em);
		left: 50%;
	}
}

h1, h2 { font-weight: normal; }

body > p {
	max-width: $column-width;
	margin: 1em auto;
	font-size: 1.5em;

	&:nth-of-type(1) {
		font-family: druk, sans-serif;
		font-size: 1.75em;
		background: url(../assets/img/BREAST-PATTERN.png) no-repeat center top;
		background-size: contain;
		padding-top: 25%;
		margin-bottom: 17em;
	}

	&:nth-of-type(2) {
// TODO: what should happen on small screens where text won't fit in circle?
		position: relative;
		z-index: 0;

		span {
			position: relative;
			display: block;
			background: $fg;
			color: $fg-alt;
			border-radius: 100%;
			height: $column-width;
			padding: 3em;
			padding-top: calc(#{$column-width/2} - 5em);

			&:before {
				display: block;
				background: url(../assets/img/WOMAN-OVAL.png) no-repeat top;
				background-size: contain;
				height: #{$column-width/2};
				width: 10vw;
				content: "";
				position: absolute;
				top: -2vw;
				left: -3vw;
				z-index: -1;
				transform: scaleX(-1);
			}

			&:after {
				display: block;
				background: url(../assets/img/WOMAN-OVAL.png) no-repeat center;
				background-size: contain;
				height: #{$column-width/3};
				width: 10vw;
				content: "";
				position: absolute;
				bottom: 0;
				right: 0;
			}
		}
	}

	&:nth-of-type(3) {
		background: url(../assets/img/DETAIL-HAIR.png) no-repeat center top;
		background-size: 30%;
		padding-top: 45%;
		margin-top: 30vh;
		font-size: 1.5em;
	}

	&:nth-of-type(5) {
		background: url(../assets/img/WOMAN-MIRRORED.png) no-repeat center top;
		background-size: 60%;
		padding-top: 50%;
		margin-top: 20vh;
		font-family: druk, sans-serif;
		font-size: 1.75em;
	}

	&:nth-of-type(6) {
		background: url(../assets/img/DETAIL-LEGS.png) no-repeat center top;
		background-size: 50%;
		padding-top: 30%;
		margin-top: 30vh;
		margin-bottom: 7em;
	}

	&:nth-of-type(7) {
		margin-bottom: 7em;
	}

	&.fin {
		margin-top: 7em;
		font-size: 2em;
		font-family: druk, sans-serif;
		color: $fg-alt;
	}
}

body > small {
	display: block;
	margin-top: 20vh;

	&:after {
		content: "";
		display: block;
		width: 1px;
		height: 30vh;
		background: $fg;
		margin: auto;
		margin-top: 3em;
	}
}

#story {
	background: $fg;
	color: $fg-alt;
	margin-top: 50vh;
	margin-bottom: 35vh;

	> h1 {
		background: $bg;
		color: $fg-alt;
		font-family: druk, sans-serif;
		font-size: 3em;
		padding-bottom: 0.75em;
	}

	p {
		font-size: 1.25em;
		max-width: $column-width;
		margin: 1em auto;
		background: url(../assets/img/DETAIL-WOMB.png) no-repeat center top;
		background-size: 30%;
		padding-top: 23%;
		margin-top: 10vh;
		padding-bottom: 35vh;
	}
}

#wallpaper {
	position: relative;
	background: url(../assets/img/BROCADE.png);
	background-size: 50%;
	img {
		pointer-events: none;
		width: 100%;
	}

	figure {
		background: black;
		border-radius: 2em;
		padding: 3em;
		text-align: left;
		h1 {
			font-size: 1.25em;
			font-weight: normal;
			font-family: druk, sans-serif;
			color: $fg-alt;

			&:before { content: "“"; }
		}
		p:after { content: "”"; }
		&:last-of-type p:after { content: ""; }

		cite {
			display: block;
			font-style: normal;
			color: $fg-alt;
			font-size: 0.9em;
			margin-top: 1.5em;
		}
	}

	&.js figure {
		opacity: 0;
		transition: opacity 0.75s;
		pointer-events: none;
		position: absolute;
		width: 45%;

		&:nth-of-type(1) {
			top: 1em;
			right: 1em;
		}

		&:nth-of-type(2) {
			top: 1em;
			left: 1em;
		}

		&:nth-of-type(3) {
			top: 33%;
			right: 1em;
		}

		&:nth-of-type(4) {
			top: 33%;
			left: 1em;
		}

		&:nth-of-type(5) {
			bottom: 1em;
			right: 1em;
		}

		audio { display: none; }
	}
}

#credits {
	position: relative;
	margin: auto;
	max-width: $column-width;
// TODO: what should happen on small screens where text won't fit in circle?
	background: $fg;
	color: $fg-alt;
	border-radius: 100%;
	padding: 3em;
	padding-top: calc(#{$column-width/2} - 4em);
	margin-top: calc(15vw + 30vh);
	height: $column-width;

	h1 {
		font-family: druk, sans-serif;
	}

	p { font-size: 1.5em; }

	&:before {
		display: block;
		background: url(../assets/img/WOMAN-ARMS.png) no-repeat center;
		background-size: contain;
		width: 16vw;
		height: 40vw;
		content: "";

		position: absolute;
		top: -15vw;
		left: calc(50% - 8vw);
	}
}

footer {
	background: $fg;
	color: $fg-alt;
	padding-top: 2em;
	padding-bottom: 0.5in;
	overflow: hidden;

	p {
		max-width: $column-width;
		margin: 3em auto;

		&:nth-of-type(1) {
			margin-top: 7em;
		}

		&:last-of-type {
			margin-bottom: 7em;
		}
	}

	address {
		display: inline-block;
		font-style: normal;
		color: $bg;
	}

	img {
		display: inline-block;
		vertical-align: middle;
		max-height: 5em;

		&[alt="Ontario Arts Council"] {
			padding-left: 0.5in;
			padding-right: 0.5in;
		}
	}
}

D interactive/index.slim => interactive/index.slim +0 -102
@@ 1,102 0,0 @@
/ Full source may be found at: https://git.singpolyma.net/post-part
  Copyright 2020 Stephen Paul Weber <singpolyma.net>

  Permission to use, copy, modify, and/or distribute this software for any
  purpose with or without fee is hereby granted, provided that the above
  copyright notice and this permission notice appear in all copies.

  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
  CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

- paras = File.read('assets/paras.txt').lines
- transcripts = File.read('assets/audio/transcripts.txt').lines.map { |x| x.chomp.split('/') }
doctype html
html
	head
		meta charset="utf-8"
		title Post-Part
		link type="text/css" rel="stylesheet" href="index.css"
		script type="text/javascript" src="index.js"
		base target="_blank"
	body
		a href="#wallpaper" target="_self" skip to wallpaper
		audio#bgmusic controls="controls" autoplay="autoplay" loop="loop"
			source src="../assets/audio/bg.opus" type="audio/ogg; codecs=opus"
			source src="../assets/audio/bg.mp3" type="audio/mpeg"
			a href="../assets/audio/bg.opus" background music

		hgroup
			h1 Post-Part
			h2 The Yellow Wallpaper

		p= paras[0]
		p: span= paras[1]
		p= paras[2]

		section#story
			h1 The Story
			p= paras[3]

		p= paras[4]

		p= paras[5]
		small Click to activate the wallpaper

		#wallpaper
			img src="../assets/img/WALLPAPER-HIDDEN.png" alt="Wallpaper"

			- (1..5).each do |n|
				figure
					figcaption
						h1= transcripts[n - 1].shift
						p
							- transcripts[n - 1].each_with_index do |t, i|
								- if t[0] == '*'
									cite= t
								- else
									- if i.positive?
									  br
									= t
					audio controls="controls"
						source src="../assets/audio/#{n}.opus" type="audio/ogg; codecs=opus"
						source src="../assets/audio/#{n}.mp3" type="audio/mpeg"
						a href="../assets/audio/#{n}.opus" listen

		section#credits
			h1= paras[6]
			p= paras[7]

		p= paras[8]
		p= paras[9]
		p= paras[10]

		p.fin Thank you

		footer
			markdown:
				This website was designed by [Nat Janin](https://natjanin.com/) and
				[Catherine Mellinger](http://www.cargocollective.com/catherinemellinger),
				developed by [Stephen Paul Weber](https://git.singpolyma.net/post-part).

				Music: Frédéric Chopin, Prelude in B minor, Op 28, No. 6 —
				performed on piano by [Marketa Ornova](http://www.marketaornova.com/).
				Used with permission from artist.

				Music originally adapted for [Cutting Paper](https://vimeo.com/250175258)
				by Jennifer Dallas and Melanie Gordon.

			p= paras[11]
			p= paras[12]

			a href="https://www.instagram.com/longernin_collective/"
				img src="../assets/img/INSTAGRAM.png" alt="Instagram"

			img src="../assets/img/OAC.svg" alt="Ontario Arts Council"

			a href="https://workmanarts.com/"
				img src="../assets/img/WORKMAN_ARTS.png" alt="Workman Arts"