/* ==================================================================
   The home page message, and the floating contact button.

   Kept out of theme.css so this can be uploaded on its own without
   carrying the whole design file with it.
   ================================================================== */

/* ---------- Home page message ---------- */

.jp-pop {
	position: fixed;
	inset: 0;
	z-index: 2000;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 24px;
}

.jp-pop[hidden] {
	display: none;
}

.jp-pop__veil {
	position: absolute;
	inset: 0;
	background: rgba(12, 13, 12, 0.66);
	backdrop-filter: blur(3px);
	animation: jp-veil-in 0.35s ease both;
}

.jp-pop__box {
	position: relative;
	width: 100%;
	max-width: 480px;
	max-height: calc(100vh - 48px);
	overflow: hidden auto;
	background: #fff;
	box-shadow: 0 40px 110px rgba(12, 13, 12, 0.38);
	animation: jp-box-in 0.5s cubic-bezier(0.16, 1, 0.3, 1) both;
}

/* With a picture it becomes two columns: the words on the left, the
   photograph filling its own side edge to edge. */
.jp-pop__box--split {
	max-width: 880px;
	display: grid;
	grid-template-columns: 1fr 1fr;
	align-items: stretch;
	overflow: hidden;
}

.jp-pop__side {
	padding: 40px 40px 34px;
	overflow-y: auto;
	max-height: calc(100vh - 48px);
}

.jp-pop__media {
	position: relative;
	overflow: hidden;
	background: var(--paper, #f5f3ee);
}

.jp-pop__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	/* Drifts in from slightly enlarged, so the picture settles rather
	   than simply appearing. Slow enough to read as intent. */
	animation: jp-media-in 1.1s cubic-bezier(0.16, 1, 0.3, 1) both;
}

/* ---------- Leaving ---------- */

/* Closing is animated too. A panel that vanishes on the frame the
   button is pressed feels like a fault; one that leaves feels answered. */
.jp-pop.is-closing .jp-pop__veil {
	animation: jp-veil-out 0.28s ease both;
}

.jp-pop.is-closing .jp-pop__box {
	animation: jp-box-out 0.28s cubic-bezier(0.4, 0, 1, 1) both;
}

@keyframes jp-veil-in {
	from { opacity: 0; }
	to   { opacity: 1; }
}

@keyframes jp-veil-out {
	from { opacity: 1; }
	to   { opacity: 0; }
}

@keyframes jp-box-in {
	from { opacity: 0; transform: translateY(26px) scale(0.97); }
	to   { opacity: 1; transform: none; }
}

@keyframes jp-box-out {
	from { opacity: 1; transform: none; }
	to   { opacity: 0; transform: translateY(16px) scale(0.98); }
}

@keyframes jp-media-in {
	from { transform: scale(1.12); }
	to   { transform: scale(1); }
}

/* The words arrive a beat after the panel, one line at a time, so the
   eye is led down to the form rather than meeting everything at once. */
