/*
Theme Name: La.frigg
Theme URI: https://la-frigg.jp
Author: La.frigg
Description: A file-first WooCommerce theme for a made-to-order doll couture atelier. Templates and styles live in the repository, not the database.
Version: 0.1.0
Requires at least: 6.0
Tested up to: 7.0
Requires PHP: 7.4
License: GPL-2.0-or-later
Text Domain: la-frigg
Domain Path: /languages
*/

/* ==========================================================================
   La.frigg — Sweet Vintage Atelier

   Written against our own markup, so there is nothing to out-specify. If a
   rule here needs !important, that is a bug in this file.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Fonts
   Latin display face only. Japanese headings use the system mincho stack:
   self-hosting a JP serif costs ~100 unicode-range files for little gain.
   -------------------------------------------------------------------------- */

@font-face {
	font-family: "Cormorant LF";
	src: url("assets/fonts/cormorant-var.woff2") format("woff2");
	font-weight: 300 500;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: "Cormorant LF";
	src: url("assets/fonts/cormorant-var-italic.woff2") format("woff2");
	font-weight: 300 500;
	font-style: italic;
	font-display: swap;
}

/* --------------------------------------------------------------------------
   2. Tokens

   Ink and paper first, champagne for detail, blush only as an accent.

   The palette started with #F3D9D2 filling seventeen panels — the footer, the
   account menu, every summary card — and the pink stopped being an accent and
   became the page. Those fills are now a warm neutral, and the pink survives
   only where it is genuinely a highlight: a hover, a status, a sale price.

   Contrast is deliberately not maximal. Ink is #2E2B27 rather than black and
   paper is #FBFAF8 rather than white, so the page reads as warm paper rather
   than as a screen.
   -------------------------------------------------------------------------- */

:root {
	/* Surfaces */
	--canvas: #FBFAF8;      /* 主背景 — 暖白 */
	--canvas-alt: #F2F0EB;  /* 板块底 — 暖灰,原为粉色 */
	--white: #FFFFFF;       /* 留白 — 商品图/价格区 */

	/* Text */
	--ink: #2E2B27;         /* 标题 — 柔黑,非纯黑 */
	--body: #56504A;        /* 正文 7.5:1 */
	--muted: #8C857C;       /* 注释 4.6:1 */

	/* Metal and accent */
	--gold: #BFA062;        /* 香槟金 — 描线/图标/角饰,绝不铺底 */
	--blush: #EBD9D6;       /* 唯一的粉 — 少量点缀 */
	--rose: #EBD9D6;        /* 别名,保留既有用法 */
	--rose-ink: #8E6A6D;    /* 可读的玫瑰色文字 4.9:1 */
	--rose-deep: #6E4F52;   /* hover */

	--hairline: rgba(46, 43, 39, .12);

	/* Radius. Was a flat 2–4px, which reads as no radius at all. */
	--r-sm: 6px;
	--r: 10px;
	--r-lg: 16px;
	--r-pill: 999px;

	--font-display: "Cormorant LF", "Hiragino Mincho ProN", "Yu Mincho",
		"Noto Serif JP", serif;
	--font-body: -apple-system, BlinkMacSystemFont, "Hiragino Kaku Gothic ProN",
		"Yu Gothic Medium", "Meiryo", system-ui, sans-serif;

	--step--1: .8rem;
	--step-0: 1rem;
	--step-1: 1.25rem;
	--step-2: 1.563rem;
	--step-3: 1.953rem;

	--gap: clamp(1.5rem, 4vw, 3rem);
	--section-y: clamp(64px, 9vw, 130px);
	--shell: min(1280px, 92vw);
	--ease: cubic-bezier(.2, .6, .2, 1);
}

/* --------------------------------------------------------------------------
   3. Reset & base
   -------------------------------------------------------------------------- */

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

body {
	margin: 0;
	background: var(--canvas);
	color: var(--body);
	font-family: var(--font-body);
	font-size: var(--step-0);
	line-height: 1.9;
	letter-spacing: .02em;
	-webkit-font-smoothing: antialiased;
}

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

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

h1, h2, h3, h4 {
	font-family: var(--font-display);
	font-weight: 300;
	color: var(--ink);
	letter-spacing: .04em;
	line-height: 1.26;
	margin: 0 0 .5em;
}

p { margin: 0 0 1.1em; }

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

.screen-reader-text {
	position: absolute;
	width: 1px; height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

.lf-skip {
	position: absolute;
	left: -9999px;
	background: var(--ink);
	color: var(--white);
	padding: 12px 20px;
	z-index: 100;
}

.lf-skip:focus { left: 12px; top: 12px; }

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

.lf-eyebrow {
	font-family: var(--font-body);
	font-size: var(--step--1);
	letter-spacing: .28em;
	text-transform: uppercase;
	/* Was rose. The eyebrow sits above every heading on the site, so pink here
	   was most of what made the palette feel pink. */
	color: var(--muted);
	margin: 0 0 1.1em;
}

.lf-eyebrow--gold { color: var(--gold); }

.lf-measure { max-width: 42em; }

.lf-btn {
	display: inline-block;
	font-family: var(--font-body);
	font-size: .8125rem;
	letter-spacing: .14em;
	text-transform: uppercase;
	padding: 15px 34px;
	/* Primary action. The spec reserves #E8B4B8 for secondary buttons and it
	   cannot carry white text anyway, so the main CTA is ink on cream. */
	background: var(--ink);
	color: var(--canvas);
	border: 0;
	border-radius: var(--r-sm);
	cursor: pointer;
	transition: background-color .35s var(--ease);
}

/*
 * Hover fills with champagne and darkens the text to ink.
 *
 * This is the one place gold is allowed as a fill. The spec's "never a gold
 * background" is a rule about the STATIC page — a gold panel would shout. On a
 * momentary hover it reads as the button lighting up, not as decoration, so the
 * rule is scoped to "no static gold fill" and the interaction is the exception.
 * Ink on this gold measures 5.65:1, above the readable line.
 *
 * The selector also has to out-rank WooCommerce, which styles button:hover to a
 * pale lilac (#dcd7e2) through a long `:where()` + `body:not(...)` chain whose
 * specificity is only `button.button:hover` (:where counts as zero). Every
 * purchase button carries both classes, so on hover the dark CTA was turning
 * lilac. Two classes here beat that, with no !important needed.
 */
.lf-btn:hover,
.lf-btn.button:hover,
.lf-btn.button:focus,
.lf-btn.button:active {
	background: var(--gold);
	color: var(--ink);
}

.lf-btn--ghost {
	background: transparent;
	color: var(--ink);
	box-shadow: inset 0 0 0 1px var(--gold);
}

/* Secondary action fills with the accent pink, not gold: the spec keeps gold
   to hairlines, icons and edges, never as a fill. */
.lf-btn--ghost:hover { background: var(--gold); color: var(--ink); }

/* Underlined text link with a rule that grows from the left. */
.lf-link {
	display: inline-block;
	font-family: var(--font-body);
	font-size: var(--step--1);
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--ink);
	padding-bottom: 4px;
	position: relative;
}

.lf-link::after {
	content: "";
	position: absolute;
	left: 0; right: 0; bottom: 0;
	height: 1px;
	background: var(--gold);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform .35s var(--ease);
}

.lf-link:hover::after { transform: scaleX(1); }

/* --------------------------------------------------------------------------
   5. Header
   -------------------------------------------------------------------------- */

.lf-header {
	position: sticky;
	top: 0;
	z-index: 40;
	background: rgba(251, 250, 248, .94);
	backdrop-filter: blur(8px);
	border-bottom: 1px solid var(--hairline);
}

.lf-header__inner {
	width: var(--shell);
	margin: 0 auto;
	min-height: 76px;
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	align-items: center;
	gap: var(--gap);
}

.lf-brand {
	margin: 0;
	text-align: center;
	grid-column: 2;
}

.lf-brand__text {
	font-family: var(--font-display);
	font-size: var(--step-2);
	letter-spacing: .12em;
	color: var(--ink);
}

.lf-nav__list { display: flex; gap: 28px; }

.lf-nav__list a {
	/* These are short labels; wrapping them mid-word ("ショッ / プ") looked
	   broken between the 780px burger breakpoint and roughly 1000px. */
	white-space: nowrap;
	font-size: .75rem;
	letter-spacing: .18em;
	text-transform: uppercase;
	color: var(--ink);
	position: relative;
	padding: 6px 0;
	display: inline-block;
}

.lf-nav__list a::after {
	content: "";
	position: absolute;
	left: 0; right: 0; bottom: 0;
	height: 1px;
	background: var(--gold);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform .3s var(--ease);
}

.lf-nav__list a:hover::after,
.lf-nav__list .current-menu-item > a::after { transform: scaleX(1); }

.lf-header__tools {
	grid-column: 3;
	display: flex;
	justify-content: flex-end;
	align-items: center;
	gap: 22px;
}

.lf-tool {
	font-size: .8rem;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--ink);
}

.lf-tool:hover { color: var(--rose-ink); }

.lf-cart-count {
	display: inline-block;
	min-width: 18px;
	margin-left: 6px;
	padding: 1px 5px;
	border-radius: var(--r-pill);
	background: var(--rose-ink);
	color: var(--white);
	font-size: .625rem;
	text-align: center;
}

.lf-burger {
	display: none;
	width: 34px; height: 34px;
	padding: 0;
	background: none;
	border: 0;
	cursor: pointer;
	position: relative;
}

.lf-burger__bar {
	position: absolute;
	left: 6px; right: 6px;
	height: 1px;
	background: var(--ink);
	transition: transform .3s var(--ease);
}

.lf-burger__bar:nth-child(1) { top: 14px; }
.lf-burger__bar:nth-child(2) { top: 20px; }

.lf-burger[aria-expanded="true"] .lf-burger__bar:nth-child(1) { transform: translateY(3px) rotate(45deg); }
.lf-burger[aria-expanded="true"] .lf-burger__bar:nth-child(2) { transform: translateY(-3px) rotate(-45deg); }

/* Fixed to the viewport (not the document): a static drawer sat at the top of
   the page, so opening it while scrolled down showed nothing until you scrolled
   back up. inset:0 pins it to the screen; z-index sits BELOW the sticky header
   (z-40) so the header's close (×) stays tappable over the panel. */
.lf-drawer {
	position: fixed;
	inset: 0;
	z-index: 35;
	background: var(--canvas);
	padding: 88px var(--gap) 32px;   /* clear the ~77px sticky header */
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
	display: flex;
	flex-direction: column;
	animation: lf-drawer-in .3s var(--ease) both;
}

/* Keep the [hidden] drawer hidden: the rule above sets display:flex, which has
   the same specificity as the UA's `[hidden]{display:none}` but comes later, so
   it would otherwise win and leave the drawer permanently open (even on desktop,
   where there is no burger to close it). This class+attribute selector outranks
   both. */
.lf-drawer[hidden] { display: none; }

@keyframes lf-drawer-in {
	from { opacity: 0; transform: translateY(-10px); }
	to   { opacity: 1; transform: translateY(0); }
}

.lf-drawer__list { margin: 4px 0 auto; }   /* auto-margin floats the foot down */

.lf-drawer__list a {
	display: flex;
	align-items: center;
	gap: 13px;
	padding: 18px 2px;
	border-bottom: 1px solid var(--hairline);
	/* Boutique serif with gentle tracking, sized closer to the header tools so
	   the menu and the small labels read as one type system, not two. */
	font-family: var(--font-display);
	font-size: 1.1rem;
	letter-spacing: .04em;
	color: var(--ink);
	transition: color .25s var(--ease), padding-left .25s var(--ease);
}

/* Each row's own line-art icon (injected in PHP, drawer only). Gold, and it
   warms to rose + lifts a touch on the current/pressed row. */
.lf-drawer__ico {
	flex: none;
	width: 22px;
	height: 22px;
	color: var(--gold);
	opacity: .9;
	transition: color .25s var(--ease), transform .3s var(--ease);
}
.lf-drawer__ico svg { width: 100%; height: 100%; display: block; }
.lf-drawer__list a:hover .lf-drawer__ico,
.lf-drawer__list .current-menu-item > a .lf-drawer__ico { color: var(--rose-ink); transform: scale(1.1); }

/* One hairline chevron at the far edge is the only marker — the column of gold
   gems read as clutter, so it is gone. */
.lf-drawer__list a::after {
	content: "";
	margin-left: auto;
	width: 7px;
	height: 7px;
	border-top: 1px solid var(--gold);
	border-right: 1px solid var(--gold);
	transform: rotate(45deg);
	opacity: .45;
	transition: opacity .25s var(--ease), transform .25s var(--ease);
}

.lf-drawer__list a:hover,
.lf-drawer__list .current-menu-item > a { color: var(--rose-ink); padding-left: 6px; }

.lf-drawer__list a:hover::after,
.lf-drawer__list .current-menu-item > a::after { opacity: 1; transform: rotate(45deg) translate(1px, -1px); }

/* Labels arrive one after another when the drawer opens. */
.lf-drawer__list li { animation: lf-drawer-item .42s var(--ease) both; }
.lf-drawer__list li:nth-child(1) { animation-delay: .07s; }
.lf-drawer__list li:nth-child(2) { animation-delay: .13s; }
.lf-drawer__list li:nth-child(3) { animation-delay: .19s; }
.lf-drawer__list li:nth-child(4) { animation-delay: .25s; }
.lf-drawer__list li:nth-child(5) { animation-delay: .31s; }
.lf-drawer__list li:nth-child(6) { animation-delay: .37s; }

