/* ==========================================================================
   xtrendence.com additions

   portfolio.css is a vendored copy of the .dev design system and is kept that
   way so it can be re-synced. Everything here is .com only: the cookie notice
   and the internal tool pages, built out of the same tokens.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Page shell
   -------------------------------------------------------------------------- */

.app {
	position: relative;
	z-index: 1;
	width: var(--shell);
	margin: 0 auto;
	padding: clamp(96px, 14vh, 132px) 0 clamp(64px, 10vh, 96px);
	min-height: 100vh;
	display: flex;
	flex-direction: column;
	gap: 24px;
}

/* Pages with one small card centre it instead of stacking from the top. */
.app--center {
	justify-content: center;
	align-items: center;
	padding-top: clamp(80px, 12vh, 120px);
}

.app-head {
	display: flex;
	flex-direction: column;
	gap: 14px;
	margin-bottom: 4px;
}

.app-head h1 {
	font-size: clamp(28px, 4vw, 42px);
}

.app-head p {
	max-width: 620px;
	color: var(--ink-2);
	font-size: 16.5px;
}

/* Back control, mirrors the dock trigger on the opposite corner. */
.back-btn {
	position: fixed;
	top: 18px;
	left: 18px;
	z-index: 300;
	display: grid;
	place-items: center;
	width: 44px;
	height: 44px;
	padding: 0;
	border-radius: var(--r-pill);
	color: var(--ink-2);
	cursor: pointer;
	transition: color 0.3s var(--ease), background 0.4s var(--ease),
		border-color 0.4s var(--ease), transform 0.45s var(--ease-spring);
}

.back-btn svg {
	width: 17px;
	height: 17px;
	fill: currentColor;
	transition: transform 0.4s var(--ease-spring);
}

#desktop .back-btn:hover {
	color: var(--ink);
	background: var(--glass-bg-hover);
	border-color: var(--glass-border-hover);
}

#desktop .back-btn:hover svg {
	transform: translateX(-3px);
}

@media screen and (max-width: 560px) {
	.back-btn {
		top: calc(14px + env(safe-area-inset-top, 0px));
		left: 14px;
	}
}

/* --------------------------------------------------------------------------
   2. Cards and grids
   -------------------------------------------------------------------------- */

.card {
	padding: 26px;
	border-radius: var(--r-lg);
}

.card-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 14px;
	margin-bottom: 18px;
}

.card-head h2 {
	font-size: 17px;
	font-weight: 600;
}

.tile-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(196px, 1fr));
	gap: 16px;
}

/* Launcher tiles, used by the tools page. */
.tile {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 14px;
	padding: 22px;
	border-radius: var(--r-lg);
	color: var(--ink);
	overflow: hidden;
	transition: transform 0.45s var(--ease-spring),
		background 0.4s var(--ease), border-color 0.4s var(--ease),
		box-shadow 0.4s var(--ease);
}

.tile-icon {
	display: grid;
	place-items: center;
	width: 46px;
	height: 46px;
	border-radius: var(--r-md);
	color: var(--ink-2);
	transition: color 0.35s var(--ease), background 0.35s var(--ease),
		transform 0.45s var(--ease-spring);
}

.tile-icon svg {
	width: 22px;
	height: 22px;
	fill: currentColor;
}

.tile b {
	font-size: 16.5px;
	font-weight: 600;
	letter-spacing: -0.02em;
}

.tile span {
	font-size: 13px;
	color: var(--ink-3);
	line-height: 1.5;
}

.tile-go {
	position: absolute;
	top: 20px;
	right: 20px;
	width: 15px;
	height: 15px;
	fill: var(--ink-3);
	opacity: 0;
	transform: translate(-6px, 6px);
	transition: opacity 0.3s var(--ease), transform 0.4s var(--ease-spring),
		fill 0.3s var(--ease);
}

#desktop .tile:hover {
	transform: translateY(-4px);
	background: var(--glass-bg-hover);
	border-color: var(--glass-border-hover);
	box-shadow: var(--glass-shadow-hover);
}

#desktop .tile:hover .tile-icon {
	color: var(--accent-ink);
	background: var(--accent-bg);
	transform: scale(1.06);
}

#desktop .tile:hover .tile-go,
.tile:focus-visible .tile-go {
	opacity: 1;
	transform: none;
	fill: var(--accent-ink);
}

/* --------------------------------------------------------------------------
   3. Forms
   -------------------------------------------------------------------------- */

.field {
	display: flex;
	flex-direction: column;
	gap: 7px;
}

.field label {
	font-family: var(--font-mono);
	font-size: 10.5px;
	letter-spacing: 0.17em;
	text-transform: uppercase;
	color: var(--ink-3);
}

.field input {
	width: 100%;
	height: 46px;
	padding: 0 14px;
	border-radius: var(--r-md);
	color: var(--ink);
	background: var(--glass-bg);
	border: 1px solid var(--glass-border);
	transition: border-color 0.3s var(--ease), background 0.3s var(--ease),
		box-shadow 0.3s var(--ease);
}

.field input::placeholder {
	color: var(--ink-3);
}

.field input:focus {
	outline: none;
	border-color: var(--accent-line);
	background: var(--glass-bg-strong);
	box-shadow: 0 0 0 3px var(--accent-bg);
}

/* Buttons reuse .btn from portfolio.css. The internal pages use a solid accent
   fill rather than the brand gradient, in both rest and hover. */
.btn--accent {
	color: var(--accent-fill-ink);
	background: var(--accent-fill);
}

