/* ==========================================================================
   Atelier — main stylesheet
   Design frame is 1600px wide. Every measurement is written in design pixels
   and multiplied by --u, so the layout scales with the viewport and stays
   proportionally identical to the Figma file (capped at 1920px).
   ========================================================================== */

:root {
	--bg: #f5f9eb;
	--ink: #202020;
	--ink-soft: #242424;
	--red: #b9000e;
	--beige: #f3f3e9;
	--white: #f6f4f0;
	--line: rgba(32, 32, 32, .5);

	/* --vw is the real content width in px (set inline in <head>), because 100vw
	   may or may not include the scrollbar depending on the browser. */
	--u: calc(min(var(--vw, 100vw), 1920px) / 1600);
	--m: calc(50 * var(--u));
	--gap: calc(30 * var(--u));
	--r: calc(50 * var(--u));
	--fs: max(13px, calc(18 * var(--u)));
	--header-h: calc(91 * var(--u));

	--font-sans: "Helvetica Neue", Helvetica, "Nimbus Sans", Arial, sans-serif;
	--font-display: "Cervo Neue", "Barlow Condensed", "Arial Narrow", sans-serif;
	--font-ui: "Inter", "Helvetica Neue", Helvetica, Arial, sans-serif;

	--ease: cubic-bezier(.2, .7, .1, 1);
	--ease-heavy: cubic-bezier(.77, 0, .18, 1);
}

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	overflow-y: scroll;
	scrollbar-gutter: stable;
	-webkit-text-size-adjust: 100%;
	text-size-adjust: 100%;
}

body {
	margin: 0;
	/* Horizontal clipping lives here, not on .site: on screens wider than the
	   1920px content box the tossed photographs may stick out into the margin. */
	overflow-x: clip;
	background: var(--bg);
	color: var(--ink);
	font-family: var(--font-sans);
	font-size: var(--fs);
	font-weight: 400;
	line-height: calc(28 / 18);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

/* While the menu is open the scrollbar gutter stays (no layout jump) and is
   painted red, so the red panel runs to the very edge of the window. */
html.menu-open {
	overflow: hidden;
	background: var(--red);
}

img {
	display: block;
	max-width: 100%;
}

a {
	color: inherit;
	text-decoration: none;
}

button {
	font: inherit;
	color: inherit;
}

h1,
h2,
h3,
p,
figure,
ul,
dl,
dd {
	margin: 0;
}

ul {
	padding: 0;
	list-style: none;
}

address {
	font-style: normal;
}

:focus-visible {
	outline: 2px solid var(--red);
	outline-offset: 4px;
}

.skip-link {
	position: fixed;
	left: var(--m);
	top: -100px;
	z-index: 400;
	padding: 10px 16px;
	background: var(--red);
	color: var(--beige);
}

.skip-link:focus {
	top: 10px;
}

/* --------------------------------------------------------------------------
   Page shell: paper texture + window shadows sit under all content
   -------------------------------------------------------------------------- */

.site {
	position: relative;
	max-width: 1920px;
	margin: 0 auto;
}

.site-bg {
	position: absolute;
	inset: 0;
	left: calc(50% - 50vw);
	right: calc(50% - 50vw);
	z-index: 1;
	opacity: .5;
	background: url("../img/texture-paper.webp") top center / 100% auto repeat-y;
	pointer-events: none;
}

.page-shadows {
	position: absolute;
	inset: 0;
	z-index: 0;
	overflow: hidden;
	pointer-events: none;
}

.shadow {
	position: absolute;
	translate: 0 calc(var(--py, 0px) + var(--kh-extra, 0px));
	will-change: translate;
}

.shadow img {
	width: 100%;
	height: auto;
	animation: sway 13s ease-in-out infinite alternate;
}

.shadow--1,
.shadow--4 {
	right: 0;
	width: calc(495 * var(--u));
}

.shadow--1 { top: calc(1193 * var(--u)); }
.shadow--4 { top: calc(5405 * var(--u)); }

.shadow--2 {
	left: 0;
	top: calc(2232 * var(--u));
	width: calc(767 * var(--u));
}

.shadow--3 {
	right: 0;
	top: calc(3980 * var(--u));
	width: calc(544 * var(--u));
}

.shadow--1 img,
.shadow--3 img,
.shadow--4 img {
	--sx: 16;
	transform-origin: right center;
}

.shadow--2 img {
	--sx: -16;
	transform-origin: left center;
	animation-duration: 17s;
}

.shadow--3 img { animation-duration: 15s; animation-delay: -6s; }
.shadow--4 img { animation-delay: -3s; }

/* Sunlight through a window: the shadow drifts and breathes very slightly. */
@keyframes sway {
	from {
		transform: translate3d(0, 0, 0) skewX(0deg);
		opacity: 1;
	}
	to {
		transform: translate3d(calc(var(--sx) * var(--u)), calc(10 * var(--u)), 0) skewX(-1.6deg);
		opacity: .72;
	}
}

.site-main,
.site-footer {
	position: relative;
	z-index: 2;
}

/* Film grain over everything — barely there. */
.grain {
	position: fixed;
	inset: -120px;
	z-index: 300;
	pointer-events: none;
	opacity: .035;
	background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
	animation: grain 1s steps(1) infinite;
}

@keyframes grain {
	0% { transform: translate(0, 0); }
	20% { transform: translate(-46px, 28px); }
	40% { transform: translate(34px, -52px); }
	60% { transform: translate(-28px, -34px); }
	80% { transform: translate(52px, 40px); }
	100% { transform: translate(0, 0); }
}

/* --------------------------------------------------------------------------
   Shared pieces
   -------------------------------------------------------------------------- */

.label {
	text-transform: uppercase;
}

.display {
	font-family: var(--font-display);
	font-weight: 600;
	font-size: calc(80 * var(--u));
	line-height: calc(90 / 80);
	color: var(--red);
	text-transform: uppercase;
}

.display .ln {
	display: block;
	overflow: hidden;
}

.display .ln > span {
	display: block;
}

/* Double-ruled link: hairline + heavy rule, like a ledger total. */
.link {
	position: relative;
	display: inline-block;
	padding-bottom: calc(8 * var(--u));
	line-height: calc(28 / 18);
	white-space: nowrap;
}

.link::before,
.link::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	background: currentColor;
}

.link::before {
	bottom: calc(5 * var(--u));
	height: 1px;
}

.link::after {
	bottom: 0;
	height: max(2px, calc(3 * var(--u)));
	transform-origin: left center;
}

.link:hover::after,
.link:focus-visible::after {
	animation: redraw .7s var(--ease-heavy);
}