@keyframes lf-drawer-item {
	from { opacity: 0; transform: translateX(-12px); }
	to   { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   6. Hero — split, type left, photo right
   -------------------------------------------------------------------------- */

.lf-hero {
	display: grid;
	grid-template-columns: 1fr 1.15fr;
	align-items: stretch;
	min-height: min(78vh, 720px);
	background: var(--canvas);
}

.lf-hero__type {
	display: flex;
	flex-direction: column;
	justify-content: center;
	padding: clamp(48px, 7vw, 96px) clamp(28px, 5vw, 80px);
}

.lf-hero__title {
	font-size: clamp(2.4rem, 5vw, 4.2rem);
	line-height: 1.1;
	margin: 0 0 .5em;
}

.lf-hero__line { display: block; }

.lf-hero__line--em {
	font-style: italic;
	color: var(--rose-ink);
	padding-left: 1.2em;
}

.lf-hero__lede {
	font-size: var(--step-1);
	line-height: 2;
	margin-bottom: 2em;
}

.lf-hero__type .lf-btn { align-self: flex-start; }

.lf-hero__figure { overflow: hidden; }

.lf-hero__figure img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* --------------------------------------------------------------------------
   7. Status rail
   -------------------------------------------------------------------------- */

.lf-rail {
	background: var(--canvas-alt);
	border-block: 1px solid var(--hairline);
}

.lf-rail__inner {
	width: var(--shell);
	margin: 0 auto;
	padding: 22px 0;
	display: flex;
	align-items: baseline;
	gap: 16px;
	flex-wrap: wrap;
}

.lf-rail__dot {
	width: 6px; height: 6px;
	border-radius: 50%;
	background: var(--gold);
	align-self: center;
	flex: none;
}

.lf-rail__state {
	margin: 0;
	font-size: var(--step--1);
	letter-spacing: .2em;
	text-transform: uppercase;
	color: var(--ink);
	flex: none;
}

.lf-rail__text {
	margin: 0;
	font-size: var(--step--1);
	color: var(--body);
	flex: 1 1 20ch;
}

/* Open state — a quiet gold "live" pulse on the dot, gilt state word. */
.lf-rail--open .lf-rail__state { color: var(--gold); }
.lf-rail--open .lf-rail__dot {
	box-shadow: 0 0 0 0 rgba(191, 160, 98, .5);
	animation: lf-rail-pulse 2.6s ease-out infinite;
}
@keyframes lf-rail-pulse {
	0%   { box-shadow: 0 0 0 0 rgba(191, 160, 98, .5); }
	70%  { box-shadow: 0 0 0 7px rgba(191, 160, 98, 0); }
	100% { box-shadow: 0 0 0 0 rgba(191, 160, 98, 0); }
}
@media (prefers-reduced-motion: reduce) {
	.lf-rail--open .lf-rail__dot { animation: none; }
}

/* --------------------------------------------------------------------------
   8. Feature — photo with the caption card pulled over its edge
   -------------------------------------------------------------------------- */

.lf-feature {
	width: var(--shell);
	margin: var(--section-y) auto;
	display: grid;
	grid-template-columns: 1.4fr 1fr;
	align-items: center;
}

.lf-feature__figure { margin: 0; overflow: hidden; }

.lf-feature__figure img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }

.lf-feature__card {
	background: var(--canvas);
	border: 1px solid var(--hairline);
	padding: clamp(28px, 4vw, 52px);
	margin-left: -12%;
	position: relative;
	z-index: 1;
}

.lf-feature__title { font-size: var(--step-3); margin-bottom: .6em; }

.lf-feature__meta {
	font-family: var(--font-display);
	font-style: italic;
	color: var(--body);
	margin-bottom: 1.6em;
}

/* --------------------------------------------------------------------------
   9. Archive — staggered grid
   -------------------------------------------------------------------------- */

.lf-archive {
	width: var(--shell);
	margin: 0 auto var(--section-y);
}

.lf-archive__head { text-align: center; margin-bottom: clamp(32px, 5vw, 64px); }

.lf-archive__head h2 { font-size: var(--step-3); }

.lf-archive__head .lf-measure { margin-inline: auto; }

.lf-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
	gap: var(--gap);
	align-items: start;
}

/* Every other card sits lower — the row reads as a hand-laid sequence
   rather than a spreadsheet.

   Offset with margin, not transform: the reveal animation animates transform
   and resets it to `none` when it finishes, which would wipe a layout offset
   expressed the same way. Layout and motion must not share a property. */
@media (min-width: 780px) {
	.lf-card--drop { margin-top: 42px; }
}

.lf-card__frame {
	display: block;
	position: relative;
	overflow: hidden;
	border: 1px solid var(--hairline);
	background: var(--white);
	aspect-ratio: 3 / 4;
}

.lf-card__frame img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform .8s var(--ease);
}

.lf-card:hover .lf-card__frame img { transform: scale(1.05); }

.lf-card__flag {
	position: absolute;
	left: 0; right: 0; bottom: 0;
	padding: 7px 0;
	text-align: center;
	background: rgba(251, 250, 248, .93);
	border-top: 1px solid var(--hairline);
	font-size: .625rem;
	letter-spacing: .2em;
	text-transform: uppercase;
	color: var(--body);
}

.lf-card__name {
	display: block;
	margin-top: 14px;
	font-family: var(--font-display);
	font-size: var(--step-0);
	color: var(--ink);
	line-height: 1.5;
}

.lf-card__price {
	display: block;
	margin-top: 4px;
	font-family: var(--font-display);
	color: var(--body);
}

.lf-card__price del { opacity: .5; margin-right: .4em; }
.lf-card__price ins { text-decoration: none; color: var(--rose-deep); }

.lf-archive__more { text-align: center; margin-top: clamp(48px, 7vw, 96px); }

/* --------------------------------------------------------------------------
   10. Atelier — centred type with a pull quote
   -------------------------------------------------------------------------- */

.lf-atelier {
	background: var(--canvas-alt);
	padding: var(--section-y) 0;
}

.lf-atelier__inner {
	width: min(760px, 90vw);
	margin: 0 auto;
	text-align: center;
}

.lf-quote { margin: 0 0 1.6em; }

.lf-quote p {
	font-family: var(--font-display);
	font-style: italic;
	font-size: clamp(1.6rem, 3.4vw, 2.4rem);
	line-height: 1.5;
	color: var(--ink);
	margin: 0;
}

.lf-atelier .lf-measure { margin-inline: auto; }

.lf-atelier__figure {
	margin: clamp(36px, 6vw, 64px) 0 0;
	overflow: hidden;
}

.lf-atelier__figure img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }

/* --------------------------------------------------------------------------
   11. Process — numbered steps on a hairline
   -------------------------------------------------------------------------- */

.lf-process {
	width: var(--shell);
	margin: var(--section-y) auto;
}

.lf-process__head { text-align: center; margin-bottom: clamp(32px, 5vw, 64px); }

.lf-process__head h2 { font-size: var(--step-3); }

.lf-steps {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
	gap: var(--gap);
	border-top: 1px solid var(--hairline);
	padding-top: clamp(32px, 4vw, 52px);
}

.lf-step { position: relative; padding-right: var(--gap); }

.lf-step__num {
	display: block;
	font-family: var(--font-display);
	font-size: var(--step-3);
	color: var(--gold);
	line-height: 1;
	margin-bottom: .5em;
}

.lf-step__title { font-size: var(--step-1); margin-bottom: .5em; }

.lf-step p { font-size: var(--step--1); margin: 0; }

/* --------------------------------------------------------------------------
   12. Footer
   -------------------------------------------------------------------------- */

.lf-footer {
	background: var(--canvas-alt);
	border-top: 1px solid var(--hairline);
}

/* A small champagne flourish that opens the footer. */
.lf-footer__flourish {
	display: block;
	width: clamp(150px, 20vw, 200px);
	margin: 0 auto;
	padding-top: clamp(40px, 6vw, 64px);
	color: var(--gold);
	opacity: .8;
}
.lf-footer__flourish svg { width: 100%; height: auto; display: block; }

.lf-footer__inner {
	width: var(--shell);
	margin: 0 auto;
	padding: clamp(32px, 4.5vw, 52px) 0 clamp(44px, 6vw, 72px);
	display: grid;
	grid-template-columns: 1.6fr 1fr 1.1fr;
	gap: clamp(2rem, 5vw, 4rem);
}

.lf-footer__mark {
	font-family: var(--font-display);
	font-size: var(--step-2);
	color: var(--ink);
	margin-bottom: .5em;
}

.lf-footer__note {
	font-size: var(--step--1);
	line-height: 1.9;
	color: var(--body);
	max-width: 42ch;
}

/* Section headers over each link column. */
.lf-footer__label {
	font-size: var(--step--1);
	letter-spacing: .18em;
	text-transform: uppercase;
	color: var(--ink);
	margin-bottom: 1.1em;
}

.lf-footer__list a {
	font-size: var(--step--1);
	letter-spacing: .04em;
	color: var(--body);
	transition: color .25s var(--ease), padding-left .25s var(--ease);
}
.lf-footer__list li { margin-bottom: .9em; }
.lf-footer__list a:hover { color: var(--rose-ink); padding-left: 4px; }

/* Shop call-to-action under the brand blurb. */
.lf-footer__cta {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	margin-top: 1.4em;
	font-size: var(--step--1);
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--ink);
	transition: gap .3s var(--ease), color .25s var(--ease);
}
.lf-footer__cta span { color: var(--gold); }
.lf-footer__cta:hover { color: var(--rose-ink); gap: 12px; }

/* Social icons — line-art gold, warm to rose and lift on hover. */
.lf-footer__social {
	display: flex;
	gap: 16px;
	margin: 1.6em 0 0;
	padding: 0;
	list-style: none;
}
.lf-footer__social a {
	display: block;
	width: 22px;
	height: 22px;
	color: var(--gold);
	transition: color .25s var(--ease), transform .3s var(--ease);
}
.lf-footer__social a:hover { color: var(--rose-ink); transform: translateY(-2px); }
.lf-footer__social svg { width: 100%; height: 100%; display: block; }

.lf-footer__contact p { font-size: var(--step--1); line-height: 1.9; color: var(--body); margin: 0 0 .4em; }
.lf-footer__mail {
	color: var(--body);
	border-bottom: 1px solid var(--hairline);
	transition: color .25s var(--ease), border-color .25s var(--ease);
}
.lf-footer__mail:hover { color: var(--rose-ink); border-color: var(--gold); }
.lf-footer__langs { color: var(--muted); letter-spacing: .06em; }

.lf-footer__base {
	border-top: 1px solid var(--hairline);
	display: flex;
	justify-content: space-between;
	align-items: center;
	flex-wrap: wrap;
	gap: 6px 16px;
	padding: 18px max(calc((100% - var(--shell)) / 2), 4vw);
	font-size: .6875rem;
	letter-spacing: .1em;
	color: var(--muted);
}
.lf-footer__base p { margin: 0; }
.lf-footer__base-note { text-transform: uppercase; color: var(--body); }

/* --------------------------------------------------------------------------
   13. Documents (about / policy / legal)
   -------------------------------------------------------------------------- */

.lf-page__inner {
	width: min(760px, 90vw);
	margin: var(--section-y) auto;
}

.lf-entry__head h1 { font-size: var(--step-3); }

.lf-doc {
	width: min(820px, 90vw);
	margin: 0 auto var(--section-y);
}

.lf-doc__head {
	text-align: center;
	padding: var(--section-y) 0 clamp(28px, 4vw, 48px);
}

.lf-doc__title { font-size: clamp(1.8rem, 3.6vw, 2.8rem); margin: 0; }

/* Hairline with a gold pip — the divider motif, reused. */
.lf-rule {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 14px;
	margin: 1.6em 0 0;
}

/* Champagne rules that fade out from the diamond, rather than two flat grey
   dashes. This ornament sits under every page heading, so it carries most of
   the decorative weight on the site and is worth the gradient. */
.lf-rule::before,
.lf-rule::after {
	content: "";
	height: 1px;
	width: clamp(30px, 6vw, 62px);
	background: linear-gradient(to right, transparent, var(--gold));
}

.lf-rule::after { background: linear-gradient(to left, transparent, var(--gold)); }

.lf-rule i {
	width: 5px;
	height: 5px;
	flex: 0 0 5px;
	background: var(--gold);
	transform: rotate(45deg);
}

.lf-doc__body { max-width: 42em; margin: 0 auto; }

.lf-doc__body h2,
.lf-doc__body h3 {
	font-size: var(--step-1);
	margin: 2.2em 0 .7em;
	padding-bottom: .5em;
	border-bottom: 1px solid var(--hairline);
}

.lf-doc__body h2:first-child,
.lf-doc__body h3:first-child { margin-top: 0; }

.lf-doc__body p { line-height: 2.05; }

.lf-doc__body ul { list-style: disc; padding-left: 1.3em; margin-bottom: 1.4em; }
.lf-doc__body li { margin-bottom: .5em; }

.lf-doc__body img { margin: 2em 0; }

.lf-doc__body a { color: var(--rose-ink); border-bottom: 1px solid var(--hairline); }
.lf-doc__body a:hover { border-bottom-color: var(--rose-ink); }

/* --------------------------------------------------------------------------
   13b. Legacy builder content
   Styling for the migration shim in inc/legacy-shortcodes.php. Goes away with
   it once the last builder page is rewritten.
   -------------------------------------------------------------------------- */

.lf-legacy__section { margin-bottom: clamp(28px, 4vw, 56px); }

.lf-legacy__row { display: grid; gap: var(--gap); }

@media (min-width: 780px) {
	.lf-doc__body .lf-legacy__row--split { grid-template-columns: 1fr 1fr; }
}

.lf-legacy__gap { height: clamp(18px, 3vw, 32px); }

.lf-legacy__rule {
	border: 0;
	border-top: 1px solid var(--hairline);
	max-width: 60px;
	margin: clamp(24px, 4vw, 40px) auto;
}

.lf-legacy__card {
	border: 1px solid var(--hairline);
	background: var(--white);
	padding: clamp(20px, 3vw, 30px);
	margin-bottom: var(--gap);
}

.lf-legacy__card h3,
.lf-legacy__card h4 {
	font-size: var(--step-1);
	margin: 0 0 .6em;
	padding: 0;
	border: 0;
	text-align: center;
}

/* The old pages centred long paragraphs; left-aligned reads far better for a
   policy someone actually has to get through. */
.lf-legacy__card p,
.lf-legacy__card p[style] { text-align: left !important; }

.lf-legacy__banner img,
.lf-legacy__img { width: 100%; margin: 0 0 var(--gap); }

.lf-legacy__banner { margin-bottom: var(--gap); }

/* --------------------------------------------------------------------------
   14. Shop archive
   -------------------------------------------------------------------------- */

.lf-shop {
	width: var(--shell);
	margin: 0 auto var(--section-y);
}

.lf-shop__head {
	text-align: center;
	padding: var(--section-y) 0 clamp(28px, 4vw, 48px);
}

.lf-shop__title { font-size: clamp(1.8rem, 3.6vw, 2.8rem); }

.lf-shop__head .lf-measure { margin-inline: auto; }

