/*
 * Karuvia — the four account pages.
 *
 * /login/ · /register/ · /vendor-login/ · /vendor-registration/, rendered by
 * Karuvia\Account\Forms in the Core plugin. The plugin ships no CSS by design (it is the
 * non-presentational half of the split), so the whole visual layer for those pages lives
 * here.
 *
 * Loaded only on those four pages — see karuvia_enqueue_assets() in inc/enqueue.php.
 *
 * Layout is a two-column pairing: the form, and the compliance summary beside it. The
 * summary is not decoration — it states obligations that already apply — so it holds its
 * ground at desktop width and follows the form on a phone, rather than being tucked away.
 *
 * Tokens come from main.css, which is a hard dependency of this file.
 */

.kv-account {
	display: grid;
	grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
	grid-template-areas:
		"switch switch"
		"panel  notes";
	gap: clamp(20px, 3vw, 44px);
	align-items: start;
	margin: clamp(24px, 4vw, 52px) auto clamp(40px, 6vw, 76px);
	max-width: 1100px;
}

/* The single-panel states (already signed in, registration closed) have no aside. */
.kv-account--done,
.kv-account--closed {
	grid-template-columns: minmax(0, 1fr);
	grid-template-areas: "panel";
	max-width: 640px;
}

.kv-account__panel { grid-area: panel; min-width: 0; }
/* The wrapper holds the column and the full row height; the panel inside it is what sticks.
   See Forms::notes() for why the panel could not travel on its own. */
.kv-account__aside { grid-area: notes; min-width: 0; align-self: stretch; }


/* ------------------------------------------------------------------ switch */

/*
 * Customer / vendor. Presented as a pair of tabs because that is what it is — one task, two
 * audiences — and because the brief asks that the two never share a form. The current tab is
 * a span, not a link: a link to the page you are on is a dead end for a screen reader.
 */
.kv-account__switch {
	grid-area: switch;
	display: inline-flex;
	gap: 4px;
	padding: 4px;
	border: 1px solid var(--stone);
	border-radius: var(--r-pill);
	background: var(--white);
	justify-self: start;
}

.kv-account__switch-item {
	display: inline-flex;
	align-items: center;
	padding: 9px 20px;
	border-radius: var(--r-pill);
	font-size: 13px;
	font-weight: 600;
	letter-spacing: .02em;
	color: var(--taupe);
	transition: background .2s ease, color .2s ease;
}

/*
 * No underline on the inactive tab.
 *
 * The current tab is a <span> and the other is an <a>, so only one of the pair was picking
 * up `.entry-content a { text-decoration: underline }` from main.css — the account pages
 * render on the full-width template, which wraps the form in .entry-content. The result was
 * a tab pair where one half looked like a body link.
 *
 * Written with the parent class so it outranks `.entry-content a` (two classes beats one
 * class plus an element) regardless of which stylesheet the browser sees last.
 */
.kv-account__switch .kv-account__switch-item,
.kv-account__switch .kv-account__switch-item:hover {
	text-decoration: none;
}

.kv-account__switch-item:hover { color: var(--forest); }

.kv-account__switch-item.is-current {
	background: var(--forest);
	color: var(--white);
	cursor: default;
}

/* ------------------------------------------------------------------- panel */

.kv-account__head { margin-bottom: clamp(18px, 2.5vw, 26px); }
.kv-account__title { font-size: clamp(26px, 3.4vw, 38px); margin: 0 0 8px; }
.kv-account__lede {
	margin: 0;
	max-width: 58ch;
	font-size: 14.5px;
	line-height: 1.75;
	color: var(--charcoal);
}

.kv-account__form { max-width: 620px; }

.kv-account__notices { margin-bottom: 18px; }
.kv-account__notices ul { margin: 0; padding: 0; list-style: none; }

/*
 * WooCommerce prints its notices with its own classes and no styling of its own worth
 * keeping here. Errors carry the terracotta rule, everything else the forest one, matching
 * the application form's convention so the two forms read as one system.
 */