@keyframes redraw {
	0% { transform: scaleX(1); transform-origin: right center; }
	45% { transform: scaleX(0); transform-origin: right center; }
	46% { transform: scaleX(0); transform-origin: left center; }
	100% { transform: scaleX(1); transform-origin: left center; }
}

/* Image frames: two opposite corners rounded. */
.r-a { border-radius: var(--r) 0 var(--r) 0; }
.r-b { border-radius: 0 var(--r) 0 var(--r); }

.ph {
	position: relative;
	overflow: hidden;
}

.ph__clip {
	position: absolute;
	inset: 0;
}

.ph > img,
.ph__clip > img {
	position: absolute;
	left: var(--x, 0);
	top: var(--y, 0);
	width: var(--w, 100%);
	height: var(--h, 100%);
	max-width: none;
	object-fit: cover;
}

/* Caption under an image: label left, number right, hairline below. */
.cap {
	position: relative;
	display: flex;
	justify-content: space-between;
	gap: calc(20 * var(--u));
	height: calc(42 * var(--u));
	margin-top: calc(20 * var(--u));
	line-height: normal;
	text-transform: uppercase;
}

.cap::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 1px;
	background: var(--line);
	transform-origin: left center;
}

/* Blurred "shadow of the signage" text. */
.ghost {
	position: absolute;
	z-index: 1;
	font-size: calc(25 * var(--u));
	line-height: calc(28 / 25);
	color: rgba(0, 0, 0, .1);
	filter: blur(calc(2 * var(--u)));
	white-space: nowrap;
	text-transform: uppercase;
	pointer-events: none;
	user-select: none;
	translate: var(--dx, 0px) 0;
	will-change: translate;
}

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */

.site-header {
	position: fixed;
	inset: 0 0 auto 0;
	z-index: 50;
	height: var(--header-h);
	transition: background-color .5s ease;
}

.admin-bar .site-header { top: 32px; }

.site-header.is-scrolled {
	background: rgba(245, 249, 235, .94);
	-webkit-backdrop-filter: blur(10px);
	backdrop-filter: blur(10px);
}

.site-header__inner {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: space-between;
	height: 100%;
	max-width: 1920px;
	margin: 0 auto;
	padding: 0 var(--m);
}

.site-header__inner::after {
	content: "";
	position: absolute;
	left: var(--m);
	right: var(--m);
	bottom: 0;
	height: 1px;
	background: var(--line);
	transform-origin: left center;
}

.site-header__logo {
	display: block;
	width: calc(133 * var(--u));
	margin-top: calc(-5 * var(--u));
	transition: opacity .5s ease, transform .7s var(--ease);
}

.site-header__logo img {
	width: 100%;
	height: auto;
}

/* On the homepage the big wordmark is the logo until you scroll past it. */
.home .site-header:not(.is-scrolled) .site-header__logo {
	opacity: 0;
	transform: translateY(calc(8 * var(--u)));
	pointer-events: none;
}

.site-header__right {
	display: flex;
	align-items: center;
	margin-left: auto;
}

.site-nav ul {
	display: flex;
	gap: calc(50 * var(--u));
}

.site-nav a {
	position: relative;
	display: block;
	line-height: normal;
	text-transform: uppercase;
	white-space: nowrap;
}

.site-nav a::before,
.site-nav a::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	background: var(--ink);
	transform: scaleX(0);
	transform-origin: left center;
	transition: transform .55s var(--ease-heavy);
}

.site-nav a::before {
	top: calc(100% + 6 * var(--u));
	height: 1px;
}

.site-nav a::after {
	top: calc(100% + 9 * var(--u));
	height: max(2px, calc(3 * var(--u)));
	transition-delay: .06s;
}

.site-nav a:hover::before,
.site-nav a:hover::after,
.site-nav a:focus-visible::before,
.site-nav a:focus-visible::after,
.site-nav .is-current a::before,
.site-nav .is-current a::after,
.home .site-header:not(.is-scrolled) .site-nav .is-cta a::before,
.home .site-header:not(.is-scrolled) .site-nav .is-cta a::after {
	transform: none;
}

.menu-toggle {
	position: relative;
	width: calc(21 * var(--u));
	height: calc(16 * var(--u));
	min-width: 16px;
	min-height: 12px;
	margin-left: calc(50 * var(--u));
	padding: 0;
	border: 0;
	background: none;
	cursor: pointer;
}

.menu-toggle::before {
	content: "";
	position: absolute;
	inset: -14px;
}

.menu-toggle span {
	position: absolute;
	right: 0;
	width: 100%;
	height: max(2px, calc(2 * var(--u)));
	background: var(--ink);
	transition: width .45s var(--ease);
}

.menu-toggle span:nth-child(1) { top: 0; }
.menu-toggle span:nth-child(2) { top: calc(50% - max(1px, calc(1 * var(--u)))); width: 81%; }
.menu-toggle span:nth-child(3) { bottom: 0; }

.menu-toggle:hover span:nth-child(1),
.menu-toggle:hover span:nth-child(3) { width: 81%; }
.menu-toggle:hover span:nth-child(2) { width: 100%; }

/* --------------------------------------------------------------------------
   Full-screen menu: a red door with its own double rule
   -------------------------------------------------------------------------- */

.site-menu {
	--k: min(var(--u), calc(100vh / 903));
	position: fixed;
	inset: 0;
	z-index: 100;
	visibility: hidden;
	transition: visibility 0s linear .9s;
}

.site-menu.is-open {
	visibility: visible;
	transition-delay: 0s;
}

.site-menu__paper {
	position: absolute;
	inset: 0;
	background: var(--bg);
	clip-path: inset(0 0 0 100%);
	transition: clip-path .7s var(--ease-heavy) .1s;
}

.site-menu__paper::before {
	content: "";
	position: absolute;
	inset: 0;
	opacity: .5;
	background: url("../img/texture-paper.webp") top center / 100% auto repeat-y;
}

.site-menu.is-open .site-menu__paper {
	clip-path: inset(0);
	transition: clip-path 1s var(--ease-heavy);
}

.site-menu__logo {
	position: absolute;
	left: var(--m);
	top: calc(50 * var(--u));
	width: calc(133 * var(--u));
	opacity: 0;
	transition: opacity .3s ease;
}

.site-menu__logo img {
	width: 100%;
	height: auto;
}

.site-menu.is-open .site-menu__logo {
	opacity: 1;
	transition: opacity .8s ease .7s;
}

.site-menu__stripe {
	position: absolute;
	top: 0;
	bottom: 0;
	right: calc(474 * var(--u));
	width: calc(10 * var(--u));
	background: var(--red);
	transform: translateX(calc(486 * var(--u)));
	transition: transform .7s var(--ease-heavy);
}

