/**
 * Portal IQ — default styling.
 *
 * Neutral on purpose: this ships to sites with wildly different themes, so
 * it does not assume any particular brand palette or type system. A theme
 * overrides the custom properties below (either globally or scoped to
 * `.piq`) to match its own look; everything else is plain, accessible,
 * system-font CSS that will never clash badly with a host theme.
 */

.piq {
	--portal-iq-accent: #2f6f4f;
	--portal-iq-accent-contrast: #ffffff;
	--portal-iq-text: #1b1f1d;
	--portal-iq-muted: #666f6a;
	--portal-iq-border: #dcdfdc;
	--portal-iq-surface: #ffffff;
	--portal-iq-surface-muted: #f6f7f6;
	--portal-iq-danger: #b3261e;
	--portal-iq-radius: 10px;
	--portal-iq-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

	font-family: var(--portal-iq-font);
	color: var(--portal-iq-text);
	max-width: 720px;
	margin: 0 auto;
	/* Tell the browser this element already handles both schemes itself, so
	   Chrome/Android's automatic "force dark" page-inversion leaves it alone
	   instead of algorithmically re-coloring it on top of our own colors
	   (the two layered together is what produces washed-out text and
	   mismatched dark surfaces). */
	color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
	.piq {
		--portal-iq-text: #f1f3f1;
		--portal-iq-muted: #a3aca6;
		--portal-iq-border: #383d3a;
		--portal-iq-surface: #202422;
		--portal-iq-surface-muted: #262b28;
		/* A meaningful chunk of this widget's content — the dashboard header,
		   tab bar, section headings, invoice table, payment-method row,
		   ticket list — sits directly on whatever background the host page
		   provides, not inside a .piq__card. In light mode that is safe to
		   leave transparent (dark text stays legible on virtually any light
		   host background), but here the text just went near-white: without
		   a matching dark backdrop of our own, a visitor whose OS prefers
		   dark mode but who is on an otherwise light host page would get
		   near-white text on that page's still-light background — unreadable.
		   Giving the widget its own surface + padding only in this branch
		   keeps light-mode's flush, blend-into-the-page look untouched. */
		background: var(--portal-iq-surface);
		border-radius: var(--portal-iq-radius);
		padding: 1.25rem;
	}
}

.piq * {
	box-sizing: border-box;
}

.piq__card {
	background: var(--portal-iq-surface);
	border: 1px solid var(--portal-iq-border);
	border-radius: var(--portal-iq-radius);
	padding: 1.5rem;
	margin-bottom: 1rem;
}

.piq__h {
	font-size: 1.25rem;
	font-weight: 600;
	margin: 0 0 0.4rem;
}

.piq__h3 {
	font-size: 1rem;
	font-weight: 600;
	margin: 1rem 0 0.5rem;
}

.piq__sub {
	color: var(--portal-iq-muted);
	margin: 0 0 1rem;
	font-size: 0.95rem;
}

.piq__muted {
	color: var(--portal-iq-muted);
	font-size: 0.9rem;
}

.piq__input {
	display: block;
	width: 100%;
	padding: 0.65rem 0.8rem;
	border: 1px solid var(--portal-iq-border);
	border-radius: calc(var(--portal-iq-radius) - 4px);
	background: var(--portal-iq-surface);
	color: var(--portal-iq-text);
	font-size: 1rem;
	margin-bottom: 0.75rem;
}

.piq__input:focus {
	outline: 2px solid var(--portal-iq-accent);
	outline-offset: 1px;
}

.piq__input--code {
	letter-spacing: 0.3em;
	text-align: center;
	font-variant-numeric: tabular-nums;
}

.piq__btn {
	display: inline-block;
	border: 1px solid var(--portal-iq-accent);
	border-radius: calc(var(--portal-iq-radius) - 4px);
	padding: 0.6rem 1rem;
	font-size: 0.95rem;
	font-weight: 600;
	cursor: pointer;
	background: transparent;
	color: var(--portal-iq-accent);
	transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, opacity 0.15s ease;
}