.kv-account__notices .woocommerce-error,
.kv-account__notices .woocommerce-message,
.kv-account__notices .woocommerce-info {
	padding: 14px 18px;
	margin: 0 0 12px;
	border-radius: 12px;
	border-left: 3px solid var(--forest);
	background: var(--cream);
	color: var(--forest);
	font-size: 14px;
	line-height: 1.65;
	list-style: none;
}

.kv-account__notices .woocommerce-error { border-left-color: var(--terracotta-ink); }
.kv-account__notices .woocommerce-error li { margin: 0 0 6px; }
.kv-account__notices .woocommerce-error li:last-child { margin-bottom: 0; }

/* -------------------------------------------------------------- fieldsets */

.kv-fieldset {
	border: 1px solid var(--stone);
	border-radius: var(--r-card);
	background: var(--white);
	padding: clamp(18px, 2.6vw, 28px);
	margin: 0 0 16px;
}

.kv-fieldset__legend {
	font-family: var(--font-display);
	font-size: 21px;
	color: var(--forest);
	padding: 0 6px;
	margin-left: -6px;
}

.kv-fieldset__note {
	margin: 6px 0 0;
	font-size: 12.5px;
	line-height: 1.65;
	color: var(--charcoal);
	max-width: 62ch;
}

/* ----------------------------------------------------------------- fields */

.kv-field { margin: 18px 0 0; }
.kv-field:first-of-type { margin-top: 14px; }

.kv-field label,
.kv-account__form > .kv-field label {
	display: block;
	font-size: 14.5px;
	font-weight: 500;
	color: var(--forest);
	line-height: 1.5;
}

.kv-req { color: var(--terracotta-ink); }

.kv-hint {
	display: block;
	font-size: 12.5px;
	line-height: 1.6;
	color: var(--charcoal);
	margin-top: 4px;
}

.kv-account input[type="text"],
.kv-account input[type="email"],
.kv-account input[type="tel"],
.kv-account input[type="password"],
.kv-account select {
	width: 100%;
	box-sizing: border-box;
	margin-top: 8px;
	border: 1px solid var(--stone);
	border-radius: 12px;
	padding: 11px 14px;
	font-family: inherit;
	font-size: 14px;
	line-height: 1.65;
	background: var(--white);
	color: var(--forest);
}

.kv-account input:focus-visible,
.kv-account select:focus-visible {
	outline: 2px solid var(--gold);
	outline-offset: 1px;
	border-color: var(--forest);
}

.kv-grid { display: grid; gap: 0 16px; }
.kv-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.kv-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

/*
 * The store address. The immutable part of the URL sits in the field rather than above it,
 * so what someone is choosing is unambiguous: they are naming the last segment, not the
 * whole address.
 */
.kv-prefixed {
	display: flex;
	align-items: stretch;
	margin-top: 8px;
	border: 1px solid var(--stone);
	border-radius: 12px;
	background: var(--white);
	overflow: hidden;
}

.kv-prefixed:focus-within { border-color: var(--forest); }

.kv-prefixed__prefix {
	display: flex;
	align-items: center;
	padding: 0 4px 0 14px;
	font-size: 13px;
	color: var(--taupe);
	background: var(--sand);
	white-space: nowrap;
	border-right: 1px solid var(--stone);
}

.kv-account .kv-prefixed input[type="text"] {
	margin-top: 0;
	border: 0;
	border-radius: 0;
	flex: 1 1 auto;
	min-width: 0;
}

.kv-account .kv-prefixed input[type="text"]:focus-visible { outline-offset: -2px; }

/* The reveal button injected by account.js. Absolutely positioned so it does not reflow the
   field when the label wraps to two lines. */
.kv-field--password { position: relative; }

.kv-reveal {
	position: absolute;
	right: 10px;
	bottom: 10px;
	border: 0;
	background: transparent;
	padding: 4px 6px;
	font-family: var(--font-body);
	font-size: 12px;
	font-weight: 600;
	letter-spacing: .02em;
	color: var(--taupe);
	cursor: pointer;
}

.kv-reveal:hover { color: var(--forest); }

