/**
 * Curio chat widget.
 *
 * Two rules govern this file and both are load-bearing.
 *
 * 1. Every selector begins inside #curio-widget. A chat widget is a guest on a
 *    page it does not own; a rule that reaches outside itself restyles somebody
 *    else's theme and the site owner blames the theme.
 *
 * 2. No colour is written literally. Everything is a custom property set by
 *    PHP from the Appearance settings, which is what makes re-skinning safe —
 *    the settings screen supplies values, never rules. The comment saying this
 *    was already in the file this replaces, and it was not true: three
 *    gradients and two focus rings still carried a previous client's coral.
 *    tests/style-test.php now fails the build if it stops being true again.
 */

#curio-widget {
	position: fixed;
	bottom: var(--curio-offset-y, 24px);
	z-index: var(--curio-z, 99999);

	/* A column, aligned to whichever edge the widget is anchored to.
	 *
	 * This element is fixed with `right` (or `left`) but no width, so it
	 * shrink-wraps to its widest visible child. As a plain block that meant the
	 * launcher moved: closed, the box was 58px and the launcher sat on the
	 * anchored edge; open, the 384px panel widened the box and the launcher —
	 * a block-level child — dropped to its left edge, so it slid across on
	 * every open and slid back on every close. The teaser had the same problem
	 * and had been patched locally with `margin-right: auto`.
	 *
	 * Aligning the children to the anchored edge fixes all of it at the root:
	 * the launcher stays put whatever else is on screen. */
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	font-family: var(--curio-family, inherit);
	font-size: var(--curio-font-size, 15px);
	line-height: 1.5;
	color: var(--curio-text);
	-webkit-font-smoothing: antialiased;
	box-sizing: border-box;
}

#curio-widget *,
#curio-widget *::before,
#curio-widget *::after {
	box-sizing: inherit;
}

#curio-widget.curio-pos-bottom-right {
	right: var(--curio-offset-x, 24px);
	left: auto;
}

#curio-widget.curio-pos-bottom-left {
	left: var(--curio-offset-x, 24px);
	right: auto;
	align-items: flex-start;
}

#curio-widget .curio-visually-hidden {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* -------------------------------------------------------------------------
   Launcher
   ------------------------------------------------------------------------- */

#curio-widget .curio-launcher {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.55em;
	min-width: var(--curio-launcher, 58px);
	height: var(--curio-launcher, 58px);
	padding: 0;
	margin: 0;
	border: 0;
	border-radius: 999px;
	background: var(--curio-accent);
	color: var(--curio-accent-text);
	box-shadow: var(--curio-shadow);
	cursor: pointer;
	transition: transform 0.18s ease, background-color 0.18s ease, box-shadow 0.18s ease,
		opacity 0.18s ease, visibility 0s;
	font: inherit;

	/* The prefix is not redundant: older iOS Safari still needs it to drop the
	   native button chrome, and a launcher that renders as a grey system pill
	   on an iPhone is the first thing a site owner will complain about. */
	appearance: none;
	-webkit-appearance: none;
}

#curio-widget.curio-launcher-pill .curio-launcher {
	padding: 0 1.15em 0 1em;
	border-radius: 999px;
}

#curio-widget .curio-launcher-text {
	font-weight: 600;
	font-size: 0.95em;
	white-space: nowrap;
}

#curio-widget .curio-launcher:hover {
	background: var(--curio-accent-hover);
	transform: translateY(-1px);
}

#curio-widget .curio-launcher:focus-visible {
	outline: none;
	box-shadow: var(--curio-shadow), 0 0 0 4px var(--curio-ring);
}

#curio-widget .curio-launcher-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.55em;
	height: 1.55em;
	flex: none;
}

#curio-widget .curio-launcher-icon svg {
	width: 100%;
	height: 100%;
}

/* Open: the launcher has become the panel, so it gets out of the way.
 *
 * It used to stay put and swap its icon for a cross — which put the same
 * control on screen twice, since the panel header already has a close button
 * two inches above it. The phone layout had always hidden it instead; this is
 * that behaviour at every size, with the scale-down making it read as the
 * launcher expanding into the panel rather than simply vanishing.
 *
 * visibility, not just opacity: a transparent button is still a tab stop and
 * still announced by a screen reader. The delay holds it visible long enough
 * to be seen shrinking, then takes it out of the tree entirely. */
