/* telli-design — gemeinsame Basis-Komponenten (App-Shell, Liquid-Blobs,
   Intro-Schriftzug, Glass-Panels, Buttons, Formulare, Toasts, Footer).
   Produkt-spezifisches CSS (Dropzone, Player, Admin-Dashboard, ...) lebt
   in der jeweiligen App und baut auf diesen Klassen auf, statt sie zu
   duplizieren. Setzt tokens.css voraus. */

/* ---------- liquid background ---------- */

.liquid-bg {
	position: fixed;
	inset: 0;
	z-index: -2;
	overflow: hidden;
	background: radial-gradient(120% 120% at 20% 10%, var(--canvas-deep), var(--canvas) 60%);
	transition: filter 0.6s ease;
}

.blob-parallax {
	position: absolute;
	inset: 0;
	transform: translate3d(calc(var(--mx) * var(--depth)), calc(var(--my) * var(--depth)), 0);
	transition: transform 0.6s var(--ease-settle);
	will-change: transform;
}

.blob {
	position: absolute;
	border-radius: 42% 58% 61% 39% / 45% 42% 58% 55%;
	filter: blur(60px);
	opacity: 0.55;
	will-change: transform, border-radius;
	mix-blend-mode: screen;
}

.blob-a {
	width: 60vmax;
	height: 60vmax;
	left: -18vmax;
	top: -14vmax;
	background: radial-gradient(circle at 35% 35%, var(--blob-copper), transparent 72%);
	animation: drift-a var(--blob-duration-a) ease-in-out infinite;
}

.blob-b {
	width: 54vmax;
	height: 54vmax;
	right: -16vmax;
	top: 8vmax;
	background: radial-gradient(circle at 60% 40%, var(--blob-sage), transparent 70%);
	animation: drift-b var(--blob-duration-b) ease-in-out infinite;
}

.blob-c {
	width: 46vmax;
	height: 46vmax;
	left: 18vmax;
	bottom: -20vmax;
	background: radial-gradient(circle at 50% 50%, var(--blob-slate), transparent 75%);
	opacity: 0.7;
	animation: drift-c var(--blob-duration-c) ease-in-out infinite;
}

@keyframes drift-a {
	0% {
		transform: translate(0, 0) scale(1);
		border-radius: 42% 58% 61% 39% / 45% 42% 58% 55%;
	}
	33% {
		transform: translate(8vw, 6vh) scale(1.08);
		border-radius: 55% 45% 40% 60% / 60% 55% 45% 40%;
	}
	66% {
		transform: translate(-4vw, 9vh) scale(0.96);
		border-radius: 38% 62% 55% 45% / 40% 60% 40% 60%;
	}
	100% {
		transform: translate(0, 0) scale(1);
		border-radius: 42% 58% 61% 39% / 45% 42% 58% 55%;
	}
}

@keyframes drift-b {
	0% {
		transform: translate(0, 0) scale(1);
		border-radius: 50% 50% 40% 60% / 55% 45% 55% 45%;
	}
	40% {
		transform: translate(-7vw, 8vh) scale(1.1);
		border-radius: 40% 60% 55% 45% / 45% 55% 40% 60%;
	}
	75% {
		transform: translate(5vw, -4vh) scale(0.94);
		border-radius: 58% 42% 48% 52% / 50% 50% 60% 40%;
	}
	100% {
		transform: translate(0, 0) scale(1);
		border-radius: 50% 50% 40% 60% / 55% 45% 55% 45%;
	}
}

@keyframes drift-c {
	0% {
		transform: translate(0, 0) scale(1);
	}
	50% {
		transform: translate(6vw, -8vh) scale(1.12);
		border-radius: 60% 40% 45% 55% / 40% 60% 55% 45%;
	}
	100% {
		transform: translate(0, 0) scale(1);
	}
}

/* Produkte können über eine eigene body-Klasse (z.B. "upload-active",
   "scanning-active") --blob-duration-* kurzzeitig verkürzen, um während
   einer laufenden Aktion mehr Bewegung zu zeigen – siehe README. */