.piq__btn:hover:not(:disabled) {
	/* Plain fallback first for browsers without color-mix() (see the badge
	   rules below for the same pattern) — a flat tint if color-mix() is
	   unsupported, a subtle accent-tinted wash if it is. */
	background: var(--portal-iq-surface-muted);
	background: color-mix(in srgb, var(--portal-iq-accent) 12%, transparent);
}

.piq__btn:focus-visible {
	outline: 2px solid var(--portal-iq-accent);
	outline-offset: 2px;
}

.piq__btn:disabled {
	opacity: 0.6;
	cursor: default;
}

.piq__btn--solid {
	background: var(--portal-iq-accent);
	color: var(--portal-iq-accent-contrast);
}

.piq__btn--solid:hover:not(:disabled) {
	background: var(--portal-iq-accent);
	background: color-mix(in srgb, var(--portal-iq-accent) 88%, black);
}

.piq__btn--outline {
	background: transparent;
	color: var(--portal-iq-accent);
}

/* Brief confirmation flash after a successful copy (e.g. a license key) —
   pairs with the button text swapping to "Copied" in portal.js so the
   confirmation reads instantly instead of only being a text change. The
   :hover variant is repeated here because :hover:not(:disabled) above has
   higher specificity than a plain two-class selector — without it, a cursor
   left resting on the button after the click it just fired (the normal
   case) would mask the confirmation with the hover tint. */
.piq__btn.is-copied,
.piq__btn.is-copied:hover {
	background: var(--portal-iq-accent);
	color: var(--portal-iq-accent-contrast);
}

.piq__btn--sm {
	padding: 0.4rem 0.75rem;
	font-size: 0.85rem;
}

.piq__btn--block {
	display: block;
	width: 100%;
	text-align: center;
}

.piq__link {
	background: none;
	border: none;
	padding: 0;
	color: var(--portal-iq-accent);
	font-size: 0.85rem;
	cursor: pointer;
	text-decoration: underline;
	transition: opacity 0.15s ease;
}

.piq__link:hover:not(:disabled) {
	opacity: 0.75;
}

.piq__link:focus-visible {
	outline: 2px solid var(--portal-iq-accent);
	outline-offset: 2px;
	border-radius: 2px;
}

.piq__link:disabled {
	opacity: 0.5;
	cursor: default;
	text-decoration: none;
}

.piq__link--danger {
	color: var(--portal-iq-danger);
}

.piq__altrow {
	display: flex;
	justify-content: space-between;
	margin-top: 0.5rem;
	gap: 1rem;
}

.piq__status {
	min-height: 1.2em;
	font-size: 0.85rem;
	margin-top: 0.4rem;
}

.piq__status.is-error {
	color: var(--portal-iq-danger);
}

.piq__status.is-ok {
	color: var(--portal-iq-accent);
}

.piq__spinner {
	width: 28px;
	height: 28px;
	margin: 3rem auto;
	border: 3px solid var(--portal-iq-border);
	border-top-color: var(--portal-iq-accent);
	border-radius: 50%;
	animation: piq-spin 0.8s linear infinite;
}

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

/* Skeleton placeholders shown the instant a tab-data fetch starts, swapped
   for the real content when it resolves — avoids the blank-then-sudden-pop
   that a bare "wait for the fetch" render produces on a slow connection. */
.piq__skeleton-row {
	padding: 0.5rem 0.4rem;
}

.piq__skeleton-bar {
	display: block;
	height: 0.85rem;
	width: 70%;
	border-radius: 4px;
	background: linear-gradient(
		90deg,
		var(--portal-iq-surface-muted) 25%,
		var(--portal-iq-border) 37%,
		var(--portal-iq-surface-muted) 63%
	);
	background-size: 400% 100%;
	animation: piq-shimmer 1.4s ease infinite;
}

@keyframes piq-shimmer {
	0% { background-position: 100% 50%; }
	100% { background-position: 0 50%; }
}

.piq__dashhead {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: 1rem;
}

.piq__who {
	font-weight: 600;
}