#curio-widget[data-curio-state="open"] .curio-launcher,
#curio-widget[data-curio-state="expanded"] .curio-launcher {
	/* Out of flow, not merely invisible. `visibility: hidden` alone keeps the
	   launcher's 58px in the column, so the panel was pushed 72px clear of the
	   bottom and sat over an empty gap the size of a button that was not there.
	   Absolute against the fixed root puts it in the same corner it already
	   occupied, so nothing jumps as it fades. */
	position: absolute;
	bottom: 0;
	right: 0;
	opacity: 0;
	transform: scale(0.7);
	visibility: hidden;
	transition: opacity 0.18s ease, transform 0.18s ease, visibility 0s linear 0.18s;
}

#curio-widget.curio-pos-bottom-left[data-curio-state="open"] .curio-launcher,
#curio-widget.curio-pos-bottom-left[data-curio-state="expanded"] .curio-launcher {
	right: auto;
	left: 0;
}

/* -------------------------------------------------------------------------
   Teaser bubble
   ------------------------------------------------------------------------- */

#curio-widget .curio-teaser {
	position: relative;
	max-width: min(19rem, calc(100vw - 3rem));
	margin-bottom: 0.75rem;
	padding: 0.85rem 2.1rem 0.85rem 1rem;
	border: 1px solid var(--curio-border);
	border-radius: var(--curio-radius-bubble);
	background: var(--curio-surface);
	box-shadow: var(--curio-shadow);
	animation: curio-rise 0.28s ease both;
}


#curio-widget .curio-teaser-text {
	margin: 0;
	font-size: 0.93em;
	color: var(--curio-text);
}

#curio-widget .curio-teaser-dismiss {
	position: absolute;
	top: 0.35rem;
	right: 0.35rem;
	display: inline-flex;
	width: 1.6rem;
	height: 1.6rem;
	padding: 0.3rem;
	border: 0;
	border-radius: 999px;
	background: transparent;
	color: var(--curio-text-muted);
	cursor: pointer;
}

#curio-widget .curio-teaser-dismiss:hover {
	background: var(--curio-surface-3);
	color: var(--curio-text);
}

#curio-widget .curio-teaser-dismiss svg {
	width: 100%;
	height: 100%;
}

/* -------------------------------------------------------------------------
   Panel
   ------------------------------------------------------------------------- */

#curio-widget .curio-panel {
	display: flex;
	flex-direction: column;
	width: min(var(--curio-width, 384px), calc(100vw - 2rem));
	height: min(var(--curio-height, 560px), calc(100vh - 7rem));

	/* No bottom margin. It used to hold the panel clear of the launcher sitting
	   underneath it; the launcher now leaves entirely when the panel opens, and
	   the only gap that should remain below is the one the site owner set as
	   the bottom offset. */
	overflow: hidden;
	border: 1px solid var(--curio-border);
	border-radius: var(--curio-radius, 16px);
	background: var(--curio-surface);
	box-shadow: var(--curio-shadow);

	/* Grows from the corner the launcher occupies, so the two read as one
	   movement: the button expands into the window and collapses back. */
	transform-origin: bottom right;
	animation: curio-rise 0.22s ease both;
}

#curio-widget.curio-pos-bottom-left .curio-panel {
	transform-origin: bottom left;
}

#curio-widget .curio-panel[hidden] {
	display: none;
}

#curio-widget[data-curio-state="expanded"] .curio-panel {
	position: fixed;
	inset: 1.5rem;
	width: auto;
	height: auto;
	max-width: 60rem;
	margin: 0 auto;
}

#curio-widget .curio-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.75rem;
	padding: 0.85rem 0.85rem 0.85rem 1rem;
	background: var(--curio-accent);
	color: var(--curio-accent-text);
	flex: none;
}

#curio-widget .curio-identity {
	display: flex;
	align-items: center;
	gap: 0.7rem;
	min-width: 0;
}