@media (prefers-reduced-motion: reduce) {
	.blob {
		animation: none !important;
	}
}

.grain {
	position: fixed;
	inset: 0;
	z-index: -1;
	pointer-events: none;
	opacity: 0.18;
	mix-blend-mode: overlay;
	background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
	background-size: 160px 160px;
}

/* ---------- layout ---------- */

.app-shell {
	position: relative;
	z-index: 1;
	max-width: 640px;
	margin: 0 auto;
	padding: clamp(var(--space-6), 5vw, var(--space-16)) var(--space-4) var(--space-16);
	display: flex;
	flex-direction: column;
	gap: var(--space-6);
	perspective: 900px;
}

.app-shell-wide {
	max-width: 880px;
}

.app-header {
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
	margin-bottom: var(--space-2);
}

.wordmark {
	display: inline-flex;
	font-size: 1.5rem;
	font-weight: 700;
	letter-spacing: -0.02em;
	text-decoration: none;
	color: var(--text);
	view-transition-name: wordmark;
}

.wm-letter,
.wm-dot {
	display: inline-block;
}

.wm-dot {
	color: var(--accent-strong);
}

/* ---------- intro: wordmark entrance ---------- */

html.js .wm-enter {
	opacity: 0;
	transform: translateY(8px);
	animation: wm-short-in 0.42s var(--ease-overshoot) forwards;
	animation-delay: 60ms;
}

@keyframes wm-short-in {
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

/* ---------- intro: full overlay (index, first visit per session) ---------- */

.intro-overlay {
	position: fixed;
	inset: 0;
	z-index: 50;
	display: none;
	align-items: center;
	justify-content: center;
	background: var(--canvas);
	pointer-events: none;
}

html.intro-full .intro-overlay {
	display: flex;
	pointer-events: auto;
	cursor: pointer;
}

.wordmark-intro {
	display: inline-flex;
	font-size: clamp(2.25rem, 11vw, 5.5rem);
	font-weight: 700;
	letter-spacing: -0.02em;
	color: var(--text);
	transform-origin: center center;
	will-change: transform;
}

html.intro-full .intro-overlay .wm-letter,
html.intro-full .intro-overlay .wm-dot {
	opacity: 0;
	transform: translateY(18px);
	filter: blur(8px);
}

html.intro-full .intro-overlay.animate .wm-letter {
	animation: intro-letter-in 0.5s var(--ease-overshoot) forwards;
	animation-delay: calc(var(--i) * 45ms);
}

html.intro-full .intro-overlay.animate .wm-dot {
	animation:
		intro-letter-in 0.5s var(--ease-overshoot) forwards calc(var(--i) * 45ms),
		intro-dot-glow 0.6s ease-out forwards calc(var(--i) * 45ms + 260ms);
}

@keyframes intro-letter-in {
	to {
		opacity: 1;
		transform: translateY(0);
		filter: blur(0);
	}
}

@keyframes intro-dot-glow {
	0% {
		filter: drop-shadow(0 0 0 transparent);
	}
	45% {
		filter: drop-shadow(0 0 16px var(--accent-strong));
	}
	100% {
		filter: drop-shadow(0 0 0 transparent);
	}
}

/* FLIP: der Zielwert (--flip-x/--flip-y/--flip-scale) wird per JS aus
   getBoundingClientRect() von Overlay- und Header-Schriftzug berechnet,
   damit die Zielposition bei jeder Fenstergröße exakt stimmt (siehe
   base.js: runIntro). */
html.intro-full .intro-overlay.flip .wordmark-intro {
	transition: transform 0.6s var(--ease-settle);
	transform: translate(var(--flip-x, 0px), var(--flip-y, 0px)) scale(var(--flip-scale, 1));
}

/* Der echte Header-Schriftzug bleibt unsichtbar (aber im Layout
   gemessen), bis das FLIP angekommen ist – verhindert die doppelte
   Animation (große Overlay-Version + eigene Kurzvariante). */
html.intro-full #header-wordmark.wm-enter {
	opacity: 0;
	animation: none;
}

