/* =============================================================================
   TinySpacer — global.css
   -----------------------------------------------------------------------------
   The reusable global design system. Tokens + primitives + components +
   utilities used by every page of the site.

   Principles:
     • Mobile-first (min-width media queries only).
     • Token-driven (change a value once, propagate everywhere).
     • Framework-free (no Bootstrap, Tailwind, jQuery, page builders).
     • Performance-first (system-font fallbacks, minimal animation, no @import).
     • Accessible by default (focus-visible rings, reduced-motion, color contrast).

   Table of contents:
     1.  Design Tokens (:root custom properties)
     2.  Fluid Typography Scale
     3.  Layout — Container
     4.  Layout — Grid System
     5.  Layout — Section & Stack Spacing
     6.  Buttons
     7.  Cards
     8.  Links (component variants)
     9.  Forms & Inputs
     10. Badges & Tags
     11. Animations (minimal)
     12. Accessibility Helpers
     13. Utility Classes
   ========================================================================== */

/* =============================================================================
   1. DESIGN TOKENS
   ========================================================================== */

:root {
	/* ---- Brand Color Primitives -------------------------------------------- */
	--ts-sage:        #7D9D78; /* Primary */
	--ts-ink:         #2F2F2F; /* Text */
	--ts-cream:       #FAF8F5; /* Background */
	--ts-sand:        #E8DFCF; /* Border */
	--ts-white:       #FFFFFF;

	/* Derived tints/shades (kept explicit for predictable rendering). */
	--ts-sage-600:    #6B8A66;
	--ts-sage-700:    #587355;
	--ts-sage-100:    #EDF2EC;
	--ts-sage-050:    #F5F8F4;
	--ts-sand-light:  #F1EAdd;
	--ts-ink-600:     #5A5A5A;
	--ts-ink-400:     #8A8A8A;

	/* ---- Semantic Colors --------------------------------------------------- */
	--ts-color-primary:        var(--ts-sage);
	--ts-color-primary-hover:  var(--ts-sage-600);
	--ts-color-primary-active: var(--ts-sage-700);
	--ts-color-primary-soft:   var(--ts-sage-100);

	--ts-color-bg:             var(--ts-cream);
	--ts-color-surface:        var(--ts-white);
	--ts-color-surface-alt:    var(--ts-sage-050);

	--ts-color-text:           var(--ts-ink);
	--ts-color-text-muted:     var(--ts-ink-600);
	--ts-color-text-subtle:    var(--ts-ink-400);
	--ts-color-heading:        var(--ts-ink);
	--ts-color-on-primary:     var(--ts-white);

	--ts-color-border:         var(--ts-sand);
	--ts-color-border-strong:  color-mix(in srgb, var(--ts-sand) 70%, var(--ts-ink));

	--ts-color-link:           var(--ts-sage-700);
	--ts-color-link-hover:     var(--ts-sage-600);

	/* Feedback (used by form validation + notices). */
	--ts-color-success:        #5B8C5A;
	--ts-color-error:          #B4544A;
	--ts-color-error-soft:     #F7E9E7;

	/* Focus ring — high-contrast against both cream and sage surfaces. */
	--ts-color-focus:          var(--ts-sage-700);

	/* ---- Typography -------------------------------------------------------- */
	--ts-font-heading: "Poppins", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
	--ts-font-body:    "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
	--ts-font-mono:    ui-monospace, "SFMono-Regular", "Menlo", "Consolas", monospace;

	/* Font weights. */
	--ts-weight-regular:  400;
	--ts-weight-medium:   500;
	--ts-weight-semibold: 600;
	--ts-weight-bold:     700;

	/* Line heights. */
	--ts-leading-tight:   1.2;
	--ts-leading-snug:    1.35;
	--ts-leading-normal:  1.6;
	--ts-leading-relaxed: 1.75;

	/* Letter spacing. */
	--ts-tracking-tight:  -0.015em;
	--ts-tracking-normal: 0;
	--ts-tracking-wide:   0.04em;
	--ts-tracking-caps:   0.08em;

	/* Fluid type scale (see section 2 for the clamp() definitions). */
	--ts-text-xs:   0.75rem;   /* 12px */
	--ts-text-sm:   0.875rem;  /* 14px */
	--ts-text-base: 1rem;      /* 16px */

	/* ---- Spacing Scale (4px base, rem-based) ------------------------------- */
	--ts-space-0:  0;
	--ts-space-1:  0.25rem;  /* 4px  */
	--ts-space-2:  0.5rem;   /* 8px  */
	--ts-space-3:  0.75rem;  /* 12px */
	--ts-space-4:  1rem;     /* 16px */
	--ts-space-5:  1.5rem;   /* 24px */
	--ts-space-6:  2rem;     /* 32px */
	--ts-space-7:  2.5rem;   /* 40px */
	--ts-space-8:  3rem;     /* 48px */
	--ts-space-10: 4rem;     /* 64px */
	--ts-space-12: 5rem;     /* 80px */
	--ts-space-16: 7rem;     /* 112px */

	/* Fluid section padding — grows with viewport, mobile-first. */
	--ts-section-y:       clamp(2.5rem, 6vw, 5.5rem);
	--ts-section-y-sm:    clamp(1.75rem, 4vw, 3.5rem);
	--ts-section-y-lg:    clamp(3.5rem, 9vw, 8rem);

	/* ---- Layout ------------------------------------------------------------ */
	--ts-container-max:   1200px;
	--ts-container-wide:  1360px;
	--ts-container-narrow: 760px; /* Ideal reading measure for articles. */
	--ts-gutter:          clamp(1rem, 4vw, 2.5rem);
	--ts-grid-gap:        clamp(1rem, 2.5vw, 2rem);

	/* ---- Border Radius (soft, Scandinavian) -------------------------------- */
	--ts-radius-sm:   6px;
	--ts-radius-md:   12px;
	--ts-radius-lg:   18px;
	--ts-radius-xl:   28px;
	--ts-radius-pill: 999px;
	--ts-radius-circle: 50%;

	/* ---- Shadows (soft, low-contrast, premium) ----------------------------- */
	--ts-shadow-xs: 0 1px 2px rgba(47, 47, 47, 0.04);
	--ts-shadow-sm: 0 2px 8px rgba(47, 47, 47, 0.05);
	--ts-shadow-md: 0 6px 20px rgba(47, 47, 47, 0.07);
	--ts-shadow-lg: 0 14px 40px rgba(47, 47, 47, 0.09);
	--ts-shadow-focus: 0 0 0 3px var(--ts-color-bg), 0 0 0 5px var(--ts-color-focus);

	/* ---- Motion ------------------------------------------------------------ */
	--ts-transition-fast: 120ms ease;
	--ts-transition-base: 200ms ease;
	--ts-transition-slow: 320ms cubic-bezier(0.22, 1, 0.36, 1);
	--ts-ease-out: cubic-bezier(0.22, 1, 0.36, 1);

	/* ---- Z-index scale ----------------------------------------------------- */
	--ts-z-base:    1;
	--ts-z-header:  100;
	--ts-z-overlay: 500;
	--ts-z-modal:   1000;
	--ts-z-toast:   1500;
}

