/* ==========================================================================
   ShinSen — plain CSS, custom properties, no framework and no build step.
   Anyone should be able to open this file and change a colour.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Fonts (self-hosted, never Google's CDN)
   -------------------------------------------------------------------------- */

/* Ropa Sans stands in for the brandbook's RopaSoftPTT.

   The brandbook asks for one family everywhere - RopaSoftPTT, in Light,
   Regular and Bold. That face is commercial: owning the print files is not a
   webfont licence, so it cannot be served from here. Ropa Sans is the same
   family's free sibling under the SIL Open Font License: same skeleton and
   proportions, without Soft's rounded terminals, and one weight instead of
   three.

   If the licence is bought, this is the only place that changes - drop the
   real files in beside these and rename. Nothing else in the file names a
   font. */
@font-face {
	font-family: "Ropa Sans";
	src: url("../fonts/ropa-sans-400-latin-ext.woff2") format("woff2");
	font-weight: 400;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-family: "Ropa Sans";
	src: url("../fonts/ropa-sans-400.woff2") format("woff2");
	font-weight: 400;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: "Jost";
	src: url("../fonts/jost-300.woff2") format("woff2");
	font-weight: 300;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: "Jost";
	src: url("../fonts/jost-400.woff2") format("woff2");
	font-weight: 400;
	font-style: normal;
	font-display: swap;
}

/* --------------------------------------------------------------------------
   2. Tokens — every colour, size and rhythm decision comes from here
   -------------------------------------------------------------------------- */

:root {
	--paper: #f5f3f0;
	--paper-light: #faf9f8;
	--white: #ffffff;
	--ink: #0d0d0d;
	--ink-soft: #3a3735;
	--muted: #7a7570;
	--line: #ddd8d2;
	--seal: #c8262c;

	/* One family for headings and for text, which is what the brandbook asks
	   for. Jost stays behind it as the fallback: if Ropa Sans ever fails to
	   load, the page should still look like this site and not like Arial. */
	--display: "Ropa Sans", "Jost", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
	--sans: "Ropa Sans", "Jost", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

	--gutter: clamp(20px, 5vw, 80px);
	/* Section padding. Was clamp(72px, 10vw, 150px), which read as too much
	   air on every page - 300px between two sections on a wide screen, and
	   still 144px on a phone. */
	--section: clamp(56px, 7vw, 104px);

	--ease-calm: cubic-bezier(0.22, 1, 0.36, 1);
	--header-h: 88px;
}

/* --------------------------------------------------------------------------
   3. Base
   -------------------------------------------------------------------------- */

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

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
}

body {
	margin: 0;
	background-color: var(--paper);
	color: var(--ink-soft);
	font-family: var(--sans);
	font-weight: 300;
	font-size: 15px;
	line-height: 1.75;
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
	overflow-x: hidden;
}

h1,
h2,
h3,
h4,
h5,
h6 {
	font-family: var(--display);
	font-weight: 300;
	line-height: 1.08;
	color: var(--ink);
	margin: 0;
}

p {
	margin: 0;
}

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

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

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

button {
	font: inherit;
	color: inherit;
	background: none;
	border: 0;
	padding: 0;
	cursor: pointer;
}

::selection {
	background-color: var(--seal);
	color: #fff;
}

:focus-visible {
	outline: 2px solid var(--seal);
	outline-offset: 3px;
}

.screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* The skip link has to undo every part of screen-reader-text, not just its
   position.
   
   It did only the position, and lost even that: screen-reader-text carries
   `position: absolute !important`, which beats a plain `position: fixed` in
   the focus rule. So the link stayed one pixel square and clipped to nothing
   while focused - present in the tab order, and invisible to the person
   tabbing through it, which is the one case it exists for. */
.skip-link:focus {
	position: fixed !important;
	top: 12px;
	left: 12px;
	width: auto;
	height: auto;
	margin: 0;
	overflow: visible;
	clip: auto;
	clip-path: none;
	white-space: normal;
	z-index: 200;
	padding: 12px 18px;
	background: var(--ink);
	color: #fff;
}

/* --------------------------------------------------------------------------
   4. Shared pieces
   -------------------------------------------------------------------------- */

.label {
	font-family: var(--sans);
	font-weight: 400;
	font-size: 11px;
	text-transform: uppercase;
	letter-spacing: 0.2em;
	line-height: 1;
}

.side-label {
	writing-mode: vertical-rl;
	text-orientation: mixed;
	font-family: var(--sans);
	font-weight: 400;
	font-size: 10px;
	text-transform: uppercase;
	letter-spacing: 0.34em;
	color: var(--muted);
}

.side-label--up {
	transform: rotate(180deg);
}

.page-gutter {
	padding-left: var(--gutter);
	padding-right: var(--gutter);
}

.section-y {
	padding-top: var(--section);
	padding-bottom: var(--section);
}

/* 44 × 1px seal bar under a heading */
.rule {
	display: block;
	width: 44px;
	height: 1px;
	background-color: var(--seal);
	margin: 24px 0 28px;
	border: 0;
}

.rule--center {
	margin-left: auto;
	margin-right: auto;
}

/* Uppercase label + red arrow that travels 8px right on hover */
.link-arrow {
	display: inline-flex;
	align-items: center;
	gap: 12px;
	color: var(--ink);
}

.link-arrow--light {
	color: var(--paper);
}

/* The second link on a product card. It is a real destination, not a lesser
   one, but the card's own link is the main road - so this one is set quieter
   and comes up to full strength on hover. */
.link-arrow--quiet {
	color: var(--muted);
	transition: color 400ms var(--ease-calm);
}

.link-arrow--quiet .link-arrow__glyph {
	color: var(--muted);
	transition: transform 450ms var(--ease-calm), color 400ms var(--ease-calm);
}

.link-arrow--quiet:hover,
.link-arrow--quiet:focus-visible {
	color: var(--ink);
}

.link-arrow--quiet:hover .link-arrow__glyph,
.link-arrow--quiet:focus-visible .link-arrow__glyph {
	color: var(--seal);
}

.link-arrow__glyph {
	color: var(--seal);
	transition: transform 450ms var(--ease-calm);
}

.link-arrow:hover .link-arrow__glyph,
.link-arrow:focus-visible .link-arrow__glyph {
	transform: translateX(8px);
}

/* Solid ink block that turns seal on hover */
.button {
	display: inline-flex;
	align-items: center;
	gap: 20px;
	padding: 16px 36px;
	background-color: var(--ink);
	color: #fff;
	transition: background-color 500ms var(--ease-calm);
}

.button:hover,
.button:focus-visible {
	background-color: var(--seal);
}

.button__glyph {
	transition: transform 450ms var(--ease-calm);
}

.button:hover .button__glyph,
.button:focus-visible .button__glyph {
	transform: translateX(6px);
}

.section-heading {
	font-size: clamp(2rem, 4.5vw, 3.25rem);
	line-height: 1.08;
	letter-spacing: -0.01em;
	color: var(--ink);
}

.section-heading--light {
	color: var(--paper);
}

.eyebrow {
	color: var(--muted);
	margin-bottom: 20px;
}

/* Image wrapper + brand placeholder */
.figure {
	overflow: hidden;
}

.figure img,
.shinsen-img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.figure--contain img {
	object-fit: contain;
}

.placeholder {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	width: 100%;
	height: 100%;
	min-height: inherit;
	background: linear-gradient(135deg, #ede9e4 0%, #e2ddd7 100%);
}

.placeholder__mark {
	width: auto;
	height: 40%;
	max-height: 160px;
	opacity: 0.1;
	pointer-events: none;
	object-fit: contain;
}

.placeholder__label {
	position: absolute;
	bottom: 20px;
	left: 0;
	right: 0;
	padding: 0 16px;
	text-align: center;
	color: var(--muted);
}

/* --------------------------------------------------------------------------
   5. Scroll reveal

   Content is VISIBLE BY DEFAULT. The hidden pre-reveal state only applies
   once the inline head script has added .js-reveal to <html>, and that script
   never adds it when the visitor prefers reduced motion. No JS, a JS error,
   or reduced motion therefore all mean: full content.
   -------------------------------------------------------------------------- */

.js-reveal [data-reveal] {
	opacity: 0;
	transform: translateY(26px);
}

.js-reveal [data-reveal].is-revealed {
	opacity: 1;
	transform: none;
	transition: opacity 1s var(--ease-calm), transform 1s var(--ease-calm);
}

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}

	/* Belt and braces: even if .js-reveal somehow lands, show everything. */
	.js-reveal [data-reveal] {
		opacity: 1 !important;
		transform: none !important;
		transition: none !important;
	}

	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
	}
}

/* --------------------------------------------------------------------------
   6. Header
   -------------------------------------------------------------------------- */

.site-header {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 50;
	border-bottom: 1px solid transparent;
	background-color: transparent;
	transition: background-color 500ms var(--ease-calm), border-color 500ms var(--ease-calm),
		backdrop-filter 500ms var(--ease-calm);
}

.site-header.is-scrolled {
	border-bottom-color: var(--line);
	background-color: rgba(245, 243, 240, 0.8);
	-webkit-backdrop-filter: blur(12px);
	backdrop-filter: blur(12px);
}

/* --------------------------------------------------------------------------
   Keeping the nav readable over the photograph.

   Every page top now runs its photograph up behind the header, which is what
   the client asked for - the labels sit on the picture. The header's text is
   ink, and over a pale photograph that is fine. The treatment shot behind the
   professional page is not pale: it is dark on the right, and Contact all but
   vanished into it.

   So the header carries its own scrim: paper at the very top, gone a little
   below the header. It is a gradient with no edge anywhere, not the bar the
   design started out with - on the four pale page tops it is invisible, and on
   a dark one it lifts just the strip the nav occupies.

   It fades out as the header becomes solid, because then the header's own
   background is doing the job.
   -------------------------------------------------------------------------- */

.site-header::before {
	content: '';
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: calc(var(--header-h) + 44px);
	pointer-events: none;
	background: linear-gradient(
		to bottom,
		rgba(245, 243, 240, 0.94) 0%,
		rgba(245, 243, 240, 0.78) 42%,
		rgba(245, 243, 240, 0.34) 72%,
		rgba(245, 243, 240, 0) 100%
	);
	transition: opacity 500ms var(--ease-calm);
}

.site-header.is-scrolled::before {
	opacity: 0;
}

/* Above the scrim: ::before is positioned, so without this it would paint over
   the header's own content. */
.site-header__inner {
	position: relative;
	z-index: 1;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
	height: var(--header-h);
}

/* Brand lockup: small parent label above the ShinSen wordmark */
.brand {
	display: inline-flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 6px;
}

.brand__parent {
	font-size: 8px;
	letter-spacing: 0.34em;
	text-transform: uppercase;
	line-height: 1;
	font-weight: 400;
	color: var(--muted);
	transition: color 300ms var(--ease-calm);
}

.brand__parent:hover {
	color: var(--ink);
}

/* --------------------------------------------------------------------------
   The lockup: the geisha mark and the packaging logotype.

   The wordmark used to be the word SHINSEN set in Cormorant, which is not the
   logotype on the box - the client said so three times. It is now the artwork
   itself, painted through a CSS mask so one file serves the ink header and the
   paper footer.

   Its alignment is measured rather than guessed. In the mark, the black fan
   ends 40.6% of the way down (row 207 of 510), so the wordmark's top sits
   there and its bottom finishes flush with the mark. Both edges then land on
   something real, which is what "align it with the bottom of the fan" asks
   for - before this it lined up with nothing.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   The lockup, to the brand's own proportions.

   The light one is assembled here from two pieces - the red and black mark
   plus the logotype as a mask - because on paper the mark has to carry its
   colour, and the dark one is the client's single white artwork. Assembled by
   eye, the two did not match: the gap was five times too wide and the name too
   tall and set too high, which is what she saw.

   So the numbers are no longer by eye. They are measured off her own file,
   shinsen-logo-light.png, as ratios of the mark's height:

       mark        1193 x 1729   aspect 0.690
       gap           87          0.0503 of the mark's height
       name        3159 x  743   0.4297 tall, starting 0.5541 down

   Both lockups take the same --mark-h, so the whole thing is resized in one
   place and the two stay identical.
   -------------------------------------------------------------------------- */

.brand__main {
	--mark-h: 40px;
	--logo-gap: 0.0503;
	--word-top: 0.5541;
	--word-h: 0.4297;

	display: flex;
	align-items: flex-start;
	gap: calc(var(--mark-h) * var(--logo-gap));
}

.brand__mark {
	height: var(--mark-h);
	width: auto;
	flex: none;
}

.brand__word {
	display: block;
	margin-top: calc(var(--mark-h) * var(--word-top));
	height: calc(var(--mark-h) * var(--word-h));
	aspect-ratio: 793 / 194;
	background-color: var(--ink);
	-webkit-mask: url("../images/shinsen-wordmark.png") left center/contain no-repeat;
	mask: url("../images/shinsen-wordmark.png") left center/contain no-repeat;
}

.brand--dark .brand__word {
	background-color: var(--paper);
}

/* The footer's single white lockup. Its own artwork already holds the mark and
   the name in the right relationship, so there is nothing to assemble here -
   just a height. 4439x1729 is the supplied file. */
.brand__main--single {
	display: block;
}

/* The artwork's full height is the mark's height, so this is the same size as
   the assembled lockup above. */