#desktop .btn--accent:hover {
	background: var(--accent-fill);
	box-shadow: 0 10px 26px -12px var(--accent-glow);
	transform: translateY(-1px);
}

.btn--block {
	width: 100%;
}

.btn[disabled] {
	opacity: 0.6;
	pointer-events: none;
}

.btn .spinner {
	width: 16px;
	height: 16px;
	border-radius: 50%;
	border: 2px solid var(--hairline);
	border-top-color: currentColor;
	animation: spin 0.8s linear infinite;
	display: none;
}

.btn.loading .spinner {
	display: block;
}

.btn.loading svg {
	display: none;
}

/* --------------------------------------------------------------------------
   4. Code and key/value readouts
   -------------------------------------------------------------------------- */

.readout {
	display: block;
	padding: 14px 16px;
	border-radius: var(--r-md);
	font-family: var(--font-mono);
	font-size: 12.5px;
	line-height: 1.7;
	color: var(--ink-2);
	background: var(--glass-bg);
	border: 1px solid var(--hairline);
	word-break: break-all;
}

.qr-frame {
	display: grid;
	place-items: center;
	padding: 18px;
	border-radius: var(--r-md);
	background: var(--glass-bg);
	border: 1px solid var(--hairline);
}

.qr-frame svg,
.qr-frame img {
	width: 232px;
	height: 232px;
	display: block;
}

/* The generated QR paints white, which vanishes on a light background. */
html.light .qr-frame {
	background: #0a0e1c;
	border-color: #0a0e1c;
}

/* --------------------------------------------------------------------------
   5. Error page
   -------------------------------------------------------------------------- */

.error-card {
	max-width: 560px;
	padding: 40px;
	text-align: center;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 16px;
	border-radius: var(--r-xl);
}

.error-code {
	font-family: var(--font-mono);
	font-size: clamp(56px, 12vw, 88px);
	font-weight: 500;
	line-height: 1;
	letter-spacing: -0.04em;
}

.error-card h1 {
	font-size: 22px;
}

.error-card p {
	color: var(--ink-2);
	font-size: 16px;
	max-width: 42ch;
}

.error-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	justify-content: center;
	margin-top: 6px;
}

/* --------------------------------------------------------------------------
   6. Cookie notice

   XNotify writes inline styles onto the card, so the overrides it needs have
   to be flagged important to land.
   -------------------------------------------------------------------------- */

/* The container caps itself at the card's own width but still adds side
   padding, so the card overflows and gets clipped. Give the container the
   slack and let the card fill what is left. */
#x-notify-container {
	z-index: 320 !important;
	max-width: min(440px, 100vw) !important;
}

.x-notification {
	width: 100% !important;
	font-family: var(--font-sans) !important;
	color: var(--ink) !important;
	border-radius: var(--r-lg) !important;
	padding: 0 !important;
	background: var(--glass-bg-strong);
	border: 1px solid var(--glass-border);
	-webkit-backdrop-filter: blur(22px) saturate(185%);
	backdrop-filter: blur(22px) saturate(185%);
	box-shadow: var(--glass-shadow);
	animation: notify-in 0.55s var(--ease-spring) backwards;
}

@keyframes notify-in {
	from {
		opacity: 0;
		transform: translateY(14px) scale(0.97);
	}
}

.cookie-consent {
	padding: 22px;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	row-gap: 12px;
	color: var(--ink);
	text-align: left;
}

.cookie-consent h2 {
	margin: 0;
	font-size: 17px;
	font-weight: 600;
	letter-spacing: -0.02em;
}

.cookie-consent p {
	margin: 0;
	font-size: 13.5px;
	line-height: 1.6;
	color: var(--ink-2);
}

.cookie-consent div {
	display: flex;
	column-gap: 10px;
	margin-top: 6px;
	width: 100%;
}

.cookie-consent button {
	flex: 1;
	height: 40px;
	padding: 0 18px;
	border-radius: var(--r-pill);
	font-size: 13.5px;
	font-weight: 550;
	font-family: inherit;
	letter-spacing: -0.005em;
	cursor: pointer;
	color: var(--ink);
	background: var(--glass-bg);
	border: 1px solid var(--glass-border);
	transition: background 0.3s var(--ease), border-color 0.3s var(--ease),
		transform 0.35s var(--ease-spring), color 0.3s var(--ease);
}

/* Solid accent, no gradient, in either state. */
.cookie-consent button:last-of-type {
	color: var(--accent-fill-ink);
	background: var(--accent-fill);
	border-color: transparent;
}

#desktop .cookie-consent button:hover {
	background: var(--glass-bg-hover);
	border-color: var(--glass-border-hover);
	transform: translateY(-1px);
}

#desktop .cookie-consent button:last-of-type:hover {
	color: var(--accent-fill-ink);
	background: var(--accent-fill);
	border-color: transparent;
	box-shadow: 0 8px 22px -10px var(--accent-glow);
}

/* The section nav sits bottom centre on small screens, so lift the notice
   clear of it rather than letting the two overlap. */
@media screen and (max-width: 820px) {
	#x-notify-container {
		bottom: 86px !important;
	}
}

@media screen and (max-width: 560px) {
	#x-notify-container {
		max-width: 100vw !important;
		width: 100vw !important;
		padding-left: 14px !important;
		padding-right: 14px !important;
	}
}

/* --------------------------------------------------------------------------
   7. Responsive
   -------------------------------------------------------------------------- */

@media screen and (max-width: 700px) {
	.card {
		padding: 20px;
	}

	.tile-grid {
		grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
	}

	.error-card {
		padding: 28px;
	}
}