.lf-shop__bar {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: var(--gap);
	flex-wrap: wrap;
	padding-bottom: 18px;
	margin-bottom: clamp(28px, 4vw, 48px);
	border-bottom: 1px solid var(--hairline);
}

.lf-shop__bar .woocommerce-result-count {
	margin: 0;
	font-size: var(--step--1);
	letter-spacing: .06em;
	color: var(--body);
}

.lf-shop__bar select {
	font-family: var(--font-body);
	font-size: var(--step--1);
	color: var(--body);
	background: var(--white);
	border: 1px solid var(--hairline);
	border-radius: var(--r-sm);
	padding: 8px 12px;
}

/* WooCommerce prints the loop as <ul class="products">; give it the same grid
   the front page uses.
   woocommerce-layout.css sizes each item with `float:left; width:22.05%;
   margin-right:3.8%` for its own float grid. Display:grid ignores the float
   but NOT the width — leaving every card a fifth of its cell wide, with the
   product title wrapping one character per line. Reset the sizing here. */
.lf-shop ul.products,
.lf-wc ul.products {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
	gap: var(--gap);
	align-items: start;
	margin: 0;
	padding: 0;
	list-style: none;
}

.lf-shop ul.products > li.product,
.lf-wc ul.products > li.product {
	float: none;
	/* !important defeats WooCommerce's own `.woocommerce ul.products li.product
	   { width: 22.05%/48% }` — same specificity as ours, and its stylesheet can
	   load after the theme's, winning the tie. Inside our grid that width shrinks
	   each card to a fraction of its track and parks it left (the "skewed to one
	   side" bug). auto lets the grid stretch the card to fill its track. */
	width: auto !important;
	margin: 0;
	padding: 0;
	clear: none;
}

/* Phones: an explicit, tidy two-up. auto-fill could otherwise leave a lone
   card in the left half with an empty column beside it. */
@media (max-width: 640px) {
	.lf-shop ul.products,
	.lf-wc ul.products {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 20px 14px;
	}
}

.lf-shop ul.products::before,
.lf-shop ul.products::after { content: none; }

.lf-card__link { display: block; }

/* Cards lift very slightly on hover — enough to feel alive, not enough to
   look like a web app. */
.lf-card {
	transition: transform .5s var(--ease);
}

.lf-card:hover { transform: translateY(-4px); }

.lf-card__frame { transition: border-color .4s var(--ease); }
.lf-card:hover .lf-card__frame { border-color: var(--gold); }

.lf-card__name { transition: color .35s var(--ease); }
.lf-card:hover .lf-card__name { color: var(--rose-ink); }

/* Grid items arrive in sequence rather than all at once. */
.has-js .lf-shop .lf-card:nth-child(4n+2) { transition-delay: .07s; }
.has-js .lf-shop .lf-card:nth-child(4n+3) { transition-delay: .14s; }
.has-js .lf-shop .lf-card:nth-child(4n+4) { transition-delay: .21s; }

/* Loop add-to-cart, when a collection is open. */
.lf-shop .lf-card .button,
.lf-wc .lf-card .button {
	display: inline-block;
	margin-top: 12px;
	font-family: var(--font-body);
	font-size: .6875rem;
	letter-spacing: .1em;
	text-transform: uppercase;
	white-space: nowrap;
	padding: 10px 16px;
	background: transparent;
	color: var(--ink);
	border: 0;
	border-radius: var(--r-sm);
	box-shadow: inset 0 0 0 1px var(--hairline);
	transition: box-shadow .3s var(--ease), color .3s var(--ease);
}

.lf-shop .lf-card .button:hover,
.lf-wc .lf-card .button:hover {
	box-shadow: inset 0 0 0 1px var(--gold);
	color: var(--rose-ink);
}

.woocommerce-no-products-found { text-align: center; padding: var(--section-y) 0; }

/* --------------------------------------------------------------------------
   15. WooCommerce wrapper (single product, cart, checkout, account)
   Presentation only. The markup below is WooCommerce's; nothing here changes
   what any of it does.
   -------------------------------------------------------------------------- */

.lf-wc__inner {
	width: var(--shell);
	margin: 0 auto;
	padding: var(--section-y) 0;
}

/* Single product layout.
   Owned here rather than left to WooCommerce's float pair, so the two columns
   are a grid and nothing depends on clearing.
   The gallery also ships at opacity:0 and is faded in by WooCommerce's own JS
   once flexslider initialises — if that script does not run, the product
   photography simply never appears. Show it, and let the JS do its work on
   top of a visible element. */
.lf-wc div.product {
	display: grid;
	/* Equal columns. Defined HERE, before the 860px single-column rule below,
	   so that mobile override actually wins — a second copy of this rule used to
	   sit further down the file, after the media query, and (media queries add
	   no specificity) it beat the mobile rule at every width, leaving the shop
	   in two cramped columns on phones with the whole right column empty. */
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	gap: clamp(32px, 5vw, 72px);
	align-items: start;
}

/* The gallery no longer arrives with an inline `opacity: 0` — the theme
   renders it itself (woocommerce/single-product/product-image.php), so there is
   no script-dependent fade to defeat and the !important that used to live here
   is gone with it. */
.lf-wc div.product .lf-gallery {
	float: none;
	width: auto;
	margin: 0;
	grid-column: 1;
}

.lf-wc div.product .summary {
	float: none;
	width: auto;
	margin: 0;
	grid-column: 2;
}

/* Description and related products run the full width beneath. */
.lf-wc div.product .woocommerce-tabs,
.lf-wc div.product .related,
.lf-wc div.product .upsells,
.lf-wc div.product .lf-details,
.lf-wc div.product .lf-reviews {
	grid-column: 1 / -1;
}

@media (max-width: 860px) {
	/* Single column, but minmax(0,1fr) — NOT plain 1fr. `1fr` is minmax(auto,1fr),
	   and that `auto` floor equals the widest child's min-content width. The
	   30-thumbnail rail's min-content is enormous, so `1fr` stretched the whole
	   product to ~2156px in a 375px viewport: the image rendered fine but sat off
	   to the left of a giant frame, so the viewport showed empty space — it read
	   as a blank gallery. minmax(0,1fr) lets the column shrink to the viewport
	   (desktop already used minmax(0,1fr); only this mobile rule was wrong). */
	.lf-wc div.product { grid-template-columns: minmax(0, 1fr); }
	.lf-wc div.product .lf-gallery,
	.lf-wc div.product .summary { grid-column: 1; min-width: 0; }
	/* Now that the frame fits, just keep an unusually tall photo from eating the
	   whole screen. object-fit works fine here — the earlier blanking was the
	   overflow above, not this. */
	.lf-wc div.product .lf-gallery__img { max-height: 80vh; object-fit: contain; }
}

.lf-wc .product_title {
	font-size: clamp(1.5rem, 2.8vw, 2.2rem);
	line-height: 1.4;
}

.lf-wc .price,
.lf-wc .amount,
.lf-wc .woocommerce-Price-amount {
	font-family: var(--font-display);
	color: var(--ink);
}

.lf-wc .price { font-size: var(--step-2); }

.lf-wc del { opacity: .5; }
.lf-wc ins { text-decoration: none; color: var(--rose-deep); }

.lf-wc .woocommerce-product-details__short-description {
	font-size: var(--step-0);
	line-height: 2;
}

/* Variation selects, quantity, and the buy button. */
.lf-wc .variations select,
.lf-wc .quantity input,
.lf-wc .form-row input.input-text,
.lf-wc .form-row select,
.lf-wc .form-row textarea {
	font-family: var(--font-body);
	background: var(--white);
	border: 1px solid var(--hairline);
	border-radius: var(--r-sm);
	padding: 10px 12px;
}

.lf-wc .variations th.label,
.lf-wc .form-row label {
	font-family: var(--font-body);
	font-size: var(--step--1);
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--body);
	font-weight: 500;
}

.lf-wc .button,
.lf-wc button.button,
.lf-wc input[type="submit"] {
	font-family: var(--font-body);
	font-size: .8125rem;
	letter-spacing: .14em;
	text-transform: uppercase;
	padding: 15px 34px;
	/* Primary action. The spec reserves #E8B4B8 for secondary buttons and it
	   cannot carry white text anyway, so the main CTA is ink on cream. */
	background: var(--ink);
	color: var(--canvas);
	border: 0;
	border-radius: var(--r-sm);
	cursor: pointer;
	transition: background-color .35s var(--ease);
}

.lf-wc .button:hover { background: var(--gold); color: var(--ink); }

/*
 * Alt buttons (single add-to-cart, proceed-to-checkout, place-order) get their
 * own colour from WooCommerce. Its selector is `.woocommerce :where(...)
 * button.button.alt:hover` — note the `button` TYPE, which makes it (0,4,1); a
 * plain `.lf-wc .button.alt:hover` is only (0,4,0) and loses by that one type
 * selector, which is why the button flashed WooCommerce's lilac on hover. The
 * type has to be matched too. These buttons are <a>, <button> or <input>, so
 * all three are qualified; each ties WooCommerce's weight and wins on source
 * order (this stylesheet loads after woocommerce.css).
 */
.lf-wc a.button.alt,
.lf-wc button.button.alt,
.lf-wc input.button.alt {
	background: var(--ink);
	color: var(--canvas);
}

.lf-wc a.button.alt:hover,
.lf-wc button.button.alt:hover,
.lf-wc input.button.alt:hover {
	background: var(--gold);
	color: var(--ink);
}

/* Variable products disable the button until a variation is chosen — read as
   "not yet", not "broken". */
.lf-wc .button.disabled,
.lf-wc .button:disabled {
	background: transparent;
	color: var(--body);
	box-shadow: inset 0 0 0 1px var(--hairline);
	opacity: 1;
}

/* Between drops the stock line is the most important sentence on the page. */
.lf-wc .stock.out-of-stock {
	display: inline-block;
	font-size: var(--step--1);
	letter-spacing: .18em;
	text-transform: uppercase;
	color: var(--body);
	background: var(--canvas-alt);
	border: 1px solid var(--hairline);
	padding: 10px 18px;
	border-radius: var(--r-sm);
}

/* Tabs and related products. */
.lf-wc .woocommerce-tabs ul.tabs {
	border-bottom: 1px solid var(--hairline);
	padding: 0;
	margin: 0 0 2em;
	display: flex;
	gap: 28px;
	list-style: none;
}

.lf-wc .woocommerce-tabs ul.tabs li { margin: 0; }

.lf-wc .woocommerce-tabs ul.tabs a {
	display: inline-block;
	padding: 12px 0;
	font-size: var(--step--1);
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--body);
	border-bottom: 1px solid transparent;
}

.lf-wc .woocommerce-tabs ul.tabs li.active a {
	color: var(--ink);
	border-bottom-color: var(--gold);
}

.lf-wc .related > h2,
.lf-wc .upsells > h2 {
	font-size: var(--step-2);
	text-align: center;
	margin-bottom: 1.2em;
}

.lf-wc .related ul.products,
.lf-wc .upsells ul.products {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
	gap: var(--gap);
	list-style: none;
	padding: 0;
}

/* Notices — the full treatment lives in section 18 (Cart & checkout); this
   earlier duplicate block was removed to keep one source of truth. */

/* --------------------------------------------------------------------------
   14. Motion
   Elements only hide once JS has confirmed it is running (html.has-js), so a
   scripting failure can never leave the page blank.
   -------------------------------------------------------------------------- */

.has-js .reveal {
	opacity: 0;
	transform: translateY(22px);
	transition: opacity .8s var(--ease), transform .8s var(--ease);

	/* Failsafe, with no JavaScript involved.
	   The hidden state above is the dangerous half of this feature: if
	   motion.js fails to load or throws, nothing ever gets .is-visible and the
	   page stays blank. motion.js carries its own timer, but that is the same
	   script that just failed. This zero-length animation fires ten seconds in
	   and holds the visible state, so the worst case is content that appears
	   late rather than content that never appears. */
	animation: lf-reveal-failsafe 0s linear 10s forwards;
}

.has-js .reveal.is-visible {
	opacity: 1;
	transform: none;
	animation: none;
}

@keyframes lf-reveal-failsafe {
	to { opacity: 1; transform: none; }
}

/* Photo panels un-mask upward instead of sliding. */
.has-js .reveal--wipe {
	opacity: 1;
	transform: none;
	clip-path: inset(0 0 100% 0);
	transition: clip-path 1.1s var(--ease);
	/* Belt and suspenders: whatever else happens, un-clip at 10s. This failsafe
	   is deliberately NOT removed when is-visible arrives — so if the clip
	   transition ever fails to settle (it froze under headless virtual-time,
	   and this is the hero photo, which must never be able to stay hidden), the
	   photo still reveals. When is-visible is present the transition shows it
	   long before 10s; the failsafe only matters when something went wrong. */
	animation: lf-wipe-failsafe 0s linear 10s forwards;
}

.has-js .reveal--wipe.is-visible {
	clip-path: inset(0 0 0 0);
}

@keyframes lf-wipe-failsafe {
	to { clip-path: inset(0 0 0 0); }
}

@media (max-width: 780px) {
	.has-js .reveal { transform: translateY(12px); transition-duration: .5s; }
}

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

	.has-js .reveal { opacity: 1; transform: none; clip-path: none; }
}

/* --------------------------------------------------------------------------
   15. Responsive
   -------------------------------------------------------------------------- */