#curio-widget .curio-avatar {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.25rem;
	height: 2.25rem;
	flex: none;
	overflow: hidden;
	border-radius: 999px;
	background: color-mix(in srgb, var(--curio-accent-text) 18%, transparent);
	color: var(--curio-accent-text);
}

#curio-widget .curio-avatar svg {
	width: 1.35rem;
	height: 1.35rem;
}

#curio-widget .curio-avatar-image {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

#curio-widget .curio-identity-text {
	display: flex;
	flex-direction: column;
	min-width: 0;
}

#curio-widget .curio-title {
	font-weight: 650;
	font-size: 0.98em;
	line-height: 1.3;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

#curio-widget .curio-subtitle {
	font-size: 0.8em;

	/* Not `opacity`. Opacity blends toward whatever is painted behind the
	   element, so the effective contrast is unknowable from the stylesheet.
	   This variable is computed in PHP as the most muted colour that still
	   clears 4.5:1 against the chosen accent, whatever that accent is. */
	color: var(--curio-accent-text-soft, currentcolor);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

#curio-widget .curio-header-actions {
	display: flex;
	gap: 0.2rem;
	flex: none;
}

#curio-widget .curio-icon-button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2rem;
	height: 2rem;
	padding: 0.4rem;
	border: 0;
	border-radius: 0.5rem;
	background: transparent;
	color: inherit;
	cursor: pointer;
	transition: background-color 0.15s ease;
}

#curio-widget .curio-icon-button:hover:not(:disabled) {
	background: color-mix(in srgb, var(--curio-accent-text) 18%, transparent);
}

#curio-widget .curio-icon-button:disabled {
	opacity: 0.45;
	cursor: not-allowed;
}

#curio-widget .curio-icon-button:focus-visible {
	outline: 2px solid var(--curio-accent-text);
	outline-offset: 1px;
}

#curio-widget .curio-icon-button svg {
	width: 100%;
	height: 100%;
}

/* Arrows out while the panel is a corner widget, arrows in once it covers the
   page — the icon says what the press will do, not what the panel currently is. */
#curio-widget .curio-expand-in {
	display: none;
}

#curio-widget[data-curio-state="expanded"] .curio-expand-out {
	display: none;
}

#curio-widget[data-curio-state="expanded"] .curio-expand-in {
	display: block;
}

/* -------------------------------------------------------------------------
   Message log
   ------------------------------------------------------------------------- */

#curio-widget .curio-log {
	flex: 1 1 auto;
	min-height: 0;
	padding: 1rem;
	overflow-y: auto;
	overscroll-behavior: contain;
	background: var(--curio-surface-2);
	display: flex;
	flex-direction: column;
	gap: 0.7rem;
	scrollbar-width: thin;
}

#curio-widget .curio-log:focus-visible {
	outline: 2px solid var(--curio-accent);
	outline-offset: -2px;
}

#curio-widget .curio-message {
	max-width: 88%;
	padding: 0.65rem 0.85rem;
	border-radius: var(--curio-radius-bubble, 14px);
	animation: curio-rise 0.2s ease both;
	word-wrap: break-word;
	overflow-wrap: anywhere;
}

#curio-widget .curio-message p {
	margin: 0 0 0.6em;
}

#curio-widget .curio-message p:last-child {
	margin-bottom: 0;
}

#curio-widget .curio-message ul {
	margin: 0.2em 0 0.6em;
	padding-left: 1.15em;
}

#curio-widget .curio-message li {
	margin: 0.15em 0;
}

#curio-widget .curio-message a {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 2px;
}

#curio-widget .curio-message-assistant {
	align-self: flex-start;
	background: var(--curio-surface);
	border: 1px solid var(--curio-border);
	border-bottom-left-radius: 0.35rem;
	color: var(--curio-text);
}

#curio-widget .curio-message-user {
	align-self: flex-end;
	background: var(--curio-accent);
	color: var(--curio-accent-text);
	border-bottom-right-radius: 0.35rem;
}

#curio-widget .curio-message-error {
	align-self: flex-start;
	background: var(--curio-surface-3);
	border: 1px dashed var(--curio-border);
	color: var(--curio-text-muted);
}

