/* Login Extender (EXPERIMENTAL) - wrapper-owned chrome around the stock
 * espresso login (Frappe 16.26.0+). Injected on /login only, and only while
 * the split layout is on and a side image is set; otherwise the stock page
 * renders untouched and this file is never loaded.
 *
 * Contract: every selector here is scoped under .lx-root. Espresso's own
 * selectors are never re-declared; the handful of .lx-root descendant rules
 * that touch stock elements are positional only (neutralising the stock
 * page's outer centering inside the rail, hiding the duplicate in-card logo
 * in split mode). Espresso variables (--bg-color, --heading-color, ...) are
 * inherited, never redefined. */

.lx-root {
	/* Wrapper-owned tokens (namespaced --lx-*). On-image colors are fixed,
	 * not theme-dependent: the photograph is mode-neutral. The scrim base is
	 * a de-hued near-black so the wrapper carries no hue opinion. */
	--lx-scrim-base: 12, 13, 14;
	--lx-on-image: #ffffff;
	--lx-on-image-soft: rgba(255, 255, 255, 0.85);
	--lx-panel-fallback: #f3f3f3;
	--lx-rail-w: 480px;
	--lx-rail-pad: 36px 44px 44px;
	--lx-overlay-inset: 48px;
	--lx-overlay-bottom: 44px;
	--lx-band-h: 148px;
	--lx-band-h-panorama: 190px;

	/* Per-device framing (Focal Compass, EXPERIMENTAL): focal point and zoom
	 * of the one side image. Defaults reproduce the shared center-focal cover
	 * crop; login_extender.js overrides them inline per device from the
	 * server-validated framing config. Applied by the media blocks at the end
	 * of this file on the shared device breakpoints
	 * (login_extender.DEVICE_BREAKPOINTS): mobile <=991, laptop 992-1439,
	 * desktop >=1440. */
	--lx-frame-desktop-pos: 50% 50%;
	--lx-frame-desktop-zoom: 1;
	--lx-frame-laptop-pos: 50% 50%;
	--lx-frame-laptop-zoom: 1;
	--lx-frame-mobile-pos: 50% 50%;
	--lx-frame-mobile-zoom: 1;

	display: flex;
	min-height: 100vh;
	min-height: 100svh;
}

[data-theme="dark"] .lx-root,
[data-theme-mode="dark"] .lx-root {
	--lx-panel-fallback: #232323;
}

.lx-root.lx-side-left {
	flex-direction: row-reverse;
}

/* ------------------------------------------------------------- form rail */
.lx-rail {
	flex: 0 0 var(--lx-rail-w);
	background: var(--bg-color);
	padding: var(--lx-rail-pad);
	display: flex;
	flex-direction: column;
	min-width: 0;
}

.lx-card-slot {
	flex: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 0;
}

/* Neutralise the stock page's outer centering inside the rail (positional
 * wrapper rule; espresso's stylesheet is untouched). */
.lx-root .page-content-wrapper {
	padding-top: 0;
	min-height: 0;
	width: 100%;
}

.lx-footer {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 12px;
	font-size: 11px;
	line-height: 1.4;
	font-weight: 400;
	color: var(--ink-gray-6);
}

.lx-footer a {
	color: inherit;
	text-decoration: none;
}

.lx-footer a:hover {
	text-decoration: underline;
}

.lx-footer-sep {
	opacity: 0.6;
	padding: 0 4px;
}

/* ----------------------------------------------------------- image panel */
.lx-panel {
	flex: 1;
	position: relative;
	overflow: hidden;
	background: var(--lx-panel-fallback);
}

.lx-panel img.lx-image {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
}

/* Corner brand chip (split mode): the brand's single home on the image, shown
 * in both quiet split and panorama. It sits in the top-leading corner on its
 * own top scrim, so it stays legible over any upload independently of the
 * bottom-left statement scrim, and never collides with the bottom-left overlay
 * or the top-right credit. Hidden on the mobile band (stacked block below),
 * where the brand band carries identity. Placement is side-agnostic: top-left
 * of the panel is the inner corner for a right image and the outer corner for
 * a left image, and the credit is always top-right, so the two never overlap. */
.lx-brand-scrim {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 150px;
	background: linear-gradient(
		180deg,
		rgba(var(--lx-scrim-base), 0.55),
		rgba(var(--lx-scrim-base), 0)
	);
	z-index: 2;
}

.lx-brandmark {
	position: absolute;
	top: 30px;
	left: 34px;
	z-index: 3;
	display: flex;
	align-items: center;
	gap: 11px;
	width: calc(100% - 100px);
	max-width: calc(100% - 100px);
}

.lx-brandmark img.lx-brandmark-logo {
	max-height: 30px;
	max-width: 120px;
	width: auto;
	display: block;
	flex: 0 0 auto;
}

.lx-brandmark-name {
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-size: 18px;
	line-height: 1.2;
	font-weight: 650;
	letter-spacing: -0.01em;
	color: var(--lx-on-image);
	text-shadow: 0 1px 10px rgba(0, 0, 0, 0.45);
}