/* Confirmation/error toast for actions taken from within the dashboard
   (subscribe, cancel, resume) — replaces bare window.alert() popups with an
   inline, dismissable-by-timeout message that matches the rest of the UI. */
.piq__toast {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	border: 1px solid var(--portal-iq-border);
	border-radius: var(--portal-iq-radius);
	background: var(--portal-iq-surface-muted);
	color: var(--portal-iq-text);
	padding: 0.7rem 1rem;
	font-size: 0.9rem;
	margin-bottom: 1rem;
	opacity: 0;
	transform: translateY(-4px);
	transition: opacity 0.2s ease, transform 0.2s ease;
}

.piq__toast.is-visible {
	opacity: 1;
	transform: translateY(0);
}

.piq__toast.is-ok {
	border-color: var(--portal-iq-accent);
}

.piq__toast.is-error {
	border-color: var(--portal-iq-danger);
	color: var(--portal-iq-danger);
}

.piq__nameprompt {
	background: var(--portal-iq-surface-muted);
	border: 1px solid var(--portal-iq-border);
	border-radius: var(--portal-iq-radius);
	padding: 1rem 1.25rem;
	margin-bottom: 1rem;
}

.piq__namerow {
	display: flex;
	gap: 0.5rem;
	align-items: center;
	flex-wrap: wrap;
}

.piq__namerow .piq__input {
	flex: 1 1 220px;
	margin-bottom: 0;
}

.piq__tabs {
	display: flex;
	gap: 0.25rem;
	border-bottom: 1px solid var(--portal-iq-border);
	margin-bottom: 1.25rem;
	/* On the narrowest phones (~320px) the three tab labels can exceed the
	   available width; flex items don't wrap here on purpose (a tab bar
	   shouldn't become two lines), so let the bar scroll horizontally
	   instead of overflowing the card / causing page-level horizontal
	   scroll. No-op at any width where the tabs already fit. */
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}

.piq__tab {
	background: none;
	border: none;
	border-bottom: 2px solid transparent;
	padding: 0.6rem 0.9rem;
	font-size: 0.95rem;
	font-weight: 600;
	color: var(--portal-iq-muted);
	cursor: pointer;
	flex-shrink: 0;
	white-space: nowrap;
	transition: color 0.15s ease, border-color 0.15s ease;
}

.piq__tab:hover:not(.is-active) {
	color: var(--portal-iq-text);
}

.piq__tab:focus-visible {
	outline: 2px solid var(--portal-iq-accent);
	outline-offset: -2px;
	border-radius: 4px;
}

.piq__tab.is-active {
	color: var(--portal-iq-accent);
	border-bottom-color: var(--portal-iq-accent);
}

.piq__tabpanel {
	display: none;
}

.piq__tabpanel.is-active {
	display: block;
	/* Small fade + settle so switching tabs reads as a transition rather than
	   an instant content swap. Only the entering panel animates — the
	   outgoing one is hidden immediately, so there is nothing to animate out. */
	animation: piq-tabfade 0.18s ease;
}

@keyframes piq-tabfade {
	from { opacity: 0; transform: translateY(3px); }
	to { opacity: 1; transform: translateY(0); }
}

/* Reuses piq-tabfade so a section that reveals itself once data is ready
   (e.g. the support-ticket list) settles in the same way as a tab switch. */
#piq-tickets:not([hidden]) {
	animation: piq-tabfade 0.18s ease;
}

.piq__section {
	margin-bottom: 1.5rem;
}

.piq__licrow {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: 0.5rem;
}

.piq__prod {
	font-weight: 600;
}

.piq__keyrow {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	margin-bottom: 0.5rem;
}

.piq__key {
	background: var(--portal-iq-surface-muted);
	border: 1px solid var(--portal-iq-border);
	border-radius: 6px;
	padding: 0.3rem 0.5rem;
	font-size: 0.85rem;
	overflow-wrap: anywhere;
}