html.intro-full #header-wordmark.wm-revealed {
	opacity: 1;
}

/* ---------- generic sequential entrance ---------- */

html.js .seq-enter {
	opacity: 0;
	transform: translateY(10px);
	animation: seq-in 0.45s var(--ease-settle) forwards;
	animation-delay: calc(var(--seq, 0) * 90ms + 60ms);
}

@keyframes seq-in {
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

.tagline {
	color: var(--text-dim);
	font-size: var(--text-sm);
}

.hint {
	color: var(--text-dim);
	font-size: var(--text-xs);
}

/* ---------- footer + language switch ---------- */

.site-footer {
	margin-top: var(--space-4);
	text-align: center;
	color: var(--text-dim);
	font-size: var(--text-xs);
}

.footer-link {
	color: var(--text-dim);
	text-decoration: underline;
	text-decoration-color: rgba(255, 255, 255, 0.25);
	text-underline-offset: 2px;
}

.footer-link:hover {
	color: var(--text);
	text-decoration-color: var(--accent-strong);
}

.lang-switch {
	display: flex;
	justify-content: center;
	gap: var(--space-2);
	margin-top: var(--space-2);
}

.lang-switch-link {
	color: var(--text-dim);
	text-decoration: none;
}

.lang-switch-link:hover {
	color: var(--text);
}

.lang-switch-link.is-active {
	color: var(--accent-strong);
	font-weight: 600;
}

/* ---------- legal / text pages ---------- */

.legal-content {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
}

.legal-content h2 {
	margin: var(--space-6) 0 0;
	font-size: var(--text-base);
	font-weight: 600;
}

.legal-content h2:first-child {
	margin-top: 0;
}

.legal-content p,
.legal-content ul {
	margin: 0;
	color: var(--text-dim);
	font-size: var(--text-sm);
	line-height: 1.6;
}

.legal-content ul {
	padding-left: var(--space-6);
}

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

.glass-panel {
	position: relative;
	background: linear-gradient(155deg, var(--glass-fill-strong), var(--glass-fill));
	border: 1px solid var(--glass-border);
	border-radius: var(--radius-lg);
	backdrop-filter: blur(22px) saturate(150%);
	-webkit-backdrop-filter: blur(22px) saturate(150%);
	box-shadow:
		0 1px 0 rgba(255, 255, 255, 0.08) inset,
		0 20px 60px -20px rgba(0, 0, 0, 0.55);
	padding: clamp(1.5rem, 4vw, 2.5rem);
	transition: border-color 0.35s ease, box-shadow 0.35s ease;
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
	.glass-panel {
		background: rgba(26, 28, 30, 0.94);
	}
}

html.js .glass-panel.panel-enter {
	opacity: 0;
	transform: translateY(14px);
	filter: blur(6px);
	animation: panel-in 0.5s var(--ease-settle) forwards;
	animation-delay: calc(var(--seq, 0) * 90ms + 60ms);
}

@keyframes panel-in {
	to {
		opacity: 1;
		transform: translateY(0);
		filter: blur(0);
	}
}

.panel-title {
	margin: 0 0 var(--space-6);
	font-size: var(--text-lg);
	font-weight: 600;
}

.form-error {
	color: var(--accent-strong);
	font-size: var(--text-sm);
}

/* Generischer Fehler-Shake für jedes Glass-Panel (Login, Passwort, ...). */
.shake-on-error {
	animation: shake-x 0.4s var(--ease-settle);
}

@keyframes shake-x {
	0%,
	100% {
		transform: translateX(0);
	}
	20% {
		transform: translateX(-8px);
	}
	40% {
		transform: translateX(6px);
	}
	60% {
		transform: translateX(-4px);
	}
	80% {
		transform: translateX(2px);
	}
}

/* ---------- form controls ---------- */

.options-grid {
	display: grid;
	gap: var(--space-4);
	margin-bottom: var(--space-6);
}

.field {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
}

.field-checkbox {
	flex-direction: row;
	align-items: center;
	gap: var(--space-2);
}

.field-label {
	font-size: var(--text-xs);
	color: var(--text-dim);
}

.input {
	background: rgba(0, 0, 0, 0.22);
	border: 1px solid var(--glass-border);
	border-radius: var(--radius-sm);
	color: var(--text);
	padding: var(--space-3);
	font: inherit;
	font-size: var(--text-sm);
	transition: border-color 0.2s ease;
}

.input:focus {
	outline: none;
	border-color: var(--accent-strong);
	box-shadow: 0 0 0 3px rgba(232, 160, 111, 0.35);
}

.field-checkbox .input,
.field-checkbox input[type="checkbox"] {
	width: 1.1rem;
	height: 1.1rem;
	accent-color: var(--accent);
}

.input-link {
	flex: 1;
	min-width: 0;
	font-family: "Space Grotesk", monospace;
}

.password-form {
	display: flex;
	gap: var(--space-3);
	margin-top: var(--space-4);
}

.password-form .input {
	flex: 1;
}

/* ---------- buttons ---------- */

.btn {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-2);
	border: 1px solid transparent;
	border-radius: var(--radius-sm);
	padding: var(--space-3) var(--space-6);
	font: inherit;
	font-weight: 600;
	font-size: var(--text-sm);
	text-decoration: none;
	cursor: pointer;
	transition: transform 0.2s var(--ease-settle), background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}