.brand__logo {
	display: block;
	height: 40px;
	width: auto;
}

.brand--dark .brand__parent {
	color: rgba(245, 243, 240, 0.55);
}

.brand--dark .brand__parent:hover {
	color: var(--paper);
}

/* Desktop navigation */
.nav-primary {
	display: none;
}

.nav-primary__list {
	display: flex;
	align-items: center;
	gap: 40px;
}

.nav-primary__link {
	color: var(--ink);
	transition: color 300ms var(--ease-calm);
}

.nav-primary__link:hover,
.nav-primary__item.is-active .nav-primary__link {
	color: var(--seal);
}

.nav-primary__item {
	position: relative;
}

/* Products dropdown — generated from the products query, never hand-maintained */
.nav-dropdown {
	position: absolute;
	left: 50%;
	top: 100%;
	transform: translateX(-50%);
	z-index: 10;
	width: 288px;
	padding-top: 20px;
	opacity: 0;
	pointer-events: none;
	transition: opacity 300ms var(--ease-calm);
}

.nav-primary__item:hover .nav-dropdown,
.nav-primary__item:focus-within .nav-dropdown {
	opacity: 1;
	pointer-events: auto;
}

.nav-dropdown__inner {
	background-color: var(--paper-light);
	border: 1px solid var(--line);
	padding: 8px;
	box-shadow: 0 20px 60px -30px rgba(13, 13, 13, 0.4);
}

.nav-dropdown__link {
	display: flex;
	align-items: baseline;
	gap: 12px;
	padding: 12px 16px;
	transition: background-color 300ms var(--ease-calm);
}

.nav-dropdown__link:hover {
	background-color: var(--white);
}

.nav-dropdown__num {
	color: var(--seal);
}

.nav-dropdown__name {
	font-family: var(--display);
	font-size: 18px;
	line-height: 1.2;
	color: var(--ink);
	display: block;
}

.nav-dropdown__tagline {
	display: block;
	margin-top: 4px;
	font-size: 10px;
	color: var(--muted);
}

.nav-dropdown__all {
	display: block;
	margin-top: 4px;
	padding: 12px 16px;
	border-top: 1px solid var(--line);
	color: var(--ink);
	transition: color 300ms var(--ease-calm);
}

.nav-dropdown__all:hover {
	color: var(--seal);
}

/* Menu trigger */
.menu-toggle {
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 6px;
	width: 28px;
	height: 24px;
}

.menu-toggle__bar {
	display: block;
	width: 100%;
	height: 1px;
	background-color: var(--ink);
}

/* Full-screen overlay menu (primary navigation below 1080px) */
.nav-overlay {
	position: fixed;
	inset: 0;
	z-index: 60;
	background-color: var(--paper);
	overflow-y: auto;
	opacity: 0;
	pointer-events: none;
	transition: opacity 500ms var(--ease-calm);
}

.nav-overlay.is-open {
	opacity: 1;
	pointer-events: auto;
}

.nav-overlay__bar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	height: var(--header-h);
}

.nav-overlay__close {
	position: relative;
	width: 24px;
	height: 24px;
}

.nav-overlay__close span {
	position: absolute;
	left: 0;
	top: 50%;
	width: 100%;
	height: 1px;
	background-color: var(--ink);
}

.nav-overlay__close span:first-child {
	transform: rotate(45deg);
}

.nav-overlay__close span:last-child {
	transform: rotate(-45deg);
}

.nav-overlay__nav {
	display: flex;
	flex-direction: column;
	gap: 24px;
	padding-top: 6vh;
	padding-bottom: 10vh;
}

.nav-overlay__link {
	font-family: var(--display);
	font-size: 36px;
	line-height: 1;
	color: var(--ink);
	transition: color 300ms var(--ease-calm);
}

.nav-overlay__link:hover {
	color: var(--seal);
}

.nav-overlay__products {
	margin-top: 24px;
	padding-top: 24px;
	border-top: 1px solid var(--line);
}

.nav-overlay__products-heading {
	color: var(--muted);
	margin-bottom: 16px;
}