@media (max-width: 980px) {
	.lf-hero { grid-template-columns: 1fr; min-height: 0; }
	.lf-hero__figure { order: -1; aspect-ratio: 4 / 3; }
	.lf-feature { grid-template-columns: 1fr; }
	.lf-feature__card { margin-left: 0; margin-top: -18%; width: 88%; }
	.lf-footer__inner { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 780px) {
	.lf-nav--left { display: none; }
	.lf-burger { display: block; }
	.lf-header__inner { grid-template-columns: auto 1fr auto; }
	.lf-brand { text-align: left; }
	.lf-tool:not(.lf-tool--cart) { display: none; }
	.lf-feature__card { margin-top: -12%; width: 92%; }
	.lf-footer__inner { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   16. My Account

   Lives inside .lf-wc, so inputs, notices and .button already inherit the
   commerce styling from section 13. What is added here is the two-column
   shell, the card treatments, and the order list.
   -------------------------------------------------------------------------- */

.lf-account__head {
	text-align: center;
	margin-bottom: clamp(36px, 5vw, 64px);
}

.lf-account__title { font-size: clamp(1.8rem, 3.6vw, 2.8rem); margin: 0; }

.lf-account__intro {
	max-width: 34em;
	margin: 1.6em auto 0;
	color: var(--muted);
}

.lf-account__grid {
	display: grid;
	grid-template-columns: 250px minmax(0, 1fr);
	gap: clamp(28px, 4vw, 56px);
	align-items: start;
}

/* --- Navigation card --- */

.lf-account__nav {
	position: sticky;
	top: 100px;
	background: var(--canvas-alt);
	border-radius: var(--r);
	padding: 14px;
	/* Rococo hairline: a gold edge, never a gold fill. */
	box-shadow: inset 0 0 0 1px rgba(191, 160, 98, .38);
}

.lf-account__nav a {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 11px 14px;
	border-radius: var(--r-sm);
	font-size: .85rem;
	letter-spacing: .06em;
	color: var(--ink);
	position: relative;
	transition: background-color .3s var(--ease), color .3s var(--ease);
}

.lf-account__icon {
	width: 18px;
	height: 18px;
	flex: 0 0 18px;
	color: var(--gold);
	transition: transform .35s var(--ease), color .3s var(--ease);
}

.lf-account__nav a:hover { background: rgba(255, 255, 255, .55); }

/* Spec: icons should move slightly on hover. Transform only, so it composites
   on the GPU and never triggers layout. */
.lf-account__nav a:hover .lf-account__icon { transform: scale(1.14) rotate(-4deg); }

.lf-account__nav .is-active > a {
	background: var(--white);
	color: var(--ink);
	box-shadow: inset 0 0 0 1px rgba(191, 160, 98, .5);
}

.lf-account__nav .is-active > a .lf-account__icon { color: var(--rose-ink); }

.lf-account__label { flex: 1 1 auto; }

/* --- Panel --- */

.lf-account__panel { min-width: 0; }

.lf-account__panel > h2:first-child,
.lf-account__panel > form > h2:first-child { margin-top: 0; }

/* --- Dashboard --- */

.lf-dash__welcome {
	background: var(--white);
	border-radius: var(--r);
	padding: clamp(26px, 4vw, 40px);
	box-shadow: 0 1px 2px rgba(74, 59, 53, .04), inset 0 0 0 1px var(--hairline);
	position: relative;
	overflow: hidden;
}

/* A single champagne corner flourish — the floral corner of the spec, kept to
   one arc so it reads as a detail and not a border. */
.lf-dash__welcome::after {
	content: "";
	position: absolute;
	top: -60px; right: -60px;
	width: 150px; height: 150px;
	border-radius: 50%;
	border: 1px solid rgba(191, 160, 98, .45);
	pointer-events: none;
}

.lf-dash__hello {
	font-size: clamp(1.4rem, 3vw, 2rem);
	margin: 0 0 .3em;
}

.lf-dash__hello em { font-style: italic; color: var(--rose-ink); }

.lf-dash__note { color: var(--muted); margin-bottom: .8em; }

.lf-dash__logout { margin: 0; }

.lf-dash__stats {
	display: flex;
	gap: 14px;
	margin: 18px 0 0;
}

.lf-dash__stat {
	flex: 1 1 0;
	background: var(--canvas-alt);
	border-radius: var(--r);
	padding: 20px 22px;
	text-align: center;
}

.lf-dash__num {
	display: block;
	font-family: var(--font-display);
	font-size: 2rem;
	line-height: 1.1;
	color: var(--ink);
}

.lf-dash__cap {
	display: block;
	font-size: .7rem;
	letter-spacing: .2em;
	color: var(--muted);
	margin-top: 4px;
}

.lf-dash__recent { margin-top: 34px; }

.lf-dash__sub {
	font-size: var(--step-1);
	margin-bottom: .8em;
	padding-bottom: .5em;
	border-bottom: 1px solid var(--hairline);
}

.lf-dash__links {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 12px;
	margin-top: 34px;
}

.lf-dash__link {
	display: block;
	padding: 20px;
	border-radius: var(--r);
	background: var(--white);
	box-shadow: inset 0 0 0 1px var(--hairline);
	transition: transform .3s var(--ease), box-shadow .3s var(--ease);
}

.lf-dash__link:hover {
	transform: translateY(-3px);
	box-shadow: inset 0 0 0 1px var(--gold), 0 8px 20px rgba(74, 59, 53, .07);
}

.lf-dash__linkTitle {
	display: block;
	font-family: var(--font-display);
	font-size: var(--step-1);
	color: var(--ink);
}

.lf-dash__linkNote {
	display: block;
	font-size: var(--step--1);
	color: var(--muted);
}

/* --- Order list --- */

.lf-orders { display: flex; flex-direction: column; gap: 10px; }

.lf-order {
	display: grid;
	grid-template-columns: minmax(0, 1.4fr) auto minmax(0, 1fr) auto;
	align-items: center;
	gap: 16px;
	padding: 18px 22px;
	background: var(--white);
	border-radius: var(--r);
	box-shadow: inset 0 0 0 1px var(--hairline);
	transition: box-shadow .3s var(--ease), transform .3s var(--ease);
}

.lf-order:hover {
	transform: translateY(-2px);
	box-shadow: inset 0 0 0 1px var(--gold), 0 6px 18px rgba(74, 59, 53, .06);
}

.lf-order__no {
	font-family: var(--font-display);
	font-size: var(--step-1);
	color: var(--ink);
}

.lf-order__no:hover { color: var(--rose-ink); }

.lf-order__date {
	display: block;
	font-size: var(--step--1);
	color: var(--muted);
}

.lf-order__status {
	font-size: .7rem;
	letter-spacing: .14em;
	padding: 5px 13px;
	border-radius: var(--r-pill);
	background: var(--canvas-alt);
	color: var(--ink);
	white-space: nowrap;
}

/* Status tints. Anything WooCommerce reports that is not listed keeps the
   neutral pink above, so a custom status can never render unstyled. */
.lf-order--completed .lf-order__status { background: rgba(191, 160, 98, .28); }
.lf-order--processing .lf-order__status { background: var(--rose); }
.lf-order--cancelled .lf-order__status,
.lf-order--failed .lf-order__status,
.lf-order--refunded .lf-order__status { background: rgba(74, 59, 53, .1); color: var(--muted); }

.lf-order__total { font-size: .95rem; color: var(--ink); }
.lf-order__total small { color: var(--muted); font-size: var(--step--1); }

.lf-order__actions { display: flex; gap: 8px; flex-wrap: wrap; }

.lf-order__btn {
	font-size: .7rem;
	letter-spacing: .12em;
	text-transform: uppercase;
	padding: 8px 16px;
	border-radius: var(--r-sm);
	white-space: nowrap;
	color: var(--ink);
	box-shadow: inset 0 0 0 1px var(--gold);
	transition: background-color .3s var(--ease);
}

.lf-order__btn:hover { background: var(--gold); color: var(--ink); }
.lf-order__btn--pay { background: var(--ink); color: var(--canvas); box-shadow: none; }
.lf-order__btn--pay:hover { background: var(--gold); color: var(--ink); }

/* --- Empty state --- */

.lf-empty { text-align: center; padding: clamp(40px, 7vw, 80px) 0; }
.lf-empty__text { color: var(--muted); margin: 1.2em 0 1.8em; }

.lf-pager { display: flex; justify-content: space-between; gap: 12px; margin-top: 26px; }

/* --- Login / register --- */

.lf-auth {
	display: grid;
	gap: clamp(20px, 3vw, 40px);
	max-width: 960px;
	margin: 0 auto;
	/* Stretch, so the short login card matches the taller register card
	   instead of ending two-thirds of the way down beside a blank column.
	   The login form then distributes itself into the height it is given. */
	align-items: stretch;
}

.lf-auth--split { grid-template-columns: repeat(2, minmax(0, 1fr)); }

.lf-auth__card {
	display: flex;
	flex-direction: column;
	background: var(--white);
	border-radius: var(--r-lg);
	padding: clamp(30px, 4vw, 52px);
	box-shadow: inset 0 0 0 1px var(--hairline);
}

/* The register side is the warm neutral panel; the login side is plain paper.
   One subtle tonal step tells them apart without a second colour. */
.lf-auth__card--alt {
	background: var(--canvas-alt);
	box-shadow: inset 0 0 0 1px rgba(191, 160, 98, .35);
}

.lf-auth__title {
	font-size: var(--step-2);
	margin: 0 0 .3em;
}

/* A short champagne rule under each heading, left-aligned — the same ornament
   the page headers use, scaled down for a card. */
.lf-auth__title::after {
	content: "";
	display: block;
	width: 40px;
	height: 1px;
	margin-top: .5em;
	background: linear-gradient(to right, var(--gold), transparent);
}

.lf-auth__note { color: var(--muted); font-size: var(--step--1); }

/* The form fills the card and pushes its button to the bottom, so two forms of
   different lengths still line their buttons up. */
.lf-form {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
	margin-top: clamp(18px, 2vw, 26px);
}

/* Everything above the button is one group; the button is pushed down to sit
   on the card's floor. */
.lf-form .lf-btn--block { margin-top: auto; }

.lf-form .lf-field { margin-bottom: 18px; }

.lf-form label {
	display: block;
	font-size: var(--step--1);
	letter-spacing: .08em;
	color: var(--ink);
	margin-bottom: 6px;
}

.lf-form .required { color: var(--rose-ink); text-decoration: none; }

.lf-form input[type="text"],
.lf-form input[type="email"],
.lf-form input[type="password"],
.lf-form select {
	width: 100%;
	padding: 12px 14px;
	font: inherit;
	font-size: .9rem;
	color: var(--ink);
	background: var(--white);
	border: 1px solid var(--hairline);
	border-radius: var(--r-sm);
	transition: border-color .3s var(--ease), box-shadow .3s var(--ease);
}

.lf-form input:focus,
.lf-form select:focus {
	outline: 0;
	border-color: var(--gold);
	box-shadow: 0 0 0 3px rgba(191, 160, 98, .18);
}

/* label.lf-check, not just .lf-check: the generic `.lf-form label` rule above
   is a class-plus-element and outranks a bare class, so without matching its
   specificity the checkbox label stayed display:block and the box stacked on
   top of its text. */
.lf-form label.lf-check,
.lf-check {
	display: flex;
	align-items: center;
	gap: 8px;
	font-size: var(--step--1);
	color: var(--muted);
	margin: 0;
}

.lf-check input {
	accent-color: var(--rose-ink);
	width: auto;
	margin: 0;
	flex: 0 0 auto;
}

/* Remember-me on the left, lost-password on the right, one line. */
.lf-auth__row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	flex-wrap: wrap;
	margin: 4px 0 22px;
}

.lf-btn--block {
	display: block;
	width: 100%;
	text-align: center;
	padding-top: 16px;
	padding-bottom: 16px;
}

.lf-auth__lost {
	font-size: var(--step--1);
	color: var(--muted);
	border-bottom: 1px solid var(--hairline);
	transition: color .25s var(--ease), border-color .25s var(--ease);
}

.lf-auth__lost:hover { color: var(--rose-ink); border-bottom-color: var(--rose-ink); }

/* --- Responsive --- */

@media (max-width: 980px) {
	.lf-account__grid { grid-template-columns: 1fr; }

	.lf-account__nav { position: static; }

	.lf-account__nav ul {
		display: flex;
		flex-wrap: wrap;
		gap: 6px;
	}

	.lf-account__nav a { padding: 9px 13px; }

	.lf-auth--split { grid-template-columns: 1fr; }
}

@media (max-width: 780px) {
	/* Cards were always the phone layout; here they simply stop being rows. */
	.lf-order {
		grid-template-columns: 1fr auto;
		gap: 8px 14px;
	}

	.lf-order__total { grid-column: 1; }
	.lf-order__actions { grid-column: 1 / -1; }

	.lf-dash__links { grid-template-columns: 1fr; }

	/* Spec: phones drop the decorative motion, keep the entrance fade. */
	.lf-order:hover,
	.lf-dash__link:hover { transform: none; }

	.lf-account__nav a:hover .lf-account__icon { transform: none; }
}

/* --- Neutralising WooCommerce's account floats -----------------------------

   woocommerce-layout.css ships:

       .woocommerce-account .woocommerce-MyAccount-navigation { float: left;  width: 30% }
       .woocommerce-account .woocommerce-MyAccount-content    { float: right; width: 68% }

   As grid items the float is dropped, but the percentage width is not — it
   resolves against the grid area, so the 250px menu column renders at 75px and
   the Japanese labels wrap to one character per line. This is the same trap
   that squeezed the shop grid: `display: grid` beats float, never width.

   Three classes so this wins on specificity and not on which stylesheet the
   browser happened to load last.
   -------------------------------------------------------------------------- */

.lf-account .lf-account__grid > .woocommerce-MyAccount-navigation,
.lf-account .lf-account__grid > .woocommerce-MyAccount-content {
	float: none;
	width: auto;
	max-width: none;
}

/* Two independent guards, so the menu cannot reach the unreadable state even
   if something else narrows it: the column refuses to collapse, and a label
   that still runs out of room clips instead of stacking vertically. */
@media (min-width: 981px) {
	.lf-account__nav { min-width: 200px; }
}

.lf-account__label {
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

/* --------------------------------------------------------------------------
   17. Single product

   Replaces the gallery rules in section 13, which laid the photographs out as
   a column because that was all the default markup allowed. The theme now
   renders its own frame and rail (woocommerce/single-product/product-image.php)
   so the layout can be a lookbook instead of a list.
   -------------------------------------------------------------------------- */

/* Product pages run a touch wider than the 1280 shell so the two equal columns
   each clear 600px. width has to be set too — the shell's own min(1280,92vw)
   already resolves below any larger max-width, so max-width alone did nothing. */
.lf-wc--product .lf-wc__inner { width: min(1340px, 94vw); max-width: none; }

/* The product grid columns and gap are defined once, in section 15, ahead of
   the 860px single-column rule — see the note there. This section only sets the
   wider product shell above. */

/* --- Gallery --- */

.lf-gallery { grid-column: 1; }

.lf-gallery__stage {
	position: relative;
	margin: 0;
	background: var(--white);
	border-radius: var(--r);
	overflow: hidden;
	box-shadow: inset 0 0 0 1px var(--hairline);
}

.lf-gallery__link {
	display: block;
	cursor: zoom-in;
}

.lf-gallery__img {
	width: 100%;
	height: auto;
	display: block;
	transition: transform .7s var(--ease);
}

.lf-gallery__stage:hover .lf-gallery__img { transform: scale(1.02); }

/* The swap fade. Applied to the frame rather than the image so a photograph
   with a different aspect ratio does not jump while it fades. */
.lf-gallery.is-swapping .lf-gallery__img { animation: lf-fade .45s var(--ease); }

@keyframes lf-fade {
	from { opacity: .25; }
	to { opacity: 1; }
}

/* --- Frame arrows and position (JS only) ------------------------------------
   Hidden until <html> gets has-js: without the script they would be dead. */

.lf-gallery__arrow { display: none; }

.has-js .lf-gallery__arrow {
	display: flex;
	align-items: center;
	justify-content: center;
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	width: 42px;
	height: 42px;
	border: 0;
	border-radius: 50%;
	background: rgba(251, 250, 248, .86);
	box-shadow: 0 2px 10px rgba(74, 59, 53, .12);
	color: var(--ink);
	font-family: var(--font-display);
	font-size: 1.6rem;
	line-height: 1;
	cursor: pointer;
	opacity: 0;
	transition: opacity .3s var(--ease), background-color .25s var(--ease), color .25s var(--ease);
}

/* Reveal on hover (desktop) and keep them reachable by keyboard. */
.lf-gallery__stage:hover .lf-gallery__arrow,
.lf-gallery__arrow:focus-visible { opacity: 1; }

.has-js .lf-gallery__arrow:hover { background: var(--gold); color: var(--ink); }

.lf-gallery__arrow--prev { left: 12px; }
.lf-gallery__arrow--next { right: 12px; }

.lf-gallery__arrow span { margin-top: -2px; }

.lf-gallery__pos {
	position: absolute;
	right: 12px;
	bottom: 12px;
	margin: 0;
	padding: 4px 11px;
	border-radius: var(--r-pill);
	background: rgba(46, 43, 39, .62);
	color: var(--canvas);
	font-size: .68rem;
	letter-spacing: .12em;
}

/* --- Thumbnail strip: one scrolling row, not a tiled block ------------------ */

.lf-gallery__rail {
	display: flex;
	gap: 8px;
	margin: 10px 0 0;
	padding: 2px;
	list-style: none;
	overflow-x: auto;
	scroll-behavior: smooth;
	scroll-snap-type: x proximity;
	/* Thin, unobtrusive scrollbar. */
	scrollbar-width: thin;
	scrollbar-color: var(--hairline) transparent;
}

.lf-gallery__rail::-webkit-scrollbar { height: 6px; }
.lf-gallery__rail::-webkit-scrollbar-thumb { background: var(--hairline); border-radius: 999px; }
.lf-gallery__rail::-webkit-scrollbar-track { background: transparent; }

.lf-gallery__thumb {
	flex: 0 0 auto;
	width: clamp(64px, 8vw, 86px);
	scroll-snap-align: start;
}

.lf-gallery__thumb a {
	display: block;
	border-radius: var(--r-sm);
	overflow: hidden;
	position: relative;
	box-shadow: inset 0 0 0 1px var(--hairline);
	transition: box-shadow .3s var(--ease), transform .3s var(--ease);
}

.lf-gallery__thumb img {
	width: 100%;
	height: 100%;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	display: block;
	transition: opacity .3s var(--ease);
}

.lf-gallery__thumb a:hover {
	transform: translateY(-2px);
	box-shadow: inset 0 0 0 1px var(--gold);
}

.lf-gallery__thumb.is-current a { box-shadow: inset 0 0 0 2px var(--rose-ink); }
.lf-gallery__thumb.is-current img { opacity: .82; }

/* --- Summary --- */

.lf-wc div.product .summary {
	/*
	 * Not sticky.
	 *
	 * It used to be `position: sticky; top: 96px` so the price and cart button
	 * would follow a very tall gallery. Two things killed that: the gallery is
	 * now a single frame plus a compact thumbnail rail, not forty stacked
	 * photos, so there is little to follow; and the summary is TALLER than that
	 * gallery, so once pinned it extended down over the full-width
	 * "商品について / 仕様" section below and printed the short description on top
	 * of the attributes. WooCommerce's own summary is not sticky — matching it
	 * removes the overlap with no downside now the gallery is short.
	 */
	position: static;
}

.lf-product__cat { margin-bottom: .8em; }
.lf-product__cat a { border-bottom: 1px solid transparent; }
.lf-product__cat a:hover { border-bottom-color: currentColor; }

.lf-wc .product_title {
	font-size: clamp(1.5rem, 2.6vw, 2.15rem);
	line-height: 1.35;
	margin-bottom: .5em;
}

.lf-wc div.product .price {
	font-family: var(--font-display);
	font-size: clamp(1.4rem, 2.4vw, 1.9rem);
	color: var(--ink);
	margin: 0 0 1.2em;
	padding-bottom: 1em;
	border-bottom: 1px solid var(--hairline);
}

/* --- Availability --- */

.lf-stock {
	display: flex;
	gap: 14px;
	align-items: flex-start;
	background: var(--canvas-alt);
	border-radius: var(--r);
	padding: 18px 20px;
	margin: 0 0 24px;
}

.lf-stock__mark {
	flex: 0 0 8px;
	width: 8px;
	height: 8px;
	margin-top: 10px;
	border-radius: 50%;
	background: var(--rose-ink);
}

/* Partly available reads as information, not as a closed door. */
.lf-stock--partial {
	background: transparent;
	box-shadow: inset 0 0 0 1px var(--gold);
}

.lf-stock--partial .lf-stock__mark { background: var(--gold); }

.lf-stock__title {
	margin: 0 0 .2em;
	font-family: var(--font-display);
	font-size: var(--step-1);
	color: var(--ink);
}

.lf-stock__note {
	margin: 0;
	font-size: var(--step--1);
	line-height: 1.8;
	color: var(--muted);
}

/* --- Variation form --- */

.lf-wc .variations {
	width: 100%;
	margin: 0 0 18px;
	border-collapse: collapse;
}

.lf-wc .variations th,
.lf-wc .variations td {
	padding: 8px 0;
	text-align: left;
	vertical-align: middle;
	border: 0;
}

.lf-wc .variations th {
	width: 34%;
	font-size: var(--step--1);
	font-weight: 400;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--muted);
}

.lf-wc .reset_variations {
	font-size: var(--step--1);
	color: var(--muted);
}

.lf-wc .woocommerce-variation-price { margin-bottom: 14px; }

.lf-wc .quantity input[type="number"] {
	width: 76px;
	padding: 12px 10px;
	text-align: center;
}

.lf-wc form.cart {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	align-items: center;
	margin-bottom: 26px;
}

.lf-wc form.cart .button { flex: 1 1 200px; }

/* --- Short description, under the buy controls --- */

.lf-wc .woocommerce-product-details__short-description {
	font-size: .94rem;
	line-height: 2;
	color: var(--body);
	border-top: 1px solid var(--hairline);
	padding-top: 22px;
}

/* This copy was pasted in from a chat window and arrived carrying utility
   classes and heading levels of its own. Rather than trust it, every heading
   inside is normalised to the same modest size. */
.lf-wc .woocommerce-product-details__short-description h2,
.lf-wc .woocommerce-product-details__short-description h3,
.lf-wc .woocommerce-product-details__short-description h4 {
	font-family: var(--font-display);
	font-size: var(--step-1);
	font-weight: 400;
	color: var(--ink);
	margin: 1.6em 0 .6em;
	padding: 0;
}

.lf-wc .woocommerce-product-details__short-description h2:first-child,
.lf-wc .woocommerce-product-details__short-description h3:first-child { margin-top: 0; }

.lf-wc .woocommerce-product-details__short-description hr {
	border: 0;
	border-top: 1px solid var(--hairline);
	margin: 1.8em 0;
}

.lf-wc .woocommerce-product-details__short-description ul {
	list-style: none;
	padding: 0;
	margin: 0 0 1.2em;
}

.lf-wc .woocommerce-product-details__short-description li {
	position: relative;
	padding-left: 1.1em;
	margin-bottom: .3em;
}

.lf-wc .woocommerce-product-details__short-description li::before {
	content: "";
	position: absolute;
	left: 0;
	top: .85em;
	width: 5px;
	height: 1px;
	background: var(--gold);
}

.lf-wc .woocommerce-product-details__short-description p { margin-bottom: .9em; }

.lf-wc .woocommerce-product-details__short-description strong { color: var(--ink); }

/* Emoji that survived as images stay inline instead of stretching to a block
   the way every other image in this scope does. */
.lf-wc .woocommerce-product-details__short-description img.wp-smiley {
	display: inline;
	width: 1em;
	height: 1em;
	margin: 0 .05em;
	border: 0;
	vertical-align: -.1em;
}

/* --- Details section, full width beneath --- */

.lf-details {
	grid-column: 1 / -1;
	margin-top: clamp(56px, 8vw, 104px);
	padding-top: clamp(40px, 6vw, 72px);
	border-top: 1px solid var(--hairline);
}

/* The product copy (short description) leads at a comfortable reading width,
   centred, so a thousand characters read as a document rather than a wall. */
.lf-details__lead {
	max-width: 820px;
	margin: 0 auto;
}

/* Specification and shipping notes sit side by side below the lead. */
.lf-details__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
	gap: clamp(32px, 5vw, 64px);
	align-items: start;
	margin-top: clamp(40px, 6vw, 72px);
	padding-top: clamp(32px, 4vw, 56px);
	border-top: 1px solid var(--hairline);
}

.lf-details__title {
	font-size: var(--step-2);
	margin-bottom: .8em;
	padding-bottom: .5em;
	border-bottom: 1px solid var(--hairline);
}

.lf-details__body { line-height: 2; }
.lf-details__body p { margin-bottom: 1em; }

/* The rich product copy carries its own headings, rules, sizing chart and a
   care list — normalise the pasted markup (which arrived with inert Tailwind
   class names and heading levels of its own) into the theme's rhythm. */
.lf-details__body--rich h2,
.lf-details__body--rich h3,
.lf-details__body--rich h4 {
	font-family: var(--font-display);
	font-weight: 400;
	font-size: var(--step-1);
	color: var(--ink);
	margin: 1.8em 0 .6em;
	padding: 0;
	border: 0;
}

.lf-details__body--rich h2:first-child,
.lf-details__body--rich h3:first-child { margin-top: 0; }

.lf-details__body--rich hr {
	border: 0;
	border-top: 1px solid var(--hairline);
	margin: 1.8em 0;
}

.lf-details__body--rich ul {
	list-style: none;
	padding: 0;
	margin: 0 0 1.2em;
}

.lf-details__body--rich li {
	position: relative;
	padding-left: 1.2em;
	margin-bottom: .5em;
}

.lf-details__body--rich li::before {
	content: "";
	position: absolute;
	left: 0;
	top: .95em;
	width: 6px;
	height: 1px;
	background: var(--gold);
}

.lf-details__body--rich li p { margin: 0; }
.lf-details__body--rich strong { color: var(--ink); }

.lf-details .shop_attributes {
	width: 100%;
	border-collapse: collapse;
}

.lf-details .shop_attributes th,
.lf-details .shop_attributes td {
	padding: 12px 0;
	text-align: left;
	border-bottom: 1px solid var(--hairline);
	font-size: .9rem;
}

.lf-details .shop_attributes th {
	width: 36%;
	font-weight: 400;
	color: var(--muted);
	letter-spacing: .08em;
}

.lf-details .shop_attributes p { margin: 0; }

/* --- Reviews (WooCommerce's own list and form, styled from outside) --- */

.lf-reviews {
	margin-top: clamp(48px, 7vw, 88px);
	padding-top: clamp(36px, 5vw, 64px);
	border-top: 1px solid var(--hairline);
	max-width: 760px;
}

.lf-reviews .lf-details__title { margin-bottom: 1em; }

.lf-reviews .commentlist { list-style: none; margin: 0 0 2.5em; padding: 0; }

.lf-reviews .commentlist li.review,
.lf-reviews .commentlist li.comment {
	padding: 20px 0;
	border-bottom: 1px solid var(--hairline);
}

.lf-reviews .comment_container { display: flex; gap: 16px; align-items: flex-start; }
.lf-reviews .comment_container img.avatar {
	width: 46px;
	height: 46px;
	border-radius: var(--r-pill);
	margin: 0;
}

.lf-reviews .comment-text { flex: 1 1 auto; min-width: 0; }
.lf-reviews .woocommerce-review__author { font-family: var(--font-display); font-size: var(--step-1); color: var(--ink); }
.lf-reviews .woocommerce-review__dash { color: var(--muted); }
.lf-reviews .woocommerce-review__published-date { font-size: var(--step--1); color: var(--muted); }
.lf-reviews .description { margin-top: .5em; }

/* WooCommerce prints its own star font via ::before; only the colour is ours. */
.lf-reviews .star-rating span::before,
.lf-reviews p.stars a::before { color: var(--gold); }
.lf-reviews .star-rating { color: var(--gold); margin: 4px 0; }

.lf-reviews .comment-reply-title {
	display: block;
	font-family: var(--font-display);
	font-size: var(--step-1);
	color: var(--ink);
	margin-bottom: .8em;
}

.lf-reviews .comment-form { display: block; }

.lf-reviews .comment-form-rating label { display: block; margin-bottom: 4px; }

.lf-reviews .comment-form input[type="text"],
.lf-reviews .comment-form input[type="email"],
.lf-reviews .comment-form textarea {
	width: 100%;
	padding: 12px 14px;
	font: inherit;
	font-size: .9rem;
	color: var(--ink);
	background: var(--white);
	border: 1px solid var(--hairline);
	border-radius: var(--r-sm);
	transition: border-color .3s var(--ease), box-shadow .3s var(--ease);
}

.lf-reviews .comment-form textarea { min-height: 120px; resize: vertical; line-height: 1.8; }

.lf-reviews .comment-form input:focus,
.lf-reviews .comment-form textarea:focus {
	outline: 0;
	border-color: var(--gold);
	box-shadow: 0 0 0 3px rgba(191, 160, 98, .18);
}

.lf-reviews .comment-form p { margin-bottom: 16px; }
.lf-reviews .comment-form label { font-size: var(--step--1); color: var(--ink); }
.lf-reviews .comment-form .required { color: var(--rose-ink); }

.lf-reviews .woocommerce-noreviews { color: var(--muted); }

/* --- Lightbox --- */

.lf-lightbox {
	position: fixed;
	inset: 0;
	z-index: 200;
	display: none;
	align-items: center;
	justify-content: center;
	background: rgba(46, 38, 35, .93);
	opacity: 0;
	transition: opacity .3s var(--ease);
}

.lf-lightbox.is-open { display: flex; opacity: 1; }

.lf-lightbox__img {
	max-width: 90vw;
	max-height: 86vh;
	width: auto;
	height: auto;
	border-radius: var(--r-sm);
	box-shadow: 0 20px 60px rgba(0, 0, 0, .45);
}

.lf-lightbox__close,
.lf-lightbox__nav {
	position: absolute;
	background: transparent;
	border: 0;
	color: var(--canvas);
	cursor: pointer;
	font-family: var(--font-display);
	line-height: 1;
	padding: 12px 18px;
	transition: color .25s var(--ease);
}

.lf-lightbox__close { top: 14px; right: 18px; font-size: 2.2rem; }
.lf-lightbox__nav { top: 50%; transform: translateY(-50%); font-size: 3rem; }
.lf-lightbox__nav--prev { left: 8px; }
.lf-lightbox__nav--next { right: 8px; }

.lf-lightbox__close:hover,
.lf-lightbox__nav:hover { color: var(--gold); }

.lf-lightbox__count {
	position: absolute;
	bottom: 18px;
	left: 0; right: 0;
	text-align: center;
	color: var(--canvas);
	font-size: var(--step--1);
	letter-spacing: .18em;
	margin: 0;
}

.lf-noscroll { overflow: hidden; }

/* --- Related --- */

.lf-wc .related { margin-top: clamp(56px, 8vw, 104px); }

/* --- Responsive --- */

@media (max-width: 860px) {
	/* The frame no longer zooms on hover on touch, and — since there is no
	   hover to reveal them on a phone — the arrows sit visible at reduced
	   opacity; the swipe is the primary control anyway. */
	.lf-gallery__stage:hover .lf-gallery__img { transform: none; }

	.has-js .lf-gallery__arrow { opacity: .9; width: 38px; height: 38px; font-size: 1.4rem; }

	.lf-wc form.cart .button { flex: 1 1 100%; }

	.lf-lightbox__nav { font-size: 2.2rem; padding: 10px 8px; }
}

@media (prefers-reduced-motion: reduce) {
	.lf-gallery.is-swapping .lf-gallery__img { animation: none; }
}

/* --------------------------------------------------------------------------
   18. Cart and checkout

   Per the design spec these two pages keep their motion to a minimum: no
   hover lifts, no staggered reveals, nothing that competes with the form.
   Whatever is not laid out here is a WooCommerce template this theme
   deliberately did not override — cart-totals, review-order and the field
   templates are styled from the outside so their logic stays untouched.
   -------------------------------------------------------------------------- */

.lf-cart__head,
.lf-checkout__head {
	text-align: center;
	margin-bottom: clamp(36px, 5vw, 60px);
}

.lf-cart__title,
.lf-checkout__title {
	font-size: clamp(1.7rem, 3.4vw, 2.6rem);
	margin: 0;
}

/* --- Cart lines --- */

.lf-cart__list { display: flex; flex-direction: column; gap: 12px; }

.lf-line {
	display: grid;
	grid-template-columns: 92px minmax(0, 1fr) auto auto 32px;
	align-items: center;
	gap: 20px;
	padding: 16px 20px;
	background: var(--white);
	border-radius: var(--r);
	box-shadow: inset 0 0 0 1px var(--hairline);
}

/* The cart thumbnail arrives as a full-size product image — WooCommerce puts
   no dimensions on it and the default table relied on a fixed cell width. */
.lf-line__media img {
	width: 92px;
	height: 118px;
	object-fit: cover;
	border-radius: var(--r-sm);
	display: block;
}

.lf-line__body { min-width: 0; }

.lf-line__body > a {
	font-family: var(--font-display);
	font-size: var(--step-1);
	color: var(--ink);
	line-height: 1.4;
}

.lf-line__body > a:hover { color: var(--rose-ink); }

/* Variation attributes, printed by wc_get_formatted_cart_item_data(). */
.lf-line__body dl.variation {
	display: flex;
	flex-wrap: wrap;
	gap: 4px 14px;
	margin: 6px 0 0;
	font-size: var(--step--1);
	color: var(--muted);
}

.lf-line__body dl.variation dt { font-weight: 400; margin: 0; }
.lf-line__body dl.variation dd { margin: 0; }
.lf-line__body dl.variation dd p { margin: 0; }

.lf-line__unit {
	margin: 6px 0 0;
	font-size: var(--step--1);
	color: var(--muted);
}

.lf-line__qty .quantity input.qty {
	width: 68px;
	padding: 10px 8px;
	text-align: center;
	font: inherit;
	font-size: .9rem;
	color: var(--ink);
	background: var(--white);
	border: 1px solid var(--hairline);
	border-radius: var(--r-sm);
}

.lf-line__sum {
	font-family: var(--font-display);
	font-size: var(--step-1);
	color: var(--ink);
	white-space: nowrap;
}

.lf-line__remove a.remove {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 30px;
	height: 30px;
	border-radius: 50%;
	font-size: 1.35rem;
	line-height: 1;
	color: var(--muted);
	transition: background-color .25s var(--ease), color .25s var(--ease);
}

.lf-line__remove a.remove:hover { background: var(--canvas-alt); color: var(--rose-deep); }

/* --- Cart actions --- */

.lf-cart__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	align-items: center;
	justify-content: space-between;
	margin-top: 18px;
	padding-top: 20px;
	border-top: 1px solid var(--hairline);
}