/* =============================================================================
   2. FLUID TYPOGRAPHY SCALE
   -----------------------------------------------------------------------------
   Type sizes use clamp() so they scale smoothly between mobile and desktop
   without layout-shifting breakpoints. Perfect-fourth-ish ratio.
   ========================================================================== */

:root {
	--ts-text-lg:   clamp(1.0625rem, 1rem + 0.3vw, 1.1875rem);  /* ~17–19px */
	--ts-text-xl:   clamp(1.25rem, 1.15rem + 0.5vw, 1.5rem);    /* ~20–24px */
	--ts-text-2xl:  clamp(1.5rem, 1.3rem + 1vw, 2rem);          /* ~24–32px */
	--ts-text-3xl:  clamp(1.875rem, 1.55rem + 1.6vw, 2.75rem);  /* ~30–44px */
	--ts-text-4xl:  clamp(2.25rem, 1.8rem + 2.4vw, 3.5rem);     /* ~36–56px */
	--ts-text-5xl:  clamp(2.75rem, 2rem + 3.6vw, 4.5rem);       /* ~44–72px */
}

/* Default heading sizes (can be overridden by .ts-h* utilities). */
h1,
.ts-h1 {
	font-size: var(--ts-text-4xl);
}

h2,
.ts-h2 {
	font-size: var(--ts-text-3xl);
}

h3,
.ts-h3 {
	font-size: var(--ts-text-2xl);
}

h4,
.ts-h4 {
	font-size: var(--ts-text-xl);
}

h5,
.ts-h5 {
	font-size: var(--ts-text-lg);
}