.site-menu__panel {
	position: absolute;
	top: 0;
	bottom: 0;
	right: 0;
	display: flex;
	flex-direction: column;
	width: calc(464 * var(--u));
	padding: calc(118 * var(--k)) calc(50 * var(--u)) calc(50 * var(--k));
	overflow-y: auto;
	background: var(--red);
	color: var(--beige);
	transform: translateX(101%);
	transition: transform .7s var(--ease-heavy) .05s;
}

.site-menu.is-open .site-menu__panel {
	transform: none;
	transition: transform .9s var(--ease-heavy);
}

.site-menu.is-open .site-menu__stripe {
	transform: none;
	transition: transform .9s var(--ease-heavy) .09s;
}

.site-menu__close {
	position: absolute;
	top: calc(13 * var(--k));
	right: calc(47 * var(--u));
	padding: 0;
	border: 0;
	background: none;
	font-family: var(--font-display);
	font-weight: 600;
	font-size: calc(50 * var(--k));
	line-height: calc(90 / 50);
	cursor: pointer;
	transition: rotate .6s var(--ease);
}

.site-menu__close:hover {
	rotate: 90deg;
}

.site-menu__list li {
	overflow: hidden;
}

.site-menu__list a {
	display: inline-flex;
	align-items: flex-start;
	gap: calc(10 * var(--u));
	font-family: var(--font-display);
	font-weight: 600;
	font-size: calc(50 * var(--k));
	line-height: calc(90 / 50);
	text-transform: uppercase;
	white-space: nowrap;
	transform: translateY(105%);
	transition: transform .4s var(--ease), opacity .4s ease;
}

.site-menu__list .is-long a {
	font-size: calc(42 * var(--k));
	line-height: calc(90 / 42);
}

.site-menu.is-open .site-menu__list a {
	transform: none;
	transition: transform 1s var(--ease) calc(.38s + var(--i, 0) * .07s), opacity .4s ease;
}

.site-menu__label {
	transition: translate .6s var(--ease);
}

.site-menu__num {
	margin-top: calc(24 * var(--k));
	font-family: var(--font-sans);
	font-weight: 400;
	font-size: var(--fs);
	line-height: normal;
}

.site-menu__list:hover a {
	opacity: .5;
}

.site-menu__list a:hover,
.site-menu__list a:focus-visible {
	opacity: 1;
}

.site-menu__list a:hover .site-menu__label {
	translate: calc(14 * var(--u)) 0;
}

.site-menu__insta {
	align-self: flex-end;
	width: calc(31 * var(--u));
	min-width: 22px;
	margin-top: auto;
	margin-right: calc(20 * var(--u));
	opacity: 0;
	transition: opacity .3s ease;
}

.site-menu__insta img {
	width: 100%;
	height: auto;
}

.site-menu.is-open .site-menu__insta {
	opacity: 1;
	transition: opacity .8s ease 1s;
}

/* --------------------------------------------------------------------------
   Home — hero
   -------------------------------------------------------------------------- */

.hero {
	padding-top: calc(144 * var(--u));
}

.hero__top {
	position: relative;
	height: calc(174 * var(--u));
	margin: 0 var(--m);
}

.hero__logo {
	width: calc(817 * var(--u));
}

.hero__logo img {
	width: 100%;
	height: auto;
}

.hero__insta {
	position: absolute;
	right: 0;
	top: 0;
	width: calc(31 * var(--u));
	min-width: 22px;
}

.hero__insta img {
	width: 100%;
	height: auto;
}

.hero__place {
	position: absolute;
	right: 0;
	top: calc(124 * var(--u));
	text-align: right;
	text-transform: uppercase;
}

.hero__media {
	position: relative;
	height: calc(758 * var(--u));
	margin: calc(49 * var(--u)) var(--m) 0;
	overflow: hidden;
}

.hero__media .ph__clip {
	overflow: hidden;
}

.hero__img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transform: translate3d(0, var(--hy, 0px), 0) scale(var(--hs, 1));
	will-change: transform;
}

.hero__cta {
	position: absolute;
	left: var(--m);
	bottom: calc(50 * var(--u));
	color: var(--white);
}

.hero__caption {
	margin: calc(20 * var(--u)) var(--m) 0;
}

/* --------------------------------------------------------------------------
   Home — welcome trio (also used for Instagram)
   -------------------------------------------------------------------------- */

.welcome {
	position: relative;
	margin-top: calc(196 * var(--u));
	padding: 0 var(--m);
}

.trio {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--gap);
	align-items: start;
	margin-top: calc(35 * var(--u));
}

.trio > :nth-child(1) { margin-top: calc(73 * var(--u)); }
.trio > :nth-child(3) { margin-top: calc(135 * var(--u)); }

.card {
	display: block;
	translate: 0 var(--py, 0px);
	will-change: translate;
}

.card__media {
	aspect-ratio: 1 / 1;
}

.card:hover .ph img,
.room:hover .ph img {
	scale: 1.045;
}

.ghost--welcome {
	top: calc(780 * var(--u));
	right: calc(1214 * var(--u));
}

/* --------------------------------------------------------------------------
   Home — where afternoons turn into long nights
   -------------------------------------------------------------------------- */

.afternoons {
	position: relative;
	height: calc(856 * var(--u));
	margin-top: calc(149 * var(--u));
}

.afternoons__body {
	position: absolute;
	left: 50%;
	top: calc(121 * var(--u));
	width: calc(786 * var(--u));
	margin-left: calc(-393 * var(--u));
	text-align: center;
}

.afternoons__text {
	width: calc(695 * var(--u));
	max-width: 100%;
	margin: calc(36 * var(--u)) auto 0;
}

.afternoons__body .link {
	margin-top: calc(43 * var(--u));
}

/* Photographs tossed on the table: image + caption rotate as one piece. */
.tilt {
	position: absolute;
	top: calc(77.5 * var(--u));
	width: calc(735 * var(--u));
}

.tilt--l {
	left: calc(-441.5 * var(--u));
	rotate: -15deg;
}

.tilt--r {
	right: calc(-441.5 * var(--u));
	rotate: 15deg;
}

.tilt__inner {
	rotate: var(--rot, 0deg);
	will-change: rotate;
}

.tilt__media {
	width: calc(353 * var(--u));
	height: calc(537 * var(--u));
	border-radius: 0 var(--r) 0 0;
}

.tilt--l .tilt__media {
	margin-left: auto;
}

/* The caption is as wide as the photograph, not the figure. */
.tilt__inner > .cap {
	width: calc(353 * var(--u));
}

