:root {
	--brand-start: #1e2a78;
	--brand-end: #2f3fa0;
	--panel-bg: #f5f6fa;
	--text-deep: #1b1f55;
	--text-muted: #6a7085;
	--card-shadow: 0 18px 50px rgba(20, 33, 85, 0.12);
}

* {
	box-sizing: border-box;
}

html,
body {
	margin: 0;
	min-height: 100%;
	min-width: 100%;
	overflow-x: hidden;
	font-family: "Manrope", "Segoe UI", Tahoma, sans-serif;
	background: var(--panel-bg);
	color: #1d233f;
}

body {
	min-height: 100vh;
	scrollbar-gutter: stable;
}

.signup-page {
	min-width: 100%;
	min-height: 100vh;
	display: grid;
	grid-template-columns: minmax(320px, 1.05fr) minmax(420px, 1.65fr);
	overflow: hidden;
	align-items: stretch;
}

/* Signup pages: blue panel fixed, form scrolls on the right */
html:has(body.signup-auth),
body.signup-auth {
	height: 100%;
	overflow: hidden;
}

.signup-auth .signup-page {
	height: 100vh;
	max-height: 100vh;
	min-height: 0;
}

.signup-auth .branding-panel {
	height: 100%;
	max-height: 100vh;
	min-height: 0;
	align-self: stretch;
}

.signup-auth .branding-content {
	min-height: 100%;
	height: 100%;
}

.signup-auth .form-panel {
	height: 100%;
	max-height: 100vh;
	min-height: 0;
	overflow-x: hidden;
	overflow-y: auto;
	scrollbar-gutter: stable;
	align-items: flex-start;
	justify-content: center;
}

.branding-panel {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	color: #ffffff;
	height: 100%;
	min-height: 100vh;
	background:
		linear-gradient(160deg, rgba(18, 27, 92, 0.88), rgba(18, 27, 92, 0.88)),
		/* Relative to THIS stylesheet, not to the site root. The absolute form
		   ("/capstoneproject/images/...") baked the development folder name into
		   the URL, so the image 404s anywhere the app is not served from that
		   exact path -- including the deployed site, where it sits at "/". CSS
		   cannot read APP_BASE_PATH, so a relative URL is the only portable
		   way to express this. */
		url("../../images/school.png");
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
	isolation: isolate;
}

.branding-panel::before {
	content: "";
	position: absolute;
	inset: 0;
	background:
		radial-gradient(circle at 22% 28%, rgba(97, 121, 255, 0.04), transparent 28%),
		radial-gradient(circle at 72% 68%, rgba(97, 121, 255, 0.04), transparent 26%),
		linear-gradient(180deg, rgba(18, 27, 92, 0.18), rgba(18, 27, 92, 0.18));
	backdrop-filter: blur(3px);
	opacity: 0.62;
	z-index: -2;
}

.branding-panel__overlay {
	position: absolute;
	inset: auto 0 0;
	height: 240px;
	background:
		radial-gradient(circle at 18% 70%, rgba(18, 27, 92, 0.88), transparent 52%),
		radial-gradient(circle at 48% 98%, rgba(18, 27, 92, 0.82), transparent 53%),
		radial-gradient(circle at 84% 72%, rgba(18, 27, 92, 0.82), transparent 45%);
	z-index: -1;
}

.branding-content {
	width: min(90%, 500px);
	display: flex;
	flex-direction: column;
	justify-content: flex-start;
	min-height: 100vh;
	padding: 44px 30px 22px;
	position: relative;
	z-index: 2;
}

.brand-header {
	display: flex;
	align-items: center;
	gap: 14px;
	margin-bottom: 56px;
}

.logo-placeholder {
	width: 98px;
	height: 98px;
	border-radius: 999px;
	overflow: hidden;
	background: rgba(255, 255, 255, 0.2);
	box-shadow: 0 8px 24px rgba(6, 14, 58, 0.34);
	border: 2px solid rgba(255, 255, 255, 0.68);
	flex-shrink: 0;
}

