/* ============================================================
   DEZACT tokens — design vocabulary. Loads first.
   ============================================================ */

/* ---- self-hosted fonts (see assets/fonts/README.txt) ---- */
@font-face {
	font-family: 'Space Grotesk';
	src: url('../fonts/SpaceGrotesk-Variable.woff2') format('woff2');
	font-weight: 300 700;
	font-display: swap;
}
@font-face {
	font-family: 'IBM Plex Mono';
	src: url('../fonts/IBMPlexMono-Regular.woff2') format('woff2');
	font-weight: 400;
	font-display: swap;
}
@font-face {
	font-family: 'IBM Plex Mono';
	src: url('../fonts/IBMPlexMono-Medium.woff2') format('woff2');
	font-weight: 500;
	font-display: swap;
}

:root {
	/* ---- material palette (from the built work: plaster, gloss acrylic, ink ribbon, oak) ---- */
	--dz-plaster:   #f4f2ee;
	--dz-gloss:     #fdfdfc;
	--dz-ink:       #141317;
	--dz-grey:      #56544f;
	--dz-grey-soft: #8f8d87;
	--dz-oak:       #b3925f;
	--dz-oak-deep:  #8a6b3c;
	--dz-oak-pale:  #e9dfc9;
	--dz-hairline:  rgba(20, 19, 23, .1);
	--dz-hairline-strong: rgba(20, 19, 23, .22);

	/* ---- material surfaces ---- */
	--dz-surface-gloss: linear-gradient(165deg, #ffffff 0%, #f3f1ec 60%, #edeae3 100%);
	--dz-surface-shell: linear-gradient(168deg, #ffffff 0%, #f7f5f1 48%, #edeae3 100%);
	--dz-surface-oak:   linear-gradient(105deg, #d5bd93, #b3925f 58%, #9c7c4c);
	--dz-sheen: inset 0 1px 0 #fff;
	--dz-shadow-shelf: 0 22px 30px -22px rgba(20, 19, 23, .5);
	--dz-shadow-hover: 0 24px 44px -28px rgba(20, 19, 23, .5);
	--dz-light-line: linear-gradient(90deg, transparent, rgba(255, 255, 255, .95), transparent);
	--dz-light-glow: 0 0 18px rgba(255, 255, 255, .7);

	/* ---- curve vocabulary ---- */
	--dz-r-blade:  999px;                 /* rows, chips, buttons, nav */
	--dz-r-sweep:  0 120px 0 0;           /* figures, teasers (one swept corner) */
	--dz-r-sweep-size: 120px;
	--dz-r-shell:  0 0 280px 0;           /* hero / big section shells */
	--dz-r-shell-size: 280px;
	--dz-r-plinth: 0 90px 0 90px;         /* recessed archive fields */

	/* ---- type ---- */
	--dz-font-sans: 'Space Grotesk', 'Helvetica Neue', Helvetica, Arial,
	                'PingFang TC', 'Noto Sans TC', 'Microsoft JhengHei', sans-serif;
	--dz-font-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Consolas, monospace;
	--dz-track-wordmark: .42em;
	--dz-track-label: .18em;

	/* ---- motion ---- */
	--dz-ease: cubic-bezier(.22, 1, .36, 1);
	--dz-speed: .4s;

	/* ---- rhythm ---- */
	--dz-gutter: clamp(20px, 4vw, 56px);
	--dz-section: clamp(56px, 8vw, 110px);
}

/* ---- motion keyframes (consumed by components.css / site.css) ---- */
@keyframes dz-rise {
	from { opacity: 0; transform: translateY(46px); }
}
@keyframes dz-aperture {
	from { clip-path: inset(14% 10% 14% 10% round 999px); opacity: .4; }
	to   { clip-path: inset(0 0 0 0 round 0); }
}
@keyframes dz-marquee {
	to { transform: translateX(-50%); }
}
@keyframes dz-pulse {
	50% { opacity: .25; }
}

@keyframes dz-unfold {
	0%   { transform: perspective(1300px) translateY(44vh) rotateX(74deg); opacity: .5; }
	55%  { transform: perspective(1300px) translateY(5vh) rotateX(56deg); opacity: 1; }
	100% { transform: perspective(1300px) translateY(0) rotateX(0deg); opacity: 1; }
}
@keyframes dz-unfold-shade {
	from { opacity: 1; }
	to   { opacity: 0; }
}

/* ---- global kill-switch ---- */
@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after {
		animation-duration: .01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: .01ms !important;
		animation-timeline: auto !important;
	}
}