#curio-widget .curio-sources {
	display: flex;
	flex-wrap: wrap;
	gap: 0.35rem;
	margin-top: 0.55rem;
	padding-top: 0.5rem;
	border-top: 1px solid var(--curio-border);
}

#curio-widget .curio-source {
	display: inline-flex;
	align-items: center;
	max-width: 100%;
	padding: 0.16rem 0.5rem;
	border: 1px solid var(--curio-border);
	border-radius: 999px;
	background: var(--curio-surface-2);
	color: var(--curio-text-muted);
	font-size: 0.78em;
	text-decoration: none;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

#curio-widget .curio-source:hover,
#curio-widget .curio-source:focus-visible {
	color: var(--curio-text);
	border-color: var(--curio-accent);
}

/* -------------------------------------------------------------------------
   Typing indicator
   ------------------------------------------------------------------------- */

#curio-widget .curio-typing {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	margin: 0;
	padding: 0.35rem 1rem 0.6rem;
	background: var(--curio-surface-2);
	flex: none;
}

#curio-widget .curio-typing[hidden] {
	display: none;
}

#curio-widget .curio-typing-dots {
	display: inline-flex;
	gap: 0.28rem;
}

#curio-widget .curio-typing-dots span {
	width: 0.42rem;
	height: 0.42rem;
	border-radius: 999px;
	background: var(--curio-text-muted);
	animation: curio-pulse 1.3s infinite ease-in-out;
}

#curio-widget .curio-typing-dots span:nth-child(2) {
	animation-delay: 0.18s;
}

#curio-widget .curio-typing-dots span:nth-child(3) {
	animation-delay: 0.36s;
}

/* -------------------------------------------------------------------------
   Reaching a person

   Sits in the conversation's own surface rather than the composer's, so it
   reads as part of what the assistant just said.

   Filled with the accent rather than outlined. An outlined control would put
   the accent colour on the panel surface, a pairing nothing in this plugin
   ever measures; accent against accent-text is the one pairing the Appearance
   tab computes and warns about, so it is the one worth reusing.
   ------------------------------------------------------------------------- */

#curio-widget .curio-handoff {
	padding: 0 1rem 0.75rem;
	background: var(--curio-surface-2);
	flex: none;
}

#curio-widget .curio-handoff[hidden] {
	display: none;
}

#curio-widget .curio-handoff-link {
	display: inline-flex;
	align-items: center;
	gap: 0.45em;
	max-width: 100%;
	padding: 0.45em 0.85em;
	border-radius: var(--curio-radius-field, 10px);
	background: var(--curio-accent);
	color: var(--curio-accent-text);
	font-size: 0.86em;
	font-weight: 600;
	line-height: 1.3;
	text-decoration: none;
	transition: background-color 0.15s ease;
}

#curio-widget .curio-handoff-link:hover {
	background: var(--curio-accent-hover);
	color: var(--curio-accent-text);
}

/*
 * Two rings rather than one translucent one. A 35%-alpha accent ring sits on
 * the conversation surface and can be almost invisible there; an inner ring in
 * that same surface, wrapped by a solid accent ring, is visible for exactly the
 * reason the button itself is — whatever the site owner chose as their accent.
 */
#curio-widget .curio-handoff-link:focus-visible {
	outline: none;
	box-shadow: 0 0 0 2px var(--curio-surface-2), 0 0 0 4px var(--curio-accent);
}

#curio-widget .curio-handoff-icon {
	display: inline-flex;
	width: 1.15em;
	height: 1.15em;
	flex: none;
}

#curio-widget .curio-handoff-icon svg {
	width: 100%;
	height: 100%;
}

#curio-widget .curio-handoff-text {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* -------------------------------------------------------------------------
   Composer
   ------------------------------------------------------------------------- */

#curio-widget .curio-composer {
	display: flex;
	align-items: flex-end;
	gap: 0.5rem;
	padding: 0.7rem;
	border-top: 1px solid var(--curio-border);
	background: var(--curio-surface);
	flex: none;
}