.tilt--l .tilt__inner > .cap {
	margin-left: auto;
}

.tilt--r .tilt__media {
	transform: scaleX(-1);
}

/* --------------------------------------------------------------------------
   Home — sleepover upstairs
   -------------------------------------------------------------------------- */

.sleepover {
	position: relative;
	padding: 0 var(--m);
}

.sleepover__head {
	display: flex;
	justify-content: space-between;
	align-items: flex-start;
	height: calc(253 * var(--u));
}

.sleepover__head .display {
	margin-top: calc(-13 * var(--u));
	text-align: right;
}

.sleepover__link {
	position: absolute;
	right: var(--m);
	top: calc(253 * var(--u));
}

.rooms {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--gap);
	align-items: start;
}

.rooms > :nth-child(2) {
	margin-top: calc(100 * var(--u));
}

.room {
	display: block;
	translate: 0 var(--py, 0px);
	will-change: translate;
}

.room__frame {
	position: relative;
}

.room__media {
	aspect-ratio: 735 / 575;
}

.badge {
	position: absolute;
	right: calc(10 * var(--u));
	bottom: calc(10 * var(--u));
	display: grid;
	place-items: center;
	width: calc(176 * var(--u));
	height: calc(66 * var(--u));
	border: max(1.5px, calc(2 * var(--u))) solid var(--red);
	border-radius: calc(52 * var(--u)) 0 calc(52 * var(--u)) 0;
}

.badge span {
	display: grid;
	place-items: center;
	width: calc(166 * var(--u));
	height: calc(58 * var(--u));
	border-radius: var(--r) 0 var(--r) 0;
	background: var(--red);
	color: var(--beige);
	text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   Home — more than words
   -------------------------------------------------------------------------- */

.coffee {
	position: relative;
	margin-top: calc(181 * var(--u));
}

.coffee .display {
	margin: 0 var(--m);
}

.coffee__media {
	height: calc(857 * var(--u));
	margin-top: calc(35 * var(--u));
}

.ghost--coffee {
	top: calc(414 * var(--u));
	right: calc(986 * var(--u));
}

/* --------------------------------------------------------------------------
   Home — upcoming events
   -------------------------------------------------------------------------- */

.events {
	position: relative;
	margin-top: calc(200 * var(--u));
	padding: 0 var(--m);
}

.events > .display {
	text-align: right;
}

.events__list {
	margin-top: calc(55 * var(--u));
}

.event {
	display: grid;
	grid-template-columns: calc(429 * var(--u)) 1fr;
	min-height: calc(104 * var(--u));
}

.event__title {
	align-self: center;
	margin-top: calc(-20 * var(--u));
	font-family: var(--font-display);
	font-weight: 600;
	font-size: calc(50 * var(--u));
	line-height: calc(90 / 50);
	color: var(--red);
	text-transform: uppercase;
	white-space: nowrap;
	transition: translate .7s var(--ease);
}

.event:hover .event__title {
	translate: calc(14 * var(--u)) 0;
}

.event__row {
	position: relative;
	display: grid;
	grid-template-columns: 1fr auto calc(254 * var(--u));
	align-items: center;
	line-height: normal;
	text-transform: uppercase;
}

.event__row::before,
.event:last-child .event__row::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	height: 1px;
	background: var(--line);
	transform-origin: left center;
}

.event__row::before { top: 0; }
.event:last-child .event__row::after { bottom: 0; }

.event__cta {
	justify-self: end;
	text-transform: none;
}

.event__cta.is-full {
	color: var(--red);
	line-height: calc(28 / 18);
	padding-bottom: calc(8 * var(--u));
}

/* --------------------------------------------------------------------------
   Home — Instagram
   -------------------------------------------------------------------------- */

.insta {
	position: relative;
	margin-top: calc(199 * var(--u));
	padding: 0 var(--m);
}

.insta__head {
	display: flex;
	justify-content: space-between;
	align-items: flex-start;
	height: calc(28 * var(--u));
}

.insta__icon {
	width: calc(31 * var(--u));
	min-width: 22px;
}

.insta__icon img {
	width: 100%;
	height: auto;
}

.ghost--insta {
	top: calc(99 * var(--u));
	left: calc(1139 * var(--u));
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.site-footer {
	margin-top: calc(201 * var(--u));
	padding: 0 var(--m) calc(38 * var(--u));
	color: var(--ink-soft);
}

.site-footer__main {
	position: relative;
	display: grid;
	grid-template-columns: calc(690 * var(--u)) 1fr auto;
	min-height: calc(447 * var(--u));
}

.site-footer__main::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 1px;
	background: var(--line);
}

.site-footer__brand {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	text-transform: uppercase;
}

.site-footer__logo {
	display: block;
	width: calc(147 * var(--u));
}

.site-footer__logo img,
.site-footer__insta img {
	width: 100%;
	height: auto;
}

.site-footer__tagline {
	margin-top: calc(50 * var(--u));
}

.site-footer__insta {
	width: calc(31 * var(--u));
	min-width: 22px;
	margin-top: calc(43 * var(--u));
}

.site-footer__address {
	margin-top: auto;
	padding-bottom: calc(26 * var(--u));
	white-space: pre-line;
}

.site-footer__nav,
.site-footer__hours {
	font-family: var(--font-ui);
}

.site-footer__nav ul {
	padding-top: calc(85 * var(--u));
}

.site-footer__nav li {
	height: calc(62 * var(--u));
	line-height: normal;
}

.site-footer__nav li:last-child {
	height: auto;
}

.site-footer__nav a {
	background: linear-gradient(currentColor, currentColor) left bottom / 0 1px no-repeat;
	transition: background-size .5s var(--ease-heavy);
}

.site-footer__nav a:hover {
	background-size: 100% 1px;
}

.site-footer__hours {
	padding-top: calc(82 * var(--u));
	text-transform: uppercase;
}

.site-footer__hours div {
	display: flex;
	height: calc(52 * var(--u));
	white-space: nowrap;
}

.site-footer__hours dt {
	width: calc(157 * var(--u));
	min-width: 7.6em;
}

.site-footer__hours dd {
	min-width: calc(108 * var(--u));
}

.site-footer__legal {
	display: flex;
	justify-content: space-between;
	gap: calc(30 * var(--u));
	margin-top: calc(30 * var(--u));
	font-weight: 300;
	line-height: 1;
	color: var(--ink-soft);
	opacity: .5;
}

.site-footer__legal ul {
	display: inline-flex;
	gap: calc(15 * var(--u));
	margin-left: calc(20 * var(--u));
}

