/* AlfaGate web and login presentation. App-owned and Frappe upgrade-safe. */

:root {
	--ag-login-canvas: #f8f7f4;
	--ag-login-surface: #ffffff;
	--ag-login-ink: #29252f;
	--ag-login-muted: #706a77;
	--ag-login-line: #e6e1e8;
	--ag-login-accent: #7557d8;
	--ag-login-accent-strong: #6043c2;
	--ag-login-accent-soft: #f0ebff;
	--ag-login-danger: #a52c43;
	--ag-login-danger-soft: #fff1f3;
	--ag-login-brand-surface: #302b3a;
	--ag-login-brand-muted: #c8c1cf;
	--ag-login-focus: #9278ea;
}

/* Hide the raw native login card until the redesign script (built from
   frontend/src/login/main.js) relocates it into the split-screen layout
   below — without this, Frappe's own default-styled login form paints
   first and is visibly replaced a moment later. Scoped to
   `.for-login > .login-content` so it only ever matches the card in its
   original, un-enhanced position; once the script moves it deeper into
   .ag-login-email-panel the selector stops matching and it's visible
   again — no JS-driven unhide required. The animation itself is a
   pure-CSS fallback, not a JS dependency: if the redesign script never
   runs (blocked, slow network, JS disabled entirely), the card reveals
   itself after 2s regardless, so the login form is never permanently
   inaccessible. */
.for-login > .login-content {
	opacity: 0;
	pointer-events: none;
	animation: ag-login-native-reveal 0.25s 2s ease-out forwards;
}

@keyframes ag-login-native-reveal {
	to {
		opacity: 1;
		pointer-events: auto;
	}
}

.ag-login-page {
	min-width: 320px;
	background: var(--ag-login-canvas);
	color: var(--ag-login-ink);
	font-family: "Plus Jakarta Sans", Inter, ui-sans-serif, system-ui, -apple-system,
		BlinkMacSystemFont, "Segoe UI", sans-serif;
}

.ag-login-page .navbar,
.ag-login-page .web-footer,
.ag-login-page footer.web-footer {
	display: none !important;
}

/* page-content-wrapper carries a 60px top padding for the navbar this page
   hides, which pushed the card down by exactly that much — measured, it put
   120px more space above the card than below (the offset counts twice once
   the section is full-height and centres its own contents). */
.ag-login-page .page-content-wrapper,
.ag-login-page .main-section,
.ag-login-page .page_content,
.ag-login-page main {
	width: 100%;
	max-width: none;
	margin: 0;
	padding: 0;
}

/* Centres the card in the viewport both ways. It used to be a plain block,
   so the card was only ever centred horizontally by its own auto margin and
   sat against the top of whatever height the page wrapper happened to have.
   dvh rather than vh so a mobile browser's collapsing address bar does not
   leave the card hanging off-centre. */
.ag-login-page .for-login {
	display: grid;
	place-items: center;
	box-sizing: border-box;
	width: 100%;
	min-height: 100vh;
	min-height: 100dvh;
	max-width: none;
	margin: 0;
	padding: 24px;
}

.ag-login-shell {
	display: grid;
	grid-template-columns: minmax(360px, 0.92fr) minmax(460px, 1.08fr);
	width: min(1180px, 100%);
	min-height: min(760px, calc(100vh - 48px));
	margin: 0 auto;
	overflow: hidden;
	border: 1px solid rgb(41 37 47 / 8%);
	border-radius: 28px;
	background: var(--ag-login-surface);
	box-shadow: 0 28px 80px rgb(48 43 58 / 12%);
}