h6,
.ts-h6 {
	font-size: var(--ts-text-base);
	text-transform: uppercase;
	letter-spacing: var(--ts-tracking-caps);
	color: var(--ts-color-text-muted);
}

/* Oversized hero/display heading. */
.ts-display {
	font-family: var(--ts-font-heading);
	font-weight: var(--ts-weight-bold);
	font-size: var(--ts-text-5xl);
	line-height: var(--ts-leading-tight);
	letter-spacing: var(--ts-tracking-tight);
}

/* Lead paragraph — intro copy under a heading. */
.ts-lead {
	font-size: var(--ts-text-xl);
	line-height: var(--ts-leading-snug);
	color: var(--ts-color-text-muted);
	font-weight: var(--ts-weight-regular);
}

/* Eyebrow / kicker label above a heading. */
.ts-eyebrow {
	display: inline-block;
	font-family: var(--ts-font-heading);
	font-size: var(--ts-text-sm);
	font-weight: var(--ts-weight-medium);
	text-transform: uppercase;
	letter-spacing: var(--ts-tracking-caps);
	color: var(--ts-color-primary);
}

.ts-muted {
	color: var(--ts-color-text-muted);
}

/* =============================================================================
   3. LAYOUT — CONTAINER
   ========================================================================== */

.ts-container {
	width: 100%;
	max-width: var(--ts-container-max);
	margin-inline: auto;
	padding-inline: var(--ts-gutter);
}

.ts-container--wide {
	max-width: var(--ts-container-wide);
}

.ts-container--narrow {
	max-width: var(--ts-container-narrow);
}

.ts-container--fluid {
	max-width: none;
}

/* =============================================================================
   4. LAYOUT — GRID SYSTEM
   -----------------------------------------------------------------------------
   A lightweight, auto-responsive grid. Two flavours:
     • .ts-grid + .ts-grid--cols-N : explicit columns that collapse on mobile.
     • .ts-grid--auto : intrinsic auto-fill grid (great for card/pin walls).
   ========================================================================== */

.ts-grid {
	display: grid;
	gap: var(--ts-grid-gap);
	grid-template-columns: 1fr;
}

/* Auto-responsive: fills as many columns as fit at the given min width. */
.ts-grid--auto {
	grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--ts-grid-min, 260px)), 1fr));
}

.ts-grid--min-sm { --ts-grid-min: 200px; }
.ts-grid--min-md { --ts-grid-min: 280px; }
.ts-grid--min-lg { --ts-grid-min: 340px; }

/* Explicit column counts — mobile stacks to 1, expands from 640px up. */
@media (min-width: 40em) { /* 640px */
	.ts-grid--cols-2 { grid-template-columns: repeat(2, 1fr); }
	.ts-grid--cols-3 { grid-template-columns: repeat(2, 1fr); }
	.ts-grid--cols-4 { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 64em) { /* 1024px */
	.ts-grid--cols-3 { grid-template-columns: repeat(3, 1fr); }
	.ts-grid--cols-4 { grid-template-columns: repeat(4, 1fr); }
}

/* Column span helpers (opt-in on wider screens). */
@media (min-width: 64em) {
	.ts-col-span-2 { grid-column: span 2; }
	.ts-col-span-3 { grid-column: span 3; }
	.ts-col-span-full { grid-column: 1 / -1; }
}

/* Content + sidebar layout (article template). */
.ts-layout-sidebar {
	display: grid;
	gap: var(--ts-space-8);
	grid-template-columns: 1fr;
}

@media (min-width: 64em) {
	.ts-layout-sidebar {
		grid-template-columns: minmax(0, 1fr) clamp(260px, 26%, 340px);
		gap: var(--ts-space-10);
	}
}

/* =============================================================================
   5. LAYOUT — SECTION & STACK SPACING
   ========================================================================== */

.ts-section {
	padding-block: var(--ts-section-y);
}

.ts-section--sm { padding-block: var(--ts-section-y-sm); }
.ts-section--lg { padding-block: var(--ts-section-y-lg); }

.ts-section--surface { background-color: var(--ts-color-surface); }
.ts-section--alt     { background-color: var(--ts-color-surface-alt); }

/* Owl-selector vertical rhythm: consistent gaps between direct children. */
.ts-stack > * + * {
	margin-block-start: var(--ts-stack-gap, var(--ts-space-4));
}

.ts-stack--xs > * + * { --ts-stack-gap: var(--ts-space-2); }
.ts-stack--sm > * + * { --ts-stack-gap: var(--ts-space-3); }
.ts-stack--md > * + * { --ts-stack-gap: var(--ts-space-5); }
.ts-stack--lg > * + * { --ts-stack-gap: var(--ts-space-7); }
.ts-stack--xl > * + * { --ts-stack-gap: var(--ts-space-10); }

/* Centered section intro block with a constrained measure. */
.ts-section-head {
	max-width: 62ch;
	margin-inline: auto;
	text-align: center;
}

/* Cluster: horizontal wrap group (tags, meta, button rows). */
.ts-cluster {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--ts-cluster-gap, var(--ts-space-3));
}