#curio-widget .curio-input {
	flex: 1 1 auto;
	min-width: 0;
	max-height: 7.5rem;
	padding: 0.6rem 0.8rem;
	border: 1px solid var(--curio-border);
	border-radius: var(--curio-radius-field, 10px);
	background: var(--curio-surface-2);
	color: var(--curio-text);
	font: inherit;
	line-height: 1.45;
	resize: none;
	overflow-y: auto;
}

#curio-widget .curio-input::placeholder {
	color: var(--curio-text-muted);
	opacity: 1;
}

#curio-widget .curio-input:focus {
	outline: none;
	border-color: var(--curio-accent);
	box-shadow: 0 0 0 3px var(--curio-ring-soft);
}

#curio-widget .curio-send {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.5rem;
	height: 2.5rem;
	flex: none;
	padding: 0.6rem;
	border: 0;
	border-radius: var(--curio-radius-field, 10px);
	background: var(--curio-accent);
	color: var(--curio-accent-text);
	cursor: pointer;
	transition: background-color 0.15s ease, opacity 0.15s ease;
}

#curio-widget .curio-send:hover:not(:disabled) {
	background: var(--curio-accent-hover);
}

#curio-widget .curio-send:disabled {
	opacity: 0.45;
	cursor: not-allowed;
}

#curio-widget .curio-send:focus-visible {
	outline: none;
	box-shadow: 0 0 0 3px var(--curio-ring);
}

#curio-widget .curio-send svg {
	width: 100%;
	height: 100%;
}

#curio-widget .curio-credit {
	margin: 0;
	padding: 0.4rem 0.7rem 0.6rem;
	background: var(--curio-surface);
	text-align: center;
	font-size: 0.72em;
}

#curio-widget .curio-credit a {
	color: var(--curio-text-muted);
	text-decoration: none;
}

#curio-widget .curio-credit a:hover {
	color: var(--curio-text);
	text-decoration: underline;
}

/* -------------------------------------------------------------------------
   Motion
   ------------------------------------------------------------------------- */

@keyframes curio-rise {
	from {
		opacity: 0;
		transform: translateY(8px) scale(0.96);
	}
	to {
		opacity: 1;
		transform: translateY(0) scale(1);
	}
}

@keyframes curio-pulse {
	0%,
	60%,
	100% {
		opacity: 0.3;
		transform: translateY(0);
	}
	30% {
		opacity: 1;
		transform: translateY(-0.18rem);
	}
}

@media (prefers-reduced-motion: reduce) {
	#curio-widget *,
	#curio-widget *::before,
	#curio-widget *::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;

		/* Delays too, not just durations. A zero-length transition that still
		   waits 180ms to start is still 180ms of waiting, and the launcher's
		   visibility is sequenced with exactly that kind of delay. */
		animation-delay: 0s !important;
		transition-delay: 0s !important;
	}
}

/* -------------------------------------------------------------------------
   Small screens
   -------------------------------------------------------------------------
   A 384px panel floating over a 390px phone is a panel with a 3px border of
   somebody's website showing round it. Below 600px the panel takes the screen,
   which is what every chat product people already use does.
   ------------------------------------------------------------------------- */

@media (width <= 600px) {
	#curio-widget .curio-panel,
	#curio-widget[data-curio-state="expanded"] .curio-panel {
		position: fixed;
		inset: 0;
		width: 100%;
		height: 100%;
		max-width: none;
		margin: 0;
		border: 0;
		border-radius: 0;
	}

	#curio-widget .curio-header {
		padding-top: max(0.85rem, env(safe-area-inset-top));
	}

	#curio-widget .curio-composer {
		padding-bottom: max(0.7rem, env(safe-area-inset-bottom));
	}

	#curio-widget[data-curio-state="expanded"] .curio-header-actions [data-curio-expand] {
		display: none;
	}
}

/* Windows high-contrast mode strips background colours; without this the
   launcher becomes an invisible button. */
@media (forced-colors: active) {
	#curio-widget .curio-launcher,
	#curio-widget .curio-send,
	#curio-widget .curio-panel {
		border: 1px solid ButtonText;
	}
}