.nav-overlay__products-list {
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.nav-overlay__product {
	display: flex;
	align-items: baseline;
	gap: 12px;
}

.nav-overlay__product-num {
	color: var(--seal);
}

.nav-overlay__product-name {
	font-family: var(--display);
	font-size: 20px;
	color: var(--ink);
	transition: color 300ms var(--ease-calm);
}

.nav-overlay__product:hover .nav-overlay__product-name {
	color: var(--seal);
}

@media (min-width: 1080px) {
	.nav-primary {
		display: block;
	}

	/* The inline nav takes over here, so the hamburger has nothing left to do.
	   Without this both were on screen at once above 1080px. The overlay goes
	   too, so a window resized from phone width while it was open cannot leave
	   it stuck over the page. */
	.menu-toggle,
	.nav-overlay {
		display: none;
	}
}

/* --------------------------------------------------------------------------
   7. Home — hero
   -------------------------------------------------------------------------- */

.hero {
	position: relative;
	display: flex;
	align-items: center;
	overflow: hidden;
	background-color: var(--paper);
	padding-top: var(--header-h);
	min-height: 100vh;
}

.hero__grid {
	display: grid;
	width: 100%;
	align-items: center;
	gap: 40px;
	padding-top: 64px;
	padding-bottom: 64px;
}

.hero__copy {
	order: 2;
	max-width: 36rem;
}

/* Sized against the other page tops, not on its own.

   Cormorant is a display serif with a small x-height, so 5.75rem of it looked
   calm; the same number in a text sans is a different thing entirely, and the
   home page ended up a quarter larger than every other heading on the site -
   which is what the client saw and called out. This sits just above the page
   heroes rather than in its own scale.

   The max-width goes up with it so the first line - "Work with the skin." -
   holds together. It is a sentence, and breaking it after "the" reads as an
   accident. */
.hero__title {
	font-size: clamp(2.35rem, 5.8vw, 4.1rem);
	line-height: 1.06;
	letter-spacing: -0.015em;
	color: var(--ink);
	text-wrap: balance;
}

.hero__sub {
	margin-top: 32px;
	max-width: 24rem;
	line-height: 2;
	color: var(--seal);
}

.hero__cta {
	margin-top: 44px;
}

/* Edge to edge on a phone as well. The grid puts a gutter on both sides, so
   the photograph sat in a framed box with paper either side - and the client's
   note was about the illustrations being boxed in, on every screen, not only
   the desktop one. Pulling it out by the gutter is enough: the section already
   hides its overflow. */
.hero__media {
	order: 1;
	position: relative;
	margin: 0 calc(var(--gutter) * -1);
	width: auto;
}

/* And up to the very top of the page, behind the header.

   The section cleared the header's height and then added its own padding on
   top of that, which put 152px of empty paper between the header and the
   photograph - the gap the client asked about. Every other page top on this
   site already runs its photograph up behind the header, which is transparent
   until you scroll and carries its own scrim to keep the nav readable, so the
   home page was the odd one out as well as the untidy one. */
@media (max-width: 767px) {
	.hero {
		padding-top: 0;
		min-height: 0;
	}

	.hero__grid {
		padding-top: 0;
		padding-bottom: 56px;
		gap: 32px;
	}
}

/* Landscape, because the home hero now carries the client's group shot of all
   three products rather than a single jar. As a 4/5 portrait frame with
   object-fit: cover it cropped the product on the right clean off. The ratio
   matches the photograph, so nothing is cut. */
.hero__jar {
	aspect-ratio: 3 / 2;
	width: 100%;
}

.hero__branch {
	position: absolute;
	top: -44px;
	right: -64px;
	width: 192px;
	aspect-ratio: 1 / 1;
	mix-blend-mode: multiply;
	pointer-events: none;
	display: none;
}

.hero__side-label {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	display: none;
}

.hero__side-label--left {
	left: 16px;
}

.hero__side-label--right {
	right: 16px;
}

.hero__side-label--left .side-label {
	transform: rotate(180deg);
}

.hero__scroll {
	position: absolute;
	bottom: 32px;
	right: 24px;
	display: none;
	align-items: center;
	gap: 12px;
}

.hero__scroll-label {
	font-size: 9px;
	color: var(--muted);
}

.hero__scroll-line {
	display: block;
	width: 1px;
	height: 40px;
	background-color: var(--line);
}

/* --------------------------------------------------------------------------
   The hero photograph, bleeding off the top and the right.

   It used to sit in a 44rem frame inside the right-hand column, with the
   hero's own padding-top holding it clear of the header - so the photograph
   was a cropped panel with a bar above it, and the client said it should
   "flow out to the side and upward, so that Philosophy and Products sit on
   it, as in the sketch". The header is already transparent until you scroll,
   so all that was needed was to take the photograph out of the column.

   It stops short of the left edge rather than covering the whole section, and
   that is deliberate. The sketch's hero image has empty space on the left for
   the headline to sit in; the group shot the client later chose has its three
   products across the middle, so text laid over the full width lands on the
   jars. Holding the photograph off the left gutter gives the headline the
   empty column the sketch assumed, while the image still runs off the top and
   the right - which is the part she actually asked for.

   The left edge is a mask, not a crop: the photograph dissolves into the
   paper instead of ending on a seam, so there is no visible frame anywhere.

   Only from 768px up. On a phone the photograph above the copy is the right
   answer and the client said the mobile version is fine.
   -------------------------------------------------------------------------- */

@media (min-width: 768px) {
	.hero {
		padding-top: 0;
		/* The copy goes to the top left, where this photograph is empty. */
		align-items: flex-start;
	}

	/* The grid stays unpositioned on purpose. Give it position: relative and
	   the absolute photograph anchors to its padding box instead of the
	   section, which left the image inset by the header's clearance - and,
	   being the only positioned sibling, painting straight over the copy. */
	.hero__grid {
		align-items: start;
		grid-template-columns: minmax(0, 1fr);
		padding-top: calc(var(--header-h) + 48px);
		padding-bottom: 96px;
	}

	/* 32rem, not 30: at 30 the headline's first line cleared the column by
	   18px, which holds for the copy that is there and breaks the moment
	   anyone adds a word. The extra 32px buys the slack without moving the
	   text far enough over the photograph to matter. */
	.hero__copy {
		order: 1;
		position: relative;
		z-index: 2;
		max-width: 32rem;
	}

	.hero__side-label,
	.hero__scroll {
		z-index: 2;
	}

	.hero__media {
		order: 2;
		position: absolute;
		/* Was 26%, which gave the photograph 74% of the page against a heading
		   on what was left - the products came out enormous and the words
		   small beside them. */
		inset: 0 0 0 38%;
		z-index: 0;
		width: auto;
		margin: 0;
		-webkit-mask: linear-gradient(
			to right,
			transparent 0,
			rgba(0, 0, 0, 0.55) 15%,
			#000 36%
		);
		mask: linear-gradient(
			to right,
			transparent 0,
			rgba(0, 0, 0, 0.55) 15%,
			#000 36%
		);
	}

	.hero__jar {
		aspect-ratio: auto;
		width: 100%;
		height: 100%;
	}

	.hero__jar img {
		width: 100%;
		height: 100%;
		object-fit: cover;
		/* Keep the top of the frame: the products stand in the lower two
		   thirds and the water reflection at the very bottom is the one part
		   of this photograph that can be cropped without losing anything. */
		object-position: 60% top;
	}

	/* A last softening over the overlap, so a long line of the headline stays
	   readable where it reaches the first few per cent of the image. It is
	   gone well before the jars. */
	.hero::before {
		content: '';
		position: absolute;
		inset: 0;
		z-index: 1;
		pointer-events: none;
		background: linear-gradient(
			to right,
			rgba(245, 243, 240, 0.85) 0%,
			rgba(245, 243, 240, 0.4) 28%,
			rgba(245, 243, 240, 0) 44%
		);
	}
}

@media (min-width: 1024px) {
	.hero__branch,
	.hero__side-label {
		display: block;
	}

	.hero__scroll {
		display: flex;
	}
}

/* --------------------------------------------------------------------------
   8. Home — the art of purity
   -------------------------------------------------------------------------- */

.philosophy {
	background-color: var(--paper-light);
}

.philosophy__grid {
	display: grid;
	align-items: center;
	gap: 48px;
}

/* The SENTAKU lockup from the packaging - the wordmark with its 選択 seal -
   above the ShinSen logotype. Both are masks, so one file each does paper and
   ink, and neither is type pretending to be a logo. */
/* Sized the way the packaging prints them: the parent mark small above, the
   product's own logotype about twice its width below. */
.philosophy__parent {
	display: block;
	height: 22px;
	width: auto;
	aspect-ratio: 404 / 147;
	background-color: var(--ink);
	-webkit-mask: url("../images/sentaku-lockup.png") left center/contain no-repeat;
	mask: url("../images/sentaku-lockup.png") left center/contain no-repeat;
}

.philosophy__caption {
	margin-top: 14px;
	color: var(--seal);
}

/* The signature under the kanji is the logotype off the packaging, like the
   one in the header - not the brand name set in Jost, which is what it was.
   Ink rather than the caption's red: this is the logotype, and the logotype is
   black. The red rule underneath keeps the accent.

   .brand__word takes its height from the lockup's --mark-h, which does not
   exist here, so both dimensions are given outright. */
.philosophy__word {
	display: block;
	margin-top: 0;
	height: 27px;
	width: auto;
	aspect-ratio: 793 / 194;
	background-color: var(--ink);
}

/* Edge to edge below the three-column layout, for the same reason as the
   sections above: centred in the gutter with air either side, it was a framed
   picture rather than part of the page. */
.philosophy__figure {
	aspect-ratio: 1 / 1;
	width: auto;
	margin: 0 calc(var(--gutter) * -1);
}

.philosophy__copy {
	max-width: 28rem;
}

.philosophy__cta {
	margin-top: 36px;
}

@media (min-width: 1024px) {
	.philosophy__grid {
		grid-template-columns: auto 1fr 1.1fr;
		gap: 56px;
	}

	.philosophy__figure {
		width: 100%;
		margin: 0;
	}
}

/* --------------------------------------------------------------------------
   9. Home — essentials row
   -------------------------------------------------------------------------- */

.essentials {
	background-color: var(--white);
}

.essentials__head {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
}

.essentials__title {
	font-size: clamp(2rem, 4.5vw, 3.25rem);
	line-height: 1.08;
	letter-spacing: -0.01em;
	color: var(--ink);
}

.essentials__count {
	color: var(--seal);
}

/* Reflows for 3–7 products without breaking */
.essentials__grid {
	display: grid;
	grid-template-columns: 1fr;
	margin-top: 32px;
}

.essentials__item {
	border-color: var(--line);
}

.essentials__link {
	display: flex;
	height: 100%;
	flex-direction: column;
	align-items: center;
	text-align: center;
	padding: 40px 24px;
}

/*
 * The same frame the collection uses, for the same reason: these two rows
 * show the same three products, and a 224px box beside a 4:5 one made them
 * look like two different sites. On the collection the products stood 321px
 * tall and here 146 - the client put the two screens side by side and the
 * difference was the first thing she saw.
 */
.essentials__figure {
	aspect-ratio: 4 / 5;
	height: auto;
	width: 100%;
	transition: transform 500ms var(--ease-calm);
}

.essentials__link:hover .essentials__figure,
.essentials__link:focus-visible .essentials__figure {
	transform: translateY(-10px);
}

.essentials__num {
	margin-top: 32px;
	color: var(--seal);
}

/* Fluid rather than a flat 24px. "ShinSen Day Moisture Cream SPF45 PA++++" is
   the longest name in the range and at 24px it broke onto a second line while
   the other two sat on one, which is what the client noticed. The size now
   follows the column, so the three names stay level. */
.essentials__name {
	margin-top: 12px;
	font-family: var(--display);
	font-size: clamp(16px, 1.5vw, 23px);
	line-height: 1.2;
	color: var(--ink);
	text-wrap: balance;
}

.essentials__tagline {
	margin-top: 12px;
	font-size: 10px;
	color: var(--muted);
}

.essentials__more {
	margin-top: 56px;
	display: flex;
	justify-content: center;
}

@media (min-width: 640px) {
	.essentials__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.essentials__item {
		border-left: 1px solid var(--line);
	}

	.essentials__item:first-child {
		border-left: 0;
	}
}

/* Three across from 1080px, where the inline nav also takes over - not 1024px.
   At 1024 a third of the row is 341px, and 48px of that went on padding, which
   is what pushed the longest product name onto a second line while the other
   two stayed on one. Two columns until then is no loss: they are wide, and the
   names sit on one line the whole way down. */
@media (min-width: 1080px) {
	.essentials__grid {
		grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
	}

	.essentials__link {
		padding-left: 16px;
		padding-right: 16px;
	}
}

/* --------------------------------------------------------------------------
   10. Home — Japanese ingredients (dark)
   -------------------------------------------------------------------------- */

.ingredients {
	overflow: hidden;
	background-color: var(--ink);
	color: var(--paper);
}

.ingredients__grid {
	display: grid;
}

.ingredients__copy-wrap {
	display: flex;
	align-items: center;
}

.ingredients__copy {
	max-width: 28rem;
}

.ingredients__text {
	color: rgba(245, 243, 240, 0.7);
}

.ingredients__cta {
	margin-top: 36px;
}

.ingredients__media {
	position: relative;
	min-height: 380px;
}

.ingredients__figure {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
}

@media (min-width: 768px) {
	.ingredients__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.ingredients__media {
		min-height: 560px;
	}
}

/* --------------------------------------------------------------------------
   11. Home — the ritual
   -------------------------------------------------------------------------- */

.ritual {
	overflow: hidden;
	background-color: var(--white);
}

.ritual__grid {
	display: grid;
	align-items: stretch;
}

/* Image sits below the steps on mobile, left of them from tablet up */
.ritual__media {
	position: relative;
	order: 2;
	min-height: 360px;
}

.ritual__figure {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
}

.ritual__content {
	order: 1;
	display: flex;
	align-items: center;
}

.ritual__inner {
	width: 100%;
	max-width: 36rem;
}

.ritual__steps {
	margin-top: 24px;
	display: flex;
	flex-direction: column;
	gap: 32px;
}

.ritual__step-num {
	color: var(--seal);
	display: block;
}

.ritual__step-title {
	margin-top: 8px;
	font-family: var(--display);
	font-size: 24px;
	line-height: 1.2;
	color: var(--ink);
}

.ritual__step-text {
	margin-top: 8px;
	font-size: 14px;
	color: var(--muted);
}

.ritual__arrow {
	display: none;
	color: var(--seal);
	align-self: flex-start;
	padding-top: 4px;
}

@media (min-width: 640px) {
	.ritual__steps {
		flex-direction: row;
		align-items: flex-start;
		gap: 20px;
	}

	.ritual__step {
		flex: 1;
	}

	.ritual__arrow {
		display: block;
	}
}

@media (min-width: 768px) {
	.ritual__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.ritual__media {
		order: 1;
		min-height: 600px;
	}

	.ritual__content {
		order: 2;
	}
}

/* --------------------------------------------------------------------------
   12. Home — partnership
   -------------------------------------------------------------------------- */

/* The photograph fills half the band edge to edge. It used to be a 288px
   square floating at the left, blended with multiply: the studio background is
   grey, the section is cream, and the seam showed no matter what. A full-bleed
   panel has no edge to hide, and the photograph is finally large enough to
   read. Same structure as the ritual band, so the scroll keeps its cadence. */

/* A calm band of its own between two full-bleed photographs. It keeps the
   paper background and a hairline above it so it cannot run into the image
   band before it - which is exactly what a half-and-half split did. */

.partner {
	position: relative;
	overflow: hidden;
	border-top: 1px solid var(--line);
	background-color: var(--paper-light);
}

.partner__inner {
	position: relative;
	z-index: 1;
}

.partner__content {
	margin: 0 auto;
	max-width: 40rem;
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
}

@media (min-width: 900px) {
	.partner__content {
		max-width: 54rem;
	}
}

.partner__title {
	font-size: clamp(2rem, 4.5vw, 3.5rem);
	line-height: 1.1;
	letter-spacing: -0.01em;
	color: var(--ink);
}

/* The accent line is the longest thing in this band - "For professionals who
   expect more from skincare." - and at 40rem it broke across two lines, which
   the client asked to fix. It gets a slightly smaller size and the room to
   run, and balanced wrapping for whatever she types in its place: a line that
   does have to wrap then splits evenly instead of leaving one word behind. */
.partner__subtitle {
	font-family: var(--display);
	font-size: clamp(1.5rem, 3.2vw, 2.25rem);
	line-height: 1.15;
	color: var(--seal);
	text-wrap: balance;
}

.partner__cta {
	margin-top: 40px;
}

/* --------------------------------------------------------------------------
   The two decorations.

   These are photographs on a pale grey studio ground, not cut-outs, so the
   ground has to be dealt with: each one is masked to dissolve away from its
   own outer corner and held well back in opacity. The subject - bowl, branch,
   berries - stays legible at the edge of the frame while the grey fades into
   the paper long before it reaches the copy.

   Hidden below 900px: on a phone there is no room beside the text, and two
   washes behind centred copy would only make it harder to read.
   -------------------------------------------------------------------------- */

.partner__decor {
	position: absolute;
	z-index: 0;
	pointer-events: none;
	/* Fainter on a phone, where they sit closer behind centred copy. */
	opacity: 0.26;
}

.partner__decor img {
	width: 100%;
	height: 100%;
	object-fit: contain;
}

.partner__decor--left {
	left: -12%;
	bottom: -6%;
	width: 52vw;
	max-width: 230px;
	aspect-ratio: 1 / 1;
	opacity: 0.18;
	/* Centred, not anchored to the outer corner. The old fade was solid in
	   the corner and gone by the middle - which is exactly where the subject
	   is in both of these, so the mountain read as a faint smudge and the
	   figure would have lost her head. This keeps the middle and softens
	   only the edge into the paper. */
	-webkit-mask-image: radial-gradient(closest-side at 50% 50%, #000 0%, #000 62%, rgba(0, 0, 0, 0.5) 84%, transparent 100%);
	mask-image: radial-gradient(closest-side at 50% 50%, #000 0%, #000 62%, rgba(0, 0, 0, 0.5) 84%, transparent 100%);
}

/* Along the bottom, like the figure opposite it. A mountain floating in the
   top corner reads as a sticker; sitting on the same line as everything else
   it reads as landscape. It also carries more weight than the figure, being
   a pale wash against her solid fill. */
.partner__decor--right {
	right: -12%;
	bottom: -6%;
	width: 46vw;
	max-width: 200px;
	aspect-ratio: 1 / 1;
	opacity: 0.4;
	-webkit-mask-image: radial-gradient(closest-side at 50% 50%, #000 0%, #000 62%, rgba(0, 0, 0, 0.5) 84%, transparent 100%);
	mask-image: radial-gradient(closest-side at 50% 50%, #000 0%, #000 62%, rgba(0, 0, 0, 0.5) 84%, transparent 100%);
}

@media (min-width: 900px) {
	/* From tablet up there is room beside the copy, so they can be larger and
	   a little stronger. They used to be hidden below this width altogether,
	   which left the phone version of this band plain - and it is the same
	   band, so it should read the same way. */
	.partner__decor {
		opacity: 0.5;
	}

	/* The figure is a solid fill and the mountain is a wash, so the same
	   opacity does not read as the same weight - matched by eye instead. */
	.partner__decor--left {
		left: -4%;
		bottom: -10%;
		width: 26vw;
		max-width: 400px;
		opacity: 0.32;
	}

	.partner__decor--right {
		right: -4%;
		bottom: -10%;
		width: 30vw;
		max-width: 460px;
		opacity: 0.72;
	}

	.partner__inner {
		/* Room for the decorations to sit beside the copy, not under it. */
		padding-left: clamp(80px, 12vw, 220px);
		padding-right: clamp(80px, 12vw, 220px);
	}
}

.site-footer {
	background-color: var(--ink);
	color: var(--paper);
}

.site-footer__top {
	display: grid;
	gap: 56px;
}

.site-footer__tagline {
	margin-top: 24px;
	max-width: 20rem;
	font-size: 14px;
	color: rgba(245, 243, 240, 0.6);
}

.site-footer__columns {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	column-gap: 32px;
	row-gap: 40px;
}

.site-footer__heading {
	margin-bottom: 20px;
	color: rgba(245, 243, 240, 0.5);
}

.site-footer__links {
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.site-footer__links a,
.site-footer__links li {
	font-size: 14px;
	color: rgba(245, 243, 240, 0.8);
	transition: color 300ms var(--ease-calm);
}

.site-footer__links a:hover {
	color: #fff;
}

/* The contact column mixes links with an address block, so it needs a little
   more air between rows than a plain list of page links. */
.site-footer__contact {
	gap: 16px;
}

.site-footer__address {
	font-style: normal;
	font-size: 14px;
	line-height: 1.6;
	color: rgba(245, 243, 240, 0.6);
}

.site-footer__social {
	margin-top: 24px;
	display: flex;
	align-items: center;
	gap: 12px;
}

.site-footer__social a {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	border: 1px solid rgba(245, 243, 240, 0.25);
	border-radius: 9999px; /* the one place a radius is allowed */
	color: rgba(245, 243, 240, 0.7);
	transition: color 300ms var(--ease-calm), border-color 300ms var(--ease-calm);
}

.site-footer__social a:hover {
	color: #fff;
	border-color: rgba(245, 243, 240, 0.6);
}

.site-footer__social svg {
	width: 16px;
	height: 16px;
}

.site-footer__bottom {
	margin-top: 64px;
	padding-top: 32px;
	border-top: 1px solid rgba(245, 243, 240, 0.15);
	display: flex;
	flex-direction: column;
	gap: 16px;
	color: rgba(245, 243, 240, 0.5);
}

.site-footer__bottom .label {
	font-size: 10px;
	color: rgba(245, 243, 240, 0.5);
}

.site-footer__legal {
	display: flex;
	gap: 32px;
}

.site-footer__legal a {
	transition: color 300ms var(--ease-calm);
}

.site-footer__legal a:hover {
	color: #fff;
}

@media (min-width: 560px) {
	/* One equal track per column that actually rendered, rather than a fixed
	   count: the products column disappears on a site with no products yet,
	   and a fixed repeat() would leave an empty track and squeeze the rest. */
	.site-footer__columns {
		grid-template-columns: none;
		grid-auto-flow: column;
		grid-auto-columns: minmax(0, 1fr);
		column-gap: 40px;
	}

	.site-footer__bottom {
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
	}
}

@media (min-width: 1024px) {
	.site-footer__top {
		grid-template-columns: minmax(0, 1fr) 2fr;
	}
}

/* --------------------------------------------------------------------------
   14. Simple pages (philosophy / professional / contact placeholders, 404)
   -------------------------------------------------------------------------- */

/* The header is fixed, so a page's first section owes it clearance - but only
   that. The grid inside already carries section-y, and adding --section here
   as well stacked two paddings: 296px of nothing above the philosophy
   heading, which is what still read as too much air after the last pass. */
/* The header is fixed, so the first section of a page has to clear it itself.
   Miss a hero out of this list and its first line is printed underneath the
   logo, which is what happened to the pages for professionals. */
.page-hero,
.product-hero {
	padding-top: var(--header-h);
	padding-bottom: 0;
}

.page-hero {
	background-color: var(--paper);
}

/* A hero is the top of a page, not a band between two others, so it wants
   less room than a mid-page section. */
.page-hero .section-y,
.product-hero .section-y {
	padding-top: clamp(28px, 3.5vw, 56px);
	padding-bottom: clamp(36px, 4.5vw, 72px);
}

/* The section straight after a hero does not need a full section's padding on
   top of the hero's own: two of them stacked pushed the first real content of
   every page below the fold. On the contact page that was the whole problem -
   you opened it and the contact details were not on screen at all. */
.page-hero + section > .section-y,
.page-hero + section > .page-gutter.section-y {
	padding-top: clamp(28px, 3.5vw, 56px);
}

/* --------------------------------------------------------------------------
   A page that is only text: the privacy policy, and anything added later.

   It carries the one kind of content on this site that nobody reads for
   pleasure and everybody has to be able to read - so it gets the plainest
   thing that works. A single column at a comfortable measure, headings that
   are clearly headings, and enough space between them to find your place.
   -------------------------------------------------------------------------- */

/* --plain takes the page-top composition back off: no photograph here, so
   nothing to lay the title over and nothing to be as tall as.

   Written as .page-hero.page-hero--plain rather than .page-hero--plain alone,
   because the composition is set inside media queries further down this file.
   At equal specificity the later rule wins, so a single class here would be
   overridden by the very rules it exists to cancel. */
.page-hero.page-hero--plain {
	display: block;
	min-height: 0;
	overflow: visible;
	align-items: initial;
}

.page-hero.page-hero--plain::before {
	content: none;
}

.page-hero.page-hero--plain .section-y {
	padding-bottom: 0;
}

.page-body {
	background: var(--paper);
}

.page-body .section-y {
	padding-top: clamp(28px, 3vw, 44px);
}

.page-content {
	max-width: 42rem;
	font-size: 15px;
	line-height: 1.85;
	color: var(--ink-soft);
}

.page-content > :first-child {
	margin-top: 0;
}

.page-content p {
	margin: 0 0 1.25em;
}

.page-content h2 {
	font-family: var(--display);
	font-weight: 300;
	font-size: clamp(1.5rem, 2.6vw, 2rem);
	line-height: 1.2;
	color: var(--ink);
	margin: 2.2em 0 0.6em;
	padding-top: 1.4em;
	border-top: 1px solid var(--line);
}

.page-content h2:first-child {
	padding-top: 0;
	border-top: 0;
}

.page-content h3 {
	font-family: var(--display);
	font-weight: 400;
	font-size: clamp(1.1rem, 1.9vw, 1.3rem);
	line-height: 1.3;
	color: var(--ink);
	margin: 1.8em 0 0.5em;
}

.page-content h4 {
	font-family: var(--sans);
	font-size: 11px;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--muted);
	margin: 1.6em 0 0.5em;
}

/* Editor content, unlike the designed sections, needs real lists: the global
   reset strips bullets everywhere, which turned the privacy policy's lists
   into an unreadable run of lines. Scoped to .page-content so the designed
   lists elsewhere keep their reset. */
.page-content ul,
.page-content ol {
	margin: 0 0 1.2em;
	padding-left: 1.25em;
	list-style: disc;
}

.page-content ol {
	list-style: decimal;
}

.page-content li {
	margin-bottom: 0.6em;
	padding-left: 0.25em;
}

.page-content li::marker {
	color: var(--seal);
}

.page-content a {
	color: var(--ink);
	text-decoration: underline;
	text-underline-offset: 3px;
	text-decoration-thickness: 1px;
	text-decoration-color: var(--line);
	transition: text-decoration-color 300ms var(--ease-calm), color 300ms var(--ease-calm);
}

.page-content a:hover {
	color: var(--seal);
	text-decoration-color: var(--seal);
}

.page-content strong {
	font-weight: 400;
	color: var(--ink);
}

/* ==========================================================================
   Home additions - optional lead and closing lines
   ========================================================================== */

.philosophy__lead {
	font-family: var(--display);
	font-size: clamp(1.25rem, 2.2vw, 1.65rem);
	line-height: 1.3;
	color: var(--ink);
	margin: 0 0 20px;
}

.philosophy__closing,
.ingredients__closing {
	font-family: var(--display);
	font-size: clamp(1.1rem, 1.8vw, 1.35rem);
	line-height: 1.35;
	margin: 20px 0 0;
}

.philosophy__closing {
	color: var(--ink);
}

.ingredients__closing {
	color: var(--paper);
}

/* ==========================================================================
   A product's page for professionals
   ========================================================================== */

/* All that is left of the hero these pages used to have. The rest of it - the
   layout, the bleed, the mask, the crop, the phone arrangement - is page-hero
   now, which is where every other page top gets the same things from. */
.pro-hero__eyebrow {
	display: block;
	color: var(--seal);
	margin-bottom: 18px;
}

/* The band after the hero does not need a full section's padding on top of the
   hero's, the same as everywhere else. */
.page-hero + .pro-sections .pro-section:first-child > .section-y {
	padding-top: clamp(28px, 3.5vw, 56px);
}

/* Alternating bands, so a run of six sections does not read as one slab. */
.pro-section:nth-child(even) {
	background: var(--paper-light);
}

.pro-section__title {
	margin-top: 0;
}

.pro-section__text {
	margin: 0 0 16px;
	max-width: 62ch;
}

.pro-section__text--after {
	margin-top: 24px;
}

.pro-list {
	margin: 24px 0 0;
	padding: 0;
	list-style: none;
	border-top: 1px solid var(--line);
}

.pro-list__item {
	padding: 14px 0;
	border-bottom: 1px solid var(--line);
}

.pro-list__name {
	display: block;
	font-family: var(--display);
	font-size: 1.05rem;
	line-height: 1.3;
	color: var(--ink);
	margin-bottom: 4px;
}

.pro-list__text {
	display: block;
	font-size: 14px;
	line-height: 1.7;
	color: var(--ink-soft);
}

/* The standing note - "Professional use only" and the like. Set apart on ink,
   because it is a condition of use rather than another paragraph. */
.pro-note {
	background: var(--ink);
}

.pro-note__text {
	margin: 0;
	padding: 26px 0;
	color: var(--paper);
	text-align: center;
}

.pro-closing {
	background: var(--white);
}

.pro-closing__inner {
	max-width: 46rem;
	margin: 0 auto;
	text-align: center;
}

.pro-closing__text {
	font-family: var(--display);
	font-size: clamp(1.15rem, 2.2vw, 1.5rem);
	line-height: 1.4;
	color: var(--ink);
	margin: 0 0 12px;
}

.pro-closing__cta {
	margin: 32px 0 0;
}

.pro-closing__back {
	margin: 40px 0 0;
}

/* The arrow points the way it is going. */
.link-arrow__glyph--back {
	order: -1;
}

.link-arrow:hover .link-arrow__glyph--back,
.link-arrow:focus-visible .link-arrow__glyph--back {
	transform: translateX(-8px);
}

/* ==========================================================================
   Shared page hero
   ========================================================================== */

.page-hero {
	position: relative;
	background: var(--paper);
	overflow: hidden;
}

.page-hero__grid {
	display: grid;
	gap: 40px;
	align-items: center;
}

@media (min-width: 860px) {
	.page-hero__grid {
		grid-template-columns: 1.05fr 1fr;
		gap: 56px;
	}
}

/* Same reason as the home hero: a sans reads bigger than the serif these
   numbers were chosen for, so every page top comes down with it.

   This is the only place the size is set. There used to be a second
   .page-hero__title rule higher up the file carrying a different number, and
   since the two have equal specificity the later one silently won - worth not
   rebuilding. */
.page-hero__title {
	font-family: var(--display);
	font-weight: 300;
	font-size: clamp(2.2rem, 5.4vw, 3.9rem);
	line-height: 1.05;
	letter-spacing: -0.012em;
	margin: 0;
	color: var(--ink);
}

.page-hero__lead {
	font-family: var(--display);
	font-size: clamp(1.25rem, 2.4vw, 1.8rem);
	line-height: 1.3;
	color: var(--ink);
	margin: 0 0 18px;
}

.page-hero__text {
	margin: 0;
	max-width: 46ch;
}

/* Every other page top has one of these. The pages for professionals open
   with three, and without this they ran together into one block. */
.page-hero__text + .page-hero__text {
	margin-top: 14px;
}

/* 4/3 rather than a portrait 4/5: on a phone the taller ratio made this
   photograph 419px of a 812px screen, which is most of a first screen spent
   on decoration - and on the contact page it pushed the details, the reason
   anyone opens that page, well past the fold. */
.page-hero__figure {
	aspect-ratio: 4 / 3;
}

/* --------------------------------------------------------------------------
   The page top on a phone: one section - copy left, photograph right.

   Stacked, it read as two things that happened to follow each other, and the
   client kept saying so however the stack was arranged. So a phone gets the
   same composition as a desktop, narrowed: the photograph held to the right
   of the section and running off the top and the right edge, the copy on the
   left of it, one block.

   What makes it work at 375px is the mask. The photograph's left edge is not
   an edge at all - it dissolves into the paper across a third of its width -
   so the copy can sit in that dissolved strip without a panel behind it and
   without the photograph looking cut. The client's instinct to blur was the
   same instinct; a fade does it without softening the part of the picture
   worth seeing.

   Below 360px there is no room for two columns at all - the copy would be
   four words wide - so the very narrowest phones keep the stack. 375px, the
   width of a plain iPhone, is above the line and gets the two columns.
   -------------------------------------------------------------------------- */

@media (max-width: 359px) {
	.page-hero__media {
		margin-left: calc(var(--gutter) * -1);
		margin-right: calc(var(--gutter) * -1);
		margin-top: 8px;
	}

	.page-hero__figure {
		aspect-ratio: 4 / 5;
	}

	.page-hero__figure img {
		object-position: var(--focal-x, 50%) var(--focal-y, 50%);
	}
}

@media (min-width: 360px) and (max-width: 859px) {
	.page-hero {
		position: relative;
		display: flex;
		align-items: center;
		overflow: hidden;
		min-height: min(82vh, 640px);
	}

	.page-hero .section-y {
		padding-top: calc(var(--header-h) + 28px);
		padding-bottom: 44px;
	}

	/* Unpositioned on purpose: give the grid position: relative and the
	   absolute photograph anchors to it rather than to the section. */
	.page-hero__grid {
		width: 100%;
	}

	.page-hero__grid > :first-child {
		position: relative;
		z-index: 2;
		max-width: 56%;
	}

	.page-hero__media {
		position: absolute;
		inset: 0 0 0 36%;
		z-index: 0;
		margin: 0;
		-webkit-mask: linear-gradient(
			to right,
			transparent 0,
			rgba(0, 0, 0, 0.5) 16%,
			#000 44%
		);
		mask: linear-gradient(
			to right,
			transparent 0,
			rgba(0, 0, 0, 0.5) 16%,
			#000 44%
		);
	}

	.page-hero__figure {
		aspect-ratio: auto;
		width: 100%;
		height: 100%;
	}

	.page-hero__figure img {
		width: 100%;
		height: 100%;
		object-fit: cover;
		object-position: var(--focal-x, 50%) var(--focal-y, 50%);
	}

	/* Over the photograph, under the copy, and gone before the subject. */
	.page-hero::before {
		content: '';
		position: absolute;
		inset: 0;
		z-index: 1;
		pointer-events: none;
		background: linear-gradient(
			to right,
			rgba(245, 243, 240, 0.9) 0%,
			rgba(245, 243, 240, 0.68) 38%,
			rgba(245, 243, 240, 0) 62%
		);
	}

	/* A narrower column needs a smaller headline and a shorter measure, or it
	   breaks into two words a line. */
	.page-hero__title {
		font-size: clamp(1.85rem, 7.4vw, 2.5rem);
	}

	.page-hero__lead {
		margin-top: 16px;
		font-size: clamp(1.05rem, 4.4vw, 1.3rem);
	}

	.page-hero__text {
		margin-top: 12px;
		font-size: 14px;
		line-height: 1.7;
	}

	/* --------------------------------------------------------------------
	   A page top whose photograph IS the product, on a phone.

	   The overlay works when the photograph is a background - a treatment
	   room, skin, a branch - because the copy can sit on it and lose
	   nothing. These are the product, shot upright, and at 375px the text
	   column covered half the jar: the one thing the page exists to show.

	   So they stack instead. The photograph takes the full width and runs
	   up behind the header, which is the frame the client asked every page
	   top to have, and the copy follows underneath with nothing on top of
	   it. Same arrangement the home page already uses on a phone.

	   Square, because the source is 4:5 with the product low and air above
	   it: a square crop biased down keeps the whole product and most of
	   what is behind it, without a half-screen-tall photograph.
	   -------------------------------------------------------------------- */
	.page-hero.page-hero--stacked {
		display: block;
		min-height: 0;
		/* The photograph is the first thing in the section now, so the
		   section stops reserving the header's height and lets the picture
		   run up under it - the frame the client asked every page top to
		   have. The header carries its own scrim, so the logo stays legible
		   on it, and the product sits well below the band it covers. */
		padding-top: 0;
	}

	.page-hero--stacked .section-y {
		padding-top: 0;
		padding-bottom: 40px;
	}

	.page-hero--stacked .page-hero__grid {
		gap: 28px;
	}

	.page-hero--stacked .page-hero__grid > :first-child {
		max-width: none;
	}

	.page-hero--stacked .page-hero__media {
		position: static;
		order: -1;
		margin: 0 calc(var(--gutter) * -1);
		-webkit-mask: none;
		mask: none;
	}

	/* Its own shape, so a photograph that is wider than it is tall - the
	   three products together on the collection page - is not cropped into
	   a square and robbed of the two on the outside. */
	.page-hero--stacked .page-hero__figure {
		aspect-ratio: var(--figure-ratio, 4 / 3);
		width: auto;
		height: auto;
	}

	/* An upright photograph would be half the screen at its own shape, so
	   those are squared off and the crop biased down to where the product
	   sits. */
	.page-hero--tall .page-hero__figure {
		aspect-ratio: 1 / 1;
	}

	.page-hero--tall .page-hero__figure img {
		object-position: 50% var(--hero-focus, 84%);
	}

	/* Nothing sits over the photograph any more, so the scrim that kept the
	   heading readable has nothing to do. */
	.page-hero.page-hero--stacked::before {
		content: none;
	}

}
/* --------------------------------------------------------------------------
   The same treatment on every page top: "taip visuose puslapių viršuose".

   These heroes had the photograph in the right-hand column with a height cap,
   which is what stopped it being a 1500px column - but it was still a framed
   panel with the header as a bar above it. Full bleed, up behind the header,
   with the copy on it and the same scrim keeping the heading readable.
   -------------------------------------------------------------------------- */

@media (min-width: 860px) {
	.page-hero {
		position: relative;
		display: flex;
		align-items: center;
		overflow: hidden;
		padding-top: 0;
		min-height: min(78vh, 680px);
	}

	/* Unpositioned, for the same reason as the home hero's grid. */
	.page-hero__grid {
		width: 100%;
		grid-template-columns: minmax(0, 1fr);
		align-items: start;
	}

	.page-hero__grid > :first-child,
	.page-hero__side-label {
		position: relative;
		z-index: 2;
	}

	.page-hero .section-y {
		padding-top: calc(var(--header-h) + 48px);
		padding-bottom: 72px;
	}

	.page-hero__grid > :first-child {
		max-width: 34rem;
	}

	/* Held off the left gutter and faded into the paper, exactly as on the
	   home page, so the heading has its own space and the photograph still
	   runs off the top and the right with no frame around it. */
	.page-hero__media {
		position: absolute;
		inset: 0 0 0 26%;
		z-index: 0;
		min-height: 0;
		margin: 0;
		-webkit-mask: linear-gradient(
			to right,
			transparent 0,
			rgba(0, 0, 0, 0.55) 15%,
			#000 36%
		);
		mask: linear-gradient(
			to right,
			transparent 0,
			rgba(0, 0, 0, 0.55) 15%,
			#000 36%
		);
	}

	/*
	 * A page top whose photograph is held further back.
	 *
	 * The band is far wider than it is tall, so an upright photograph put in
	 * it loses more than half its height: 54% of a 4:5 shot survives at the
	 * standard width, which is why the pages for professionals read as blown
	 * up - you are looking at the middle of a photograph, very close.
	 * Narrowing the band raises that to about 64%, and the picture stops
	 * shouting because less of it was thrown away to fill the width.
	 *
	 * Only these pages. The product page tops were tuned carton by carton,
	 * and changing their shape would undo that work.
	 */
	/*
	 * The collection's page top, for the same reason as the pulled ones: its
	 * band is 74% of the viewport wide against a 3:2 photograph, so on a wide
	 * short window it showed 0.59 of that photograph while the three products
	 * occupy 0.58 of it - no crop value fits in the 0.01 that leaves, and the
	 * tube lost its top. 35vw floors the height against the width and takes
	 * the share to about 0.71.
	 */
	/*
	 * The collection's page top is the home page's hero, and it took four
	 * passes to see why copying its numbers was not enough.
	 *
	 * This file - the three products together - carries headroom a phone
	 * needs and a desktop does not, so both places scale it back by 1.441
	 * from the bottom edge. That transform runs after object-fit has already
	 * chosen its crop, so the two compound: every --hero-focus value tried
	 * here was being measured against the untransformed frame and then moved
	 * again by the scale. The arithmetic said it fitted while the screen
	 * showed the jars cut off, which is exactly the sort of disagreement that
	 * sends a fix back and forth.
	 *
	 * So it now takes the home hero's arrangement whole rather than its
	 * numbers piecemeal: the same 38% band, the same crop held to the top of
	 * the frame, the same scale-back. --hero-focus is deliberately not used
	 * here - with the band this shape there is nothing left to crop, and a
	 * second knob on the same axis is what caused the trouble.
	 */
	/*
	 * Height off the width alone, with no vh term. A vh term is what made
	 * this look right here and wrong on the client's screen: on a window that
	 * is narrow and tall the band turns upright, cover then crops sideways
	 * instead of down, and the 1.441 pushes the outer two products past the
	 * edges. Tying the height to the width keeps the band the same shape at
	 * every window, so the composition cannot change underneath us.
	 */
	.page-hero--collection {
		min-height: max(40vw, 420px);
	}

	.page-hero--collection .page-hero__media {
		inset: 0 0 0 38%;
	}

	.page-hero--collection .page-hero__figure img {
		object-position: 60% top;
	}

	.page-hero--pulled .page-hero__media {
		/*
		 * 52%, not 44%. The tube fills just over half its own frame, and a
		 * band this wide shows only a little more than that - it fitted by a
		 * few percent and lost its cap on any window shorter than the one it
		 * was measured on. Narrowing the band is the honest way to pull a
		 * photograph back: it shows more of the real picture, where padding
		 * the file again only stacked artefacts on the wall behind it.
		 *
		 * 50% and not 52%, so a page top splits exactly where the bands below
		 * it do. Philosophy had its opening photograph starting at 21% and the
		 * band under it at 50%, and two full-bleed pictures meeting on two
		 * different lines is what the client saw as them doubling up.
		 */
		inset: 0 0 0 50%;
	}

	/*
	 * And a crop of their own. These bands carry upright product photographs
	 * whose subject runs from about 36% to 87% of the frame; the 84% the
	 * product pages use puts the top of that outside the band as soon as the
	 * window is short, which is how the SPF tube lost its cap. 60% sits the
	 * whole product inside at every window shape the band takes.
	 */
	.page-hero--pulled {
		--hero-focus: 76%;
	}

	.page-hero__figure {
		aspect-ratio: auto;
		width: 100%;
		height: 100%;
	}

	.page-hero__figure img {
		width: 100%;
		height: 100%;
		object-fit: cover;
		object-position: 55% var(--hero-focus, center);
	}

	/*
	 * A product photographed upright, shown in a page top that is wide.
	 *
	 * The client's product photographs are 4:5 with the carton low in the
	 * frame and air above it - which is what leaves room for the heading. A
	 * centred crop is right for the landscape photographs every other page
	 * top carries, and on these it cut the carton in half, taking the
	 * product's own name off the page the product is the subject of.
	 *
	 * Taller, and the crop biased downwards: the whole carton stays in frame
	 * and the branch above it keeps enough of itself to still read as one.
	 */
	.page-hero.page-hero--tall {
		min-height: min(88vh, 860px);
	}

	/*
	 * A page top carrying an upright product shot needs a height that answers
	 * to its own width, not only to the window's height.
	 *
	 * The band is half the viewport wide, so on a wide screen it grows
	 * sideways while 88vh holds it down, and the share of the photograph it
	 * can show falls with it. On a wide, short window that share drops to
	 * about 61% while the SPF tube occupies 65% of its frame - at which point
	 * no crop value can keep the whole tube in view, which is why it looked
	 * right in a tall narrow pane and lost its cap in a real browser window.
	 *
	 * 44vw floors the height against the width, holding the band at 1.14 or
	 * squarer, so the photograph always gives up at least 70% of its height
	 * and the product fits with room to spare.
	 */
	.page-hero.page-hero--tall.page-hero--pulled {
		min-height: max(min(88vh, 860px), 44vw);
	}

	.page-hero--tall .page-hero__figure img {
		object-position: 55% var(--hero-focus, 84%);
	}

	.page-hero::before {
		content: '';
		position: absolute;
		inset: 0;
		z-index: 1;
		pointer-events: none;
		background: linear-gradient(
			to right,
			rgba(245, 243, 240, 0.85) 0%,
			rgba(245, 243, 240, 0.4) 28%,
			rgba(245, 243, 240, 0) 44%
		);
	}
}

.page-hero__side-label {
	display: none;
}

@media (min-width: 1180px) {
	.page-hero__side-label {
		display: block;
		position: absolute;
		left: 18px;
		top: 50%;
		transform: translateY(-50%);
		z-index: 2;
	}
}

/* ==========================================================================
   Product hero
   ========================================================================== */

.product-hero {
	position: relative;
	background: var(--paper);
	overflow: hidden;
}

.product-hero__grid {
	display: grid;
	gap: 40px;
	align-items: center;
}

@media (min-width: 860px) {
	/* Two columns again from tablet up: the name above the description in the
	   left column, the photograph spanning both rows on the right. The stacked
	   order below this width - name, photograph, description - is simply the
	   markup order, which is why the blocks are separate in the first place. */
	.product-hero__grid {
		grid-template-columns: 1fr 1fr;
		grid-template-rows: auto auto;
		column-gap: 56px;
		row-gap: 0;
	}

	.product-hero__head {
		grid-column: 1;
		grid-row: 1;
		align-self: end;
	}

	.product-hero__detail {
		grid-column: 1;
		grid-row: 2;
		align-self: start;
		padding-top: 26px;
	}

	.product-hero__media {
		grid-column: 2;
		grid-row: 1 / span 2;
	}
}

.product-hero__num {
	display: block;
	color: var(--seal);
	margin-bottom: 14px;
}

/* A product opened with a photograph borrows the page top, so it needs only
   the two pieces that page tops do not have: the number above the name, and
   the badges under the copy. */
.product-hero--photo .product-hero__badges {
	margin-top: 28px;
}

/* Matched to .page-hero__title above: a product opened with a photograph is a
   page top like any other, and the two had drifted a size apart. */
.product-hero__title {
	font-family: var(--display);
	font-weight: 300;
	font-size: clamp(2.2rem, 5.4vw, 3.9rem);
	line-height: 1.05;
	letter-spacing: -0.012em;
	margin: 0;
	color: var(--ink);
}

.product-hero__tagline {
	font-family: var(--display);
	font-size: clamp(1.15rem, 2vw, 1.5rem);
	line-height: 1.35;
	color: var(--ink);
	margin: 0 0 18px;
}

.product-hero__intro {
	margin: 0 0 22px;
	max-width: 46ch;
}

/* The photograph between the name and the description wants a little air of
   its own on a phone, where the three blocks are stacked. */
.product-hero__media {
	margin: 4px 0;
}

.product-hero__badges {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.badge {
	border: 1px solid var(--line);
	padding: 8px 14px;
	color: var(--muted);
}

.product-hero__figure {
	aspect-ratio: 4 / 5;
}

@media (min-width: 860px) {
	/* A height, not a ratio: a ratio made this as tall as its column is wide,
	   834x1043 at 1900px, and the hero ran to 1259px.

	   The height is also what decides how large the product is actually drawn,
	   because object-fit: contain sizes the image by whichever edge runs out
	   first - in a frame wider than it is tall, that is always the height. At
	   46vh the cut-outs came out around 414px in a 612px frame, with a wide
	   band of nothing either side of them. 58vh draws them at 498px. */
	.product-hero__figure {
		aspect-ratio: auto;
		height: clamp(420px, 58vh, 620px);
	}
}

.product-hero__side-label {
	display: none;
}

@media (min-width: 1180px) {
	.product-hero__side-label {
		display: block;
		position: absolute;
		right: 18px;
		top: 50%;
		transform: translateY(-50%);
		z-index: 2;
	}
}

/* ==========================================================================
   Product tab bar
   ========================================================================== */

.product-tabs {
	position: sticky;
	top: 0;
	z-index: 20;
	background: rgba(245, 243, 240, 0.9);
	backdrop-filter: blur(10px);
	border-top: 1px solid var(--line);
	border-bottom: 1px solid var(--line);
}

.product-tabs__list {
	display: flex;
	gap: 28px;
	margin: 0;
	padding-top: 18px;
	padding-bottom: 18px;
	list-style: none;
	overflow-x: auto;
	scrollbar-width: none;
}

.product-tabs__list::-webkit-scrollbar {
	display: none;
}

/* --------------------------------------------------------------------------
   Something to aim a thumb at.

   These labels are 11px, which makes a link about 13px tall - fine for a
   mouse, and small for a finger. WCAG 2.2 asks for 24x24 CSS pixels on a
   target that is not a word inside a sentence, and the audit counted twelve
   to seventeen of them on a phone: the tab bar, the footer's lists, the
   arrows, the Sentaku Group line.

   The fix is padding rather than type size, so nothing about the design
   changes - the text stays where it is and the target grows around it.
   -------------------------------------------------------------------------- */

.product-tabs__link {
	display: inline-flex;
	align-items: center;
	min-height: 26px;
	color: var(--muted);
	white-space: nowrap;
	transition: color 0.3s ease;
}

.site-footer__links a,
.site-footer__legal a,
.brand__parent {
	display: inline-flex;
	align-items: center;
	min-height: 26px;
}

.link-arrow {
	min-height: 26px;
}

.product-tabs__link:hover,
.product-tabs__link:focus-visible,
.product-tabs__link.is-active {
	color: var(--seal);
}

/* ==========================================================================
   Product sections
   ========================================================================== */

.product-overview {
	background: var(--paper-light);
	overflow: hidden;
}

.product-overview__grid {
	display: grid;
}

@media (min-width: 860px) {
	.product-overview__grid {
		grid-template-columns: 1fr 1fr;
		align-items: stretch;
	}
}

.product-overview__lead {
	font-family: var(--display);
	font-size: clamp(1.2rem, 2.2vw, 1.6rem);
	line-height: 1.3;
	color: var(--ink);
	margin: 0 0 18px;
}

.product-overview__text {
	margin: 0;
	max-width: 52ch;
}

.product-overview__media {
	min-height: 320px;
}

/* A photograph takes its own shape, so nothing is cropped. */
.product-overview__figure {
	aspect-ratio: var(--figure-ratio, auto);
	height: 100%;
}

/* A floor, not a fallback. This also used to test the frame's style
   attribute, which stopped meaning anything once the measurements moved to
   the wrapper - see the note beside .copy-media__figure. */
.product-overview__figure {
	min-height: 320px;
}

/*
 * On a phone the same figure has to take its width from the page instead.
 *
 * aspect-ratio plus height: 100% means the figure derives its WIDTH from its
 * height, and the panel around it carries a 320px min-height. At 375px that
 * produced a 498px-wide figure - and because the column is an auto grid
 * track, sized to the widest thing in it, the copy beside it was dragged out
 * to 480px and clipped against the section's overflow: hidden. The heading
 * and the lead lost their last words with nothing to scroll to.
 *
 * Stacked on a phone there is no second column whose height has to be
 * matched, so the figure takes its width from the page and its height from
 * its own shape, and the track is pinned to the container.
 */
/*
 * On a phone the copy and the photograph share the band rather than stacking.
 *
 * Stacked, the picture landed under the last paragraph and read as an
 * afterthought - the client asked for it on the same line. This is the
 * arrangement the page tops already use at this width: copy on the left with
 * its own scrim, photograph held off the left edge and faded into the paper,
 * the two occupying one section instead of two.
 *
 * It also settles the overflow that lived here. A figure with an
 * aspect-ratio and height: 100% takes its WIDTH from its height, and the
 * panel carried a 320px min-height: at 375px that made the figure 498px wide,
 * and because the column is an auto grid track it dragged the copy out to
 * 480px and clipped it. Absolutely positioned, the figure is no longer in the
 * track at all and cannot widen it.
 */
@media (max-width: 859px) {
	.product-overview--beside {
		position: relative;
	}

	.product-overview__grid {
		grid-template-columns: minmax(0, 1fr);
	}

	/* Stacked, which is every photograph that fills its own frame. The
	   figure takes its width from the page and its height from its shape;
	   left to derive width from the panel's min-height it came out 498px
	   wide at 375px and dragged the copy out of the screen with it. */
	.product-overview:not(.product-overview--beside) .product-overview__media {
		min-height: 0;
	}

	.product-overview:not(.product-overview--beside) .product-overview__figure {
		width: 100%;
		height: auto;
		max-width: 100%;
	}

	.product-overview--beside .product-overview__copy {
		position: relative;
		z-index: 2;
		max-width: 62%;
	}

	.product-overview--beside .product-overview__media {
		position: absolute;
		inset: 0 0 0 40%;
		z-index: 0;
		min-height: 0;
		margin: 0;
		-webkit-mask-image: linear-gradient(to right, transparent 0, rgba(0, 0, 0, 0.5) 16%, #000 44%);
		mask-image: linear-gradient(to right, transparent 0, rgba(0, 0, 0, 0.5) 16%, #000 44%);
	}

	.product-overview--beside .product-overview__figure {
		width: 100%;
		height: 100%;
		max-width: 100%;
		aspect-ratio: auto;
	}

	/* Over the photograph, under the copy, gone before the subject. */
	.product-overview--beside::before {
		content: '';
		position: absolute;
		inset: 0;
		z-index: 1;
		pointer-events: none;
		background: linear-gradient(
			to right,
			rgba(250, 249, 248, 0.92) 0%,
			rgba(250, 249, 248, 0.7) 40%,
			rgba(250, 249, 248, 0) 64%
		);
	}
}

/* A cut-out is the other case entirely: shown whole with air around it, on the
   section, the way the product heroes show one. Given its own shape it became
   a tall narrow strip of carton in the middle of a wide column. */
.product-overview__figure--cutout {
	aspect-ratio: auto;
	height: clamp(340px, 34vw, 460px);
	min-height: 0;
}

.product-overview__figure--cutout img {
	padding: 8%;
}

.product-benefits {
	background: var(--white);
}

.product-benefits__grid {
	display: grid;
	gap: 34px;
	margin-top: 44px;
}

@media (min-width: 620px) {
	.product-benefits__grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 1024px) {
	.product-benefits__grid {
		grid-template-columns: repeat(4, 1fr);
		gap: 0;
	}

	.product-benefits__item {
		padding: 0 28px;
		border-left: 1px solid var(--line);
	}

	.product-benefits__item:first-child {
		padding-left: 0;
		border-left: 0;
	}
}

/* The client's line icons: black on transparent, so they take the ink of the
   page and need nothing but a size. Held small - they are a mark beside a
   benefit, not an illustration of it. */
.product-benefits__icon {
	width: 44px;
	height: 44px;
	margin-bottom: 20px;
}

.product-benefits__icon img {
	width: 100%;
	height: 100%;
	object-fit: contain;
}

.product-benefits__title {
	color: var(--ink);
	margin: 0 0 12px;
}

.product-benefits__text {
	margin: 0;
	font-size: 14px;
}

.product-tech {
	background: var(--paper);
}

.product-tech__grid {
	display: grid;
	gap: 34px;
	margin-top: 44px;
}

@media (min-width: 620px) {
	.product-tech__grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 1024px) {
	.product-tech__grid {
		grid-template-columns: repeat(4, 1fr);
	}
}

/*
 * Discs, not framed squares.
 *
 * These were a white square with the picture letterboxed inside it, and on
 * the paper background every one of them read as a box first and a picture
 * second. Nearly all of the client's illustrations are already composed in
 * the round - a droplet, a bead of oil, a spread of cream - so the frame was
 * fighting the artwork.
 *
 * Rounded corners are deliberately absent everywhere else in this design, and
 * this is the client asking for them here: the exception is hers, not a
 * drift.
 */
.product-tech__figure {
	aspect-ratio: 1 / 1;
	margin-bottom: 20px;
	border-radius: 50%;
	overflow: hidden;
	/* A hairline instead of a filled box: the disc reads as drawn on the
	   page rather than sitting on top of it. */
	box-shadow: inset 0 0 0 1px var(--line);
	/* Sized, not stretched to its column. Four columns on a wide screen made
	   these 295px across, which is a row of plates rather than a row of
	   illustrations; one per row on a phone made them the whole screen. The
	   cap holds them to the same size at every width, which is what makes the
	   row read as one set. */
	max-width: 170px;
}

.product-tech__name {
	color: var(--ink);
	margin: 0 0 12px;
}

.product-tech__text {
	margin: 0;
	font-size: 14px;
}

.product-ritual {
	background: var(--white);
	overflow: hidden;
}

.product-ritual__grid {
	display: grid;
}

@media (min-width: 860px) {
	.product-ritual__grid {
		grid-template-columns: 1fr 1fr;
		align-items: stretch;
	}
}

.product-ritual__media {
	order: 2;
	min-height: 320px;
}

.product-ritual__copy {
	order: 1;
}

@media (min-width: 860px) {
	.product-ritual__media {
		order: 1;
	}

	.product-ritual__copy {
		order: 2;
	}
}

.product-ritual__figure {
	height: 100%;
	min-height: 320px;
}

.product-ritual__intro {
	margin: 0 0 32px;
	max-width: 46ch;
}

.product-ritual__steps {
	display: grid;
	gap: 26px;
	margin: 0;
	padding: 0;
	list-style: none;
}

/* The link the client's copy closes this section with. Spaced like the other
   closing links on the site, so it reads as the end of the section rather than
   a fifth step. */
.product-ritual__cta {
	margin: 40px 0 0;
}

@media (min-width: 620px) {
	.product-ritual__steps {
		grid-template-columns: repeat(2, 1fr);
		gap: 30px 24px;
	}
}

.product-ritual__step {
	position: relative;
}

.product-ritual__num {
	display: block;
	color: var(--seal);
	margin-bottom: 8px;
}

.product-ritual__name {
	font-family: var(--display);
	font-weight: 300;
	font-size: 1.35rem;
	line-height: 1.2;
	margin: 0 0 6px;
	color: var(--ink);
}

.product-ritual__text {
	margin: 0;
	font-size: 14px;
}

.product-ritual__arrow {
	display: none;
	color: var(--seal);
}

.product-details {
	background: var(--paper-light);
}

.product-details__wrap {
	display: grid;
	gap: 40px;
	margin-top: 44px;
}

@media (min-width: 860px) {
	.product-details__wrap {
		grid-template-columns: 1fr 1fr;
		gap: 56px;
	}
}

.product-details__list {
	margin: 0;
}

.product-details__row {
	display: grid;
	gap: 4px;
	padding: 16px 0;
	border-bottom: 1px solid var(--line);
}

@media (min-width: 620px) {
	.product-details__row {
		grid-template-columns: 180px 1fr;
		gap: 20px;
		align-items: baseline;
	}
}

.product-details__label {
	color: var(--muted);
	margin: 0;
}

.product-details__value {
	margin: 0;
}

.product-details__composition-title {
	color: var(--muted);
	margin: 0 0 12px;
}

.product-details__composition-text {
	margin: 0;
	font-size: 13px;
	line-height: 1.8;
	color: var(--ink-soft);
}

/* The link to the full professional information. Sits under the composition
   when there is one, and on its own when there is not. */
.product-details__pro {
	margin: 24px 0 0;
}

.product-details__composition-text + .product-details__pro,
.product-details__composition-title + .product-details__pro {
	padding-top: 20px;
	border-top: 1px solid var(--line);
}

.related {
	background: var(--white);
}

.related__grid {
	display: grid;
	gap: 30px;
	margin-top: 44px;
}

@media (min-width: 620px) {
	.related__grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 1024px) {
	.related__grid {
		grid-template-columns: repeat(4, 1fr);
	}
}

.related__link {
	display: block;
	text-align: center;
}

.related__figure {
	aspect-ratio: 4 / 5;
	margin-bottom: 20px;
	transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

.related__link:hover .related__figure {
	transform: translateY(-10px);
}

.related__name {
	font-family: var(--display);
	font-weight: 300;
	font-size: 1.2rem;
	line-height: 1.25;
	margin: 0 0 8px;
	color: var(--ink);
}

.related__tagline {
	margin: 0;
	color: var(--muted);
	font-size: 10px;
}

/* ==========================================================================
   Products archive
   ========================================================================== */

.collection {
	background: var(--paper-light);
}

.collection__head {
	text-align: center;
	max-width: 640px;
	margin: 0 auto 60px;
}

.collection__lead {
	font-family: var(--display);
	font-size: clamp(1.2rem, 2.2vw, 1.6rem);
	line-height: 1.3;
	color: var(--ink);
	margin: 0 0 16px;
}

.collection__text {
	margin: 0;
}

/* One grid of products.

   The category rows this replaced - a heading on the left, that category's
   products on the right - were mostly empty space with one product in each,
   and the rules between them cut the page into three. The products now run
   together and each carries its category as an eyebrow.

   Three columns at desktop, so the range as it stands sits on one line, and a
   fourth or fifth product wraps underneath with nothing here to change. Never
   auto-fit: it collapses the tracks it has no items for and stretches what is
   left, which is what once blew a single product up to the full width of a
   row. */
.collection__items {
	display: grid;
	gap: 30px;
	margin-top: 28px;
}

@media (min-width: 620px) {
	.collection__items {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 36px;
	}
}

@media (min-width: 1024px) {
	.collection__items {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: 48px;
	}
}

/*
 * Centred, like the row on the home page and for the same reason: the product
 * stands in the middle of its frame, and the category, the name and the size
 * were ranged left underneath it, so each card read as two things that had
 * been put next to each other rather than one. The professional link below
 * the card follows it.
 */
.collection__link {
	display: block;
	text-align: center;
}

.collection__pro {
	justify-content: center;
}

/* No panel behind the product.

   These are cut-outs on transparent backgrounds, and a white block behind one
   put it back in a box - which is what the client was looking at when she
   said the photographs needed to be background-free. The cut-out now sits
   straight on the section. */
.collection__figure {
	aspect-ratio: 4 / 5;
	margin-bottom: 20px;
	transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

/* The cut-outs are drawn at different scales, so each one is brought to the
   same size here rather than left as the file happens to be.
   shinsen_cutout_scale() measures it; a file already right sends nothing. */
.collection__figure img {
	transform: scale(var(--cutout-scale, 1));
}

.collection__link:hover .collection__figure {
	transform: translateY(-10px);
}

.collection__item-cat {
	margin: 0 0 8px;
	color: var(--seal);
}

.collection__item-name {
	font-family: var(--display);
	font-weight: 300;
	font-size: 1.15rem;
	line-height: 1.25;
	margin: 0 0 8px;
	color: var(--ink);
}

.collection__item-size {
	margin: 0 0 14px;
	color: var(--muted);
	font-size: 10px;
}

/* Sits under the card's own link, separated by a hairline so it reads as a
   second destination rather than as more of the same block. */
/* The cards become flex columns so this link lands on the same line across the
   row, whatever the length of the name or tagline above it. */
.collection__item,
.related__item,
.essentials__item {
	display: flex;
	flex-direction: column;
}

.collection__link,
.related__link,
.essentials__link {
	flex: 1 1 auto;
}

.collection__pro,
.related__pro {
	margin-top: 16px;
	padding-top: 16px;
	border-top: 1px solid var(--line);
	width: 100%;
}

/* The home and professional rows centre their cards, and their padding lives
   on the link rather than the item, so this one carries its own. */
.essentials__pro {
	align-self: center;
	margin: 0 16px 40px;
	padding-top: 18px;
	border-top: 1px solid var(--line);
}

.closing {
	background: var(--white);
}

.closing__inner {
	text-align: center;
	max-width: 680px;
	margin: 0 auto;
}

.closing__title {
	font-family: var(--display);
	font-weight: 300;
	font-size: clamp(1.7rem, 3.6vw, 2.6rem);
	line-height: 1.12;
	letter-spacing: -0.01em;
	margin: 0;
	color: var(--ink);
}

.closing__text {
	margin: 0 0 28px;
}

.closing__cta {
	margin: 0;
}

/* ==========================================================================
   Philosophy page
   ========================================================================== */

.essence {
	background: var(--paper-light);
}

.essence__inner,
.story__inner,
.rooted__inner {
	max-width: 720px;
}

/* --------------------------------------------------------------------------
   Copy with a photograph beside it.

   Used by "Our story" and "Rooted in Japan", on opposite sides, to break up
   the run of text sections on the philosophy page. Either image can be left
   out in Settings, and --solo puts that section back to full-width text.
   -------------------------------------------------------------------------- */

.copy-media {
	display: grid;
	gap: 36px;
}

.copy-media--solo {
	display: block;
}

/* The photographs run off the edge of the page rather than sitting in it.

   Framed, they read as pictures pasted onto the page - the client's words were
   that they simply look bad - and a photograph shot on a white ground makes it
   worse, because its own background becomes a pale rectangle on the paper.
   Carrying the image past the gutter removes the outer edge entirely: what is
   left is a band of photograph, which is what the ingredients and ritual
   sections have always done and why those never looked pasted on.

   The inner edge stays, and should: it is where the photograph meets its text,
   and the gap there is what keeps the two readable as a pair. */
/*
 * A photograph fills its half of the band. No fade, at either edge.
 *
 * Every softening attempt made this worse rather than better. A fade works
 * by letting the paper win at the edge, and on anything that does not end in
 * paper it reads as a grey band with a line at each end - the client called
 * it, accurately, a blurred box. Easing the ramp, lengthening it and
 * measuring it per photograph all moved the problem without solving it.
 *
 * So the section photographs now do what the home page has always done: fill
 * their half of the band, stretch to its height, run off the outer edge. The
 * edge that remains is the edge of a panel, and a panel does not need
 * disguising.
 */
.copy-media__media {
	position: relative;
	min-height: clamp(320px, 62vw, 460px);
}

.copy-media__figure {
	height: 100%;
}

.copy-media__figure img,
.product-overview__figure img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: var(--focal-x, 50%) var(--focal-y, 50%);
}

@media (min-width: 860px) {
	/*
	 * No gap, and the reason is alignment rather than taste.
	 *
	 * A gap moves the seam between copy and photograph off the centre by half
	 * its width. With 64px here, 1.15fr on the ingredients grid and nothing on
	 * the rest, Philosophy had its three photographs starting at three
	 * different places down the page - which is what the client kept seeing as
	 * sections that do not line up.
	 *
	 * Every band that pairs copy with a photograph now splits at exactly 50%,
	 * the way the home page always did. The copy does not need the gap: its
	 * own page-gutter already holds it off the seam by the same distance it is
	 * held off the edge of the page.
	 */
	.copy-media {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 0;
		align-items: stretch;
	}

	/* The copy's own 720px cap is for a full-width column; in half of one it
	   only gets in the way. */
	.copy-media__copy {
		max-width: none;
	}

	.copy-media--reverse .copy-media__copy {
		order: 2;
	}

	.copy-media--reverse .copy-media__media {
		order: 1;
	}

	/*
	 * From here up the photograph is a panel: it fills its half of the band,
	 * stretched to the band's height and running off the outer edge, exactly
	 * as the home page has always shown these. Nothing is masked and nothing
	 * floats, so there is no edge left to disguise.
	 */
	.copy-media {
		align-items: stretch;
	}

	/*
	 * How tall the band is depends on the photograph in it.
	 *
	 * A panel crops to fill, and a fixed height crops an upright photograph
	 * savagely: a 2:3 shot in a 720x486 panel shows 45% of itself, which is
	 * what "not the full picture" meant. The height a panel needs to show all
	 * of one is its own width divided by the photograph's ratio, so that is
	 * what it asks for.
	 *
	 * The ceiling used to be a fixed 860px, and that was the bug behind the
	 * portrait losing its forehead: the panel is half the viewport, so on a
	 * wide screen it grows sideways while a fixed ceiling holds it down, and
	 * the crop gets worse the larger the monitor. At 1520px the portrait
	 * showed 91% of itself and at 1835px only 75%. A ceiling in vw rises with
	 * the panel, so the share stays the same at every width; 78vw still stops
	 * one upright picture from making a section taller than two screens.
	 *
	 * --figure-ratio is already on the wrapper, measured from the file.
	 */
	.copy-media__media {
		min-height: clamp(440px, calc(50vw / var(--figure-ratio, 1.4)), 78vw);
	}

	.copy-media__figure {
		position: absolute;
		inset: 0;
		width: 100%;
		height: 100%;
		aspect-ratio: auto;
	}

}

.essence__text,
.story__text {
	margin: 0 0 20px;
}

.story {
	background: var(--paper);
}

.story__closing {
	font-family: var(--display);
	font-size: clamp(1.2rem, 2.2vw, 1.6rem);
	line-height: 1.3;
	color: var(--ink);
	margin: 28px 0 0;
}

.pillars {
	background: var(--white);
}

.pillars__head {
	text-align: center;
	margin-bottom: 56px;
}

.pillars__grid {
	display: grid;
	gap: 34px;
}

@media (min-width: 620px) {
	.pillars__grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 1024px) {
	.pillars__grid {
		grid-template-columns: repeat(4, 1fr);
		gap: 0;
	}

	.pillars__item {
		padding: 0 28px;
		border-left: 1px solid var(--line);
	}

	.pillars__item:first-child {
		padding-left: 0;
		border-left: 0;
	}

	.pillars__grid--three {
		grid-template-columns: repeat(3, 1fr);
	}
}

.pillars__name {
	color: var(--ink);
	margin: 0 0 12px;
}

.pillars__text {
	margin: 0;
	font-size: 14px;
}

.rooted {
	background: var(--paper);
}

.rooted--center {
	background: var(--paper-light);
}

.rooted__inner--center {
	max-width: 680px;
	margin: 0 auto;
	text-align: center;
}

.rooted__text {
	margin: 0;
}

.phil-ingredients {
	background: var(--ink);
	color: var(--paper);
	overflow: hidden;
}

.phil-ingredients__grid {
	display: grid;
}

@media (min-width: 960px) {
	/* Equal halves, like every other band - 1.15fr put this photograph's edge
	   3.5% off the line the others share. */
	.phil-ingredients__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		align-items: stretch;
	}
}

.phil-ingredients__lead {
	margin: 0 0 36px;
	color: rgba(245, 243, 240, 0.72);
	max-width: 48ch;
}

.phil-ingredients__list {
	margin: 0;
}

.phil-ingredients__row {
	padding: 20px 0;
	border-top: 1px solid rgba(245, 243, 240, 0.16);
}

.phil-ingredients__name {
	margin: 0 0 8px;
	color: var(--paper);
}

.phil-ingredients__text {
	margin: 0;
	font-size: 14px;
	color: rgba(245, 243, 240, 0.72);
}

.phil-ingredients__media {
	min-height: 320px;
}

.phil-ingredients__figure {
	height: 100%;
	min-height: 320px;
}

.difference {
	background: var(--white);
	overflow: hidden;
}

.difference__grid {
	display: grid;
}

@media (min-width: 860px) {
	.difference__grid {
		grid-template-columns: 1fr 1fr;
		align-items: stretch;
	}
}

.difference__media {
	min-height: 320px;
}

.difference__figure {
	height: 100%;
	min-height: 320px;
}

.difference__text {
	margin: 0 0 28px;
	max-width: 48ch;
}

.difference__cta {
	margin: 0;
}

/* ==========================================================================
   Contact page
   ========================================================================== */

.contact {
	background: var(--paper);
}

.contact__grid {
	display: grid;
	gap: 40px;
	align-content: start;
}

@media (min-width: 860px) {
	/* The details get the wider column: they are what a visitor came to this
	   page for, while the column beside them is one sentence and a button
	   until a form plugin fills it out. An even split left that half looking
	   abandoned, and align-items: start stops the short column stretching to
	   the tall one's height. */
	.contact__grid {
		grid-template-columns: 0.8fr 1.2fr;
		gap: 72px;
		align-items: start;
	}
}

.contact__note,
.contact__fallback-text {
	margin: 0 0 24px;
	max-width: 44ch;
}

.contact__block {
	padding: 18px 0;
	border-bottom: 1px solid var(--line);
}

.contact__block:first-of-type {
	border-top: 1px solid var(--line);
}

.contact__label {
	margin: 0 0 8px;
	color: var(--muted);
}

.contact__value {
	margin: 0 0 4px;
}

.contact__value:last-child {
	margin-bottom: 0;
}

@media (min-width: 560px) {
	/* Label beside the value instead of above it. With the labels stacked on
	   top, reading the details meant zig-zagging down the page; in a column
	   they line up and the values read straight down beside them. */
	.contact__block {
		display: grid;
		grid-template-columns: 7.5rem 1fr;
		column-gap: 28px;
		align-items: baseline;
	}

	.contact__label {
		margin: 0;
	}

	.contact__block .contact__value {
		grid-column: 2;
	}
}

.contact__value a {
	color: var(--ink-soft);
	border-bottom: 1px solid var(--line);
	transition: color 0.3s ease, border-color 0.3s ease;
}

.contact__value a:hover,
.contact__value a:focus-visible {
	color: var(--seal);
	border-color: var(--seal);
}

/* The form: underline fields, no boxes, no radius.

   Written against .contact__form rather than the theme's own class names, so
   that a plugin form pasted into the shortcode field - Contact Form 7, say -
   lands in the same clothes instead of arriving with its own. */
.contact__form input[type="text"],
.contact__form input[type="email"],
.contact__form input[type="tel"],
.contact__form textarea {
	width: 100%;
	border: 0;
	border-bottom: 1px solid var(--line);
	border-radius: 0;
	background: transparent;
	padding: 14px 0;
	font-family: var(--sans);
	font-weight: 300;
	font-size: 15px;
	color: var(--ink);
}

.contact__form input:focus,
.contact__form textarea:focus {
	outline: 0;
	border-bottom-color: var(--seal);
}

.contact__form label {
	display: block;
	margin-bottom: 18px;
	font-family: var(--sans);
	font-weight: 400;
	font-size: 11px;
	text-transform: uppercase;
	letter-spacing: 0.2em;
	color: var(--muted);
}

.contact__form input[type="submit"] {
	margin-top: 12px;
	border: 0;
	border-radius: 0;
	background: var(--ink);
	color: var(--paper);
	padding: 18px 34px;
	font-family: var(--sans);
	font-weight: 400;
	font-size: 11px;
	text-transform: uppercase;
	letter-spacing: 0.2em;
	cursor: pointer;
	transition: background-color 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}

.contact__form input[type="submit"]:hover,
.contact__form input[type="submit"]:focus-visible {
	background: var(--seal);
}

/* --- the theme's own form ------------------------------------------------ */

.form__row {
	margin: 0 0 34px;
}

/* Scoped to .contact__form so it outranks the .contact__form label rule above,
   which is written for whatever a plugin might emit and sets a wider gap. */
.contact__form .form__label {
	display: block;
	margin-bottom: 10px;
	color: var(--muted);
}

/* A colour change alone is not a focus state - it is invisible to anyone who
   cannot see the difference between grey and red. The line thickens as well,
   and keyboard users additionally get a ring, which pointer users never see. */
.form__input:focus {
	outline: 0;
	border-bottom-width: 2px;
	border-bottom-color: var(--seal);
	padding-bottom: 13px;
}

.form__input:focus-visible {
	outline: 2px solid var(--seal);
	outline-offset: 3px;
}

.form__input--area {
	resize: vertical;
	min-height: 150px;
	line-height: 1.75;
}

.form__row--error .form__input {
	border-bottom-color: var(--seal);
}

.form__error {
	display: block;
	margin-top: 8px;
	font-size: 13px;
	line-height: 1.5;
	color: var(--seal);
}

.form__actions {
	margin: 40px 0 0;
}

.form__privacy {
	margin: 22px 0 0;
	max-width: 44ch;
	font-size: 13px;
	line-height: 1.7;
	color: var(--muted);
}

.form__privacy a {
	color: var(--muted);
	border-bottom: 1px solid var(--line);
	transition: color 0.3s ease, border-color 0.3s ease;
}

.form__privacy a:hover,
.form__privacy a:focus-visible {
	color: var(--seal);
	border-color: var(--seal);
}

/* Only ever present in the frozen review copy, where the form cannot post
   anywhere. The snapshot adds it; WordPress never renders it. */
.form__privacy--preview {
	margin: 0 0 26px;
	padding-left: 14px;
	border-left: 2px solid var(--line);
	font-style: italic;
}

/* The honeypot. Off-screen rather than display:none, because some bots skip
   fields that are plainly hidden and this one is meant to look ordinary. */
.form__trap {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

/* What the visitor sees after pressing send, either way. */
.form-notice {
	padding: 26px 28px;
	border-left: 2px solid var(--seal);
	background: var(--paper-light);
}

.form-notice--sent {
	border-left-color: var(--ink);
}

.form-notice__title {
	margin: 0;
	font-family: var(--display);
	font-size: clamp(1.3rem, 2.2vw, 1.7rem);
	line-height: 1.2;
	color: var(--ink);
}

.form-notice__text {
	margin: 10px 0 0;
	max-width: 46ch;
	font-size: 14px;
	line-height: 1.7;
	color: var(--ink-soft);
}

.form-notice--error .form-notice__text {
	margin-top: 0;
}

/* Sticky tab bar overlaps anchors without this. The last five are section
   anchors that can be linked to directly from outside the site. */
#overview,
#benefits,
#technology,
#ritual,
#details,
#ingredients,
#science,
#education,
#partner,
#collection {
	scroll-margin-top: 80px;
}

/* --------------------------------------------------------------------------
   The collection page's top, where the photograph is three products wide.

   Every other page top carries a portrait with room to its left, so the
   heading sits in that room and the copy never reaches the subject. The
   collection shot has all three products spread across it, and the empty
   margin on its left is much narrower - narrower still once the panel, which
   is taller than the photograph's own shape, crops the sides to fill.

   Measured across the range: with the copy at its natural 34rem the lead only
   cleared the first jar above about 1640px. Every ordinary laptop had the
   sentence running onto the packaging.

   So below 1000px it stacks, the way the phone does, because at that width
   the two cannot share a line - the copy alone wants 58% of the screen and
   the products start at 40% of it. Above that the measure follows the
   viewport instead of being fixed, which holds the gap roughly constant
   rather than letting it close as the screen narrows.
   -------------------------------------------------------------------------- */

@media (min-width: 860px) and (max-width: 999px) {
	.page-hero.page-hero--stacked:not(.page-hero--tall) {
		display: block;
		min-height: 0;
		padding-top: var(--header-h);
	}

	.page-hero--stacked:not(.page-hero--tall) .section-y {
		padding-top: 0;
		padding-bottom: 40px;
	}

	.page-hero--stacked:not(.page-hero--tall) .page-hero__grid {
		grid-template-columns: minmax(0, 1fr);
		gap: 28px;
	}

	.page-hero--stacked:not(.page-hero--tall) .page-hero__grid > :first-child {
		max-width: none;
	}

	.page-hero--stacked:not(.page-hero--tall) .page-hero__media {
		position: static;
		order: -1;
		margin: 0 calc(var(--gutter) * -1);
		-webkit-mask: none;
		mask: none;
	}

	.page-hero--stacked:not(.page-hero--tall) .page-hero__figure {
		aspect-ratio: var(--figure-ratio, 4 / 3);
		width: auto;
		height: auto;
	}

	.page-hero.page-hero--stacked:not(.page-hero--tall)::before {
		content: none;
	}
}

@media (min-width: 1000px) {
	.page-hero--stacked:not(.page-hero--tall) .page-hero__grid > :first-child {
		max-width: clamp(16rem, calc(46vw - 200px), 34rem);
	}
}

/* --------------------------------------------------------------------------
   The group photograph carries headroom that only a phone needs.

   The three products sit 13.5% down the original frame, and on a phone the
   header covers 35% of the band they are shown in - so they landed against
   the logo. No crop fixes that: cropping can only move a subject up, never
   down. The only thing that moves them down is more picture above them, so
   the file was given some, weighted to the top and keeping its shape.

   A wide screen does not want it. There the panel is close to the
   photograph's own proportions, so almost nothing is cropped away and the
   headroom simply made the products small and low.

   So it is scaled back off. 1.441 is exactly the factor the canvas grew by,
   and taking the origin from the bottom edge returns both axes to where they
   were: the products land back at their old height, and the side padding
   lands exactly on the frame's edges. The phone keeps the air; the desktop
   is the composition the client already signed off.
   -------------------------------------------------------------------------- */

@media (min-width: 768px) {
	.hero__jar img {
		transform: scale(1.441);
		transform-origin: 50% 100%;
	}
}

/* The collection page stacks below 1000px, so its own version starts there. */
@media (min-width: 1000px) {
	.page-hero--stacked:not(.page-hero--tall) .page-hero__figure img {
		transform: scale(1.441);
		transform-origin: 50% 100%;
	}
}

/* The overview and the ritual photographs are panels too, on the same
   footing as the section photographs above: they fill their half of the
   band and run off the outer edge, and nothing is masked. Every attempt to
   soften these edges read worse than the edge itself. A cut-out is shown
   whole with air around it and never had an edge to soften.
   -------------------------------------------------------------------------- */


/* --------------------------------------------------------------------------
   Representatives by country.

   The same markup on the contact page and in the footer, so a row the client
   adds cannot look like two different things in two places. Only the colours
   differ - paper on the contact page, ink in the footer - and the list wraps,
   because she expects to add countries over time and a fixed set of columns
   would be wrong the moment she added the fourth.
   -------------------------------------------------------------------------- */

.reps {
	margin-top: 36px;
}

.reps__heading {
	margin: 0 0 20px;
	color: var(--muted);
}

.reps__list {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
	gap: 28px 32px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.reps__item {
	padding-top: 16px;
	border-top: 1px solid var(--line);
}

.reps__country {
	margin: 0 0 8px;
	color: var(--seal);
}

.reps__name {
	margin: 0 0 6px;
	font-size: 15px;
	line-height: 1.5;
	color: var(--ink);
}

.reps__address,
.reps__line {
	margin: 0 0 4px;
	font-size: 14px;
	line-height: 1.6;
	font-style: normal;
	color: var(--ink-soft);
}

.reps__line a {
	color: var(--ink-soft);
	border-bottom: 1px solid var(--line);
	transition: color 0.3s ease, border-color 0.3s ease;
}

.reps__line a:hover,
.reps__line a:focus-visible {
	color: var(--seal);
	border-color: var(--seal);
}

/* On the ink of the footer the same list, in the footer's own weights. */
.reps--dark {
	margin-top: 56px;
	padding-top: 40px;
	border-top: 1px solid rgba(245, 243, 240, 0.12);
}

.reps--dark .reps__heading {
	color: rgba(245, 243, 240, 0.5);
}

.reps--dark .reps__item {
	border-top-color: rgba(245, 243, 240, 0.12);
}

.reps--dark .reps__name {
	color: var(--paper);
}

.reps--dark .reps__address,
.reps--dark .reps__line {
	color: rgba(245, 243, 240, 0.6);
}

.reps--dark .reps__line a {
	color: rgba(245, 243, 240, 0.6);
	border-bottom-color: rgba(245, 243, 240, 0.2);
}

.reps--dark .reps__line a:hover,
.reps--dark .reps__line a:focus-visible {
	color: var(--paper);
	border-bottom-color: var(--paper);
}

/* ==========================================================================
   Full-bleed panel framing
   --------------------------------------------------------------------------
   These panels are half the viewport wide and as tall as the text beside
   them, so their shape rarely matches the photograph. The images are served
   uncropped and framed here instead: taller panels bring the panel closer to
   the source proportions, and object-position keeps the subject - the face,
   the blossom - inside the frame rather than letting cover centre it.
   ========================================================================== */

.ingredients__media,
.ritual__media,
.product-overview__media,
.product-ritual__media,
.phil-ingredients__media,
.difference__media {
	min-height: clamp(320px, 50vw, 420px);
}

/*
 * Every section that pairs copy with a photograph shows it the same way.
 *
 * The home page's ritual has always stretched its picture to the height of
 * the band; the others centred theirs instead, which is what left a
 * photograph floating with paper above and below it - one component fixed at
 * a time while the rest stayed as they were. They are listed together here
 * so the next one cannot drift.
 *
 * A cut-out is not a panel: it is a product on the section's own background,
 * shown whole with air around it, and it keeps its own rules.
 */
@media (min-width: 860px) {
	.product-overview__media:not(.product-overview__media--cutout),
	.product-ritual__media,
	.phil-ingredients__media,
	.difference__media {
		position: relative;
		/* A ceiling in vw, for the reason beside .copy-media__media: a fixed
		   one in pixels makes the crop worse the wider the screen. */
		min-height: clamp(440px, calc(50vw / var(--figure-ratio, 1.4)), 78vw);
	}

	.product-overview__media:not(.product-overview__media--cutout) .product-overview__figure,
	.product-ritual__figure,
	.phil-ingredients__figure,
	.difference__figure {
		position: absolute;
		inset: 0;
		width: 100%;
		height: 100%;
		min-height: 0;
		aspect-ratio: auto;
	}
}

@media (min-width: 860px) {
	/* The home page's two keep a fixed height; the rest take theirs from the
	   photograph in them, in the block above. Listing them here as well would
	   have overridden it - this rule comes later in the file. */
	.ingredients__media,
	.ritual__media {
		/* Was clamp(520px, 42vw, 720px). These panels set the height of the
		   whole band, so 720px of photograph beside three short paragraphs was
		   the other half of the too-much-air problem. */
		min-height: clamp(420px, 32vw, 540px);
	}
}

/* The treatment photograph is a portrait with the face near the top. */
.ritual__figure img,
.product-ritual__figure img,
.difference__figure img {
	object-position: center 22%;
}

/* The blossom sits right of centre in the ingredients photograph. */
.ingredients__figure img,
.phil-ingredients__figure img {
	object-position: 68% center;
}

/* The partnership decorations are framed by their masks, not by a panel - see
   the partnership section above. */
.partner__decor--left img {
	object-position: 62% center;
}

.partner__decor--right img {
	object-position: 40% center;
}

/* Cut-out products are shown whole, with a little air around them. */
.essentials__figure img,
.collection__figure img,
.related__figure img {
	padding: 6%;
}

/*
 * A ceiling on that frame. The box is 4:5 against the column, and a column at
 * a desktop width is a third of the page - which made the frame 675px tall and
 * the row on its own taller than the window, with the product names falling
 * off the bottom of the screen. The cap is read off the window rather than off
 * a fixed pixel count, so the row stays on one screen whatever height the
 * window has. The cut-out shrinks with the frame and the width it no longer
 * needs becomes air either side, which is what the frame was giving it anyway.
 */
.essentials__figure,
.collection__figure,
.related__figure {
	max-height: min(38vh, 420px);
	/*
	 * width, because of what aspect-ratio does when a max-height stops it. A
	 * box with a ratio and no stated width recomputes its width from the
	 * capped height, so these frames narrowed from the column to 265px and,
	 * being blocks, sat against the column's left edge - the three products
	 * stopped lining up down the middle of the page. Holding the width makes
	 * the cap act on the height alone; the product is centred in the frame by
	 * object-fit and the width it no longer fills is air either side.
	 */
	width: 100%;
}

/* Where products stand together their relative size is information, so each
   one is shown at its own scale rather than at the scale its cut-out happens
   to be drawn at. shinsen_product_scale() carries it; a product left at the
   default sends nothing. The collection is deliberately not in this list. */
.essentials__figure img,
.related__figure img {
	transform: scale(var(--product-scale, 1));
}

/* The disc is filled, not padded: these are square sources, so covering it
   crops nothing and the picture reaches the edge the way the artwork was
   composed to. */
.product-tech__figure img {
	padding: 0;
	object-fit: cover;
}

/* Less of it on the product hero. 6% of a 612px frame is 37px on every side,
   which on top of contain's own letterboxing left the product noticeably
   smaller than the space it was given. */
.product-hero__figure img {
	padding: 2%;
}