.jp-pop__side > * {
	animation: jp-line-in 0.5s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.jp-pop__side > *:nth-child(1) { animation-delay: 0.16s; }
.jp-pop__side > *:nth-child(2) { animation-delay: 0.23s; }
.jp-pop__side > *:nth-child(3) { animation-delay: 0.30s; }
.jp-pop__side > *:nth-child(4) { animation-delay: 0.37s; }

@keyframes jp-line-in {
	from { opacity: 0; transform: translateY(12px); }
	to   { opacity: 1; transform: none; }
}

/* A close button people can find and hit. A faint one does not keep
   anybody on the page — it makes them leave the site instead.

   It is a white disc rather than a bare character because it sits over
   the photograph, where a dark mark on its own disappears into whatever
   happens to be behind it. The disc carries its own background, so it
   reads against a bright sky and a dark doorway alike. */
.jp-pop__x {
	position: absolute;
	top: 14px;
	right: 14px;
	z-index: 3;
	display: grid;
	place-items: center;
	width: 38px;
	height: 38px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: #fff;
	font-size: 21px;
	font-weight: 300;
	line-height: 1;
	color: #0c0d0c;
	cursor: pointer;
	box-shadow: 0 4px 16px rgba(12, 13, 12, 0.2);
	transition: transform 0.24s ease, background-color 0.2s ease, color 0.2s ease;
}

.jp-pop__x:hover,
.jp-pop__x:focus-visible {
	background: #0c0d0c;
	color: #fff;
	transform: rotate(90deg);
}

.jp-pop__x:focus-visible {
	outline: 2px solid var(--gold-solid, #b08d57);
	outline-offset: 3px;
}

.jp-pop__title {
	margin: 4px 0 11px;
	font-size: clamp(1.32rem, 2.1vw, 1.62rem);
	line-height: 1.22;
}

.jp-pop__text {
	margin: 0 0 20px;
	font-size: 0.94rem;
	line-height: 1.68;
	color: rgba(12, 13, 12, 0.7);
}

.jp-pop__form .field {
	margin-bottom: 10px;
}

.jp-pop__form input {
	width: 100%;
	padding: 13px 15px;
	border: 1px solid rgba(12, 13, 12, 0.16);
	background: #fff;
	font: inherit;
	font-size: 0.94rem;
	color: #0c0d0c;
	transition: border-color 0.2s ease;
}

.jp-pop__form input:focus {
	outline: 0;
	border-color: #0c0d0c;
}

.jp-pop__form .btn {
	margin-top: 8px;
}

/* Saying no should be as easy as saying yes. Hiding the way out turns a
   message into a trap, and a trap is what gets remembered. */
.jp-pop__no {
	display: block;
	width: 100%;
	margin-top: 14px;
	padding: 6px;
	border: 0;
	background: transparent;
	font: inherit;
	font-size: 0.8rem;
	color: rgba(12, 13, 12, 0.5);
	text-decoration: underline;
	cursor: pointer;
}

.jp-pop__no:hover {
	color: #0c0d0c;
}

/* A laptop in a browser with toolbars has less height than it looks.
   Below this the panel gives up its padding before it gives up the
   button, which is the part that has to stay visible. */
@media (max-height: 720px) {
	.jp-pop__side {
		padding: 28px 36px 24px;
	}

	.jp-pop__text {
		margin-bottom: 16px;
	}
}

@media (max-width: 820px) {
	/* Side by side stops working before the picture stops earning its
	   place, so it becomes a band across the top instead of vanishing. */
	.jp-pop__box--split {
		max-width: 460px;
		grid-template-columns: 1fr;
	}

	.jp-pop__media {
		order: -1;
		height: 160px;
	}

	.jp-pop__side {
		padding: 32px 26px 28px;
		max-height: none;
	}
}

@media (max-width: 520px) {
	.jp-pop {
		padding: 14px;
	}

	.jp-pop__media {
		height: 128px;
	}
}

/* ---------- Floating contact button ---------- */

.jp-float {
	position: fixed;
	right: 24px;
	bottom: 24px;
	z-index: 1500;
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: 12px;
}

.jp-float__btn {
	position: relative;
	width: 58px;
	height: 58px;
	border: 0;
	border-radius: 50%;
	background: #0c0d0c;
	color: #fff;
	display: grid;
	place-items: center;
	cursor: pointer;
	box-shadow: 0 12px 34px rgba(12, 13, 12, 0.3);
	transition: transform 0.22s ease;
}

/* A ring that swells and fades, over and over. It is what makes the eye
   go to the corner at all — a still circle down there is furniture. The
   ring sits behind the button and ignores the pointer, so it can never
   get in the way of the press it is advertising. */
.jp-float__btn::before,
.jp-float__btn::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 50%;
	background: var(--gold-solid, #b08d57);
	z-index: -1;
	pointer-events: none;
	animation: jp-ring 2.6s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

/* The second ring is the same animation started halfway through, so the
   pulse reads as continuous rather than as a repeating gap. */
.jp-float__btn::after {
	animation-delay: 1.3s;
}

@keyframes jp-ring {
	0%   { transform: scale(1);    opacity: 0.55; }
	70%  { transform: scale(1.85); opacity: 0;    }
	100% { transform: scale(1.85); opacity: 0;    }
}

/* Once it is open the ring has done its job, and carrying on would only
   pull at somebody who is already reading the options. */
.jp-float.is-open .jp-float__btn::before,
.jp-float.is-open .jp-float__btn::after {
	animation: none;
	opacity: 0;
}

.jp-float__btn:hover {
	transform: translateY(-3px) scale(1.04);
}

.jp-float.is-open .jp-float__btn {
	transform: rotate(90deg);
}

.jp-float__btn svg {
	width: 25px;
	height: 25px;
	stroke: currentColor;
	fill: none;
	stroke-width: 1.7;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* One button, two faces: the open one is swapped for a close one, so the
   control never moves and never doubles. */
.jp-float__shut,
.jp-float.is-open .jp-float__open {
	display: none;
}

.jp-float.is-open .jp-float__shut {
	display: block;
}

.jp-float__menu {
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: 9px;
}

.jp-float__menu[hidden] {
	display: none;
}

/* Bottom upward, one after another — they appear to unfold out of the
   button rather than being dropped beside it. */
.jp-float__item {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 12px 18px;
	background: #fff;
	color: #0c0d0c;
	font-size: 0.87rem;
	font-weight: 500;
	text-decoration: none;
	white-space: nowrap;
	border: 1px solid rgba(12, 13, 12, 0.1);
	box-shadow: 0 10px 28px rgba(12, 13, 12, 0.16);
	transform-origin: bottom right;
	animation: jp-item-in 0.34s cubic-bezier(0.16, 1, 0.3, 1) both;
	transition: background-color 0.18s ease, color 0.18s ease, transform 0.18s ease;
}

.jp-float__item:nth-last-child(1) { animation-delay: 0.02s; }
.jp-float__item:nth-last-child(2) { animation-delay: 0.09s; }
.jp-float__item:nth-last-child(3) { animation-delay: 0.16s; }

@keyframes jp-item-in {
	from { opacity: 0; transform: translateY(14px) scale(0.9); }
	to   { opacity: 1; transform: none; }
}

.jp-float__item:hover {
	background: #0c0d0c;
	color: #fff;
	transform: translateX(-3px);
}

.jp-float__icon {
	display: flex;
	flex: none;
}

.jp-float__icon svg {
	width: 18px;
	height: 18px;
	stroke: currentColor;
	fill: none;
	stroke-width: 1.7;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* WhatsApp keeps its own colour: people know the green before they read
   the word beside it. */
.jp-float__item--wa .jp-float__icon {
	color: #25d366;
}

.jp-float__item--wa:hover .jp-float__icon {
	color: #fff;
}

@media (max-width: 600px) {
	.jp-float {
		right: 16px;
		bottom: 16px;
	}

	.jp-float__btn {
		width: 52px;
		height: 52px;
	}
}

/* Somebody who has asked their system for less movement is asking for a
   reason — motion sickness, or a vestibular condition. Everything still
   works; it simply stops moving. */
@media (prefers-reduced-motion: reduce) {

	.jp-pop__veil,
	.jp-pop__box,
	.jp-pop__side > *,
	.jp-pop__media img,
	.jp-float__item {
		animation: none !important;
	}

	.jp-float__btn::before,
	.jp-float__btn::after {
		display: none;
	}

	.jp-float__btn,
	.jp-float__item,
	.jp-pop__x {
		transition: none;
	}
}

/* "Send a message" is a button, not a link — it opens the panel rather
   than going anywhere. It has to be told to look like its neighbours,
   which a browser styles as a button by default. */
button.jp-float__item {
	border: 1px solid rgba(12, 13, 12, 0.1);
	font: inherit;
	font-size: 0.87rem;
	font-weight: 500;
	cursor: pointer;
}

/* ---------- The panel's second job ---------- */

/* Asking for an address is a short form; answering a question needs room
   to write. The extra fields are in the page either way and revealed by
   a class, so nothing has to be built when the button is pressed. */
.jp-pop__ask,
.jp-pop__go-ask {
	display: none;
}

.jp-pop.is-ask .jp-pop__ask {
	display: block;
}

.jp-pop.is-ask .jp-pop__go {
	display: none;
}

.jp-pop.is-ask .jp-pop__go-ask {
	display: inline;
}

.jp-pop__ask select,
.jp-pop__ask textarea {
	width: 100%;
	padding: 13px 15px;
	border: 1px solid rgba(12, 13, 12, 0.16);
	background: #fff;
	font: inherit;
	font-size: 0.94rem;
	color: #0c0d0c;
	transition: border-color 0.2s ease;
}

.jp-pop__ask textarea {
	resize: vertical;
	min-height: 84px;
}

.jp-pop__ask select:focus,
.jp-pop__ask textarea:focus {
	outline: 0;
	border-color: #0c0d0c;
}

/* ---------- Sent ---------- */

.jp-pop__note {
	margin: 0 0 12px;
	padding: 10px 13px;
	background: rgba(12, 13, 12, 0.05);
	font-size: 0.86rem;
	line-height: 1.5;
}

.jp-pop__note.is-bad {
	background: rgba(179, 45, 46, 0.08);
	color: #8d2324;
}

.jp-pop__done {
	display: grid;
	place-items: center;
	gap: 6px;
	min-height: 260px;
	text-align: center;
	animation: jp-line-in 0.45s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.jp-pop__tick {
	display: grid;
	place-items: center;
	width: 54px;
	height: 54px;
	border-radius: 50%;
	background: var(--gold-solid, #b08d57);
	color: #fff;
	font-size: 25px;
	line-height: 1;
	animation: jp-tick 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) 0.12s both;
}

@keyframes jp-tick {
	from { transform: scale(0.4); opacity: 0; }
	to   { transform: scale(1);   opacity: 1; }
}

.jp-pop__done h2 {
	margin: 8px 0 0;
	font-size: 1.4rem;
}

.jp-pop__done p {
	margin: 0;
	max-width: 30ch;
	font-size: 0.92rem;
	line-height: 1.6;
	color: rgba(12, 13, 12, 0.65);
}

/* While it is in flight the button says so rather than sitting there
   looking as though the press did nothing. */
.btn.is-sending {
	opacity: 0.6;
	pointer-events: none;
}

/* Once the form has been replaced by the thank-you, the column centres
   what is left. Only then: while the form is there it should start at
   the top, beside the picture, the way a form is read. */
.jp-pop__side:has(.jp-pop__done) {
	display: grid;
	place-items: center;
}

/* ------------------------------------------------------------------
   Social links in the footer.
   The footer sits on near-black, so these are drawn in white at
   reduced strength and come up to full on hover — the same treatment
   the rest of the footer's links get.
------------------------------------------------------------------ */
.footer__social {
	display: flex;
	flex-wrap: wrap;
	gap: 14px;
	margin-top: 22px;
}

.footer__social a {
	display: grid;
	place-items: center;
	width: 38px;
	height: 38px;
	border: 1px solid rgba(255, 255, 255, 0.18);
	border-radius: 50%;
	color: rgba(255, 255, 255, 0.75);
	transition: color 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}

.footer__social a:hover,
.footer__social a:focus-visible {
	color: #fff;
	border-color: rgba(255, 255, 255, 0.55);
	transform: translateY(-2px);
}

.footer__social svg {
	width: 17px;
	height: 17px;
	stroke: currentColor;
	fill: none;
	stroke-width: 1.6;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* The filled marks bring their own fill and turn the stroke off, so
   they need no help — but they do need to be the same visual weight
   as the drawn ones beside them. */
.footer__social svg [fill="currentColor"] {
	fill: currentColor;
}

/* An uploaded icon, in either bar. Both are near-black, so it is
   flattened to white the same way the footer logo is: brightness(0)
   makes every colour black, then invert(1) lifts it to solid white.
   That is why the field asks for a solid shape and not a logo — a
   full-colour mark loses its colours here. */
.topbar__social .jp-social__own,
.footer__social .jp-social__own {
	width: 18px;
	height: 18px;
	object-fit: contain;
	filter: brightness(0) invert(1);
	opacity: 0.75;
	transition: opacity 0.2s ease;
}

.topbar__social a:hover .jp-social__own,
.footer__social a:hover .jp-social__own {
	opacity: 1;
}
