/* Viscom ERP login page. Tokens and rules: ~/code/viscom-erp/DESIGN.md.
   The page extends Frappe's templates/base.html without the website bundle, so everything visual is
   defined here. Colours that the client may change (the accent and its dark shade, the photo focal
   point) arrive as inline custom properties on .vc-login from Viscom Login Settings; the values below
   are only the fallbacks. */

@font-face {
	font-family: "Geist";
	font-style: normal;
	font-weight: 100 900;
	font-display: swap;
	src: url("/assets/viscom_erp/fonts/geist-latin.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: "Geist";
	font-style: normal;
	font-weight: 100 900;
	font-display: swap;
	src: url("/assets/viscom_erp/fonts/geist-latin-ext.woff2") format("woff2");
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
	color-scheme: light;
	--vc-bg: #f7f6f2;
	--vc-surface: #ffffff;
	--vc-ink: #141414;
	--vc-muted: #5f5e59;
	--vc-line: #8f8d84; /* input borders: 3.3:1 on white, 3.1:1 on the base (WCAG 1.4.11) */
	--vc-line-strong: #6f6d67;
	--vc-line-soft: #d9d7cf;
	--vc-placeholder: #737169; /* 4.9:1 on white */
	--vc-accent: #4eb848;
	--vc-accent-deep: #2f7a2b;
	--vc-danger: #b3261e;
	--vc-danger-bg: #fbeceb;
	--vc-success-bg: #e8f5e6;
	--vc-radius: 8px;
	--vc-font: "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
	--vc-photo-panel: #add35c; /* the flat lime backdrop of the 2025 photo, sampled at both top corners */
	--vc-photo-justify: flex-end;
	--vc-photo-trim: 0px;
	--vc-photo-ratio: 1920 / 863;
	--vc-hover-fill: color-mix(in srgb, var(--vc-ink) 5%, transparent);
	--vc-motion: 160ms;
}

html, body.vc-login-body {
	margin: 0;
	padding: 0;
	min-height: 100%;
	background: var(--vc-bg);
	color: var(--vc-ink);
	font-family: var(--vc-font);
	font-size: 16px;
	line-height: 1.5;
	-webkit-font-smoothing: antialiased;
	-webkit-text-size-adjust: 100%;
	text-size-adjust: 100%;
}
body.vc-login-body { overflow-x: hidden; }
*, *::before, *::after { box-sizing: border-box; }
img { display: block; max-width: 100%; }

/* ---------------------------------------------------------------- layout */

.vc-login {
	/* derived from the settings-driven accent shade (inline on this element), so they must be
	   declared here, not on :root, to see the override */
	--vc-focus: var(--vc-accent-deep); /* 4.9:1 on the base; the brand green alone is 2.4:1 */
	--vc-success: var(--vc-accent-deep);
	min-height: 100vh;
	min-height: 100dvh;
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	grid-template-rows: auto minmax(0, 1fr);
	grid-template-areas: "photo" "form";
}
.vc-form-column {
	grid-area: form;
	display: flex;
	flex-direction: column;
	gap: 28px;
	padding: 24px 20px 28px;
}
/* The photograph is never cropped (CEO 2026-09-21: every face stays visible). The panel carries the
   photo's own backdrop colour, the image is contained inside it whole, so the panel reads as one
   green surface with the full picture in it. Stacked layout: a full-width band at the photo's ratio. */
.vc-photo-column {
	grid-area: photo;
	position: relative;
	margin: 0;
	min-height: 0;
	overflow: hidden;
	background: var(--vc-photo-panel);
	/* the band keeps the photo's own aspect ratio (served by the controller), so nothing is
	   letterboxed: the picture is the band */
	aspect-ratio: var(--vc-photo-ratio);
	display: flex;
	flex-direction: column;
	justify-content: var(--vc-photo-justify);
}
.vc-photo {
	display: block;
	width: 100%;
	max-width: none;
	height: auto;
	object-fit: contain;
	/* hides the compression halo on the photo's top rows (backdrop pixels only) so that edge
	   blends into the panel; the other edges meet the form column, the viewport or the photo's own
	   floor, where a trim would paint a lime stroke instead. From settings, 0 disables. A viewport
	   shorter than the photo at panel width (1920x500) scrolls rather than shrinking the picture. */
	clip-path: inset(var(--vc-photo-trim) 0 0 0);
}
.vc-caption {
	position: absolute;
	left: 20px;
	bottom: 16px;
	margin: 0;
	padding: 6px 12px;
	border-radius: 999px;
	background: color-mix(in srgb, var(--vc-ink) 72%, transparent);
	color: var(--vc-surface);
	font-size: 13px;
	font-weight: 500;
	letter-spacing: 0.01em;
}

.vc-brand { flex: 0 0 auto; }
.vc-logo { width: auto; height: 58px; } /* 2026-09-23: bumped 44->58 (+32%), CEO "make the logo bigger" */
.vc-card-slot { flex: 1 0 auto; width: 100%; max-width: 400px; }
.vc-card-slot > section { width: 100%; }
.vc-card { width: 100%; }

.vc-footer {
	flex: 0 0 auto;
	margin: 0;
	color: var(--vc-muted);
	font-size: 13px;
	line-height: 1.5;
}
.vc-footer p { margin: 0; }

/* tablets: wider gutters and the full-size logo, still one column */
@media (min-width: 600px) {
	.vc-form-column { padding: 32px 48px 32px; }
	.vc-logo { height: 74px; } /* 2026-09-23: bumped 56->74 (+32%), CEO "make the logo bigger" */
}

/* the split: 900 and up, form column left (about 40 percent), photo panel right, full height */
@media (min-width: 900px) {
	.vc-login {
		grid-template-columns: clamp(420px, 40%, 560px) minmax(0, 1fr);
		grid-template-rows: minmax(0, 1fr);
		grid-template-areas: "form photo";
	}
	.vc-form-column {
		gap: 40px;
		padding: 40px 32px 32px;
	}
	.vc-card-slot {
		display: flex;
		align-items: center;
	}
	.vc-photo-column { min-height: 100vh; min-height: 100dvh; aspect-ratio: auto; }
	.vc-caption { left: 32px; bottom: 28px; }
}
@media (min-width: 1200px) {
	.vc-form-column { padding: 48px 64px 40px; }
}

/* ---------------------------------------------------------------- type */

.vc-card-head { margin: 0 0 24px; }
.vc-heading {
	margin: 0 0 8px;
	font-size: 28px;
	line-height: 1.15;
	font-weight: 600;
	letter-spacing: -0.01em;
	text-wrap: balance;
}
.vc-intro {
	margin: 0;
	color: var(--vc-muted);
	font-size: 16px;
	line-height: 1.5;
}
@media (min-width: 1200px) {
	.vc-heading { font-size: 32px; line-height: 1.1; }
}

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

.vc-form { margin: 0; }
.vc-fields { display: flex; flex-direction: column; gap: 18px; }
.vc-field { display: flex; flex-direction: column; gap: 6px; }
.vc-field-password { position: relative; }
.vc-forgot {
	position: absolute;
	top: 0;
	right: 0;
	line-height: 1.4;
}
.vc-label {
	font-size: 14px;
	line-height: 1.4;
	font-weight: 500;
	color: var(--vc-ink);
}
.vc-input {
	appearance: none;
	width: 100%;
	height: 48px;
	margin: 0;
	padding: 0 14px;
	border: 1px solid var(--vc-line);
	border-radius: var(--vc-radius);
	background: var(--vc-surface);
	color: var(--vc-ink);
	font: inherit;
	font-size: 16px;
	line-height: 1.5;
	transition: border-color var(--vc-motion) ease, box-shadow var(--vc-motion) ease;
}
.vc-input::placeholder { color: var(--vc-placeholder); opacity: 1; }
.vc-input:hover { border-color: var(--vc-line-strong); }
.vc-input:focus { outline: none; border-color: var(--vc-accent-deep); } /* 4.9:1 boundary for mouse focus too */
.vc-input:focus-visible { outline: 2px solid var(--vc-focus); outline-offset: 2px; }
.vc-field.invalid .vc-input,
.vc-fields.invalid .vc-input,
.vc-input[aria-invalid="true"] { border-color: var(--vc-danger); }
.vc-field-error {
	display: none;
	margin: 0;
	color: var(--vc-danger);
	font-size: 13px;
	line-height: 1.5;
}
.vc-field.invalid .vc-field-error:not(:empty) { display: block; }

.vc-password { position: relative; }
.vc-password .vc-input { padding-right: 52px; }
.vc-toggle {
	position: absolute;
	top: 2px;
	right: 2px;
	width: 44px;
	height: 44px;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 6px;
	background: transparent;
	color: var(--vc-muted);
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	transition: color var(--vc-motion) ease, background-color var(--vc-motion) ease;
}
.vc-toggle:hover { color: var(--vc-ink); background: var(--vc-hover-fill); }
.vc-toggle:focus-visible { outline: 2px solid var(--vc-focus); outline-offset: -2px; color: var(--vc-ink); }
.vc-toggle .vc-icon-eye-off { display: none; }
.vc-toggle.is-visible .vc-icon-eye { display: none; }
.vc-toggle.is-visible .vc-icon-eye-off { display: block; }

.vc-link {
	display: inline-block;
	padding: 4px 0; /* 24px minimum target height (WCAG 2.5.8) without moving the text */
	margin: -4px 0;
	color: var(--vc-accent-deep);
	font-size: 14px;
	font-weight: 500;
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
	border-radius: 3px;
	transition: color var(--vc-motion) ease;
}
.vc-link:hover { color: var(--vc-ink); }
.vc-link:focus-visible { outline: 2px solid var(--vc-focus); outline-offset: 2px; }

.vc-actions { display: flex; flex-direction: column; gap: 12px; margin-top: 24px; }
.vc-button {
	appearance: none;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 48px;
	margin: 0;
	padding: 0 20px;
	border: 1px solid transparent;
	border-radius: var(--vc-radius);
	background: var(--vc-accent);
	color: var(--vc-ink);
	font: inherit;
	font-size: 16px;
	font-weight: 600;
	letter-spacing: 0.01em;
	text-decoration: none;
	cursor: pointer;
	transition: filter var(--vc-motion) ease, background-color var(--vc-motion) ease, color var(--vc-motion) ease;
}
.vc-button:hover { filter: brightness(0.94); }
.vc-button:active { filter: brightness(0.9); }
.vc-button:focus-visible { outline: 2px solid var(--vc-focus); outline-offset: 3px; }
.vc-button:disabled { opacity: 0.55; cursor: not-allowed; filter: none; }
/* busy: the fill stays, the label changes and a spinner appears; disabled so no second submit */
.vc-button.is-busy { opacity: 1; cursor: progress; }
.vc-button .vc-spinner { display: none; margin-right: 10px; }
.vc-button.is-busy .vc-spinner { display: block; animation: vc-spin 900ms linear infinite; }
@keyframes vc-spin { to { transform: rotate(360deg); } }
.vc-button-secondary {
	background: transparent;
	border-color: var(--vc-line-strong);
	color: var(--vc-ink);
	font-weight: 500;
}
.vc-button-secondary:hover { background: var(--vc-hover-fill); filter: none; }
.vc-social { display: flex; flex-direction: column; gap: 12px; }

.vc-switch { margin: 20px 0 0; font-size: 14px; color: var(--vc-muted); }

/* ---------------------------------------------------------------- banners */

.vc-banner {
	display: none;
	align-items: flex-start;
	gap: 10px;
	padding: 12px 14px;
	border: 1px solid color-mix(in srgb, var(--vc-danger) 25%, transparent);
	border-radius: var(--vc-radius);
	background: var(--vc-danger-bg);
	color: var(--vc-danger);
	font-size: 14px;
	line-height: 1.45;
	font-weight: 500;
}
.vc-banner .vc-icon { flex: 0 0 auto; margin-top: 1px; }
.vc-banner-static { display: flex; margin-bottom: 18px; }
.vc-banner-success {
	border-color: color-mix(in srgb, var(--vc-success) 30%, transparent);
	background: var(--vc-success-bg);
	color: var(--vc-success);
}
/* login.js sets display: flex inline when it has a message; nothing else may show an empty banner */

/* ---------------------------------------------------------------- stock behaviour hooks */

/* login.js appends a #freeze overlay for the duration of the request; keep it as an invisible click
   shield (the busy button is the visible feedback), no grey flash */
#freeze { position: fixed; inset: 0; z-index: 10; opacity: 0; }

/* a failed attempt: login.js adds .invalid-login for 500ms */
@keyframes vc-shake {
	10%, 90% { transform: translate3d(-1px, 0, 0); }
	20%, 80% { transform: translate3d(2px, 0, 0); }
	30%, 50%, 70% { transform: translate3d(-3px, 0, 0); }
	40%, 60% { transform: translate3d(3px, 0, 0); }
}
.vc-card.invalid-login { animation: vc-shake 400ms cubic-bezier(0.36, 0.07, 0.19, 0.97) both; }

/* the splash login.js swaps into <body> after a successful sign-in, before the redirect */
.splash {
	min-height: 100vh;
	display: grid;
	place-items: center;
	background: var(--vc-bg);
}
.splash img { width: auto; max-width: 200px; }

/* the two-factor prompt login.js renders into .login-content (2FA is off for this site; kept usable) */
#twofactor_div { display: flex; flex-direction: column; gap: 14px; }
#twofactor_div .form-control {
	height: 48px;
	padding: 0 14px;
	border: 1px solid var(--vc-line);
	border-radius: var(--vc-radius);
	font: inherit;
}
#twofactor_div .btn {
	height: 48px;
	border: 0;
	border-radius: var(--vc-radius);
	background: var(--vc-accent);
	color: var(--vc-ink);
	font: inherit;
	font-weight: 600;
}
.indicator { font-size: 14px; color: var(--vc-muted); }

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