.lf-coupon { display: flex; gap: 8px; }

.lf-coupon input.input-text {
	width: 190px;
	padding: 12px 14px;
	font: inherit;
	font-size: .875rem;
	color: var(--ink);
	background: var(--white);
	border: 1px solid var(--hairline);
	border-radius: var(--r-sm);
}

.lf-coupon input.input-text:focus,
.lf-line__qty input.qty:focus {
	outline: 0;
	border-color: var(--gold);
	box-shadow: 0 0 0 3px rgba(191, 160, 98, .18);
}

/* --- Cart totals (WooCommerce's own template, styled from outside) --- */

.lf-cart__collaterals {
	display: flex;
	justify-content: flex-end;
	margin-top: clamp(30px, 4vw, 48px);
}

.cart_totals {
	width: min(420px, 100%);
	background: var(--canvas-alt);
	border-radius: var(--r);
	padding: clamp(24px, 3vw, 32px);
	box-shadow: inset 0 0 0 1px rgba(191, 160, 98, .4);
}

.cart_totals h2 {
	font-size: var(--step-2);
	margin: 0 0 1em;
	padding-bottom: .5em;
	border-bottom: 1px solid var(--hairline);
}

.cart_totals table { width: 100%; border-collapse: collapse; }

.cart_totals th,
.cart_totals td {
	padding: 10px 0;
	text-align: left;
	border: 0;
	font-size: .92rem;
	vertical-align: top;
}