/* =============================================================================
   6. BUTTONS
   ========================================================================== */

.ts-btn {
	--_btn-bg: var(--ts-color-primary);
	--_btn-fg: var(--ts-color-on-primary);
	--_btn-border: transparent;

	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--ts-space-2);
	padding: 0.75rem 1.5rem;
	font-family: var(--ts-font-heading);
	font-size: var(--ts-text-base);
	font-weight: var(--ts-weight-medium);
	line-height: 1.1;
	text-align: center;
	text-decoration: none;
	white-space: nowrap;
	color: var(--_btn-fg);
	background-color: var(--_btn-bg);
	border: 1.5px solid var(--_btn-border);
	border-radius: var(--ts-radius-pill);
	cursor: pointer;
	user-select: none;
	transition: background-color var(--ts-transition-base),
		color var(--ts-transition-base),
		border-color var(--ts-transition-base),
		transform var(--ts-transition-fast),
		box-shadow var(--ts-transition-base);
}

.ts-btn:hover {
	background-color: var(--ts-color-primary-hover);
	color: var(--ts-color-on-primary);
	transform: translateY(-1px);
	box-shadow: var(--ts-shadow-sm);
}

.ts-btn:active {
	background-color: var(--ts-color-primary-active);
	transform: translateY(0);
	box-shadow: none;
}

/* Secondary — outlined on cream. */
.ts-btn--secondary {
	--_btn-bg: transparent;
	--_btn-fg: var(--ts-color-primary-active);
	--_btn-border: var(--ts-color-primary);
}

.ts-btn--secondary:hover {
	background-color: var(--ts-color-primary-soft);
	color: var(--ts-color-primary-active);
}

/* Ghost — text-like button for low-emphasis actions. */
.ts-btn--ghost {
	--_btn-bg: transparent;
	--_btn-fg: var(--ts-color-text);
	--_btn-border: transparent;
}

.ts-btn--ghost:hover {
	background-color: var(--ts-color-surface-alt);
	color: var(--ts-color-text);
	box-shadow: none;
}

/* Neutral — white surface with subtle border (works on colored blocks). */
.ts-btn--neutral {
	--_btn-bg: var(--ts-color-surface);
	--_btn-fg: var(--ts-color-text);
	--_btn-border: var(--ts-color-border);
}

.ts-btn--neutral:hover {
	--_btn-bg: var(--ts-color-surface);
	--_btn-fg: var(--ts-color-primary-active);
	border-color: var(--ts-color-primary);
}

/* Sizes. */
.ts-btn--sm {
	padding: 0.5rem 1rem;
	font-size: var(--ts-text-sm);
}

.ts-btn--lg {
	padding: 0.95rem 2rem;
	font-size: var(--ts-text-lg);
}

/* Modifiers. */
.ts-btn--block {
	display: flex;
	width: 100%;
}

.ts-btn--pill { border-radius: var(--ts-radius-pill); }

.ts-btn[disabled],
.ts-btn:disabled,
.ts-btn[aria-disabled="true"] {
	opacity: 0.55;
	cursor: not-allowed;
	pointer-events: none;
	box-shadow: none;
	transform: none;
}

/* =============================================================================
   7. CARDS
   ========================================================================== */

.ts-card {
	display: flex;
	flex-direction: column;
	background-color: var(--ts-color-surface);
	border: 1px solid var(--ts-color-border);
	border-radius: var(--ts-radius-lg);
	box-shadow: var(--ts-shadow-sm);
	overflow: hidden;
	transition: transform var(--ts-transition-slow),
		box-shadow var(--ts-transition-slow),
		border-color var(--ts-transition-base);
}

/* Interactive card (links to a post / pin). */
.ts-card--interactive {
	cursor: pointer;
}