.btn:hover {
	transform: translateY(-2px);
}

.btn:active {
	transform: scale(0.97);
}

.btn:focus-visible {
	outline: none;
	box-shadow: 0 0 0 3px rgba(232, 160, 111, 0.45);
}

.btn-primary {
	background: linear-gradient(135deg, var(--accent-strong), var(--blob-copper));
	color: #1a1310;
}

.btn-primary:hover {
	filter: brightness(1.08);
}

.btn-sheen {
	overflow: hidden;
}

.btn-sheen::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(115deg, transparent 30%, rgba(255, 255, 255, 0.4) 48%, transparent 66%);
	background-size: 220% 100%;
	background-position: 150% 0;
	pointer-events: none;
}

html.js .btn-sheen::after {
	animation: btn-sheen-sweep 4.5s ease-in-out infinite;
}

@keyframes btn-sheen-sweep {
	0%,
	55% {
		background-position: 150% 0;
	}
	85% {
		background-position: -50% 0;
	}
	100% {
		background-position: -50% 0;
	}
}

.btn-ghost {
	background: transparent;
	border-color: var(--glass-border);
	color: var(--text);
}

.btn-ghost:hover {
	border-color: var(--glass-border-active);
}

.btn-danger {
	background: color-mix(in srgb, var(--danger) 12%, transparent);
	border-color: color-mix(in srgb, var(--danger) 50%, transparent);
	color: var(--danger-strong);
}

.btn-danger:hover {
	border-color: color-mix(in srgb, var(--danger) 85%, transparent);
	box-shadow: 0 0 0 1px color-mix(in srgb, var(--danger) 50%, transparent), 0 14px 34px -16px color-mix(in srgb, var(--danger) 60%, transparent);
}

.btn-danger:focus-visible {
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 45%, transparent);
}

.btn-disabled {
	opacity: 0.45;
	cursor: not-allowed;
	pointer-events: none;
}

.btn-small {
	padding: var(--space-2) var(--space-4);
	font-size: var(--text-xs);
	flex-shrink: 0;
}

.actions-row {
	display: flex;
	justify-content: flex-end;
	gap: 0.75rem;
}

/* ---------- progress bar ---------- */

.progress-track {
	position: relative;
	height: 10px;
	border-radius: 999px;
	background: rgba(255, 255, 255, 0.08);
	overflow: hidden;
}