.site-footer__legal-left {
	display: flex;
	flex-wrap: wrap;
}

.site-footer__legal a:hover {
	text-decoration: underline;
	text-underline-offset: .2em;
}

/* --------------------------------------------------------------------------
   Generic pages (until their own designs are built)
   -------------------------------------------------------------------------- */

.page-plain {
	min-height: 70vh;
	padding: calc(200 * var(--u)) var(--m) 0;
}

.page-plain__content {
	max-width: 46em;
	margin-top: calc(60 * var(--u));
}

.page-plain__content > * + * {
	margin-top: 1em;
}

.page-plain__content a {
	text-decoration: underline;
	text-underline-offset: .2em;
}

/* --------------------------------------------------------------------------
   Reveals — only when JS is running; content is visible without it
   -------------------------------------------------------------------------- */

/* Text settles in. */
.js [data-reveal=""] {
	opacity: 0;
	transform: translateY(calc(22 * var(--u)));
	transition: opacity 1.1s ease var(--d, 0s), transform 1.3s var(--ease) var(--d, 0s);
}

.js [data-reveal=""].is-in {
	opacity: 1;
	transform: none;
}

/* A photograph developing: unveiled top-down, sepia first, colour after. */
/* The clip sits on an inner wrapper: an element that clips itself to nothing
   is never reported as visible by IntersectionObserver. */
.js [data-reveal="photo"] .ph__clip {
	clip-path: inset(0 0 100% 0);
	transition: clip-path 1.5s var(--ease-heavy) var(--d, 0s);
}

.js [data-reveal="photo"] img {
	filter: sepia(.9) saturate(.5) brightness(1.14) contrast(.84);
	scale: 1.16;
	transition: filter 2.6s ease-out calc(var(--d, 0s) + .2s), scale 2.8s var(--ease) var(--d, 0s);
}

.js [data-reveal="photo"].is-in .ph__clip {
	clip-path: inset(0);
}

.js [data-reveal="photo"].is-in img {
	filter: none;
	scale: 1;
}

.js .hero__media .hero__cta {
	opacity: 0;
	transition: opacity 1.2s ease 2s;
}

.js .hero__media.is-in .hero__cta {
	opacity: 1;
}

.js .card:hover [data-reveal="photo"].is-in img,
.js .room:hover [data-reveal="photo"].is-in img {
	scale: 1.045;
	transition: scale 1.6s var(--ease);
}

/* Headlines rise out of their own line, like type being set. */
.js [data-reveal="lines"] .ln > span {
	transform: translateY(108%) rotate(2.5deg);
	transform-origin: left bottom;
	transition: transform 1.3s var(--ease) calc(var(--d, 0s) + var(--i, 0) * .13s);
}

.js [data-reveal="lines"].is-in .ln > span {
	transform: none;
}

/* Hairlines are ruled from left to right, then the words appear. */
.js [data-reveal="cap"]::after {
	transform: scaleX(0);
	transition: transform 1.5s var(--ease-heavy) var(--d, 0s);
}

.js [data-reveal="cap"] > * {
	opacity: 0;
	transition: opacity 1s ease calc(var(--d, 0s) + .4s);
}

.js [data-reveal="cap"].is-in::after {
	transform: none;
}

.js [data-reveal="cap"].is-in > * {
	opacity: 1;
}

.js .event[data-reveal="row"] .event__row::before,
.js .event[data-reveal="row"] .event__row::after {
	transform: scaleX(0);
	transition: transform 1.5s var(--ease-heavy) var(--d, 0s);
}

.js .event[data-reveal="row"] .event__title,
.js .event[data-reveal="row"] .event__row > * {
	opacity: 0;
	transition: opacity 1s ease calc(var(--d, 0s) + .35s), translate .7s var(--ease);
}

.js .event[data-reveal="row"].is-in .event__row::before,
.js .event[data-reveal="row"].is-in .event__row::after {
	transform: none;
}

.js .event[data-reveal="row"].is-in .event__title,
.js .event[data-reveal="row"].is-in .event__row > * {
	opacity: 1;
}

/* The wordmark comes down in one press: ink settling, plate lifting. */
.js [data-reveal="typeset"] img {
	opacity: 0;
}

.js [data-reveal="typeset"].is-in img {
	animation: ink 1.1s var(--ease) var(--d, 0s) both, press 1.6s var(--ease) var(--d, 0s) both;
}

@keyframes ink {
	from { opacity: 0; filter: blur(calc(5 * var(--u))); }
	55% { filter: blur(0); }
	to { opacity: 1; filter: blur(0); }
}

@keyframes press {
	from { transform: scale(1.025); }
	to { transform: none; }
}

/* A rubber stamp coming down. */
.js [data-reveal="stamp"] {
	opacity: 0;
	transform: scale(1.8) rotate(-14deg);
	transition: opacity .2s ease-in var(--d, 0s), transform .5s cubic-bezier(.3, 1.5, .5, 1) var(--d, 0s);
}

.js [data-reveal="stamp"].is-in {
	opacity: 1;
	transform: none;
}

/* Tossed photographs slide in from off the table. */
.js .tilt[data-reveal] {
	opacity: 0;
	transition: opacity .9s ease var(--d, 0s), translate 1.7s var(--ease) var(--d, 0s), rotate 1.7s var(--ease) var(--d, 0s);
}

.js .tilt--l[data-reveal] { translate: -28% 10%; rotate: -36deg; }
.js .tilt--r[data-reveal] { translate: 28% 10%; rotate: 36deg; }

.js .tilt[data-reveal].is-in { opacity: 1; translate: 0 0; }
.js .tilt--l[data-reveal].is-in { rotate: -15deg; }
.js .tilt--r[data-reveal].is-in { rotate: 15deg; }

/* Header rule draws itself on first load. */
.js .site-header__inner::after {
	transform: scaleX(0);
	transition: transform 1.6s var(--ease-heavy) .1s;
}

.js.is-ready .site-header__inner::after {
	transform: none;
}

.js .site-header__right {
	opacity: 0;
	transition: opacity 1s ease .5s;
}

.js.is-ready .site-header__right {
	opacity: 1;
}

/* --------------------------------------------------------------------------
   Mobile (no Figma frame for this — built from the same system)
   -------------------------------------------------------------------------- */