.ts-card--interactive:hover,
.ts-card--interactive:focus-within {
	transform: translateY(-4px);
	box-shadow: var(--ts-shadow-lg);
	border-color: color-mix(in srgb, var(--ts-color-primary) 35%, var(--ts-color-border));
}

/* Media at the top of a card — Pinterest-style tall imagery. */
.ts-card__media {
	position: relative;
	overflow: hidden;
	background-color: var(--ts-color-surface-alt);
	aspect-ratio: 4 / 5; /* Portrait, Pinterest-friendly. */
}

.ts-card__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform var(--ts-transition-slow);
}

.ts-card--interactive:hover .ts-card__media img {
	transform: scale(1.04);
}

.ts-card__body {
	display: flex;
	flex-direction: column;
	gap: var(--ts-space-2);
	padding: var(--ts-space-5);
}

.ts-card__title {
	font-family: var(--ts-font-heading);
	font-size: var(--ts-text-lg);
	font-weight: var(--ts-weight-semibold);
	line-height: var(--ts-leading-snug);
	color: var(--ts-color-heading);
}

/* Stretched-link pattern: make the whole card clickable while keeping
   the anchor as the semantic/accessible target. */
.ts-card__title a::after {
	content: "";
	position: absolute;
	inset: 0;
}

.ts-card__title a {
	text-decoration: none;
	color: inherit;
}

.ts-card--interactive .ts-card__body {
	position: relative; /* Anchor for stretched-link. */
}

.ts-card__excerpt {
	font-size: var(--ts-text-base);
	color: var(--ts-color-text-muted);
	line-height: var(--ts-leading-normal);
}

.ts-card__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--ts-space-3);
	margin-block-start: var(--ts-space-1);
	font-size: var(--ts-text-sm);
	color: var(--ts-color-text-subtle);
}

.ts-card__footer {
	margin-block-start: auto;
	padding-block-start: var(--ts-space-3);
}

/* Flat variant — no shadow, border only. */
.ts-card--flat {
	box-shadow: none;
}

.ts-card--flat:hover {
	box-shadow: var(--ts-shadow-md);
}

/* =============================================================================
   8. LINKS (component variants)
   ========================================================================== */

/* Understated link used inside dense UI (meta rows, footers). */
.ts-link {
	color: var(--ts-color-link);
	text-decoration: none;
	font-weight: var(--ts-weight-medium);
	transition: color var(--ts-transition-fast);
}