.piq__badge {
	display: inline-block;
	font-size: 0.75rem;
	font-weight: 600;
	padding: 0.15rem 0.5rem;
	border-radius: 999px;
	background: var(--portal-iq-surface-muted);
	color: var(--portal-iq-muted);
	text-transform: capitalize;
}

.piq__badge--active,
.piq__badge--trialing {
	/* Fallback for browsers without color-mix() support (e.g. Safari <16.2) —
	   an invalid color-mix() value is dropped by the parser, so without this
	   line first those browsers would fall through to no background at all
	   instead of just missing the accent tint. */
	background: var(--portal-iq-surface-muted);
	background: color-mix(in srgb, var(--portal-iq-accent) 18%, transparent);
	color: var(--portal-iq-accent);
}

.piq__badge--onetime {
	background: var(--portal-iq-surface-muted);
}

.piq__badge--danger {
	/* Same plain-fallback-then-color-mix pattern as .piq__badge--active above. */
	background: var(--portal-iq-surface-muted);
	background: color-mix(in srgb, var(--portal-iq-danger) 16%, transparent);
	color: var(--portal-iq-danger);
}

.piq__subrow,
.piq__trial {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	flex-wrap: wrap;
	margin-top: 0.5rem;
}

.piq__trial.is-expired .piq__trialmsg {
	color: var(--portal-iq-danger);
}

.piq__trialmsg {
	margin: 0;
	font-size: 0.9rem;
	color: var(--portal-iq-muted);
}

.piq__billing {
	font-size: 0.85rem;
	color: var(--portal-iq-muted);
}

.piq__pm {
	padding: 0.5rem 0.4rem;
	margin: 0 -0.4rem;
	border-bottom: 1px solid var(--portal-iq-border);
	border-radius: 6px;
	font-size: 0.9rem;
	transition: background-color 0.15s ease;
}

.piq__pm:hover {
	background: var(--portal-iq-surface-muted);
}

.piq__cardform {
	margin-top: 1rem;
	padding: 1rem;
	border: 1px solid var(--portal-iq-border);
	border-radius: var(--portal-iq-radius);
}

.piq__stripe {
	padding: 0.65rem 0.8rem;
	border: 1px solid var(--portal-iq-border);
	border-radius: calc(var(--portal-iq-radius) - 4px);
	background: var(--portal-iq-surface);
	margin-bottom: 0.75rem;
}

.piq__cardactions {
	display: flex;
	gap: 0.75rem;
	align-items: center;
}

.piq__table-wrap {
	/* Safety net for narrow screens: if a currency/amount/status column ever
	   forces the table wider than the card, scroll just the table instead of
	   the whole page. No effect once the table already fits (the common
	   case). */
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}

.piq__table {
	width: 100%;
	border-collapse: collapse;
	font-size: 0.9rem;
}

.piq__table td {
	padding: 0.5rem 0.4rem;
	border-bottom: 1px solid var(--portal-iq-border);
}

.piq__table tbody tr {
	transition: background-color 0.15s ease;
}

.piq__table tbody tr:hover {
	background: var(--portal-iq-surface-muted);
}

.piq__ticket {
	padding: 0.75rem 0.4rem;
	margin: 0 -0.4rem;
	border-bottom: 1px solid var(--portal-iq-border);
	border-radius: 6px;
	transition: background-color 0.15s ease;
}

.piq__ticket:hover {
	background: var(--portal-iq-surface-muted);
}

.piq__ticketrow {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 0.5rem;
}

.piq__ticketsubj {
	font-weight: 600;
	font-size: 0.9rem;
}

.piq__ticketsum {
	margin: 0.35rem 0;
	font-size: 0.85rem;
	color: var(--portal-iq-muted);
}

@media (prefers-reduced-motion: reduce) {
	.piq__spinner,
	.piq__skeleton-bar {
		animation: none;
	}

	.piq__tabpanel.is-active,
	#piq-tickets:not([hidden]) {
		animation: none;
	}

	.piq__toast,
	.piq__btn,
	.piq__link,
	.piq__tab,
	.piq__pm,
	.piq__ticket,
	.piq__table tbody tr {
		transition: none;
	}
}