@media (max-width: 767px) {
	:root {
		--u: calc(min(var(--vw, 100vw), 488px) / 390);
		--m: calc(20 * var(--u));
		--gap: calc(16 * var(--u));
		--r: calc(32 * var(--u));
		--fs: calc(15 * var(--u));
		--header-h: calc(64 * var(--u));
	}

	body {
		line-height: 1.5;
	}

	.display {
		font-size: calc(44 * var(--u));
		line-height: 1.08;
		text-wrap: balance;
	}

	/* Headline lines flow as one balanced paragraph instead of fixed lines. */
	.display .ln,
	.display .ln > span {
		display: inline;
	}

	.js [data-reveal="lines"] {
		opacity: 0;
		transform: translateY(calc(20 * var(--u)));
		transition: opacity 1.1s ease var(--d, 0s), transform 1.3s var(--ease) var(--d, 0s);
	}

	.js [data-reveal="lines"].is-in {
		opacity: 1;
		transform: none;
	}

	.cap {
		height: calc(38 * var(--u));
		margin-top: calc(14 * var(--u));
	}

	.ghost {
		font-size: calc(18 * var(--u));
		filter: blur(calc(1.5 * var(--u)));
	}

	.link {
		padding-bottom: calc(7 * var(--u));
	}

	.link::before { bottom: calc(4 * var(--u)); }

	/* Header */
	.admin-bar .site-header { top: 46px; }

	.site-nav {
		display: none;
	}

	.site-header__logo {
		width: calc(104 * var(--u));
		margin-top: 0;
	}

	.menu-toggle {
		width: calc(24 * var(--u));
		height: calc(18 * var(--u));
		margin-left: 0;
	}

	/* Menu */
	.site-menu {
		--k: min(var(--u), calc(100vh / 760));
	}

	.site-menu__logo {
		display: none;
	}

	.site-menu__stripe {
		right: auto;
		left: calc(12 * var(--u));
		width: calc(6 * var(--u));
		transform: translateX(100vw);
	}

	.site-menu__panel {
		left: calc(26 * var(--u));
		width: auto;
		padding: calc(110 * var(--k)) calc(28 * var(--u)) calc(36 * var(--k));
	}

	.site-menu__close {
		top: calc(10 * var(--k));
		right: calc(24 * var(--u));
		font-size: calc(40 * var(--k));
	}

	.site-menu__list a {
		gap: calc(8 * var(--u));
		font-size: calc(44 * var(--k));
		line-height: calc(74 / 44);
	}

	.site-menu__list .is-long a {
		font-size: calc(38 * var(--k));
		line-height: calc(74 / 38);
	}

	.site-menu__num {
		margin-top: calc(18 * var(--k));
		font-size: calc(13 * var(--u));
	}

	.site-menu__insta {
		margin-right: 0;
		width: calc(28 * var(--u));
	}

	/* Hero */
	.hero {
		padding-top: calc(92 * var(--u));
	}

	.hero__top {
		display: grid;
		grid-template-columns: 1fr auto;
		align-items: end;
		row-gap: calc(18 * var(--u));
		height: auto;
	}

	.hero__logo {
		grid-column: 1 / -1;
		width: 100%;
	}

	.hero__insta {
		position: static;
		grid-column: 2;
		grid-row: 2;
		width: calc(26 * var(--u));
	}

	.hero__place {
		position: static;
		grid-column: 1;
		grid-row: 2;
		text-align: left;
	}

	.hero__media {
		height: auto;
		aspect-ratio: 4 / 5;
		margin-top: calc(24 * var(--u));
	}

	.hero__cta {
		left: calc(20 * var(--u));
		bottom: calc(22 * var(--u));
		text-shadow: 0 1px 14px rgba(0, 0, 0, .45);
	}

	.hero__caption {
		flex-direction: column;
		gap: calc(2 * var(--u));
		height: auto;
		margin-top: calc(14 * var(--u));
		padding-bottom: calc(14 * var(--u));
		line-height: 1.5;
	}

	/* Welcome */
	.welcome {
		margin-top: calc(84 * var(--u));
	}

	.trio {
		grid-template-columns: 1fr;
		gap: calc(34 * var(--u));
		margin-top: calc(20 * var(--u));
	}

	.trio > :nth-child(n) {
		margin-top: 0;
	}

	.card,
	.room {
		translate: none;
	}

	.ghost--welcome {
		top: auto;
		bottom: calc(-52 * var(--u));
		right: 38%;
	}

	/* Afternoons */
	.afternoons {
		height: auto;
		margin-top: calc(120 * var(--u));
		padding-bottom: 104vw;
	}

	.afternoons__body {
		position: static;
		width: auto;
		margin: 0;
		padding: 0 var(--m);
	}

	.afternoons__text {
		width: auto;
		margin-top: calc(20 * var(--u));
	}

	.afternoons__body .link {
		margin-top: calc(26 * var(--u));
	}

	.tilt {
		top: auto;
		bottom: 6vw;
		width: 96vw;
	}

	.tilt--l { left: -56vw; rotate: -12deg; }
	.tilt--r { right: -56vw; rotate: 12deg; }

	.js .tilt--l[data-reveal].is-in { rotate: -12deg; }
	.js .tilt--r[data-reveal].is-in { rotate: 12deg; }

	.tilt__media {
		width: 46vw;
		height: 70vw;
	}

	.tilt__inner > .cap {
		width: 46vw;
	}

	/* Sleepover */
	.sleepover {
		margin-top: calc(40 * var(--u));
	}

	.sleepover__head {
		flex-direction: column;
		gap: calc(18 * var(--u));
		height: auto;
	}

	.sleepover__head .display {
		align-self: flex-end;
		margin-top: 0;
	}

	.sleepover__link {
		position: static;
		display: table;
		margin: calc(22 * var(--u)) 0 calc(28 * var(--u)) auto;
	}

	.rooms {
		grid-template-columns: 1fr;
		gap: calc(34 * var(--u));
	}

	.rooms > :nth-child(2) {
		margin-top: 0;
	}

	.badge {
		right: calc(8 * var(--u));
		bottom: calc(8 * var(--u));
		width: calc(118 * var(--u));
		height: calc(46 * var(--u));
		border-radius: calc(36 * var(--u)) 0 calc(36 * var(--u)) 0;
	}

	.badge span {
		width: calc(110 * var(--u));
		height: calc(38 * var(--u));
		border-radius: calc(32 * var(--u)) 0 calc(32 * var(--u)) 0;
		font-size: calc(13 * var(--u));
	}

	/* Coffee */
	.coffee {
		margin-top: calc(100 * var(--u));
	}

	.coffee__media {
		height: auto;
		aspect-ratio: 1 / 1;
		margin-top: calc(24 * var(--u));
	}

	.ghost--coffee {
		top: calc(150 * var(--u));
		right: 30%;
	}

	/* Events */
	.events {
		margin-top: calc(100 * var(--u));
	}

	.events__list {
		margin-top: calc(28 * var(--u));
	}

	.event {
		position: relative;
		grid-template-columns: 1fr;
		min-height: 0;
		padding: calc(18 * var(--u)) 0 calc(20 * var(--u));
	}

	.event::before,
	.event:last-child::after {
		content: "";
		position: absolute;
		left: 0;
		right: 0;
		height: 1px;
		background: var(--line);
	}

	.event::before { top: 0; }
	.event:last-child::after { bottom: 0; }

	.event__row::before,
	.event:last-child .event__row::after {
		display: none;
	}

	.event__title {
		margin-top: 0;
		font-size: calc(34 * var(--u));
		line-height: 1.2;
		white-space: normal;
	}

	.event__row {
		grid-template-columns: 1fr auto;
		grid-template-areas: "summary cta" "date cta";
		row-gap: calc(2 * var(--u));
		margin-top: calc(8 * var(--u));
		line-height: 1.5;
	}

	.event__summary { grid-area: summary; }
	.event__date { grid-area: date; opacity: .7; }
	.event__cta { grid-area: cta; align-self: end; }

	/* Instagram: a strip you swipe through */
	.insta {
		margin-top: calc(100 * var(--u));
	}

	.insta .trio {
		display: flex;
		gap: var(--gap);
		margin: calc(20 * var(--u)) calc(-1 * var(--m)) 0;
		padding: 0 var(--m);
		overflow-x: auto;
		scroll-snap-type: x mandatory;
		scroll-padding-left: var(--m);
		scrollbar-width: none;
	}

	.insta .trio::-webkit-scrollbar {
		display: none;
	}

	.insta .trio > * {
		flex: 0 0 78%;
		scroll-snap-align: start;
	}

	.ghost--insta {
		display: none;
	}

	/* Footer */
	.site-footer {
		margin-top: calc(100 * var(--u));
		padding-bottom: calc(28 * var(--u));
	}

	.site-footer__main {
		grid-template-columns: 1fr;
		min-height: 0;
		padding-bottom: calc(30 * var(--u));
	}

	.site-footer__logo {
		width: calc(132 * var(--u));
	}

	.site-footer__tagline {
		margin-top: calc(26 * var(--u));
	}

	.site-footer__insta {
		margin-top: calc(22 * var(--u));
		width: calc(28 * var(--u));
	}

	.site-footer__address {
		margin-top: calc(30 * var(--u));
		padding-bottom: 0;
	}

	.site-footer__nav ul {
		padding-top: calc(36 * var(--u));
	}

	.site-footer__nav li {
		height: calc(40 * var(--u));
	}

	.site-footer__hours {
		padding-top: calc(26 * var(--u));
	}

	.site-footer__hours div {
		justify-content: space-between;
		height: calc(34 * var(--u));
	}

	.site-footer__hours dt {
		width: auto;
	}

	.site-footer__legal {
		flex-direction: column;
		gap: calc(14 * var(--u));
		margin-top: calc(22 * var(--u));
		font-size: calc(13 * var(--u));
		line-height: 1.5;
	}

	.site-footer__legal ul {
		flex-wrap: wrap;
		gap: calc(4 * var(--u)) calc(14 * var(--u));
		margin-left: 0;
		width: 100%;
		margin-top: calc(6 * var(--u));
	}

	.page-plain {
		padding-top: calc(120 * var(--u));
	}

	.grain {
		animation: none;
	}
}