.cart_totals th { font-weight: 400; color: var(--muted); }
.cart_totals td { text-align: right; color: var(--ink); }

.cart_totals .order-total th,
.cart_totals .order-total td {
	padding-top: 16px;
	border-top: 1px solid var(--hairline);
	font-family: var(--font-display);
	font-size: var(--step-1);
	color: var(--ink);
}

.cart_totals .woocommerce-shipping-methods { margin: 0; padding: 0; list-style: none; }
.cart_totals .woocommerce-shipping-methods li { margin-bottom: 4px; }
.cart_totals .woocommerce-shipping-destination { font-size: var(--step--1); color: var(--muted); }

.wc-proceed-to-checkout { margin-top: 22px; }

.wc-proceed-to-checkout .checkout-button {
	display: block;
	width: 100%;
	text-align: center;
	box-sizing: border-box;
}

/* --- Checkout --- */

.lf-checkout__grid {
	display: grid;
	grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
	gap: clamp(28px, 4vw, 60px);
	align-items: start;
}

.lf-checkout__summary {
	position: sticky;
	top: 96px;
	background: var(--canvas-alt);
	border-radius: var(--r);
	padding: clamp(24px, 3vw, 32px);
	box-shadow: inset 0 0 0 1px rgba(191, 160, 98, .4);
}

.lf-checkout__summary h3 {
	font-size: var(--step-2);
	margin: 0 0 1em;
	padding-bottom: .5em;
	border-bottom: 1px solid var(--hairline);
}

/* The billing and shipping columns stack: side by side they force both
   address forms into half a column each, which is where the cramped field
   widths in the default layout came from. */
.lf-checkout .col2-set { display: block; }
.lf-checkout .col2-set .col-1 { margin-bottom: clamp(28px, 4vw, 44px); }

.lf-checkout h3,
.lf-checkout .woocommerce-billing-fields h3,
.lf-checkout .woocommerce-shipping-fields h3,
.lf-checkout .woocommerce-additional-fields h3 {
	font-family: var(--font-display);
	font-weight: 300;
	font-size: var(--step-2);
	color: var(--ink);
	margin: 0 0 1em;
}

/* Fields: label above input, full width. The default puts them inline, which
   is what produced the ragged left edge of the form. */
.lf-checkout .form-row {
	display: flex;
	flex-direction: column;
	margin: 0 0 16px;
	padding: 0;
	width: 100%;
	float: none;
}

.lf-checkout .form-row label {
	font-size: var(--step--1);
	letter-spacing: .06em;
	color: var(--ink);
	margin-bottom: 6px;
}

.lf-checkout .form-row .required { color: var(--rose-ink); text-decoration: none; border: 0; }
.lf-checkout .form-row .optional { color: var(--muted); }

.lf-checkout .form-row input.input-text,
.lf-checkout .form-row textarea,
.lf-checkout .form-row select,
.lf-checkout .form-row .select2-selection {
	width: 100%;
	padding: 12px 14px;
	font: inherit;
	font-size: .9rem;
	color: var(--ink);
	background: var(--white);
	border: 1px solid var(--hairline);
	border-radius: var(--r-sm);
	transition: border-color .3s var(--ease), box-shadow .3s var(--ease);
}

.lf-checkout .form-row textarea { min-height: 110px; resize: vertical; line-height: 1.7; }

.lf-checkout .form-row input:focus,
.lf-checkout .form-row textarea:focus,
.lf-checkout .form-row select:focus {
	outline: 0;
	border-color: var(--gold);
	box-shadow: 0 0 0 3px rgba(191, 160, 98, .18);
}

/* Two-up for the name pair on wide screens; everything else stays full width. */
@media (min-width: 720px) {
	.lf-checkout .woocommerce-billing-fields__field-wrapper,
	.lf-checkout .woocommerce-shipping-fields__field-wrapper {
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: 0 16px;
	}

	.lf-checkout .form-row-wide,
	.lf-checkout .form-row:not(.form-row-first):not(.form-row-last) { grid-column: 1 / -1; }
}

/* Checkboxes stay on one line with their label. */
.lf-checkout .form-row.woocommerce-validated label.checkbox,
.lf-checkout label.checkbox,
.lf-checkout .woocommerce-form__label-for-checkbox {
	flex-direction: row;
	align-items: center;
	gap: 8px;
	display: flex;
	margin: 0;
}

.lf-checkout .woocommerce-form__label-for-checkbox input { accent-color: var(--rose-ink); }

#ship-to-different-address {
	font-family: var(--font-display);
	font-size: var(--step-1);
	margin: 0 0 1em;
}

#ship-to-different-address label { display: inline-flex; align-items: center; gap: 10px; }

/* --- Order review (WooCommerce's own template) --- */

.woocommerce-checkout-review-order-table {
	width: 100%;
	border-collapse: collapse;
	margin-bottom: 20px;
}

.woocommerce-checkout-review-order-table th,
.woocommerce-checkout-review-order-table td {
	padding: 10px 0;
	text-align: left;
	border: 0;
	font-size: .92rem;
	vertical-align: top;
}

.woocommerce-checkout-review-order-table thead th {
	font-weight: 400;
	font-size: var(--step--1);
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--muted);
	border-bottom: 1px solid var(--hairline);
	padding-bottom: 12px;
}

.woocommerce-checkout-review-order-table td:last-child,
.woocommerce-checkout-review-order-table th:last-child { text-align: right; }

.woocommerce-checkout-review-order-table .product-name { color: var(--ink); line-height: 1.6; }
.woocommerce-checkout-review-order-table .product-quantity { color: var(--muted); }

.woocommerce-checkout-review-order-table .variation {
	margin: 4px 0 0;
	font-size: var(--step--1);
	color: var(--muted);
}

.woocommerce-checkout-review-order-table tfoot th { font-weight: 400; color: var(--muted); }

.woocommerce-checkout-review-order-table tfoot .order-total th,
.woocommerce-checkout-review-order-table tfoot .order-total td {
	padding-top: 16px;
	border-top: 1px solid var(--hairline);
	font-family: var(--font-display);
	font-size: var(--step-1);
	color: var(--ink);
}

/* --- Payment --- */

#payment {
	background: var(--white);
	border-radius: var(--r);
	padding: 20px;
	box-shadow: inset 0 0 0 1px var(--hairline);
}

#payment ul.payment_methods {
	margin: 0 0 16px;
	padding: 0 0 16px;
	list-style: none;
	border-bottom: 1px solid var(--hairline);
}

#payment ul.payment_methods li { margin-bottom: 10px; }

#payment ul.payment_methods label {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	font-size: .92rem;
	color: var(--ink);
}

#payment ul.payment_methods input[type="radio"] { accent-color: var(--rose-ink); }

#payment .payment_box {
	background: var(--canvas);
	border-radius: var(--r-sm);
	padding: 14px 16px;
	margin: 8px 0 0;
	font-size: var(--step--1);
	line-height: 1.8;
	color: var(--muted);
}

#payment .payment_box p:last-child { margin-bottom: 0; }

#payment .woocommerce-privacy-policy-text {
	font-size: var(--step--1);
	color: var(--muted);
	line-height: 1.8;
}

#payment #place_order {
	width: 100%;
	margin-top: 8px;
	box-sizing: border-box;
}

/* --- Notices --- */

.lf-wc .woocommerce-message,
.lf-wc .woocommerce-info,
.lf-wc .woocommerce-error {
	position: relative;
	background: var(--canvas-alt);
	border-radius: var(--r);
	border-left: 3px solid var(--gold);
	padding: 14px 18px;
	margin: 0 0 22px;
	font-size: .92rem;
	line-height: 1.7;
	color: var(--ink);
	list-style: none;
}