.ts-link:hover {
	color: var(--ts-color-link-hover);
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

/* "Read more" style link with an animated arrow. */
.ts-link--arrow {
	display: inline-flex;
	align-items: center;
	gap: var(--ts-space-2);
	font-family: var(--ts-font-heading);
}

.ts-link--arrow::after {
	content: "\2192"; /* → */
	transition: transform var(--ts-transition-base);
}

.ts-link--arrow:hover::after {
	transform: translateX(4px);
}

/* Reset a link to inherit surrounding text (e.g. wrapping a card region). */
.ts-link--plain {
	color: inherit;
	text-decoration: none;
}

/* =============================================================================
   9. FORMS & INPUTS
   ========================================================================== */

.ts-form {
	display: flex;
	flex-direction: column;
	gap: var(--ts-space-5);
}

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

.ts-label {
	font-family: var(--ts-font-heading);
	font-size: var(--ts-text-sm);
	font-weight: var(--ts-weight-medium);
	color: var(--ts-color-heading);
}

.ts-label .ts-required {
	color: var(--ts-color-error);
}

/* Shared control styling. */
.ts-input,
.ts-textarea,
.ts-select,
input[type="text"],
input[type="email"],
input[type="url"],
input[type="password"],
input[type="search"],
input[type="tel"],
input[type="number"],
input[type="date"],
textarea,
select {
	width: 100%;
	padding: 0.75rem 1rem;
	font-family: var(--ts-font-body);
	font-size: var(--ts-text-base);
	color: var(--ts-color-text);
	background-color: var(--ts-color-surface);
	border: 1.5px solid var(--ts-color-border);
	border-radius: var(--ts-radius-md);
	transition: border-color var(--ts-transition-base), box-shadow var(--ts-transition-base);
	appearance: none;
}

.ts-textarea,
textarea {
	min-height: 8rem;
	resize: vertical;
	line-height: var(--ts-leading-normal);
}

/* Custom select chevron (SVG data-URI keeps it dependency-free). */
.ts-select,
select {
	padding-inline-end: 2.75rem;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%235A5A5A' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 1rem center;
	background-size: 1.1em;
}

.ts-input::placeholder,
.ts-textarea::placeholder,
textarea::placeholder {
	color: var(--ts-color-text-subtle);
}

/* Focus state for controls. */
.ts-input:focus,
.ts-textarea:focus,
.ts-select:focus,
input:focus,
textarea:focus,
select:focus {
	outline: none;
	border-color: var(--ts-color-primary);
	box-shadow: 0 0 0 3px var(--ts-color-primary-soft);
}

/* Validation states. */
.ts-input--error,
.ts-field--error .ts-input,
.ts-field--error .ts-textarea,
.ts-field--error .ts-select,
input[aria-invalid="true"],
textarea[aria-invalid="true"] {
	border-color: var(--ts-color-error);
}

.ts-input--error:focus,
input[aria-invalid="true"]:focus {
	box-shadow: 0 0 0 3px var(--ts-color-error-soft);
}

.ts-field__hint {
	font-size: var(--ts-text-sm);
	color: var(--ts-color-text-muted);
}

.ts-field__error {
	font-size: var(--ts-text-sm);
	color: var(--ts-color-error);
}

/* Disabled controls. */
input:disabled,
textarea:disabled,
select:disabled {
	background-color: var(--ts-color-surface-alt);
	opacity: 0.7;
	cursor: not-allowed;
}

/* Checkbox & radio — accent color keeps them native + accessible. */
input[type="checkbox"],
input[type="radio"] {
	width: 1.15rem;
	height: 1.15rem;
	accent-color: var(--ts-color-primary);
	cursor: pointer;
}

.ts-check {
	display: flex;
	align-items: flex-start;
	gap: var(--ts-space-3);
	font-size: var(--ts-text-base);
	line-height: var(--ts-leading-snug);
}

/* Inline form (newsletter signup: input + button side by side). */
.ts-form-inline {
	display: flex;
	flex-wrap: wrap;
	gap: var(--ts-space-3);
}

.ts-form-inline > .ts-input {
	flex: 1 1 14rem;
}

/* Search field with rounded pill affordance. */
.ts-input--search {
	border-radius: var(--ts-radius-pill);
	padding-inline-start: 1.25rem;
}

/* =============================================================================
   10. BADGES & TAGS
   ========================================================================== */

.ts-badge {
	display: inline-flex;
	align-items: center;
	gap: var(--ts-space-1);
	padding: 0.3rem 0.75rem;
	font-family: var(--ts-font-heading);
	font-size: var(--ts-text-xs);
	font-weight: var(--ts-weight-medium);
	letter-spacing: var(--ts-tracking-wide);
	text-transform: uppercase;
	color: var(--ts-color-primary-active);
	background-color: var(--ts-color-primary-soft);
	border-radius: var(--ts-radius-pill);
}

.ts-badge--neutral {
	color: var(--ts-color-text-muted);
	background-color: var(--ts-color-surface-alt);
}

/* Category/tag chip (link). */
.ts-tag {
	display: inline-block;
	padding: 0.3rem 0.85rem;
	font-size: var(--ts-text-sm);
	color: var(--ts-color-text-muted);
	text-decoration: none;
	background-color: var(--ts-color-surface);
	border: 1px solid var(--ts-color-border);
	border-radius: var(--ts-radius-pill);
	transition: color var(--ts-transition-fast), border-color var(--ts-transition-fast), background-color var(--ts-transition-fast);
}

.ts-tag:hover {
	color: var(--ts-color-primary-active);
	background-color: var(--ts-color-primary-soft);
	border-color: transparent;
}

/* =============================================================================
   11. ANIMATIONS (minimal)
   -----------------------------------------------------------------------------
   One subtle entrance animation for on-scroll reveals. Kept intentionally
   restrained per the Scandinavian aesthetic. All motion is gated behind
   prefers-reduced-motion (section 12).
   ========================================================================== */

@keyframes ts-fade-up {
	from {
		opacity: 0;
		transform: translateY(12px);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

@keyframes ts-fade-in {
	from { opacity: 0; }
	to { opacity: 1; }
}

.ts-animate-fade-up {
	animation: ts-fade-up var(--ts-transition-slow) both;
}

.ts-animate-fade-in {
	animation: ts-fade-in var(--ts-transition-base) both;
}

/* Reveal-on-scroll hook: JS adds .is-visible when the element enters view.
   Falls back to fully visible if JS never runs. */
.ts-reveal {
	opacity: 1;
}

@media (prefers-reduced-motion: no-preference) {
	.ts-reveal {
		opacity: 0;
		transform: translateY(16px);
		transition: opacity var(--ts-transition-slow), transform var(--ts-transition-slow);
	}

	.ts-reveal.is-visible {
		opacity: 1;
		transform: none;
	}
}

/* =============================================================================
   12. ACCESSIBILITY HELPERS
   ========================================================================== */

/* Visually hidden but available to screen readers. */
.ts-visually-hidden,
.screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* Skip link — visible on focus, jumps to main content. */
.ts-skip-link {
	position: absolute;
	inset-inline-start: var(--ts-space-4);
	inset-block-start: -100%;
	z-index: var(--ts-z-toast);
	padding: var(--ts-space-3) var(--ts-space-5);
	font-family: var(--ts-font-heading);
	font-weight: var(--ts-weight-medium);
	color: var(--ts-color-on-primary);
	background-color: var(--ts-color-primary-active);
	border-radius: var(--ts-radius-md);
	box-shadow: var(--ts-shadow-md);
	transition: inset-block-start var(--ts-transition-base);
}

.ts-skip-link:focus {
	inset-block-start: var(--ts-space-4);
	color: var(--ts-color-on-primary);
}

/* Global focus-visible ring — keyboard users only, never on mouse click. */
:where(a, button, input, textarea, select, summary, [tabindex]):focus-visible {
	outline: none;
	border-radius: var(--ts-radius-sm);
	box-shadow: var(--ts-shadow-focus);
}

/* Ensure controls with their own box-shadow focus keep a clear ring. */
.ts-btn:focus-visible {
	box-shadow: var(--ts-shadow-focus);
}

/* Anchor scroll offset so fixed header doesn't cover targets. */
:target {
	scroll-margin-top: var(--ts-space-10);
}

/* High-contrast mode: keep borders visible when colors are overridden. */
@media (forced-colors: active) {
	.ts-btn,
	.ts-card,
	.ts-input,
	.ts-tag {
		border: 1px solid CanvasText;
	}
}

/* Respect reduced-motion globally: neutralize transitions/animations. */
@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
		scroll-behavior: auto !important;
	}
}

/* =============================================================================
   13. UTILITY CLASSES
   -----------------------------------------------------------------------------
   A small, curated utility layer. Kept deliberately minimal — components do
   the heavy lifting; utilities handle one-off tweaks.
   ========================================================================== */

/* ---- Display ------------------------------------------------------------- */
.ts-hidden { display: none !important; }
.ts-block  { display: block !important; }
.ts-inline-block { display: inline-block !important; }
.ts-flex   { display: flex !important; }
.ts-grid-d { display: grid !important; }

/* ---- Flexbox helpers ----------------------------------------------------- */
.ts-items-center   { align-items: center; }
.ts-items-start    { align-items: flex-start; }
.ts-items-end      { align-items: flex-end; }
.ts-justify-center { justify-content: center; }
.ts-justify-between { justify-content: space-between; }
.ts-flex-wrap      { flex-wrap: wrap; }
.ts-flex-col       { flex-direction: column; }
.ts-flex-1         { flex: 1 1 0%; }
.ts-gap-2 { gap: var(--ts-space-2); }
.ts-gap-3 { gap: var(--ts-space-3); }
.ts-gap-4 { gap: var(--ts-space-4); }
.ts-gap-5 { gap: var(--ts-space-5); }
.ts-gap-6 { gap: var(--ts-space-6); }

/* ---- Text alignment & style ---------------------------------------------- */
.ts-text-center { text-align: center; }
.ts-text-start  { text-align: start; }
.ts-text-end    { text-align: end; }
.ts-text-balance { text-wrap: balance; }
.ts-uppercase   { text-transform: uppercase; letter-spacing: var(--ts-tracking-caps); }
.ts-nowrap      { white-space: nowrap; }
.ts-truncate {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* Clamp text to N lines (Pinterest card titles/excerpts). */
.ts-clamp-2,
.ts-clamp-3 {
	display: -webkit-box;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.ts-clamp-2 { -webkit-line-clamp: 2; line-clamp: 2; }
.ts-clamp-3 { -webkit-line-clamp: 3; line-clamp: 3; }

/* ---- Font weight --------------------------------------------------------- */
.ts-font-regular  { font-weight: var(--ts-weight-regular); }
.ts-font-medium   { font-weight: var(--ts-weight-medium); }
.ts-font-semibold { font-weight: var(--ts-weight-semibold); }
.ts-font-bold     { font-weight: var(--ts-weight-bold); }
.ts-font-heading  { font-family: var(--ts-font-heading); }

/* ---- Colors -------------------------------------------------------------- */
.ts-text-primary { color: var(--ts-color-primary); }
.ts-text-muted   { color: var(--ts-color-text-muted); }
.ts-text-subtle  { color: var(--ts-color-text-subtle); }
.ts-bg-surface   { background-color: var(--ts-color-surface); }
.ts-bg-alt       { background-color: var(--ts-color-surface-alt); }
.ts-bg-primary-soft { background-color: var(--ts-color-primary-soft); }

/* ---- Radius & shadow ----------------------------------------------------- */
.ts-rounded-sm { border-radius: var(--ts-radius-sm); }
.ts-rounded-md { border-radius: var(--ts-radius-md); }
.ts-rounded-lg { border-radius: var(--ts-radius-lg); }
.ts-rounded-xl { border-radius: var(--ts-radius-xl); }
.ts-rounded-pill { border-radius: var(--ts-radius-pill); }
.ts-shadow-sm { box-shadow: var(--ts-shadow-sm); }
.ts-shadow-md { box-shadow: var(--ts-shadow-md); }
.ts-shadow-lg { box-shadow: var(--ts-shadow-lg); }
.ts-border { border: 1px solid var(--ts-color-border); }

/* ---- Margin utilities (block-flow, responsive-safe) ---------------------- */
.ts-m-0 { margin: 0 !important; }
.ts-mt-0 { margin-block-start: 0; }
.ts-mt-2 { margin-block-start: var(--ts-space-2); }
.ts-mt-3 { margin-block-start: var(--ts-space-3); }
.ts-mt-4 { margin-block-start: var(--ts-space-4); }
.ts-mt-5 { margin-block-start: var(--ts-space-5); }
.ts-mt-6 { margin-block-start: var(--ts-space-6); }
.ts-mt-8 { margin-block-start: var(--ts-space-8); }
.ts-mb-2 { margin-block-end: var(--ts-space-2); }
.ts-mb-3 { margin-block-end: var(--ts-space-3); }
.ts-mb-4 { margin-block-end: var(--ts-space-4); }
.ts-mb-5 { margin-block-end: var(--ts-space-5); }
.ts-mb-6 { margin-block-end: var(--ts-space-6); }
.ts-mb-8 { margin-block-end: var(--ts-space-8); }
.ts-mx-auto { margin-inline: auto; }

/* ---- Padding utilities --------------------------------------------------- */
.ts-p-0 { padding: 0 !important; }
.ts-p-4 { padding: var(--ts-space-4); }
.ts-p-5 { padding: var(--ts-space-5); }
.ts-p-6 { padding: var(--ts-space-6); }
.ts-py-4 { padding-block: var(--ts-space-4); }
.ts-py-6 { padding-block: var(--ts-space-6); }
.ts-px-4 { padding-inline: var(--ts-space-4); }
.ts-px-6 { padding-inline: var(--ts-space-6); }

/* ---- Sizing -------------------------------------------------------------- */
.ts-w-full { width: 100%; }
.ts-max-w-prose { max-width: 65ch; }
.ts-max-w-narrow { max-width: var(--ts-container-narrow); }

/* ---- Aspect ratios (media placeholders) ---------------------------------- */
.ts-ratio-square   { aspect-ratio: 1 / 1; }
.ts-ratio-portrait { aspect-ratio: 4 / 5; }
.ts-ratio-video    { aspect-ratio: 16 / 9; }
.ts-object-cover { object-fit: cover; width: 100%; height: 100%; }

/* ---- Responsive visibility ----------------------------------------------- */
@media (max-width: 47.99em) { /* < 768px */
	.ts-hide-mobile { display: none !important; }
}

@media (min-width: 48em) { /* >= 768px */
	.ts-hide-desktop { display: none !important; }
}

/* ---- Misc ---------------------------------------------------------------- */
.ts-relative { position: relative; }
.ts-overflow-hidden { overflow: hidden; }
.ts-pointer { cursor: pointer; }
.ts-list-none { list-style: none; padding: 0; }