/* --------------------------------------------------------------------------
   Reduced motion: everything simply there
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation: none !important;
		transition-duration: .01ms !important;
		transition-delay: 0s !important;
	}

	.js [data-reveal],
	.js [data-reveal] > *,
	.js [data-reveal] .ln > span,
	.js [data-reveal] img {
		opacity: 1 !important;
		transform: none !important;
		clip-path: none !important;
		filter: none !important;
		scale: 1 !important;
	}

	.js .tilt[data-reveal] { translate: 0 0 !important; }
	.js .tilt--l[data-reveal] { rotate: -15deg !important; }
	.js .tilt--r[data-reveal] { rotate: 15deg !important; }

	.js [data-reveal]::after,
	.js .event__row::before,
	.js .event__row::after,
	.js .site-header__inner::after {
		transform: none !important;
	}

	.js .site-header__right {
		opacity: 1 !important;
	}
}

/* --------------------------------------------------------------------------
   Opening sequence (home). A case of loose type covers the page: a hundred
   odd letters in all sizes, turned every which way. The seven that spell the
   wordmark are dragged one by one to their place at the top of the hero,
   still crooked, and set upright on arrival; the rest sink into the paper as
   the page comes through. main.js clones the letters and sets left/top/width
   plus --sx/--sy (push-out), --sr (lying angle), --sr2 (angle on arrival)
   and --k (size). Everything here is keyframed, so no step depends on a
   transition starting from an animated value.
   -------------------------------------------------------------------------- */

.intro {
	display: none;
	position: fixed;
	inset: 0;
	z-index: 100;
	overflow: hidden;
	background-color: var(--bg);
	transition: background-color 1s ease .2s;
}

.intro-pending .intro {
	display: block;
}

.intro-pending .hero__logo img {
	opacity: 0;
}

.intro.is-leaving {
	background-color: transparent;
	pointer-events: none;
}

.intro__letter {
	position: absolute;
	left: 0;
	top: 0;
	height: auto;
	opacity: 0;
	transform: translate(var(--sx, 0px), var(--sy, 0px)) rotate(var(--sr, 0deg)) scale(var(--k, 1));
	transform-origin: 50% 50%;
	will-change: transform, opacity;
}

/* Tipped out of the case: each piece drops in at its own moment. */
.intro.is-set .intro__letter {
	animation: letter-toss .7s var(--ease) var(--d, 0s) both;
}

@keyframes letter-toss {
	from {
		opacity: 0;
		transform: translate(var(--sx, 0px), calc(var(--sy, 0px) - 30 * var(--u))) rotate(calc(var(--sr, 0deg) - 30deg)) scale(calc(var(--k, 1) * 1.25));
	}
	to {
		opacity: 1;
		transform: translate(var(--sx, 0px), var(--sy, 0px)) rotate(var(--sr, 0deg)) scale(var(--k, 1));
	}
}

/* Picked up and dragged into place (first two thirds), then set upright
   with a small wobble (last third). */
.intro.is-leaving .intro__letter {
	animation: letter-place 1.7s var(--d2, 0s) both;
}