/*
 * Kill WooCommerce's built-in notice icon.
 *
 * WooCommerce draws a coloured glyph in a ::before from its own icon font
 * (a red "!" on errors, #b81c23), positioned with a left padding this theme's
 * flat padding does not reserve — so it collided with the text and read as a
 * clashing second element. The left border already signals the notice type in
 * this palette, so the glyph is dropped entirely.
 */
.lf-wc .woocommerce-message::before,
.lf-wc .woocommerce-info::before,
.lf-wc .woocommerce-error::before,
.lf-wc .woocommerce-message::after,
.lf-wc .woocommerce-info::after,
.lf-wc .woocommerce-error::after {
	display: none;
}

.lf-wc .woocommerce-error { border-left-color: var(--rose-deep); }

.lf-wc .woocommerce-message li,
.lf-wc .woocommerce-info li,
.lf-wc .woocommerce-error li { margin: 0; padding: 0; }

.lf-wc .woocommerce-message a,
.lf-wc .woocommerce-info a { color: var(--rose-ink); border-bottom: 1px solid currentColor; }

/* --- Responsive --- */

@media (max-width: 980px) {
	.lf-checkout__grid { grid-template-columns: 1fr; }

	/* Sticky in one column would pin the summary over the fields. */
	.lf-checkout__summary { position: static; }

	.lf-cart__collaterals { justify-content: stretch; }
	.cart_totals { width: 100%; }
}

@media (max-width: 720px) {
	.lf-line {
		grid-template-columns: 72px minmax(0, 1fr) 28px;
		gap: 6px 14px;
		padding: 14px;
	}

	.lf-line__media { grid-row: span 2; }
	.lf-line__media img { width: 72px; height: 92px; }

	.lf-line__qty,
	.lf-line__sum { grid-column: 2; justify-self: start; }

	.lf-line__remove { grid-column: 3; grid-row: 1; align-self: start; }

	.lf-cart__actions { flex-direction: column; align-items: stretch; }
	.lf-coupon { flex-direction: column; }
	.lf-coupon input.input-text { width: 100%; }
}

/* --------------------------------------------------------------------------
   19. Language switcher

   First version put a filled pill on the current language and greyed the other
   one out. That read as a disabled toggle rather than a choice: the language
   you could actually switch to looked like the one that was turned off. Both
   codes now carry the same weight, and the current one is marked the way the
   nav marks its current item — a gold hairline underneath.
   -------------------------------------------------------------------------- */

.lf-lang {
	display: flex;
	align-items: center;
	gap: 7px;
}

.lf-lang__globe {
	width: 14px;
	height: 14px;
	flex: 0 0 14px;
	color: var(--gold);
}

.lf-lang__list { display: flex; align-items: center; gap: 9px; }

.lf-lang__item a {
	display: inline-block;
	position: relative;
	padding: 3px 1px;
	font-size: .8rem;
	letter-spacing: .12em;
	color: var(--ink);
	transition: color .25s var(--ease);
}

/* The same growing rule the primary nav uses, so the header has one idiom. */
.lf-lang__item a::after {
	content: "";
	position: absolute;
	left: 0; right: 0; bottom: 0;
	height: 1px;
	background: var(--gold);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform .3s var(--ease);
}

.lf-lang__item a:hover { color: var(--rose-ink); }
.lf-lang__item a:hover::after,
.lf-lang__item.is-current a::after { transform: scaleX(1); }

/* Separator between the codes, drawn rather than typed so it never wraps. */
.lf-lang__item + .lf-lang__item { position: relative; }

.lf-lang__item + .lf-lang__item::before {
	content: "";
	position: absolute;
	left: -5px;
	top: 50%;
	transform: translateY(-50%);
	width: 1px;
	height: 9px;
	background: var(--hairline);
}

.lf-lang--drawer { margin-top: 4px; }
.lf-lang--drawer .lf-lang__globe { width: 16px; height: 16px; flex-basis: 16px; }
.lf-lang--drawer .lf-lang__item a { font-size: .8rem; padding: 6px 1px; }

/* --------------------------------------------------------------------------
   20. Drawer footer
   -------------------------------------------------------------------------- */

.lf-drawer__foot {
	margin-top: 22px;
	padding-top: 22px;
	border-top: 1px solid var(--hairline);
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
}

.lf-drawer__tool {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	font-size: .8rem;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--ink);
	padding: 8px 0;
}

.lf-drawer__tool:hover { color: var(--rose-ink); }

/* --------------------------------------------------------------------------
   21. Journal — index, archives, search
   -------------------------------------------------------------------------- */

.lf-archive__inner {
	width: var(--shell);
	max-width: 1180px;
	margin: 0 auto;
	padding: var(--section-y) 0;
}

.lf-archive__head {
	text-align: center;
	margin-bottom: clamp(40px, 6vw, 72px);
}

.lf-archive__title { font-size: clamp(1.7rem, 3.4vw, 2.6rem); margin: 0; }

.lf-archive__intro {
	max-width: 34em;
	margin: 1.6em auto 0;
	color: var(--muted);
}

.lf-archive__grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
	gap: clamp(28px, 4vw, 52px);
}

.lf-post { display: flex; flex-direction: column; }

.lf-post__media {
	display: block;
	overflow: hidden;
	border-radius: var(--r);
	background: var(--canvas-alt);
	aspect-ratio: 4 / 3;
	margin-bottom: 18px;
}

.lf-post__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform .8s var(--ease);
}

.lf-post:hover .lf-post__media img { transform: scale(1.04); }

.lf-post__meta {
	display: flex;
	align-items: center;
	gap: 12px;
	margin: 0 0 .5em;
	font-size: var(--step--1);
	letter-spacing: .1em;
	color: var(--muted);
}

.lf-post__cat {
	padding: 3px 10px;
	border-radius: var(--r-pill);
	background: var(--canvas-alt);
	color: var(--ink);
	font-size: .68rem;
}

.lf-post__title {
	font-size: var(--step-2);
	line-height: 1.4;
	margin: 0 0 .5em;
}

.lf-post__title a:hover { color: var(--rose-ink); }

.lf-post__excerpt {
	color: var(--body);
	font-size: .94rem;
	line-height: 1.95;
	margin-bottom: 1em;
}

/* Push the read-more to the bottom so cards of different lengths still line up. */
.lf-post .lf-link { margin-top: auto; align-self: flex-start; }

/* --- Pagination --- */

.lf-archive .navigation.pagination { margin-top: clamp(44px, 6vw, 76px); }

.lf-archive .nav-links {
	display: flex;
	justify-content: center;
	align-items: center;
	gap: 6px;
	flex-wrap: wrap;
}

.lf-archive .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 38px;
	height: 38px;
	padding: 0 12px;
	border-radius: var(--r-sm);
	font-size: .85rem;
	color: var(--ink);
	box-shadow: inset 0 0 0 1px var(--hairline);
	transition: box-shadow .25s var(--ease), background-color .25s var(--ease);
}

.lf-archive .page-numbers:hover { box-shadow: inset 0 0 0 1px var(--gold); }

.lf-archive .page-numbers.current {
	background: var(--ink);
	color: var(--canvas);
	box-shadow: none;
}

.lf-archive .page-numbers.dots { box-shadow: none; color: var(--muted); }

/* --------------------------------------------------------------------------
   22. Journal — single post
   -------------------------------------------------------------------------- */

.lf-single {
	width: var(--shell);
	max-width: 820px;
	margin: 0 auto;
	padding: var(--section-y) 0;
}

.lf-single__head { text-align: center; margin-bottom: clamp(30px, 4vw, 48px); }

.lf-single__meta {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 14px;
	font-size: var(--step--1);
	letter-spacing: .12em;
	color: var(--muted);
	margin-bottom: 1em;
}

.lf-single__cat {
	padding: 3px 12px;
	border-radius: var(--r-pill);
	background: var(--canvas-alt);
	color: var(--ink);
}

.lf-single__cat:hover { background: var(--rose); }

.lf-single__title {
	font-size: clamp(1.6rem, 3.4vw, 2.5rem);
	line-height: 1.35;
	margin: 0;
}

.lf-single__hero {
	margin: 0 0 clamp(30px, 4vw, 52px);
	border-radius: var(--r);
	overflow: hidden;
}

.lf-single__hero img { width: 100%; height: auto; }

.lf-single__body { max-width: none; }

.lf-single__body h2,
.lf-single__body h3 { margin-top: 1.8em; }

.lf-single__body blockquote {
	margin: 2em 0;
	padding: 0 0 0 1.4em;
	border-left: 2px solid var(--gold);
	font-family: var(--font-display);
	font-size: var(--step-1);
	font-style: italic;
	color: var(--ink);
}

.lf-single__body figure { margin: 2em 0; }
.lf-single__body figcaption {
	margin-top: .6em;
	font-size: var(--step--1);
	color: var(--muted);
	text-align: center;
}

.lf-single__tags {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: clamp(32px, 4vw, 48px) 0 0;
	padding: 0;
	list-style: none;
}

.lf-single__tags a {
	display: inline-block;
	padding: 5px 14px;
	border-radius: var(--r-pill);
	font-size: var(--step--1);
	color: var(--muted);
	box-shadow: inset 0 0 0 1px var(--hairline);
	transition: box-shadow .25s var(--ease), color .25s var(--ease);
}

.lf-single__tags a:hover { color: var(--ink); box-shadow: inset 0 0 0 1px var(--gold); }

/* --- Previous / next --- */

.lf-adjacent {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 12px;
	margin-top: clamp(44px, 6vw, 72px);
	padding-top: clamp(28px, 4vw, 44px);
	border-top: 1px solid var(--hairline);
}

.lf-adjacent__link {
	display: block;
	padding: 18px 20px;
	border-radius: var(--r);
	background: var(--white);
	box-shadow: inset 0 0 0 1px var(--hairline);
	transition: box-shadow .3s var(--ease), transform .3s var(--ease);
}

.lf-adjacent__link:hover {
	transform: translateY(-2px);
	box-shadow: inset 0 0 0 1px var(--gold);
}

/* A post with only a next link should not sit under the "previous" column. */
.lf-adjacent__link--next:only-child { grid-column: 2; }

.lf-adjacent__link--next { text-align: right; }

.lf-adjacent__label {
	display: block;
	font-size: var(--step--1);
	letter-spacing: .16em;
	color: var(--muted);
	margin-bottom: .3em;
}

.lf-adjacent__title {
	display: block;
	font-family: var(--font-display);
	font-size: var(--step-1);
	color: var(--ink);
	line-height: 1.4;
}

/* --------------------------------------------------------------------------
   23. Search form and 404
   -------------------------------------------------------------------------- */

.lf-search {
	display: flex;
	gap: 8px;
	max-width: 460px;
	margin: 1.8em auto 0;
}

.lf-search__field {
	flex: 1 1 auto;
	min-width: 0;
	padding: 12px 14px;
	font: inherit;
	font-size: .9rem;
	color: var(--ink);
	background: var(--white);
	border: 1px solid var(--hairline);
	border-radius: var(--r-sm);
}

.lf-search__field:focus {
	outline: 0;
	border-color: var(--gold);
	box-shadow: 0 0 0 3px rgba(191, 160, 98, .18);
}

.lf-empty .lf-btn + .lf-btn { margin-left: 10px; }

/* --------------------------------------------------------------------------
   404 — a soft landing: a line-drawn bow, a big numeral, two ways home
   -------------------------------------------------------------------------- */

.lf-404 {
	width: var(--shell);
	margin: 0 auto;
	min-height: 62vh;
	display: grid;
	place-items: center;
	padding: var(--section-y) 0;
	text-align: center;
}

.lf-404__inner {
	width: 100%;          /* fill the shell, don't grow to the buttons' width —
	                         otherwise the action row never runs out of room and
	                         so never wraps, and long labels overflow the screen */
	max-width: 46ch;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 16px;
}

.lf-404__bow {
	display: block;
	width: clamp(76px, 13vw, 112px);
	color: var(--gold);
}

.lf-404__bow svg {
	width: 100%;
	height: auto;
	transform-origin: 50% 34%;
	animation: lf-404-sway 5s ease-in-out infinite;
}

@keyframes lf-404-sway {
	0%, 100% { transform: rotate(-4deg); }
	50%      { transform: rotate(4deg); }
}

.lf-404__code {
	margin: 4px 0 0;
	font-family: var(--font-display);
	font-size: clamp(3.6rem, 13vw, 6.4rem);
	line-height: .86;
	letter-spacing: .04em;
	color: var(--ink);
}

.lf-404__title {
	margin: 0;
	font-family: var(--font-display);
	font-weight: 500;
	font-size: clamp(1.35rem, 3.6vw, 2rem);
	color: var(--ink);
}

.lf-404__text {
	margin: 0;
	max-width: 40ch;
	color: var(--body);
	line-height: 1.95;
}

.lf-404__actions {
	margin-top: 14px;
	display: flex;
	gap: 14px;
	flex-wrap: wrap;
	justify-content: center;
}

/* Narrow phones: the English labels don't fit two-up, so stack them and let
   each button take a comfortable, equal width instead of overflowing. */
@media (max-width: 480px) {
	.lf-404__actions {
		flex-direction: column;
		align-items: stretch;
		width: 100%;
		max-width: 260px;
	}
	.lf-404__actions .lf-btn { text-align: center; }
}

@media (prefers-reduced-motion: reduce) {
	.lf-404__bow svg { animation: none; }
}

/* --------------------------------------------------------------------------
   24. Journal responsive
   -------------------------------------------------------------------------- */

@media (max-width: 780px) {
	.lf-archive__grid { grid-template-columns: 1fr; }

	.lf-adjacent { grid-template-columns: 1fr; }
	.lf-adjacent__link--next { text-align: left; }
	.lf-adjacent__link--next:only-child { grid-column: 1; }

	.lf-post:hover .lf-post__media img { transform: none; }

	.lf-search { flex-direction: column; }

	.lf-empty .lf-btn + .lf-btn { margin: 10px 0 0; display: inline-block; }
}