.school-logo {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.system-title h1 {
	margin: 0;
	font-size: clamp(2.1rem, 2.35vw, 2.7rem);
	letter-spacing: 0.6px;
	line-height: 1;
	font-weight: 800;
}

.script-word {
	font-family: "Cormorant Garamond", Georgia, serif;
	font-style: italic;
	font-weight: 600;
	font-size: 1.1em;
	margin-left: 4px;
	opacity: 0.96;
}

.system-title p {
	margin: 6px 0 0;
	font-size: 1.02rem;
	line-height: 1.3;
	opacity: 0.92;
}

.brand-message {
	max-width: 390px;
}

.brand-message h2 {
	margin: 0;
	font-family: "Space Mono", "Manrope", monospace;
	font-size: clamp(2.15rem, 2.9vw, 3.2rem);
	letter-spacing: 0.4px;
	line-height: 1.12;
	text-wrap: balance;
}

.brand-message p {
	margin-top: 22px;
	font-size: 1.16rem;
	line-height: 1.55;
	opacity: 0.76;
}

.brand-footer {
	margin-top: auto;
	padding-bottom: 8px;
	font-size: 0.93rem;
	opacity: 0.74;
	letter-spacing: 0.15px;
	text-align: center;
}

.form-panel {
	display: flex;
	justify-content: center;
	align-items: flex-start;
	background: var(--panel-bg);
	padding: clamp(40px, 5vw, 64px) clamp(28px, 4vw, 56px);
	overflow: hidden;
	min-height: 100vh;
}

.signup-card {
	width: 100%;
	max-width: 620px;
	background: #ffffff;
	border-radius: 20px;
	border: 1px solid rgba(216, 220, 235, 0.95);
	box-shadow: var(--card-shadow);
	padding: clamp(32px, 4vw, 44px);
	opacity: 0;
	transform: translateY(12px);
	animation: signup-card-in 0.36s ease-out forwards;
}

.signup-card h2 {
	margin: 0;
	font-size: clamp(1.75rem, 2.5vw, 2.15rem);
	line-height: 1.15;
	font-weight: 800;
	color: #33489f;
}

.signup-subtitle {
	margin: 10px 0 0;
	font-size: 0.98rem;
	font-weight: 500;
	color: #5d6da8;
	line-height: 1.5;
}

.form-status {
	margin: 16px 0 0;
	padding: 12px 14px;
	border-radius: 12px;
	font-size: 0.92rem;
	font-weight: 600;
	line-height: 1.45;
}

.form-status.status-error {
	background: rgba(207, 61, 74, 0.1);
	color: #9f2530;
	border: 1px solid rgba(207, 61, 74, 0.2);
}

.form-status.status-success {
	background: rgba(68, 179, 95, 0.12);
	color: #1e7a4a;
	border: 1px solid rgba(68, 179, 95, 0.22);
}

.signup-switch {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 8px;
	margin: 0 0 10px;
	align-items: center;
}

.signup-switch__link {
	display: inline-flex;
	justify-content: center;
	align-items: center;
	height: 34px;
	border-radius: 999px;
	background: #e5e8f3;
	border: 1px solid #ccd4ee;
	color: #4158b4;
	font-size: 0.88rem;
	font-weight: 700;
	text-decoration: none;
	transition: transform 0.2s ease, background-color 0.2s ease, color 0.2s ease;
}

.signup-switch__link:hover,
.signup-switch__link:focus-visible {
	background: #dbe2f8;
	outline: none;
}

.signup-switch__link.is-active {
	background: linear-gradient(145deg, #4d69d6, #6f86e5);
	border-color: #5d77df;
	color: #ffffff;
	box-shadow: 0 8px 14px rgba(60, 86, 198, 0.26);
}

body.is-switching .signup-card {
	animation: signup-card-out 0.22s ease-in forwards;
}

.signup-form {
	display: flex;
	flex-direction: column;
	gap: 22px;
	margin-top: 28px;
}

.form-row {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 20px;
}

.form-row--optional {
	gap: 20px;
}

/* A form-row with a single field (e.g. Strand shown alone once a track with
   no sub-strand has already mirrored its value into it, or a lone field
   before its would-be row partner is chosen) should fill the row instead of
   sitting in the first grid column with an empty gap beside it. */
.form-row--single {
	grid-template-columns: 1fr;
}

/* .form-row's own `display: grid` (author-origin) otherwise beats the
   browser's default `[hidden] { display: none }` UA rule regardless of
   selector specificity, so a JS-hidden Strand row would stay visible. */
#strandFieldGroup[hidden] {
	display: none;
}

/* Optional grade/track/strand group on the teacher signup form. Boxing the
   three dropdowns together (rather than leaving them loose among the required
   fields) is what makes "you may skip all of this" readable at a glance --
   the border is where the optional part visibly starts and stops. */
.signup-optional-block {
	display: flex;
	flex-direction: column;
	gap: 16px;
	margin: 0;
	padding: 18px 16px 16px;
	border: 1px dashed #cdd6f2;
	border-radius: 14px;
	background: #f7f9ff;
}

.signup-optional-block__legend {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 0 6px;
	margin-left: -6px;
	font-size: 0.95rem;
	font-weight: 700;
	color: #33489f;
}

.signup-optional-block__intro {
	margin-top: -4px;
}

.signup-optional-block__intro strong {
	color: #33489f;
}

.signup-optional-block__footer {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: 8px;
}

.signup-optional-block .form-row {
	gap: 16px;
}

/* Text-only action for low-stakes, reversible controls (e.g. clearing the
   optional section back to nothing) -- deliberately quieter than
   .secondary-btn so it never competes with the real submit button. */
.link-btn {
	padding: 0;
	border: 0;
	background: none;
	font-family: inherit;
	font-size: 0.84rem;
	font-weight: 700;
	color: #4f66d2;
	text-decoration: underline;
	cursor: pointer;
}

.link-btn:hover,
.link-btn:focus-visible {
	color: #33489f;
	outline: none;
}

.link-btn[hidden] {
	display: none;
}

.field-group {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.field-group label {
	font-size: 0.95rem;
	font-weight: 700;
	color: #33489f;
	line-height: 1.35;
}

.field-optional {
	font-size: 0.78rem;
	font-weight: 600;
	color: #8a94b8;
	text-transform: uppercase;
	letter-spacing: 0.04em;
}

.signup-step-label {
	margin: 22px 0 6px;
	padding-top: 14px;
	border-top: 1px solid #e4e7f5;
	font-size: 0.82rem;
	font-weight: 700;
	color: #33489f;
	text-transform: uppercase;
	letter-spacing: 0.05em;
}

.signup-step-label:first-of-type {
	margin-top: 0;
	padding-top: 0;
	border-top: none;
}

.field-group input,
.field-group select {
	min-height: 46px;
	border: 1px solid #d4daeb;
	border-radius: 12px;
	background: #ffffff;
	padding: 0 14px;
	font-family: inherit;
	font-size: 0.96rem;
	color: #2b2b2b;
	transition: border-color 0.18s ease, box-shadow 0.18s ease;
}

.field-group input::placeholder {
	color: #6f6f6f;
}

/* Read-only stand-in for the email input on the signup details step, once the
   email is already verified and shouldn't be editable. Sized to match the
   real inputs it sits alongside. */
.verified-email-display {
	display: flex;
	align-items: center;
	gap: 10px;
	min-height: 46px;
	border: 1px solid #cfe8d8;
	border-radius: 12px;
	background: #f2fbf5;
	padding: 0 14px;
}

.verified-email-display__check {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 20px;
	height: 20px;
	border-radius: 50%;
	background: #2f9e5c;
	color: #ffffff;
	font-size: 0.72rem;
	flex-shrink: 0;
}

.verified-email-display__value {
	flex: 1;
	font-size: 0.96rem;
	color: #2b2b2b;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.verified-email-display__change {
	font-size: 0.85rem;
	font-weight: 700;
	color: #4f66d2;
	white-space: nowrap;
}

.field-group input:focus-visible,
.field-group select:focus-visible {
	outline: none;
	border-color: #4f66d2;
	box-shadow: 0 0 0 3px rgba(79, 102, 210, 0.24);
}

.select-wrap {
	position: relative;
}

.select-wrap::after {
	content: "";
	position: absolute;
	right: 10px;
	top: 50%;
	width: 0;
	height: 0;
	border-left: 5px solid transparent;
	border-right: 5px solid transparent;
	border-top: 5px solid #33489f;
	transform: translateY(-25%);
	pointer-events: none;
}

.select-wrap select {
	width: 100%;
	appearance: none;
	padding-right: 30px;
	color: #33489f;
	font-weight: 600;
}

.primary-btn {
	width: 100%;
	min-height: 48px;
	margin: 8px 0 0;
	border: none;
	border-radius: 12px;
	background: linear-gradient(145deg, #4d69d6, #6f86e5);
	color: #ffffff;
	font-family: inherit;
	font-size: 0.98rem;
	font-weight: 700;
	letter-spacing: 0.4px;
	cursor: pointer;
	box-shadow: 0 10px 18px rgba(60, 86, 198, 0.35);
	transition: transform 0.2s ease, filter 0.2s ease;
	line-height: 1;
	padding: 12px 18px;
}

.primary-btn:hover {
	transform: translateY(-1px);
	filter: brightness(1.03);
}

.primary-btn:focus-visible {
	outline: 3px solid rgba(79, 102, 210, 0.35);
	outline-offset: 2px;
}

.form-bottom {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 16px;
	margin-top: 8px;
	padding-top: 22px;
	border-top: 1px solid #e8ecf5;
}

.form-bottom-links {
	display: flex;
	flex-wrap: wrap;
	gap: 10px 18px;
}

.privacy-note {
	display: flex;
	align-items: flex-start;
	gap: 8px;
	font-size: 0.82rem;
	font-weight: 600;
	color: #5d6da8;
	line-height: 1.45;
}

.privacy-note svg {
	flex-shrink: 0;
	width: 16px;
	height: 16px;
	margin-top: 1px;
}

.field-checkbox-row {
	margin-top: 4px;
}

.checkbox-label {
	display: flex;
	align-items: flex-start;
	gap: 8px;
	font-size: 0.82rem;
	color: #5d6da8;
	line-height: 1.45;
	cursor: pointer;
}

.checkbox-label input[type="checkbox"] {
	margin-top: 2px;
	width: auto;
	flex-shrink: 0;
	accent-color: #33489f;
	cursor: pointer;
}

.login-link {
	font-size: 0.92rem;
	font-weight: 700;
	color: #33489f;
	text-decoration: none;
}

.login-link:hover,
.login-link:focus-visible {
	color: #27397d;
	text-decoration: underline;
	outline: none;
}

.login-link--muted {
	color: #6a7085;
	font-weight: 600;
}

@keyframes signup-card-in {
	from {
		opacity: 0;
		transform: translateY(12px);
	}

	to {
		opacity: 1;
		transform: translateY(0);
	}
}

@keyframes signup-card-out {
	from {
		opacity: 1;
		transform: translateY(0);
	}

	to {
		opacity: 0;
		transform: translateY(-8px);
	}
}

@media (max-width: 1280px) {
	.signup-page {
		grid-template-columns: minmax(280px, 1fr) minmax(360px, 1.35fr);
	}
}

@media (prefers-reduced-motion: reduce) {
	.signup-card,
	body.is-switching .signup-card {
		animation: none;
		opacity: 1;
		transform: none;
	}
}

@media (max-width: 980px) {
	.signup-switch {
		grid-template-columns: 1fr;
	}

	html:has(body.signup-auth),
	body.signup-auth {
		height: auto;
		overflow: auto;
	}

	.signup-auth .signup-page {
		height: auto;
		max-height: none;
		overflow: visible;
	}

	.signup-auth .form-panel {
		height: auto;
		max-height: none;
		overflow: visible;
	}

	.signup-page {
		grid-template-columns: 1fr;
		overflow: visible;
	}

	.branding-panel {
		height: auto;
		min-height: 420px;
	}

	.branding-content {
		min-height: 420px;
		height: auto;
	}

	.form-panel {
		padding: 28px 18px 40px;
		min-height: auto;
		overflow: visible;
	}

	.signup-card {
		padding: 28px 22px;
	}

	.form-row {
		grid-template-columns: 1fr;
	}
}

.secondary-btn {
	min-height: 46px;
	padding: 0 18px;
	border-radius: 12px;
	border: 1.5px solid #bac6f4;
	background: #edf1ff;
	color: #4f66d2;
	font-family: inherit;
	font-weight: 700;
	font-size: 0.9rem;
	cursor: pointer;
	transition: background-color 0.18s ease, border-color 0.18s ease;
}

.secondary-btn:hover,
.secondary-btn:focus-visible {
	background: #e3e9ff;
	border-color: #9fb0ef;
	outline: none;
}

.secondary-btn--block {
	width: 100%;
}

.field-hint {
	margin: 0;
	font-size: 0.86rem;
	color: #6a7085;
	line-height: 1.45;
}

.field-hint.status-success {
	color: #1e7a4a;
}

.field-hint.status-error {
	color: #9f2530;
}

.captcha-group {
	padding: 12px 14px;
	border: 1px dashed #cdd6f2;
	border-radius: 12px;
	background: #f7f9ff;
}

.captcha-question {
	font-weight: 700;
	color: #33489f;
	cursor: default;
}

.captcha-input-row {
	display: flex;
	gap: 8px;
}

.captcha-input-row input {
	flex: 1;
	min-width: 0;
}

.captcha-refresh-btn {
	flex-shrink: 0;
	width: 46px;
	height: 46px;
	border-radius: 12px;
	border: 1.5px solid #bac6f4;
	background: #edf1ff;
	color: #4f66d2;
	display: flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	transition: background-color 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}

.captcha-refresh-btn svg {
	width: 18px;
	height: 18px;
}

.captcha-refresh-btn:hover,
.captcha-refresh-btn:focus-visible {
	background: #e3e9ff;
	border-color: #9fb0ef;
	outline: none;
}

.captcha-refresh-btn:active {
	transform: rotate(120deg);
}

.password-match-hint {
	margin: 4px 0 0;
	font-size: 0.86rem;
	color: #9f2530;
	line-height: 1.45;
}

/* Login pages — same card/form UI as signup */
.field-group.is-error input,
.field-group.is-error select {
	border-color: #cf3d4a;
	box-shadow: 0 0 0 3px rgba(207, 61, 74, 0.12);
}

.field-group.is-success input,
.field-group.is-success select {
	border-color: #2e9f63;
	box-shadow: 0 0 0 3px rgba(46, 159, 99, 0.12);
}

.auth-forgot-note {
	margin: 0;
	font-size: 0.88rem;
	font-weight: 600;
	color: #6a7085;
	line-height: 1.45;
}

.auth-forgot-note .forgot-link {
	font-weight: 700;
}

.forgot-link {
	color: #5670da;
	text-decoration: none;
	font-weight: 600;
}

.forgot-link:hover,
.forgot-link:focus-visible {
	text-decoration: underline;
	outline: none;
}

.auth-cta {
	margin-top: 4px;
	padding-top: 20px;
	border-top: 1px solid #e8ecf5;
	text-align: center;
}

.auth-cta p {
	margin: 0 0 12px;
	color: #5d6da8;
	font-size: 0.92rem;
	line-height: 1.45;
}

.secondary-btn--pill {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 44px;
	padding: 0 22px;
	border-radius: 999px;
	border: 1.5px solid #bac6f4;
	background: #edf1ff;
	color: #4f66d2;
	font-family: inherit;
	font-weight: 700;
	font-size: 0.92rem;
	text-decoration: none;
	transition: background-color 0.18s ease, border-color 0.18s ease;
}

.secondary-btn--pill:hover,
.secondary-btn--pill:focus-visible {
	background: #e3e9ff;
	border-color: #9fb0ef;
	outline: none;
}


/* ---------------------------------------------------------------------------
   Password strength meter + requirements checklist.
   assets/js/password-strength.js is loaded on both signup pages, but this
   stylesheet never carried styles for what it renders -- the meter came out as
   unstyled markup during registration, which is exactly where a new user most
   needs to see the password rules. Kept in step with the login.css block.
   --------------------------------------------------------------------------- */
.password-strength-meter {
	margin: 8px 0 0;
	display: flex;
	align-items: center;
	gap: 10px;
}

.password-strength-meter__track {
	flex: 1;
	height: 6px;
	border-radius: 999px;
	background: #e4e7f5;
	overflow: hidden;
}

.password-strength-meter__bar {
	height: 100%;
	width: 0;
	border-radius: 999px;
	transition: width 0.2s ease, background-color 0.2s ease;
	background: var(--error, #9f2530);
}

.password-strength-meter__bar.is-weak {
	background: #cf3d4a;
}

.password-strength-meter__bar.is-fair {
	background: #d98c1f;
}

.password-strength-meter__bar.is-good {
	background: #c7b526;
}

.password-strength-meter__bar.is-strong {
	background: var(--success, #2e9f63);
}

.password-strength-meter__label {
	font-size: 0.82rem;
	font-weight: 700;
	white-space: nowrap;
	color: #cf3d4a;
}

.password-strength-meter__label.is-weak {
	color: #cf3d4a;
}

.password-strength-meter__label.is-fair {
	color: #d98c1f;
}

.password-strength-meter__label.is-good {
	color: #a89620;
}

.password-strength-meter__label.is-strong {
	color: var(--success, #2e9f63);
}

.password-rules {
	list-style: none;
	margin: 8px 0 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
	gap: 4px 14px;
}

.password-rules__item {
	display: flex;
	align-items: center;
	gap: 7px;
	font-size: 0.78rem;
	line-height: 1.4;
	color: #7a86ad;
	transition: color 0.15s ease;
}

.password-rules__mark {
	flex: 0 0 auto;
	width: 14px;
	height: 14px;
	border-radius: 50%;
	border: 1.5px solid #c3cbe4;
	position: relative;
	transition: background 0.15s ease, border-color 0.15s ease;
}

.password-rules__item.is-met {
	color: #2f7d4a;
}

.password-rules__item.is-met .password-rules__mark {
	background: #34a05c;
	border-color: #34a05c;
}

/* Checkmark drawn with two borders so no icon font or SVG is needed. */
.password-rules__item.is-met .password-rules__mark::after {
	content: "";
	position: absolute;
	left: 4px;
	top: 1px;
	width: 3px;
	height: 7px;
	border: solid #fff;
	border-width: 0 1.5px 1.5px 0;
	transform: rotate(45deg);
}

/* Explains why the "I agree" checkbox starts disabled. It was previously only a
   title attribute, which never appears on touch devices and is invisible unless
   you happen to hover a control you cannot click. */
.agree-terms-hint {
	margin: 6px 0 0 26px;
	font-size: 0.78rem;
	line-height: 1.4;
	color: var(--text-muted, #6a7085);
}

/* Once the agreement has been read the checkbox ticks itself, so the line stops
   being an instruction and becomes the confirmation of what just happened --
   it stays visible rather than disappearing, because a box that ticked on its
   own needs to say so. */
.agree-terms-hint.is-complete {
	color: #1f7a4d;
	font-weight: 600;
}

/* Consent sits directly above the submit button now, so it has to read as a
   deliberate step rather than another line of small print. The panel separates
   it from the fields above and ties it to the button below. */
.field-checkbox-row--consent {
	margin: 18px 0 14px;
	padding: 14px 16px;
	border: 1px solid #d5dcf4;
	border-radius: 12px;
	background: #f7f9ff;
}

.field-checkbox-row--consent .checkbox-label {
	font-size: 0.86rem;
	color: #3c4a80;
}

.field-checkbox-row--consent .agree-terms-hint {
	margin-bottom: 0;
}

/* Shown when a paste into a password field is refused
   (assets/js/password-paste-guard.js). */
.field-hint--warning {
	color: #a4432b;
	font-weight: 600;
}