.ag-login-brand {
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	min-width: 0;
	padding: clamp(32px, 5vw, 64px);
	background:
		radial-gradient(circle at 12% 8%, rgb(137 105 235 / 28%), transparent 36%),
		linear-gradient(145deg, #383144 0%, var(--ag-login-brand-surface) 68%);
	color: #fff;
}

/* The browser's own default :visited link color otherwise beats a plain
   .ag-login-brand__top{color:inherit} rule (a:visited carries a pseudo-class
   PLUS the `a` type in its specificity, which outranks a single class) —
   explicit per-state overrides are the standard fix, not a workaround. */
.ag-login-brand__top,
.ag-login-brand__top:link,
.ag-login-brand__top:visited,
.ag-login-brand__top:hover,
.ag-login-brand__top:active {
	display: flex;
	align-items: center;
	gap: 12px;
	color: #fff;
	text-decoration: none;
}

.ag-login-mark {
	display: block;
	width: 38px;
	height: 38px;
	border: 1px solid rgb(255 255 255 / 22%);
	border-radius: 12px;
	object-fit: cover;
}

.ag-login-wordmark {
	font-size: 19px;
	font-weight: 750;
	letter-spacing: -0.03em;
}

.ag-login-brand__story {
	max-width: 480px;
	margin-block: 48px;
}

.ag-login-eyebrow {
	margin: 0 0 12px;
	color: var(--ag-login-accent);
	font-size: 11px;
	font-weight: 800;
	letter-spacing: 0.13em;
}

.ag-login-brand .ag-login-eyebrow {
	color: #b8a7f6;
}

.ag-login-brand h1 {
	margin: 0;
	color: #fff;
	font-size: clamp(2.2rem, 4.8vw, 4.6rem);
	font-weight: 700;
	line-height: 1.02;
	letter-spacing: -0.055em;
}

.ag-login-brand__story > p:last-child {
	max-width: 40ch;
	margin: 22px 0 0;
	color: var(--ag-login-brand-muted);
	font-size: 1rem;
	line-height: 1.65;
}

.ag-login-capabilities {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 10px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.ag-login-capabilities li {
	display: flex;
	align-items: center;
	min-height: 48px;
	gap: 10px;
	padding: 10px 12px;
	border: 1px solid rgb(255 255 255 / 12%);
	border-radius: 12px;
	background: rgb(255 255 255 / 6%);
	color: #f6f3fa;
	font-size: 13px;
	font-weight: 650;
}

.ag-login-capabilities svg {
	width: 18px;
	height: 18px;
	flex: 0 0 auto;
	fill: none;
	stroke: #b9a8f5;
	stroke-linecap: round;
	stroke-linejoin: round;
	stroke-width: 1.8;
}

.ag-login-auth {
	display: flex;
	width: min(100%, 560px);
	flex-direction: column;
	justify-content: center;
	margin: auto;
	padding: clamp(32px, 6vw, 76px);
}

.ag-login-intro h2 {
	margin: 0;
	color: var(--ag-login-ink);
	font-size: clamp(1.9rem, 3vw, 2.55rem);
	font-weight: 720;
	line-height: 1.16;
	letter-spacing: -0.045em;
}

.ag-login-intro > p:last-child {
	margin: 12px 0 0;
	color: var(--ag-login-muted);
	font-size: 0.95rem;
	line-height: 1.55;
}

.ag-login-tabs {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 4px;
	margin: 28px 0 24px;
	padding: 4px;
	border-radius: 12px;
	background: #f1eef3;
}

.ag-login-tabs button {
	min-height: 44px;
	padding: 8px 12px;
	border: 0;
	border-radius: 9px;
	background: transparent;
	color: var(--ag-login-muted);
	font: inherit;
	font-size: 13px;
	font-weight: 700;
	cursor: pointer;
}

.ag-login-tabs button[aria-selected="true"] {
	background: #fff;
	color: var(--ag-login-ink);
	box-shadow: 0 3px 10px rgb(49 39 62 / 8%);
}

/* Mobile OTP is app-only. Shown muted rather than removed, so the option is
   not a mystery — it still takes a click and answers why. Deliberately not
   the `disabled` attribute: a disabled button fires no click, and then it
   could not explain itself. */
.ag-login-tabs button[aria-disabled="true"] {
	color: var(--ag-login-muted);
	opacity: 0.62;
	cursor: help;
}

.ag-login-tabs button[aria-disabled="true"]:hover {
	opacity: 0.78;
}

.ag-otp-panel {
	min-width: 0;
}

.ag-login-page :where(button, input, a):focus-visible {
	outline: 3px solid var(--ag-login-focus) !important;
	outline-offset: 2px;
	box-shadow: none !important;
}

.ag-login-email-panel > .page-card-head {
	display: none;
}

.ag-login-page .login-content.page-card {
	width: 100%;
	max-width: none;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	background: transparent;
	box-shadow: none;
}

.ag-login-page .page-card .page-card-body,
.ag-login-page .page-card .page-card-actions {
	padding: 0;
}

.ag-login-page .form-group {
	margin-bottom: 18px;
}

.ag-login-page .form-label,
.ag-otp-form label,
.ag-role-choice legend {
	display: block;
	margin: 0 0 7px;
	color: var(--ag-login-ink);
	font-size: 13px;
	font-weight: 700;
}

.ag-login-page .form-label.sr-only {
	position: static !important;
	width: auto !important;
	height: auto !important;
	overflow: visible !important;
	clip: auto !important;
	white-space: normal !important;
}

.ag-login-page .form-control,
.ag-otp-form input:not([type="radio"]) {
	width: 100%;
	min-height: 48px;
	padding: 11px 14px 11px 42px;
	border: 1px solid #cfc8d3;
	border-radius: 11px;
	background: #fff;
	color: var(--ag-login-ink);
	font: inherit;
	font-size: 1rem;
	line-height: 1.4;
}

.ag-login-page .form-control:hover,
.ag-otp-form input:not([type="radio"]):hover {
	border-color: #a69dad;
}

.ag-login-page .form-control:focus,
.ag-otp-form input:not([type="radio"]):focus {
	border-color: var(--ag-login-accent);
	outline: 0;
	box-shadow: 0 0 0 3px rgb(117 87 216 / 15%);
}

.ag-login-page .field-icon {
	left: 14px;
	color: var(--ag-login-muted);
}

/* .toggle-password is itself the <svg>, not a button wrapping one, so width
   and height here size the drawing — setting them to the tap target scaled
   the eye to 44px. content-box keeps them describing the glyph while the
   padding does the target: an 18px eye (a touch above the 16px field icons
   beside it, since this one is interactive) inside a 44px hit area. */
.ag-login-page .toggle-password {
	right: 10px;
	box-sizing: content-box;
	width: 18px;
	height: 18px;
	padding: 13px;
	color: var(--ag-login-muted) !important;
	cursor: pointer;
}

.ag-login-page .toggle-password:hover {
	color: var(--ag-login-accent-strong) !important;
}

/* Frappe reports sign-in failures inside the card: an error banner above
   the fields, a message under an input, and a success banner for the email
   link. All three are raised as toasts instead (mirrorNativeMessages in
   login/main.js), so they are hidden here rather than shown twice.
   Only the message text is hidden, never the state around it: a field-level
   failure still marks its .form-group .invalid (red border), and a rejected
   password still shakes the card, so the toast says what went wrong while
   the form keeps saying where. */
.ag-login-page .login-error-banner,
.ag-login-page .login-success-banner,
.ag-login-page .field-error {
	display: none !important;
}

.ag-login-page .forgot-password-message {
	margin: -4px 0 18px;
	text-align: right;
}

.ag-login-page a,
.ag-text-button {
	color: var(--ag-login-accent-strong);
	font-weight: 650;
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
}

.ag-login-page .btn-primary,
.ag-login-primary {
	width: 100%;
	min-height: 48px;
	padding: 11px 16px;
	border: 1px solid var(--ag-login-accent) !important;
	border-radius: 11px;
	background: var(--ag-login-accent) !important;
	color: #fff !important;
	font: inherit;
	font-size: 14px;
	font-weight: 750;
	box-shadow: 0 8px 22px rgb(117 87 216 / 20%);
	cursor: pointer;
}

.ag-login-page .btn-primary:hover,
.ag-login-primary:hover {
	border-color: var(--ag-login-accent-strong) !important;
	background: var(--ag-login-accent-strong) !important;
}

.ag-login-page button:disabled {
	cursor: wait;
	opacity: 0.68;
}

.ag-login-page .login-divider {
	margin: 22px 0 12px;
}

.ag-login-page .btn-default,
.ag-login-page .btn-login-option {
	min-height: 44px;
	border: 1px solid var(--ag-login-line);
	border-radius: 10px;
	background: #fff;
	color: var(--ag-login-ink);
	font-weight: 650;
}

.ag-role-choice {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 9px;
	margin: 0 0 20px;
	padding: 0;
	border: 0;
}

.ag-role-choice legend {
	grid-column: 1 / -1;
}

.ag-role-choice label {
	position: relative;
	margin: 0;
	cursor: pointer;
}

.ag-role-choice input {
	position: absolute;
	opacity: 0;
}

.ag-role-choice span {
	display: grid;
	min-height: 44px;
	place-items: center;
	border: 1px solid var(--ag-login-line);
	border-radius: 10px;
	background: #fff;
	color: var(--ag-login-muted);
	font-size: 13px;
	font-weight: 700;
}

.ag-role-choice input:checked + span {
	border-color: var(--ag-login-accent);
	background: var(--ag-login-accent-soft);
	color: var(--ag-login-accent-strong);
}

.ag-role-choice input:focus-visible + span {
	outline: 3px solid var(--ag-login-focus);
	outline-offset: 2px;
}

.ag-mobile-input {
	position: relative;
}

.ag-mobile-input > span {
	position: absolute;
	z-index: 1;
	top: 50%;
	left: 14px;
	color: var(--ag-login-muted);
	font-size: 14px;
	font-weight: 700;
	transform: translateY(-50%);
}

.ag-mobile-input input {
	padding-left: 52px !important;
}

.ag-field-help,
.ag-otp-sent {
	margin: 8px 0 18px;
	color: var(--ag-login-muted);
	font-size: 12px;
	line-height: 1.55;
}

.ag-otp-code-step > input {
	padding-left: 14px !important;
	letter-spacing: 0.28em;
	text-align: center;
}

.ag-otp-code-step .ag-login-primary {
	margin-top: 18px;
}

.ag-otp-secondary {
	display: flex;
	justify-content: space-between;
	gap: 12px;
	margin-top: 10px;
}

.ag-text-button {
	min-height: 44px;
	padding: 8px 2px;
	border: 0;
	background: transparent;
	font: inherit;
	font-size: 12px;
	cursor: pointer;
}

/* ── toasts ───────────────────────────────────────────────────────────────
   Sign-in feedback appears as a snackbar in the top-right rather than a box
   inside the card, so a message never reflows the form under the pointer
   mid-click. Fixed to the viewport, above the card's own stacking. */
.ag-toasts {
	position: fixed;
	top: 20px;
	right: 20px;
	z-index: 9999;
	display: grid;
	gap: 10px;
	justify-items: end;
	pointer-events: none;
}

.ag-toast {
	display: flex;
	align-items: flex-start;
	gap: 11px;
	width: min(380px, calc(100vw - 40px));
	padding: 13px 15px;
	border: 1px solid var(--ag-login-line);
	border-left: 3px solid var(--ag-login-accent);
	border-radius: 12px;
	background: #fff;
	box-shadow: 0 18px 40px -16px rgb(38 22 56 / 35%);
	color: var(--ag-login-ink);
	font-size: 13px;
	line-height: 1.5;
	cursor: pointer;
	pointer-events: auto;
	animation: ag-toast-in 0.32s cubic-bezier(0.22, 0.7, 0.3, 1) both;
}

.ag-toast p {
	margin: 0;
}

/* The dot is the only thing that differs per type, so colour is set once
   here and inherited by the left border via currentColor. */
.ag-toast i {
	flex: none;
	width: 8px;
	height: 8px;
	margin-top: 6px;
	border-radius: 50%;
	background: currentColor;
}

.ag-toast--success {
	border-left-color: #12855a;
	color: #12855a;
}

.ag-toast--error {
	border-left-color: var(--ag-login-danger);
	color: var(--ag-login-danger);
}

.ag-toast--info {
	border-left-color: var(--ag-login-accent);
	color: var(--ag-login-accent-strong);
}

.ag-toast p {
	color: var(--ag-login-ink);
}

.ag-toast.is-leaving {
	animation: ag-toast-out 0.26s ease forwards;
}

@keyframes ag-toast-in {
	from { opacity: 0; transform: translateX(16px) scale(0.97); }
	to   { opacity: 1; transform: none; }
}

@keyframes ag-toast-out {
	to { opacity: 0; transform: translateX(16px) scale(0.97); }
}

@media (prefers-reduced-motion: reduce) {
	.ag-toast, .ag-toast.is-leaving { animation: none; }
}

.ag-login-page :where(.for-forgot, .for-login-with-email-link, .for-signup) {
	width: min(480px, calc(100% - 32px));
	margin: clamp(40px, 10vh, 100px) auto;
	padding: clamp(24px, 5vw, 42px);
	border: 1px solid var(--ag-login-line);
	border-radius: 22px;
	background: #fff;
	box-shadow: 0 24px 70px rgb(48 43 58 / 10%);
}

.ag-login-page :where(.for-forgot, .for-login-with-email-link, .for-signup) .page-card-head h4 {
	color: var(--ag-login-ink);
	font-size: 1.8rem;
	letter-spacing: -0.04em;
}

.ag-login-page :where(.for-forgot, .for-login-with-email-link, .for-signup) .app-logo {
	width: 54px;
	height: 54px;
	margin-bottom: 16px;
	object-fit: contain;
	border-radius: 12px;
}

@media (max-width: 940px) {
	.ag-login-page .for-login {
		padding: 16px;
	}

	.ag-login-shell {
		grid-template-columns: minmax(300px, 0.78fr) minmax(420px, 1.22fr);
		min-height: calc(100vh - 32px);
		border-radius: 22px;
	}

	.ag-login-brand {
		padding: 32px;
	}

	.ag-login-brand h1 {
		font-size: clamp(2.1rem, 5vw, 3.4rem);
	}

	.ag-login-auth {
		padding: 38px;
	}
}

/* Keep the complete desktop sign-in journey visible on short laptop windows. */
@media (min-width: 761px) and (max-height: 820px) {
	.ag-login-page .for-login {
		padding: 16px;
	}

	.ag-login-shell {
		min-height: calc(100vh - 64px);
		min-height: calc(100dvh - 64px);
		border-radius: 22px;
	}

	.ag-login-brand {
		padding: 28px 32px;
	}

	.ag-login-brand__story {
		margin-block: 20px;
	}

	.ag-login-brand h1 {
		font-size: clamp(2.2rem, 4.2vw, 3.7rem);
	}

	.ag-login-brand__story > p:last-child {
		margin-top: 14px;
		line-height: 1.5;
	}

	.ag-login-auth {
		padding: 28px 38px;
	}

	.ag-login-tabs {
		margin: 16px 0 14px;
	}

	.ag-login-page .form-group {
		margin-bottom: 12px;
	}

	.ag-login-page .forgot-password-message {
		margin: -2px 0 12px;
	}

	.ag-login-page .login-divider {
		margin: 14px 0 8px;
	}
}

@media (max-width: 760px) {
	.ag-login-page .for-login {
		padding: 0;
	}

	.ag-login-shell {
		display: flex;
		min-height: 100vh;
		flex-direction: column;
		border: 0;
		border-radius: 0;
		box-shadow: none;
	}

	.ag-login-brand {
		display: flex;
		min-height: auto;
		flex-direction: row;
		align-items: center;
		padding: 18px 20px;
	}

	.ag-login-brand__story,
	.ag-login-capabilities {
		display: none;
	}

	.ag-login-auth {
		width: 100%;
		max-width: 560px;
		justify-content: flex-start;
		padding: clamp(30px, 8vw, 48px) 20px 44px;
	}

	.ag-login-tabs {
		margin-top: 24px;
	}
}

@media (max-width: 380px) {
	.ag-login-tabs {
		grid-template-columns: 1fr;
	}

	.ag-role-choice {
		grid-template-columns: 1fr;
	}
}

@media (prefers-reduced-motion: reduce) {
	.ag-login-page *,
	.ag-login-page *::before,
	.ag-login-page *::after {
		scroll-behavior: auto !important;
		transition-duration: 0.01ms !important;
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
	}
}

@media (forced-colors: active) {
	.ag-login-tabs button[aria-selected="true"],
	.ag-role-choice input:checked + span {
		border: 2px solid CanvasText;
	}
}

/* Hide framework brand links without removing page-owned support content. */
a[href*="frappeframework.com"],
a[href*="erpnext.com"],
a[href*="frappe.io"],
.frappe-footer,
.frappe-brand,
.powered-by-frappe,
.footer-powered-by {
	display: none !important;
}

.web-footer,
footer.web-footer {
	border-top: 1px solid var(--border-color, #e8e8e8);
	padding: 20px 0;
	color: var(--text-muted, #888);
	font-size: 12px;
	text-align: center;
}