@keyframes letter-place {
	0% {
		opacity: 1;
		transform: translate(var(--sx, 0px), var(--sy, 0px)) rotate(var(--sr, 0deg)) scale(var(--k, 1));
		animation-timing-function: cubic-bezier(.6, .05, .25, 1);
	}
	64% {
		opacity: 1;
		transform: translate(0, 0) rotate(var(--sr2, 0deg)) scale(1.03);
		animation-timing-function: cubic-bezier(.3, 1.35, .45, 1);
	}
	100% {
		opacity: 1;
		transform: translate(0, 0) rotate(0deg) scale(1);
	}
}

/* The rest sink back into the paper. */
.intro.is-leaving .intro__letter--extra {
	animation: letter-sink .8s var(--ease) var(--d3, 0s) both;
}

@keyframes letter-sink {
	from {
		opacity: 1;
		transform: rotate(var(--sr, 0deg)) scale(var(--k, 1));
	}
	to {
		opacity: 0;
		transform: translate(0, calc(16 * var(--u))) rotate(var(--sr, 0deg)) scale(calc(var(--k, 1) * .9));
	}
}

/* --------------------------------------------------------------------------
   Handwriting for the tiled wall (bundled, OFL/Apache licensed).
   -------------------------------------------------------------------------- */

@font-face { font-family: "Permanent Marker"; src: url("../fonts/hand-marker.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "Caveat"; font-weight: 500; src: url("../fonts/hand-caveat.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "Kalam"; src: url("../fonts/hand-kalam.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "Patrick Hand"; src: url("../fonts/hand-patrick.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "Shadows Into Light"; src: url("../fonts/hand-shadows.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "Reenie Beanie"; src: url("../fonts/hand-reenie.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "Homemade Apple"; src: url("../fonts/hand-homemade.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "Gloria Hallelujah"; src: url("../fonts/hand-gloria.woff2") format("woff2"); font-display: swap; }

/* --------------------------------------------------------------------------
   Home — the tiled wall. Glazed tiles on grey grout; each note sits on its
   own tile (or two) and is written on, line by line, when the wall comes
   into view. --tw is the tile width, everything on the wall scales with it.
   -------------------------------------------------------------------------- */

.tiles {
	/* Loose tiles on a thin joint. Every tile in the sprite is cut out along
	   its own edge (transparent around it), so the wall ends on the tiles
	   themselves: rounded corners, uneven edges, no box. */
	--grout: 0px;
	--tw: calc(1600 * var(--u) / 9);
	position: relative;
	z-index: 3;
	display: grid;
	grid-template-columns: repeat(9, 1fr);
	grid-template-rows: repeat(5, 1fr);
	gap: var(--grout);
}

/* Grout behind the joints only: pulled in past the outer tile edges so
   nothing grey shows outside the wall. */
.tiles::before {
	content: "";
	position: absolute;
	inset: calc(4 * var(--u));
	background: #dcd9d2;
}

.tile {
	position: relative;
	display: block;
	grid-column: var(--c);
	grid-row: var(--r);
	/* Each cut-out carries the photo's joint as transparent margin; the tiles
	   overlap a hair so the joint between them stays thin. */
	margin: calc(-1.2 * var(--u));
	background: url("../img/tiles-sprite.webp") no-repeat;
	background-size: 1500% 200%;
	background-position: calc(var(--sx, 0) * 100% / 14) calc(var(--sy, 0) * 100%);
	transform: scaleX(var(--flip, 1));
}

/* A breath of the page colour over the glaze, so the wall sits in the page. */
.tiles::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	background: var(--bg);
	opacity: .06;
	pointer-events: none;
}

/* The notes sit on the grid over the tiles. */
.note {
	position: relative;
	z-index: 1;
	grid-column: var(--c);
	grid-row: var(--r) / span var(--rs, 1);
	display: grid;
	grid-template-rows: repeat(var(--rs, 1), 1fr);
	align-items: start;
	margin: 0;
	padding: 0 calc(var(--tw) * .08);
	font-family: var(--hand), var(--font-sans);
	font-size: calc(var(--tw) * .145 * var(--hs, 1));
	line-height: 1.12;
	color: var(--ink, #1b1d33);
	transform: rotate(var(--tilt, 0deg));
	transform-origin: 50% 50%;
	pointer-events: none;
}

.note__ln {
	display: block;
	white-space: nowrap;
}

/* One part per tile: a note that runs on starts again at the top of the
   next tile, so no line ever sits on the joint. --dy drops the first part. */
.note__part {
	display: block;
	padding-top: calc(var(--tw) * .09);
}

.note__part:first-child {
	padding-top: calc(var(--tw) * (.09 + var(--dy, 0)));
}

.note__sig {
	margin-top: calc(var(--tw) * .035);
	padding-left: 38%;
	font-size: .78em;
	opacity: .9;
}

/* Written on: a soft edge sweeps along each line like a pen. Lines wait for
   the one before (--wt), and each takes --wd. */
.js .note .note__ln {
	-webkit-mask-image: linear-gradient(90deg, #000 42%, rgba(0, 0, 0, 0) 58%);
	mask-image: linear-gradient(90deg, #000 42%, rgba(0, 0, 0, 0) 58%);
	-webkit-mask-size: 260% 100%;
	mask-size: 260% 100%;
	-webkit-mask-position: 100% 0;
	mask-position: 100% 0;
}

.js .note.is-on .note__ln {
	animation: write var(--wd, .8s) linear var(--wt, 0s) both;
}

@keyframes write {
	from { -webkit-mask-position: 100% 0; mask-position: 100% 0; }
	to { -webkit-mask-position: 0% 0; mask-position: 0% 0; }
}

@media (max-width: 767px) {
	.tiles {
		--grout: 0px;
		--tw: calc(390 * var(--u) / 4);
		grid-template-columns: repeat(4, 1fr);
		grid-template-rows: repeat(7, 1fr);
		height: auto;
		aspect-ratio: 4 / 7;
	}

	.tiles::before {
		inset: calc(3 * var(--u));
	}

	.tile {
		grid-column: var(--mc);
		grid-row: var(--mr);
		margin: calc(-.8 * var(--u));
	}

	.tile:nth-child(n + 29) {
		display: none;
	}

	.note {
		grid-column: var(--mc);
		grid-row: var(--mr) / span var(--rs, 1);
		font-size: calc(var(--tw) * .16 * var(--hs, 1));
	}

	.note__sig {
		padding-left: 18%;
	}
}

@media (prefers-reduced-motion: reduce) {
	.js .note .note__ln {
		-webkit-mask-image: none;
		mask-image: none;
		animation: none;
	}
}

/* Still cards (welcome, sleepover) keep a quiet hover. */
.js .card:hover .ph img,
.js .room:hover .ph img {
	scale: 1.045;
	transition: scale 1.6s var(--ease);
}