/* The hint sits under the input, so the button has to clear it. */
.kv-field--password .kv-hint + .kv-reveal,
.kv-field--password:has(.kv-hint) .kv-reveal { bottom: 34px; }

/* ---------------------------------------------------------------- consent */

.kv-fieldset--consent { background: var(--cream); }

.kv-check {
	display: flex;
	gap: 10px;
	align-items: flex-start;
	margin-top: 12px;
	font-size: 13.5px;
	line-height: 1.65;
	color: var(--charcoal);
	font-weight: 400;
}

.kv-check:first-of-type { margin-top: 6px; }

/* Drawn, not native.
   `accent-color` only tints a box the operating system paints, and an unchecked native checkbox
   on this ivory panel is a pale outline on a pale ground — the client's review called it "almost
   invisible", which it was. The same problem was already solved for the signed-in account
   screens; this brings the auth screens in line. */
.kv-check {
	cursor: pointer;
	padding: 4px 6px 4px 0;
	border-radius: 8px;
}

.kv-check:hover { color: var(--forest); }
.kv-check:hover input { border-color: var(--gold); }

.kv-check input {
	appearance: none;
	-webkit-appearance: none;
	margin-top: 2px;
	width: 18px;
	height: 18px;
	flex: 0 0 18px;
	border: 1px solid var(--stone);
	border-radius: 5px;
	background: var(--white);
	display: inline-grid;
	place-content: center;
	cursor: pointer;
	transition: border-color .15s ease, background .15s ease;
}

/* The tick is drawn with a pseudo-element so it inherits the brand colour rather than the
   operating system's. */
.kv-check input::before {
	content: "";
	width: 10px;
	height: 10px;
	transform: scale(0);
	transition: transform .12s ease-in-out;
	box-shadow: inset 1em 1em var(--white);
	clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
}

.kv-check input:checked {
	background: var(--forest);
	border-color: var(--forest);
}

.kv-check input:checked::before { transform: scale(1); }

/* Focus lands on the input, but the whole row is the target, so the ring goes round the row. */
.kv-check:has( input:focus-visible ) {
	outline: 2px solid var(--gold);
	outline-offset: 2px;
}

.kv-check input:focus-visible { outline: none; }

.kv-check a { text-decoration: underline; text-underline-offset: 2px; }

.kv-check--inline { margin: 0; align-items: center; padding-left: 0; }

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

.kv-account__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 16px;
	margin: 20px 0 0;
}

.kv-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	font-family: var(--font-body);
	font-size: 13.5px;
	font-weight: 600;
	letter-spacing: .02em;
	padding: 13px 26px;
	border-radius: var(--r-pill);
	border: 1px solid transparent;
	cursor: pointer;
	transition: background .2s ease, color .2s ease, border-color .2s ease, transform .2s ease;
}

.kv-btn--primary { background: var(--forest); color: var(--white); }
.kv-btn--primary:hover { background: var(--forest-soft); color: var(--white); transform: translateY(-1px); }
.kv-btn--ghost { background: transparent; color: var(--forest); border-color: var(--stone); }
.kv-btn--ghost:hover { background: var(--forest); border-color: var(--forest); color: var(--gold-on-dark); }

.kv-account__lost { margin: 14px 0 0; font-size: 13px; }
.kv-account__lost a { text-decoration: underline; text-underline-offset: 2px; }

.kv-account__cross {
	margin: 22px 0 0;
	padding-top: 18px;
	border-top: 1px solid var(--stone);
	font-size: 13.5px;
	color: var(--charcoal);
}

.kv-account__cross a { font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }
.kv-account__cross--muted { margin-top: 10px; padding-top: 0; border-top: 0; font-size: 12.5px; }

/* ------------------------------------------------------------------ notes */

.kv-account__notes {
	/* The site header is sticky at 0 and about 79px tall once the top bar has scrolled away,
	   so 100px leaves the panel clear of it rather than tucked underneath. */
	position: sticky;
	top: 100px;
	border: 1px solid var(--stone);
	border-radius: var(--r-card);
	background: var(--sand);
	padding: clamp(18px, 2.4vw, 26px);
	/* Tighter at the top than on the other three sides, so the heading sits on roughly the
	   same baseline as the form's "Sign in" rather than floating below it. The sides and
	   bottom keep the panel's normal breathing room. */
	padding-top: clamp(14px, 1.5vw, 18px);
}