/* Panorama scrim (P1, split mode): guarantees headline legibility on any
 * upload; never editable. */
.lx-scrim {
	position: absolute;
	inset: 0;
	background: linear-gradient(
		11deg,
		rgba(var(--lx-scrim-base), 0.78) 0%,
		rgba(var(--lx-scrim-base), 0.34) 34%,
		rgba(var(--lx-scrim-base), 0) 62%
	);
}

/* Panorama overlay (P3/P4, split mode): bottom-left of the image panel. */
.lx-overlay {
	position: absolute;
	left: var(--lx-overlay-inset);
	right: var(--lx-overlay-inset);
	bottom: var(--lx-overlay-bottom);
}

.lx-headline {
	font-size: 40px;
	line-height: 1.12;
	font-weight: 600;
	letter-spacing: -0.015em;
	color: var(--lx-on-image);
	text-wrap: balance;
	max-width: 520px;
	margin: 0;
}

.lx-welcome {
	font-size: 15px;
	line-height: 1.5;
	font-weight: 400;
	color: var(--lx-on-image-soft);
	max-width: 460px;
	margin: 10px 0 0;
}

/* Mobile band content lives in the same panel; hidden at split widths. */
.lx-band-scrim,
.lx-band-content {
	display: none;
}

/* ---------------------------------------------- image credit (attribution) */
/* Info-icon reveal, top-right of the image panel (clear of the bottom-left
 * statement overlay). The button toggles the single static credit on click,
 * tap, or keyboard activation through .is-open; hover-capable devices also
 * reveal it on hover. On-image colors are fixed (the photo is mode-neutral),
 * matching the overlay treatment above. */
.lx-credit {
	position: absolute;
	top: 20px;
	right: 20px;
	z-index: 3;
}

.lx-credit::after {
	content: "";
	position: absolute;
	top: 30px;
	right: 0;
	width: 244px;
	height: 8px;
}

.lx-credit-btn {
	width: 30px;
	height: 30px;
	padding: 0;
	border-radius: 50%;
	border: 1px solid rgba(255, 255, 255, 0.7);
	background: rgba(var(--lx-scrim-base), 0.55);
	color: var(--lx-on-image);
	font: italic 15px/1 Georgia, "Times New Roman", serif;
	display: flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
}

.lx-credit-btn:hover,
.lx-credit-btn:focus-visible {
	background: rgba(var(--lx-scrim-base), 0.82);
}

.lx-credit-pop {
	position: absolute;
	top: 38px;
	right: 0;
	width: 244px;
	background: rgba(var(--lx-scrim-base), 0.95);
	color: var(--lx-on-image);
	border-radius: 10px;
	padding: 12px 14px;
	font-size: 12.5px;
	line-height: 1.5;
	box-shadow: 0 12px 30px rgba(0, 0, 0, 0.4);
	opacity: 0;
	visibility: hidden;
	transform: translateY(-4px);
	transition: opacity 120ms ease, transform 120ms ease;
}

.lx-credit.is-open .lx-credit-pop {
	opacity: 1;
	visibility: visible;
	transform: translateY(0);
}

@media (hover: hover) {
	.lx-credit:hover .lx-credit-pop {
		opacity: 1;
		visibility: visible;
		transform: translateY(0);
	}
}

.lx-credit-title {
	font-weight: 650;
	margin-bottom: 2px;
}

.lx-credit-line {
	color: var(--lx-on-image-soft);
}

.lx-credit-link {
	color: #7fd3c4;
	text-decoration: underline;
}

.lx-credit-note {
	color: rgba(255, 255, 255, 0.6);
	font-size: 11px;
	margin-top: 6px;
}

/* Split mode: espresso renders app_logo inside .page-card-head, which would
 * duplicate the brand shown on the image (the corner chip on desktop/laptop,
 * the brand band on mobile), so the in-card logo image is always hidden - one
 * brand presentation per view, at every width (positional wrapper rule). This
 * rule only loads while the split is active, so the stock login is untouched. */
.lx-root .page-card-head img.app-logo {
	display: none;
}

@media (min-width: 992px) {
	/* The stock website chrome changes .container padding at viewport
	 * breakpoints (40/80/24px at 992/1200/1440px in split mode). In the rail,
	 * that keys the form width to the viewport, so the form reflows when the
	 * viewport changes even though the rail does not. The rail already owns
	 * the horizontal gutters (--lx-rail-pad); zero the stock padding so the
	 * card sizes to the rail alone (positional wrapper rule). Stacked mode
	 * (<=991px) keeps the stock padding: there the rail spans the viewport,
	 * so viewport-keyed padding is container-keyed. */
	.lx-root .page-content-wrapper .container {
		padding-left: 0;
		padding-right: 0;
	}
}