/* --------------------------------------------------------------------------
   25. Ornament

   The rococo half of the brief, which the build had been skipping: corner
   flourishes, a heading ornament, and radii large enough to actually read as
   radii. All of it is hairline champagne on paper — an edge, never a fill —
   and all of it is drawn in CSS, so it costs no image and no request.

   Restraint is the rule from the spec: ornament belongs on headings and on the
   edges of panels, never on product photography, prices or the checkout form.
   -------------------------------------------------------------------------- */

/* --- Corner brackets ------------------------------------------------------

   Two opposite corners only. Four corners reads as a picture frame and starts
   competing with the garment; two is a suggestion. */

.lf-corners { position: relative; }

.lf-corners::before,
.lf-corners::after {
	content: "";
	position: absolute;
	width: 22px;
	height: 22px;
	border: 1px solid var(--gold);
	opacity: .5;
	pointer-events: none;
	transition: opacity .45s var(--ease), width .45s var(--ease), height .45s var(--ease);
}

.lf-corners::before {
	top: 9px;
	left: 9px;
	border-width: 1px 0 0 1px;
	border-radius: var(--r-sm) 0 0 0;
}

.lf-corners::after {
	right: 9px;
	bottom: 9px;
	border-width: 0 1px 1px 0;
	border-radius: 0 0 var(--r-sm) 0;
}

/* The brackets draw themselves outward on hover — the "hover 微光" of the spec,
   done with the ornament instead of a glow. */
.lf-corners:hover::before,
.lf-corners:hover::after {
	width: 30px;
	height: 30px;
	opacity: .85;
}

/* --- Panels ---------------------------------------------------------------

   The cards that carry the site's structure get the corner treatment. Product
   cards deliberately do not: the photograph is the subject there. */

.lf-account__nav,
.lf-dash__welcome,
.lf-auth__card,
.cart_totals,
.lf-checkout__summary,
.lf-details__block {
	position: relative;
}

.lf-account__nav::after,
.lf-dash__welcome::before,
.lf-auth__card::after,
.cart_totals::after,
.lf-checkout__summary::after {
	content: "";
	position: absolute;
	right: 10px;
	bottom: 10px;
	width: 22px;
	height: 22px;
	border: 1px solid var(--gold);
	border-width: 0 1px 1px 0;
	border-radius: 0 0 var(--r-sm) 0;
	opacity: .45;
	pointer-events: none;
}

/* The dashboard already carried a champagne arc; keep it, and let the bracket
   sit at the opposite corner rather than fighting it. */
.lf-dash__welcome::before {
	right: auto;
	bottom: auto;
	top: 10px;
	left: 10px;
	border-width: 1px 0 0 1px;
	border-radius: var(--r-sm) 0 0 0;
}

/* --------------------------------------------------------------------------
   26. Motion

   Everything here is transform or opacity, so it composites on the GPU and
   never triggers layout. Nothing runs on the cart or the checkout.
   -------------------------------------------------------------------------- */

/* --- Staggered entrance ---------------------------------------------------

   Grid children fade in one after another rather than as a block. The delay is
   capped: past the eighth card a visitor is scrolling, and waiting on a queue
   of delays feels broken rather than considered. */

.lf-archive__grid .reveal:nth-child(1) { transition-delay: 0ms; }
.lf-archive__grid .reveal:nth-child(2) { transition-delay: 70ms; }
.lf-archive__grid .reveal:nth-child(3) { transition-delay: 140ms; }
.lf-archive__grid .reveal:nth-child(4) { transition-delay: 210ms; }
.lf-archive__grid .reveal:nth-child(n+5) { transition-delay: 260ms; }

/* --- Hover: cards ---------------------------------------------------------

   One lift value across the site so the whole thing feels like one hand. */

.lf-card,
.lf-post__media,
.lf-dash__link,
.lf-order,
.lf-adjacent__link {
	transition: transform .4s var(--ease), box-shadow .4s var(--ease);
}

.lf-card:hover,
.lf-dash__link:hover,
.lf-order:hover,
.lf-adjacent__link:hover { transform: translateY(-4px); }

/* --- Hover: gold underline on links --------------------------------------- */

.lf-footer__list a,
.lf-account__nav a,
.lf-single__tags a { transition: color .3s var(--ease), background-color .3s var(--ease); }

/* --- Buttons -------------------------------------------------------------- */

.lf-btn {
	position: relative;
	transition: background-color .35s var(--ease), transform .25s var(--ease);
}

.lf-btn:hover { transform: translateY(-1px); }
.lf-btn:active { transform: translateY(0); }

/*
 * The champagne "sheen" sweep was removed.
 *
 * It was a gradient ::after parked at translateX(-100%), meant to be clipped by
 * the button's overflow:hidden and only visible sweeping across on hover. In
 * practice it leaked one button-width into the left gutter as a faint gold band
 * that moved on hover — a real artifact, spotted on the login page. And it is
 * now redundant: hover fills the whole button with champagne, so a champagne
 * sheen crossing a champagne button shows nothing. Dropping it removes both the
 * bug and the overflow:hidden that existed only to contain it.
 */

/* --- Icon micro-motion ---------------------------------------------------- */

.lf-lang__globe { transition: transform .5s var(--ease); }
.lf-lang:hover .lf-lang__globe { transform: rotate(22deg); }

/* --------------------------------------------------------------------------
   27. Ornament & motion — responsive and accessibility
   -------------------------------------------------------------------------- */

@media (max-width: 780px) {
	/* Spec: phones drop the decorative layer and keep the page quick. */
	.lf-corners::before,
	.lf-corners::after { display: none; }

	.lf-card:hover,
	.lf-dash__link:hover,
	.lf-order:hover,
	.lf-adjacent__link:hover,
	.lf-btn:hover { transform: none; }

	.lf-archive__grid .reveal:nth-child(n) { transition-delay: 0ms; }
}

/* The cart and checkout stay still, whatever the screen size. */
.woocommerce-cart .lf-btn:hover,
.woocommerce-checkout .lf-btn:hover { transform: none; }

@media (prefers-reduced-motion: reduce) {
	.lf-corners::before,
	.lf-corners::after { transition: none; }

	.lf-archive__grid .reveal:nth-child(n) { transition-delay: 0ms; }
}

/* --------------------------------------------------------------------------
   28. Preloader

   Hidden by default and only shown to a scripted browser that has not seen it
   this session. The important property is that NOTHING about hiding it depends
   on JavaScript: the fade-out is a keyframe animation with `forwards`, so if
   motion.js fails to load or throws, the veil still leaves. The script can only
   make it leave sooner.

   Total cost: no image beyond the logo the header already loads, no request,
   and it never blocks the content rendering behind it.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   Cookie consent — a small card in the corner, never a wall
   -------------------------------------------------------------------------- */

.lf-cookie {
	position: fixed;
	z-index: 200;
	left: clamp(14px, 3vw, 28px);
	bottom: clamp(14px, 3vw, 28px);
	width: min(384px, calc(100vw - 28px));
	display: flex;
	align-items: center;
	gap: 14px;
	padding: 15px 16px;
	background: var(--white);
	border: 1px solid var(--hairline);
	border-radius: var(--r-lg);
	box-shadow: 0 14px 44px rgba(46, 43, 39, .16);
	animation: lf-cookie-in .5s var(--ease) both;
}

.lf-cookie[hidden] { display: none; }

@keyframes lf-cookie-in {
	from { opacity: 0; transform: translateY(22px); }
	to   { opacity: 1; transform: none; }
}

.lf-cookie.is-out { animation: lf-cookie-out .38s var(--ease) forwards; }

@keyframes lf-cookie-out {
	to { opacity: 0; transform: translateY(22px); }
}

.lf-cookie__icon { flex: none; width: 42px; height: 42px; }

.lf-cookie__icon svg {
	width: 100%;
	height: 100%;
	display: block;
	transform-origin: 50% 62%;
	animation: lf-cookie-wobble 3.4s ease-in-out infinite;
}

@keyframes lf-cookie-wobble {
	0%, 100% { transform: rotate(-7deg); }
	50%      { transform: rotate(7deg); }
}

.lf-cookie__text {
	flex: 1 1 auto;
	margin: 0;
	font-size: .82rem;
	line-height: 1.65;
	color: var(--body);
}

.lf-cookie__text a {
	color: var(--rose-ink);
	text-decoration: underline;
	text-underline-offset: 2px;
}

.lf-cookie__accept {
	flex: none;
	font-family: var(--font-body);
	font-size: .72rem;
	letter-spacing: .1em;
	text-transform: uppercase;
	white-space: nowrap;
	color: var(--canvas);
	background: var(--ink);
	border: 0;
	border-radius: var(--r-pill);
	padding: 10px 18px;
	cursor: pointer;
	transition: background .3s var(--ease), color .3s var(--ease), transform .2s var(--ease);
}

.lf-cookie__accept:hover { background: var(--gold); color: var(--ink); }
.lf-cookie__accept:active { transform: scale(.96); }

@media (max-width: 480px) {
	.lf-cookie {
		left: 12px;
		right: 12px;
		bottom: 12px;
		width: auto;
		flex-wrap: wrap;
	}
	.lf-cookie__text { flex: 1 1 60%; }
	.lf-cookie__accept { flex: 1 0 100%; margin-top: 2px; padding: 12px; }
}

@media (prefers-reduced-motion: reduce) {
	.lf-cookie__icon svg { animation: none; }
}

/* --------------------------------------------------------------------------
   Preloader
   -------------------------------------------------------------------------- */

.lf-preloader { display: none; }

.has-js:not(.lf-seen) .lf-preloader {
	display: flex;
	position: fixed;
	inset: 0;
	z-index: 300;
	align-items: center;
	justify-content: center;
	background: var(--canvas);

	/* Hard backstop: if motion.js never runs, the veil still lifts on its own at
	   2.4s. In the normal case motion.js adds .is-done around 1.3s (once the
	   wordmark has drawn in) and it lifts then — this delay only has to sit
	   safely LATER than that so it does not cut the animation short. */
	animation: lf-preloader-out .5s var(--ease) 2.4s forwards;
}

/* motion.js adds this on window load; if the page was quick, the veil goes
   at once instead of waiting out the 1.15s above. */
.has-js .lf-preloader.is-done {
	animation: lf-preloader-out .45s var(--ease) forwards;
}

@keyframes lf-preloader-out {
	to {
		opacity: 0;
		visibility: hidden;
	}
}

.lf-preloader__inner {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 16px;
}

/* Start visible and animate FROM hidden, not the other way round. Written as
   `opacity: 0` these two were invisible whenever the animation did not run —
   the same fails-hidden shape as the entrance reveals. Now a stalled animation
   leaves a plain logo rather than an empty white screen. */
/*
 * The wordmark is "drawn" — revealed left to right behind a moving clip, the
 * way the handwritten logo would be inked. A true SVG stroke animation would
 * need vector paths of the logo, which we do not have; a left-to-right wipe on
 * the script reads as the same gesture and works on the PNG we do have.
 *
 * `backwards` holds the from-state during the .1s delay; if the animation never
 * runs (it is the same fails-visible reasoning as the reveals) the logo simply
 * shows in full.
 */
.lf-preloader__logo {
	opacity: 1;
	animation: lf-preloader-draw 1.15s var(--ease) .1s backwards;
}

.lf-preloader__text {
	opacity: 1;
	animation: lf-preloader-mark .8s var(--ease) .05s backwards;
}

@keyframes lf-preloader-draw {
	from { clip-path: inset(0 100% 0 0); opacity: .85; }
	to   { clip-path: inset(0 0 0 0); opacity: 1; }
}

.lf-preloader__logo { width: 180px; height: auto; }

.lf-preloader__text {
	font-family: var(--font-display);
	font-size: var(--step-3);
	letter-spacing: .14em;
	color: var(--ink);
}

@keyframes lf-preloader-mark {
	from { opacity: 0; transform: translateY(6px); }
	to   { opacity: 1; transform: none; }
}

/* A champagne hairline drawing itself out from the centre. This is the only
   thing that actually reads as "loading", and it is one element. */
.lf-preloader__rule {
	display: block;
	width: 120px;
	height: 1px;
	background: linear-gradient(to right, transparent, var(--gold), transparent);
	transform: scaleX(1);
	animation: lf-preloader-rule 1.1s var(--ease) .2s backwards;
}

@keyframes lf-preloader-rule {
	from { transform: scaleX(0); }
	to   { transform: scaleX(1); }
}

/* Reduced motion: no veil at all. Someone who has asked for less movement
   should not be shown a full-screen animation before the page they wanted. */
@media (prefers-reduced-motion: reduce) {
	.has-js:not(.lf-seen) .lf-preloader { display: none; }
}

/* --------------------------------------------------------------------------
   29. Cinematic layer (assets/fx.js)

   Parallax, a cursor-tracking glow and card tilt. Everything is transform or a
   custom-property-driven gradient, and the whole layer is inert under
   prefers-reduced-motion (fx.js returns early and these rules do no harm on
   their own).
   -------------------------------------------------------------------------- */

/* --- Parallax figures --- */

.lf-fx-frame { overflow: hidden; }

.lf-fx-parallax {
	transform: scale(1.12);      /* oversized so the slide never bares an edge */
	will-change: transform;
	backface-visibility: hidden;
}

/* --- Hero cursor glow --- */

.lf-hero { position: relative; }

.lf-fx-glow {
	position: absolute;
	inset: 0;
	z-index: 3;
	pointer-events: none;
	background: radial-gradient(
		circle at var(--gx, 50%) var(--gy, 40%),
		rgba(201, 169, 106, .5),
		rgba(201, 169, 106, 0) 42%
	);
	/* Lights the content beneath rather than washing over it, so the ink text
	   under the glow stays perfectly readable. */
	mix-blend-mode: soft-light;
	opacity: 1;
	transition: opacity .45s var(--ease);
}

/* The hero content sits above the photo but the glow (z-index 3) rides over
   both — soft-light keeps it gentle. Type stays selectable via pointer-events. */
.lf-hero__type,
.lf-hero__figure { position: relative; z-index: 1; }

/* --- Card tilt --- */

.lf-card { will-change: transform; transform-style: preserve-3d; }

/* Fast, near-instant follow while the cursor is on the card; the base .lf-card
   transition (.4s) eases it back home when the class is removed on leave. */
.lf-card.is-tilting { transition: transform .12s var(--ease), box-shadow .4s var(--ease); }

/* Reduced motion: strip the parallax scale too, so nothing is left oversized. */
@media (prefers-reduced-motion: reduce) {
	.lf-fx-parallax { transform: none; }
	.lf-fx-glow { display: none; }
}