.progress-fill {
	position: absolute;
	inset: 0 auto 0 0;
	width: 0%;
	border-radius: 999px;
	background: linear-gradient(90deg, var(--blob-copper), var(--accent-strong));
	box-shadow: 0 0 12px 1px rgba(232, 160, 111, 0.55);
	transition: width 0.25s var(--ease-settle);
}

.progress-fill::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, 0.35) 50%, transparent 70%);
	background-size: 200% 100%;
	animation: shimmer 1.6s linear infinite;
}

@keyframes shimmer {
	from {
		background-position: 200% 0;
	}
	to {
		background-position: -200% 0;
	}
}

.progress-stats {
	display: flex;
	justify-content: space-between;
	gap: var(--space-3);
	margin: var(--space-3) 0 0;
	color: var(--text-dim);
	font-size: var(--text-xs);
}

/* ---------- file-type icons (siehe telli-design/icons) ---------- */

.file-icon {
	flex-shrink: 0;
	color: var(--text-dim);
	vertical-align: -4px;
}

.name-with-icon {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	min-width: 0;
}

.name-with-icon span {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* ---------- toasts ---------- */

.toast-container {
	position: fixed;
	z-index: 200;
	right: var(--space-6);
	bottom: var(--space-6);
	display: flex;
	flex-direction: column-reverse;
	gap: var(--space-2);
	max-width: min(360px, calc(100vw - var(--space-8)));
}

.toast {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	padding: var(--space-3) var(--space-4);
	border-radius: var(--radius-md);
	background: linear-gradient(155deg, var(--glass-fill-strong), var(--glass-fill));
	border: 1px solid var(--glass-border);
	backdrop-filter: blur(22px) saturate(150%);
	-webkit-backdrop-filter: blur(22px) saturate(150%);
	box-shadow: 0 12px 34px -16px rgba(0, 0, 0, 0.6);
	font-size: var(--text-sm);
	color: var(--text);
	animation: toast-in 0.3s var(--ease-settle);
}

.toast.toast-error {
	border-color: color-mix(in srgb, var(--danger) 50%, transparent);
}

.toast-close {
	margin-left: auto;
	background: none;
	border: none;
	color: var(--text-dim);
	cursor: pointer;
	font-size: 1.1rem;
	line-height: 1;
	padding: 0 var(--space-1);
}

.toast.is-leaving {
	animation: toast-out 0.25s ease-in forwards;
}

@keyframes toast-in {
	from {
		opacity: 0;
		transform: translateY(12px);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

@keyframes toast-out {
	to {
		opacity: 0;
		transform: translateY(8px);
	}
}

@media (max-width: 600px) {
	.toast-container {
		left: var(--space-4);
		right: var(--space-4);
		bottom: var(--space-4);
		max-width: none;
		align-items: center;
	}
}

@media (prefers-reduced-motion: reduce) {
	.toast {
		animation: none !important;
	}
}

/* ---------- responsive ---------- */

@media (max-width: 480px) {
	.actions-row {
		flex-direction: column-reverse;
	}

	.actions-row .btn {
		width: 100%;
	}

	.password-form {
		flex-direction: column;
	}
}

/* ---------- view transitions (progressive enhancement) ---------- */

@view-transition {
	navigation: auto;
}

::view-transition-old(root),
::view-transition-new(root) {
	animation-duration: 0.35s;
	animation-timing-function: var(--ease-settle);
}

/* ---------- reduced motion: collapse everything to a simple fade ---------- */

@media (prefers-reduced-motion: reduce) {
	html.intro-full .intro-overlay {
		display: none !important;
	}

	.wm-letter,
	.wm-dot,
	.wm-enter,
	.seq-enter,
	.glass-panel.panel-enter,
	.btn-sheen::after,
	.blob-parallax,
	.shake-on-error {
		animation: none !important;
		transition: none !important;
		opacity: 1 !important;
		transform: none !important;
		filter: none !important;
	}

	.progress-fill,
	.btn,
	.input {
		transition-duration: 0.01ms !important;
	}
}