/* ------------------------------------------- stacked mode (mobile <=991px) */
@media (max-width: 991px) {
	.lx-root,
	.lx-root.lx-side-left {
		flex-direction: column;
	}

	/* The image panel collapses to a fixed-height brand band at the top
	 * (never bottom - side has no meaning stacked). */
	.lx-panel {
		order: -1;
		flex: 0 0 var(--lx-band-h);
	}

	.lx-root.lx-panorama .lx-panel {
		flex-basis: var(--lx-band-h-panorama);
	}

	/* The split-mode panorama layer is desktop/laptop chrome. */
	.lx-scrim,
	.lx-overlay {
		display: none;
	}

	/* Band scrim is part of the base (it guarantees lockup legibility),
	 * not a panorama element. */
	.lx-band-scrim {
		display: block;
		position: absolute;
		inset: 0;
		background: linear-gradient(
			5deg,
			rgba(var(--lx-scrim-base), 0.62),
			rgba(var(--lx-scrim-base), 0.05) 60%
		);
	}

	.lx-band-content {
		display: block;
		position: absolute;
		left: 24px;
		right: 24px;
		bottom: 16px;
	}

	.lx-band-lockup {
		display: flex;
		align-items: center;
		gap: 9px;
	}

	.lx-band-content img.lx-band-logo {
		display: block;
		max-height: 26px;
		width: auto;
	}

	.lx-band-name {
		font-size: 14.5px;
		line-height: 1.2;
		font-weight: 650;
		color: #ffffff;
		text-shadow: 0 1px 8px rgba(0, 0, 0, 0.35);
	}

	/* Panorama band: logo above headline above welcome (the slot the removed
	 * accent rule vacates), so mobile always shows brand. */
	.lx-band-content.lx-band-panorama img.lx-band-logo {
		margin-bottom: 9px;
	}

	.lx-band-headline {
		font-size: 21px;
		line-height: 1.2;
		font-weight: 600;
		letter-spacing: -0.01em;
		color: #ffffff;
		margin: 0;
	}

	.lx-band-welcome {
		font-size: 12px;
		line-height: 1.45;
		font-weight: 400;
		color: var(--lx-on-image-soft);
		margin: 3px 0 0;
	}

	/* Mobile drops the rail's footer entirely; the form area is flex: 1 of a
	 * column spanning the viewport so the band height is never double-counted
	 * against espresso's own 100svh-based sizing. */
	.lx-rail {
		flex: 1 1 auto;
		padding: 0;
	}

	.lx-footer {
		display: none;
	}

	/* The corner brand chip is desktop/laptop chrome; on mobile the brand band
	 * carries the single brand, so hide the chip and its scrim there. */
	.lx-brandmark,
	.lx-brand-scrim {
		display: none;
	}

	/* Credit info button sits top-right of the brand band; larger touch
	 * target on mobile. The band is short and .lx-panel clips overflow, so
	 * the revealed popover is positioned relative to the viewport (the band
	 * is always at the top on mobile) to avoid being cut off. */
	.lx-credit {
		top: 14px;
		right: 14px;
	}

	.lx-credit-btn {
		width: 40px;
		height: 40px;
		font-size: 18px;
	}

	.lx-credit-pop {
		position: fixed;
		top: 62px;
		right: 14px;
		z-index: 10;
	}

	.lx-root .page-content-wrapper {
		height: 100%;
	}
}

/* --------------------- per-device framing (shared breakpoints, see tokens) */
/* transform-origin at the focal point keeps the placed subject anchored
 * while zoom scales the cover-cropped image around it. */
@media (min-width: 1440px) {
	.lx-panel img.lx-image {
		object-position: var(--lx-frame-desktop-pos);
		transform: scale(var(--lx-frame-desktop-zoom));
		transform-origin: var(--lx-frame-desktop-pos);
	}
}

@media (min-width: 992px) and (max-width: 1439px) {
	.lx-panel img.lx-image {
		object-position: var(--lx-frame-laptop-pos);
		transform: scale(var(--lx-frame-laptop-zoom));
		transform-origin: var(--lx-frame-laptop-pos);
	}
}

@media (max-width: 991px) {
	.lx-panel img.lx-image {
		object-position: var(--lx-frame-mobile-pos);
		transform: scale(var(--lx-frame-mobile-zoom));
		transform-origin: var(--lx-frame-mobile-pos);
	}
}

/* Espresso-xs (<576px): the stock card goes full-bleed with its own 100svh
 * minimum; inside the wrapper the band already owns part of the viewport, so
 * the card fills the remaining form area instead (positional rule; the calc
 * is used because the card's intermediate stock ancestors carry no height for
 * a percentage to resolve against). */
@media (max-width: 575.98px) {
	.lx-card-slot {
		align-items: stretch;
	}

	.lx-root .page-card {
		min-height: calc(100svh - var(--lx-band-h));
	}

	.lx-root.lx-panorama .page-card {
		min-height: calc(100svh - var(--lx-band-h-panorama));
	}
}