/*
 * `.kv-account` in front for specificity, not for tidiness.
 *
 * These pages are WordPress pages whose body is a shortcode, so page.php wraps the whole form
 * in `.entry-content` — and main.css styles long-form prose there with
 * `.entry-content h2 { font-size: 30px; margin-top: 1.6em; }`. That selector (0-1-1) outranks a
 * lone class (0-1-0), so the panel heading was rendering at 30px with 48px of margin above it
 * that nothing on the page had asked for. That margin was the "large empty space at the top of
 * the information box" in the client's review: the padding was never the problem.
 */
.kv-account .kv-account__notes-title {
	font-size: 19px;
	margin: 0 0 12px;
}

.kv-account__notes-list {
	margin: 0;
	padding: 0;
	list-style: none;
	display: grid;
	gap: 12px;
}

.kv-account__notes-list li {
	position: relative;
	padding-left: 18px;
	font-size: 13px;
	line-height: 1.7;
	color: var(--charcoal);
}

.kv-account__notes-list li::before {
	content: "";
	position: absolute;
	left: 0;
	top: .62em;
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: var(--gold);
}

.kv-account__error {
	padding: 14px 18px;
	border-radius: 12px;
	border-left: 3px solid var(--terracotta-ink);
	background: var(--cream);
	color: var(--forest);
}

/* ----------------------------------------------------------------- mobile */

/* 1024, not 900. The client asked for the panel below the form on tablet as well as phone, and
   a landscape tablet is 1024 wide — at the old breakpoint it still got the two-column desktop
   layout with a sticky aside. */
@media (max-width: 1024px) {
	.kv-account {
		grid-template-columns: minmax(0, 1fr);
		grid-template-areas:
			"switch"
			"panel"
			"notes";
	}

	/* Below the form and inert: a panel that follows the scroll makes sense beside the form,
	   not beneath it, where it would chase the visitor up its own column. */
	.kv-account__aside { align-self: auto; }
	.kv-account__notes { position: static; }
	.kv-grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 560px) {
	.kv-grid--2,
	.kv-grid--3 { grid-template-columns: minmax(0, 1fr); }

	.kv-account__switch { width: 100%; }
	.kv-account__switch-item { flex: 1 1 0; justify-content: center; padding: 9px 12px; }
	.kv-prefixed { flex-direction: column; }
	.kv-prefixed__prefix { border-right: 0; border-bottom: 1px solid var(--stone); padding: 8px 14px; }
}

/* ------------------------------------------------- submit loading state */

/*
 * The client's review asked that the form show it is working. Sign-in is a full page POST, so
 * the gap between the click and the next document is dead air unless the button says otherwise.
 *
 * A dim plus a spinner rather than a word swap: the button's own text is its accessible name
 * and WooCommerce reads its value from the POST, so replacing the label would change both.
 * `aria-busy` on the form carries the state to assistive technology; the spinner is decorative
 * and hidden from it.
 */
.kv-btn.is-loading {
	position: relative;
	color: transparent;
	pointer-events: none;
}

.kv-btn.is-loading::after {
	content: "";
	position: absolute;
	inset: 0;
	margin: auto;
	width: 16px;
	height: 16px;
	border: 2px solid currentcolor;
	border-top-color: var(--white);
	border-radius: 50%;
	color: rgba(255, 255, 255, .45);
	animation: kv-spin .6s linear infinite;
}

/* The ghost button sits on the light ground, so its spinner needs the dark ink instead. */
.kv-btn--ghost.is-loading::after {
	border-top-color: var(--forest);
	color: rgba(20, 49, 40, .3);
}

@keyframes kv-spin {
	to { transform: rotate(360deg); }
}

/* Respect a reduced-motion preference: hold the dim, drop the spin. */
@media (prefers-reduced-motion: reduce) {
	.kv-btn.is-loading::after { animation: none; }
}
