/**
 * Cammunity Design System — CSS variables.
 *
 * The single source of truth for all design tokens. Never hardcode colour
 * values in templates or views; use the tokens (or the utility classes
 * below, which resolve to them).
 *
 * The palette is the mobile app's (constants/Colours.ts): the orange
 * (#FF4F01) that turns to amber (#FF7E00) and yellow (#FDE047) in the logo
 * swirl, ink-black controls (#111111) and a quiet grey ladder. Cammunity
 * renders in one theme, light — the app's userInterfaceStyle — so a token
 * can be read as a literal colour and never needs a per-theme counterpart.
 */

:root {
  /* ── Core colours ── */
  --background: #ffffff;
  --foreground: #111111;
  --surface: #fafaf9;
  --card: #ffffff;
  --card-foreground: #111111;
  --popover: #ffffff;
  --popover-foreground: #111111;
  --border-subtle: #f1f1f3;
  --border: #e6e6ea;
  --border-strong: #dadada;
  --input: #d5d8de;
  --ring: rgba(255, 79, 1, 0.45);

  /* ── Ink (the app's black buttons) ── */
  --ink: #111111;
  --ink-hover: #2b2b2b;
  --ink-foreground: #ffffff;

  /* ── Muted ── */
  --muted: #f4f4f5;
  --muted-strong: #eeeeee;
  --muted-foreground: #7a7a7a;
  --muted-foreground-strong: #25282b;

  /* ── Brand (orange scale) ── */
  --primary: #ff4f01;
  --primary-hover: #e84600;
  --primary-active: #d13f00;
  --primary-foreground: #ffffff;
  --primary-subtle: #fff2e5;
  --primary-border: rgba(255, 79, 1, 0.32);
  --primary-glow: rgba(255, 79, 1, 0.26);

  /* ── Spectrum ──
     Orange is the brand. Amber and yellow are its companions from the logo
     swirl: they exist for the gradient, warm highlights, ratings and
     accent-on-accent detail, never as a second brand colour standing alone. */
  --accent-2: #ff7e00;
  --accent-2-subtle: rgba(255, 126, 0, 0.12);
  --accent-2-border: rgba(255, 126, 0, 0.35);

  --accent-3: #fde047;
  --accent-3-subtle: rgba(253, 224, 71, 0.22);
  --accent-3-border: rgba(253, 224, 71, 0.6);
  --accent-3-ink: #8a6a00;

  --gradient-brand: linear-gradient(135deg, var(--primary) 0%, var(--accent-2) 52%, var(--accent-3) 100%);
  --gradient-edge: linear-gradient(90deg, transparent, var(--primary-border) 20%, var(--accent-3-border) 80%, transparent);
  --gradient-soft: linear-gradient(160deg, var(--primary-subtle), transparent 60%);

  /* ── Semantic colours ── */
  --success: #1a9f5a;
  --success-fg: #12784a;
  --success-subtle: rgba(26, 159, 90, 0.12);
  --warning: #f2a516;
  --warning-fg: #9a6200;
  --warning-subtle: rgba(242, 165, 22, 0.14);
  --danger: #e02b2b;
  --danger-fg: #c21f1f;
  --danger-subtle: rgba(224, 43, 43, 0.1);
  --info: #2f6fed;
  --info-fg: #2255c4;
  --info-subtle: rgba(47, 111, 237, 0.1);

  /* ── Typography ── */
  --font-sans: "Work Sans", ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;

  --text-xs: clamp(0.75rem, 0.72rem + 0.15vw, 0.8125rem);
  --text-sm: clamp(0.875rem, 0.84rem + 0.2vw, 0.9375rem);
  --text-base: clamp(1rem, 0.95rem + 0.25vw, 1.0625rem);
  --text-lg: clamp(1.125rem, 1.05rem + 0.4vw, 1.25rem);
  --text-xl: clamp(1.25rem, 1.15rem + 0.6vw, 1.5rem);
  --text-2xl: clamp(1.5rem, 1.3rem + 1vw, 1.875rem);
  --text-3xl: clamp(1.875rem, 1.6rem + 1.4vw, 2.375rem);
  --text-4xl: clamp(2.25rem, 1.9rem + 1.9vw, 3.125rem);
  --text-5xl: clamp(2.75rem, 2.2rem + 3vw, 4.25rem);

  --line-tight: 1.08;
  --line-snug: 1.25;
  --line-normal: 1.5;
  --line-relaxed: 1.65;

  --letter-tighter: -0.04em;
  --letter-tight: -0.02em;
  --letter-wide: 0.03em;
  --letter-widest: 0.12em;

  /* ── Spacing ── */
  --space-xs: clamp(0.25rem, 0.2rem + 0.25vw, 0.375rem);
  --space-sm: clamp(0.5rem, 0.4rem + 0.5vw, 0.75rem);
  --space-md: clamp(0.75rem, 0.6rem + 0.75vw, 1rem);
  --space-lg: clamp(1rem, 0.8rem + 1vw, 1.5rem);
  --space-xl: clamp(1.5rem, 1.2rem + 1.5vw, 2rem);
  --space-2xl: clamp(2rem, 1.6rem + 2vw, 3rem);
  --space-3xl: clamp(3rem, 2.4rem + 3vw, 4rem);
  --space-4xl: clamp(4rem, 3.2rem + 4vw, 6rem);

  /* ── Border radius ── */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 14px;
  --radius-xl: 20px;
  --radius-2xl: 28px;
  --radius-full: 9999px;

  /* ── Motion ── */
  --duration-fast: 120ms;
  --duration-base: 200ms;
  --duration-slow: 320ms;
  --duration-slower: 480ms;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);

  /* ── Shadows (light theme: soft, warm-tinted) ── */
  --shadow-sm: 0 1px 2px rgba(17, 17, 17, 0.06), 0 1px 3px rgba(17, 17, 17, 0.04);
  --shadow-md: 0 4px 14px rgba(17, 17, 17, 0.07), 0 1px 3px rgba(17, 17, 17, 0.05);
  --shadow-lg: 0 14px 40px rgba(17, 17, 17, 0.1), 0 4px 10px rgba(17, 17, 17, 0.05);
  --shadow-xl: 0 28px 70px rgba(17, 17, 17, 0.14), 0 10px 22px rgba(17, 17, 17, 0.06);
  --shadow-glow: 0 0 32px var(--primary-glow);
  --shadow-brand: 0 22px 50px -18px var(--primary-glow), 0 8px 20px -10px rgba(253, 224, 71, 0.35);

  /* The header's height, so anchored scrolls and sticky panels agree. */
  --header-h: 4.25rem;
}

/* ══════════════════════════════════════════════════════════════════ */
/* Base styles                                                         */
/* ══════════════════════════════════════════════════════════════════ */

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  scroll-padding-top: calc(var(--header-h) + 1rem);
  scroll-behavior: smooth;
  color-scheme: light;
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--line-normal);
  color: var(--foreground);
  background: var(--background);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

img, video { display: block; max-width: 100%; }
button { font: inherit; color: inherit; }
a { color: inherit; }

.font-mono { font-family: var(--font-mono); }

/* ══════════════════════════════════════════════════════════════════ */
/* Token utility classes (coexist with the Tailwind runtime)           */
/* ══════════════════════════════════════════════════════════════════ */

.bg-background { background-color: var(--background); }
.bg-surface { background-color: var(--surface); }
.bg-card { background-color: var(--card); }
.bg-popover { background-color: var(--popover); }
.bg-ink { background-color: var(--ink); }
.bg-muted { background-color: var(--muted); }
.bg-muted-strong { background-color: var(--muted-strong); }
.bg-primary { background-color: var(--primary); }
.bg-primary-subtle { background-color: var(--primary-subtle); }
.bg-accent-2 { background-color: var(--accent-2); }
.bg-accent-3 { background-color: var(--accent-3); }
.bg-accent-3-subtle { background-color: var(--accent-3-subtle); }
.bg-success { background-color: var(--success); }
.bg-success-subtle { background-color: var(--success-subtle); }
.bg-warning-subtle { background-color: var(--warning-subtle); }
.bg-danger { background-color: var(--danger); }
.bg-danger-subtle { background-color: var(--danger-subtle); }
.bg-info-subtle { background-color: var(--info-subtle); }

.text-foreground { color: var(--foreground); }
.text-ink { color: var(--ink); }
.text-ink-foreground { color: var(--ink-foreground); }
.text-muted-foreground { color: var(--muted-foreground); }
.text-muted-strong { color: var(--muted-foreground-strong); }
.text-primary { color: var(--primary); }
.text-primary-hover { color: var(--primary-hover); }
.text-primary-foreground { color: var(--primary-foreground); }
.text-accent-2 { color: var(--accent-2); }
.text-accent-3 { color: var(--accent-3); }
.text-accent-3-ink { color: var(--accent-3-ink); }
.text-success { color: var(--success-fg); }
.text-warning { color: var(--warning-fg); }
.text-danger { color: var(--danger-fg); }
.text-info { color: var(--info-fg); }

.border-border { border-color: var(--border); }
.border-border-subtle { border-color: var(--border-subtle); }
.border-border-strong { border-color: var(--border-strong); }
.border-input { border-color: var(--input); }
.border-primary { border-color: var(--primary); }
.border-primary-border { border-color: var(--primary-border); }
.border-danger { border-color: var(--danger); }
.border-ink { border-color: var(--ink); }

.divide-border > * + * { border-color: var(--border); }

.ring-ring { --tw-ring-color: var(--ring); }

.shadow-glow { box-shadow: var(--shadow-glow); }
.shadow-brand { box-shadow: var(--shadow-brand); }

/* ── Gradient primitives ──
   The brand gradient is the logo swirl: orange → amber → yellow. Use it for
   emphasis (a headline word, a rule, a stat, the CTA), never for body text. */
.bg-gradient-brand { background-image: var(--gradient-brand); }
.bg-gradient-soft { background-image: var(--gradient-soft); }

.text-gradient {
  background-image: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

/* A 1px gradient hairline: replaces flat section borders. */
.rule-gradient {
  height: 1px;
  border: 0;
  background-image: var(--gradient-edge);
}

/* ══════════════════════════════════════════════════════════════════ */
/* Component primitives                                                */
/* ══════════════════════════════════════════════════════════════════ */

/* Buttons are pills. The surfaces around them are not — cards stay at 14px,
   inputs at 10px — and that is deliberate: the one shape on the page that
   is fully round is the one thing meant to be pressed. Vertical padding and
   font-size match .input exactly, so a button beside a field is the same
   height as it; only the corners differ. Size is a class (.btn-sm/.btn-lg),
   never a text utility at the call site: Tailwind's stylesheet loads after
   this one and would silently win. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font-weight: 600;
  font-size: var(--text-sm);
  line-height: 1.25;
  border-radius: var(--radius-full);
  padding: 0.6875rem 1.5rem;
  min-height: 2.75rem;
  transition: background-color var(--duration-base) var(--ease-out),
    background-image var(--duration-base) var(--ease-out),
    border-color var(--duration-base) var(--ease-out),
    box-shadow var(--duration-base) var(--ease-out),
    color var(--duration-base) var(--ease-out),
    transform var(--duration-base) var(--ease-out);
  cursor: pointer;
  border: 1px solid transparent;
  text-decoration: none;
  white-space: nowrap;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.btn:disabled { opacity: 0.55; cursor: not-allowed; }
.btn:active:not(:disabled) { transition-duration: var(--duration-fast); }

.btn-sm {
  font-size: 0.875rem;
  min-height: 2.25rem;
  padding: 0.375rem 1rem;
}
.btn-lg {
  font-size: var(--text-base);
  min-height: 3.125rem;
  padding: 0.75rem 1.875rem;
}
.btn-block { width: 100%; }

/* Icon-only button: a glyph in a hit target, quiet until hovered. */
.btn-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.5rem;
  border-radius: var(--radius-full);
  border: 0;
  background: transparent;
  color: var(--muted-foreground);
  cursor: pointer;
  transition: color var(--duration-base) var(--ease-out),
    background-color var(--duration-base) var(--ease-out),
    transform var(--duration-base) var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}
.btn-icon:hover:not(:disabled) {
  color: var(--foreground);
  background-color: var(--muted);
}
.btn-icon:active:not(:disabled) { transform: scale(0.94); }
.btn-icon:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-icon-danger:hover:not(:disabled) { color: var(--danger-fg); background-color: var(--danger-subtle); }
/* A glyph button that sits on a photo (favourite hearts, gallery arrows). */
.btn-icon-float {
  background-color: rgba(255, 255, 255, 0.92);
  color: var(--foreground);
  box-shadow: var(--shadow-sm);
  backdrop-filter: blur(6px);
}
.btn-icon-float:hover:not(:disabled) { background-color: #fff; color: var(--primary); }

/* The primary button is ink: the app's black pill. The inset hairline along
   the top is what makes it read as a raised object rather than a swatch. */
.btn-primary {
  background-color: var(--ink);
  color: var(--ink-foreground);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), 0 1px 2px rgba(17, 17, 17, 0.25);
}
.btn-primary:hover:not(:disabled) {
  background-color: var(--ink-hover);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14), 0 10px 24px -10px rgba(17, 17, 17, 0.5), 0 2px 6px rgba(17, 17, 17, 0.2);
  transform: translateY(-1px);
}
.btn-primary:active:not(:disabled) {
  transform: translateY(0);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.35);
}

/* The brand button carries the logo gradient — one per surface, for the
   action the page exists for (Book now, Search, List your gear). */
.btn-brand {
  background-color: var(--primary);
  background-image: linear-gradient(135deg, var(--primary) 0%, var(--accent-2) 100%);
  color: var(--primary-foreground);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28), 0 1px 2px rgba(255, 79, 1, 0.3);
}
.btn-brand:hover:not(:disabled) {
  background-image: linear-gradient(135deg, var(--primary-hover) 0%, var(--accent-2) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), 0 12px 28px -10px var(--primary-glow), 0 2px 6px rgba(255, 79, 1, 0.25);
  transform: translateY(-1px);
}
.btn-brand:active:not(:disabled) {
  transform: translateY(0);
  filter: brightness(0.96);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.22);
}

.btn-secondary {
  background-color: var(--card);
  color: var(--foreground);
  border-color: var(--border-strong);
  box-shadow: var(--shadow-sm);
}
.btn-secondary:hover:not(:disabled) {
  border-color: var(--ink);
  background-color: var(--surface);
}
.btn-secondary:active:not(:disabled) { background-color: var(--muted); }

/* Tinted secondary: the orange outline treatment for a lighter brand CTA. */
.btn-outline-brand {
  background-color: transparent;
  color: var(--primary);
  border-color: var(--primary-border);
}
.btn-outline-brand:hover:not(:disabled) {
  background-color: var(--primary-subtle);
  border-color: var(--primary);
}

.btn-ghost { background: transparent; color: var(--foreground); }
.btn-ghost:hover:not(:disabled) { background-color: var(--muted); }
.btn-ghost:active:not(:disabled) { background-color: var(--muted-strong); }

.btn-danger {
  background-color: var(--danger);
  color: #fff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), 0 1px 2px rgba(224, 43, 43, 0.3);
}
.btn-danger:hover:not(:disabled) {
  filter: brightness(1.06);
  transform: translateY(-1px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22), 0 10px 26px -12px var(--danger), 0 2px 6px rgba(224, 43, 43, 0.25);
}
.btn-danger:active:not(:disabled) { transform: translateY(0); filter: brightness(0.96); }
.btn-danger-outline {
  background-color: transparent;
  color: var(--danger-fg);
  border-color: var(--danger);
}
.btn-danger-outline:hover:not(:disabled) { background-color: var(--danger-subtle); }

@media (prefers-reduced-motion: reduce) {
  .btn-primary:hover:not(:disabled),
  .btn-brand:hover:not(:disabled),
  .btn-danger:hover:not(:disabled) { transform: none; }
}

/* Segmented control: a row of mutually exclusive choices (booking tabs,
   sort orders, category chips). Selection reads from aria-selected where
   the control is a real tablist, and from .is-on where it is not. */
.seg { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.seg-item {
  border-radius: var(--radius-full);
  border: 1px solid var(--border);
  background-color: var(--card);
  padding: 0.45rem 0.95rem;
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.35;
  color: var(--muted-foreground-strong);
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out),
    background-color var(--duration-fast) var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}
.seg-item:hover:not(:disabled) { border-color: var(--ink); }
.seg-item[aria-selected="true"],
.seg-item.is-on {
  color: var(--ink-foreground);
  border-color: var(--ink);
  background-color: var(--ink);
  font-weight: 600;
}
/* The tinted variant: brand orange rather than ink, for filter chips. */
.seg-brand .seg-item[aria-selected="true"],
.seg-brand .seg-item.is-on {
  color: var(--primary);
  border-color: var(--primary-border);
  background-color: var(--primary-subtle);
}
/* Scrolling variant for phones: one row, swipe sideways, no wrap. */
.seg-scroll {
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 2px;
}
.seg-scroll::-webkit-scrollbar { display: none; }

/* Underline tabs: the app's top-tab bar (Bookings, Profile sections). */
.tabs {
  display: flex;
  gap: 0.25rem;
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
  scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tab {
  position: relative;
  padding: 0.75rem 0.9rem;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--muted-foreground);
  background: transparent;
  border: 0;
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--duration-fast) var(--ease-out);
}
.tab:hover { color: var(--foreground); }
.tab::after {
  content: "";
  position: absolute;
  left: 0.5rem;
  right: 0.5rem;
  bottom: -1px;
  height: 2px;
  border-radius: 2px;
  background: var(--primary);
  transform: scaleX(0);
  transition: transform var(--duration-base) var(--ease-out);
}
.tab[aria-selected="true"] { color: var(--foreground); font-weight: 600; }
.tab[aria-selected="true"]::after { transform: scaleX(1); }

.card {
  background-color: var(--card);
  color: var(--card-foreground);
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
}

/* Panel — the marketing-weight surface: a card with the brand hairline
   along its upper edge and a warm wash, so it reads as raised rather than
   as a rectangle drawn on the background. */
.panel {
  position: relative;
  isolation: isolate;
  background-color: var(--card);
  background-image: var(--gradient-soft);
  color: var(--card-foreground);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-md);
  overflow: hidden;
}
.panel::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 2px;
  background-image: var(--gradient-brand);
  opacity: 0.9;
  pointer-events: none;
}

/* Adds a hover response to a .card or .panel that is a link or tile: it
   rises, its edge picks up the brand, and the shadow warms. */
.panel-interactive {
  transition: transform var(--duration-base) var(--ease-out),
    border-color var(--duration-base) var(--ease-out),
    box-shadow var(--duration-base) var(--ease-out);
}
.panel-interactive:hover {
  transform: translateY(-3px);
  border-color: var(--primary-border);
  box-shadow: var(--shadow-brand);
}

/* A panel whose contents are irreversible: the edge states it before the
   copy does. */
.panel-danger { border-color: var(--danger); background-image: linear-gradient(165deg, var(--danger-subtle), transparent 55%); }
.panel-danger::before { background-image: linear-gradient(90deg, var(--danger), transparent); }

/* The layer a modal sits on: the page stays visible but held back. */
.scrim {
  background: rgba(17, 17, 17, 0.42);
  backdrop-filter: blur(6px) saturate(0.9);
}

/* The small uppercase label that names a field, a dialog section or a
   sidebar group. Fixed size: it is chrome, not copy. */
.field-label {
  display: block;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--letter-widest);
  color: var(--muted-foreground);
}
.field-label-brand { color: var(--primary); }
.field-label-danger { color: var(--danger-fg); }

/* Eyebrow: the sentence-case brand kicker above a marketing heading. */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: var(--letter-wide);
  text-transform: uppercase;
  color: var(--primary);
}
.eyebrow::before {
  content: "";
  width: 1.75rem;
  height: 2px;
  border-radius: 2px;
  background-image: var(--gradient-brand);
}

.input {
  width: 100%;
  padding: 0.6875rem 0.9375rem;
  min-height: 2.75rem;
  background-color: var(--card);
  color: var(--foreground);
  border: 1px solid var(--input);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-family: inherit;
  line-height: 1.25;
  transition: border-color var(--duration-base) var(--ease-out), box-shadow var(--duration-base) var(--ease-out);
  -webkit-appearance: none;
  appearance: none;
}
textarea.input { min-height: 6rem; line-height: var(--line-normal); resize: vertical; }
select.input {
  padding-right: 2.5rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%237a7a7a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.875rem center;
}
.input:hover:not(:focus):not(:disabled) { border-color: var(--border-strong); }
.input:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-subtle);
}
.input::placeholder { color: var(--muted-foreground); opacity: 0.8; }
.input:disabled { background-color: var(--muted); color: var(--muted-foreground); cursor: not-allowed; }
.input[aria-invalid="true"] { border-color: var(--danger); }
.input[aria-invalid="true"]:focus { box-shadow: 0 0 0 3px var(--danger-subtle); }
/* An input with a leading glyph: the field pads for it, the glyph sits absolutely. */
.input-icon { padding-left: 2.75rem; }
.input-glyph {
  position: absolute;
  left: 0.9375rem;
  top: 50%;
  transform: translateY(-50%);
  color: var(--muted-foreground);
  pointer-events: none;
}

/* Checkbox: a real <input type=checkbox> painted with appearance:none, so
   it keeps native keyboard and label semantics. The tick is a sibling SVG
   (.checkbox-tick) rather than a pseudo-element, because ::before/::after
   do not render on <input> in Firefox. */
.checkbox-wrap { position: relative; display: inline-flex; flex-shrink: 0; }
.checkbox-tick {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 0.8rem;
  height: 0.8rem;
  color: #fff;
  stroke-width: 3.25;
  pointer-events: none;
  opacity: 0;
  transform: scale(0.7);
  transition: opacity var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out);
}
.checkbox:checked + .checkbox-tick { opacity: 1; transform: scale(1); }
.checkbox {
  appearance: none;
  -webkit-appearance: none;
  flex-shrink: 0;
  width: 1.25rem;
  height: 1.25rem;
  margin: 0;
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background-color: var(--card);
  cursor: pointer;
  position: relative;
  transition: background-color var(--duration-base) var(--ease-out),
    border-color var(--duration-base) var(--ease-out),
    box-shadow var(--duration-base) var(--ease-out);
}
.checkbox:hover:not(:disabled) { border-color: var(--primary); }
.checkbox:checked { background-color: var(--primary); border-color: var(--primary); }
.checkbox:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--primary-subtle); }
.checkbox:active:not(:disabled) { transform: scale(0.92); }
.checkbox:disabled { opacity: 0.5; cursor: not-allowed; }

/* Toggle switch: the app's AppToggleSwitch. A real checkbox, painted. */
.switch {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  width: 2.75rem;
  height: 1.625rem;
  flex-shrink: 0;
  border-radius: var(--radius-full);
  background-color: var(--border-strong);
  cursor: pointer;
  transition: background-color var(--duration-base) var(--ease-out);
  margin: 0;
}
.switch::after {
  content: "";
  position: absolute;
  top: 0.1875rem;
  left: 0.1875rem;
  width: 1.25rem;
  height: 1.25rem;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
  transition: transform var(--duration-base) var(--ease-spring);
}
.switch:checked { background-color: var(--primary); }
.switch:checked::after { transform: translateX(1.125rem); }
.switch:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--primary-subtle); }
.switch:disabled { opacity: 0.5; cursor: not-allowed; }

/* Range slider (price filter). The filled portion is a gradient stop at
   --slider-pct, set inline by the component. */
.slider {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  height: 1.5rem;
  background: transparent;
  cursor: pointer;
  --slider-track: linear-gradient(to right, var(--primary) var(--slider-pct, 50%), var(--border) var(--slider-pct, 50%));
}
.slider::-webkit-slider-runnable-track { height: 0.375rem; border-radius: 999px; background: var(--slider-track); }
.slider::-moz-range-track { height: 0.375rem; border-radius: 999px; background: var(--slider-track); }
.slider::-webkit-slider-thumb {
  appearance: none;
  -webkit-appearance: none;
  width: 1.25rem;
  height: 1.25rem;
  margin-top: -0.4375rem;
  border-radius: 999px;
  background: #fff;
  border: 2px solid var(--primary);
  box-shadow: var(--shadow-sm);
  transition: transform var(--duration-base) var(--ease-out);
}
.slider::-moz-range-thumb {
  width: 1.25rem;
  height: 1.25rem;
  border-radius: 999px;
  background: #fff;
  border: 2px solid var(--primary);
  box-shadow: var(--shadow-sm);
}
.slider:hover::-webkit-slider-thumb { transform: scale(1.1); }
.slider:focus-visible { outline: none; }
.slider:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 4px var(--primary-subtle); }

.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 12px;
  font-weight: 600;
  border-radius: var(--radius-full);
  padding: 0.2rem 0.6rem;
  line-height: 1.3;
  white-space: nowrap;
}
.badge-brand { background: var(--primary-subtle); color: var(--primary); }
.badge-ink { background: var(--ink); color: var(--ink-foreground); }
.badge-muted { background: var(--muted); color: var(--muted-foreground-strong); }
.badge-yellow { background: var(--accent-3); color: var(--ink); }
.badge-success { background: var(--success-subtle); color: var(--success-fg); }
.badge-warning { background: var(--warning-subtle); color: var(--warning-fg); }
.badge-danger { background: var(--danger-subtle); color: var(--danger-fg); }
.badge-info { background: var(--info-subtle); color: var(--info-fg); }
/* A badge floated over a photo. */
.badge-float { background: rgba(255, 255, 255, 0.94); color: var(--foreground); box-shadow: var(--shadow-sm); backdrop-filter: blur(6px); }

/* Avatar: a circle that shows a photo or the initials over the brand wash. */
.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  background-image: var(--gradient-brand);
  color: #fff;
  font-weight: 700;
  font-size: 0.875rem;
  letter-spacing: 0.02em;
  overflow: hidden;
  user-select: none;
}
.avatar img { width: 100%; height: 100%; object-fit: cover; }
.avatar-sm { width: 2rem; height: 2rem; font-size: 0.75rem; }
.avatar-lg { width: 4rem; height: 4rem; font-size: 1.25rem; }
.avatar-xl { width: 6rem; height: 6rem; font-size: 1.75rem; }

/* Icon in a tinted well: the glyph beside a feature or a menu row. */
.icon-tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--radius-md);
  background: var(--primary-subtle);
  color: var(--primary);
}
.icon-tile-sm { width: 2rem; height: 2rem; border-radius: var(--radius-sm); }
.icon-tile-lg { width: 3.25rem; height: 3.25rem; border-radius: var(--radius-lg); }
.icon-tile-ink { background: var(--ink); color: #fff; }
.icon-tile-muted { background: var(--muted); color: var(--muted-foreground-strong); }
.icon-tile-yellow { background: var(--accent-3-subtle); color: var(--accent-3-ink); }
.icon-tile-success { background: var(--success-subtle); color: var(--success-fg); }
.icon-tile-danger { background: var(--danger-subtle); color: var(--danger-fg); }
.icon-tile-info { background: var(--info-subtle); color: var(--info-fg); }

/* Skeleton: a loading placeholder that shimmers. Size it with utilities. */
.skeleton {
  position: relative;
  overflow: hidden;
  background-color: var(--muted);
  border-radius: var(--radius-md);
}
.skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background-image: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.7), transparent);
  animation: shimmer 1.4s var(--ease-in-out) infinite;
}
@keyframes shimmer { to { transform: translateX(100%); } }

/* Menu row: the app's account list rows — glyph, label, chevron. */
.menu-row {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  width: 100%;
  padding: 0.875rem 1rem;
  border-radius: var(--radius-md);
  text-align: left;
  background: transparent;
  border: 0;
  cursor: pointer;
  color: var(--foreground);
  text-decoration: none;
  transition: background-color var(--duration-fast) var(--ease-out);
}
.menu-row:hover { background-color: var(--muted); }
.menu-row-danger { color: var(--danger-fg); }
.menu-row-danger:hover { background-color: var(--danger-subtle); }

/* Photo frame: the aspect-locked image well listing cards and galleries use. */
.photo {
  position: relative;
  overflow: hidden;
  background: var(--muted);
  border-radius: var(--radius-lg);
}
.photo img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--duration-slower) var(--ease-out); }
.photo-zoom:hover img { transform: scale(1.04); }
.photo-4x3 { aspect-ratio: 4 / 3; }
.photo-1x1 { aspect-ratio: 1 / 1; }
.photo-16x9 { aspect-ratio: 16 / 9; }
.photo-contain img { object-fit: contain; }

/* Prose: long-form copy (guides, FAQ answers, terms, blog bodies). */
.prose { color: var(--muted-foreground-strong); line-height: var(--line-relaxed); }
.prose > * + * { margin-top: 1em; }
.prose h1, .prose h2, .prose h3, .prose h4 { color: var(--foreground); font-weight: 700; letter-spacing: var(--letter-tight); line-height: var(--line-snug); }
.prose h1 { font-size: var(--text-3xl); margin-top: 1.5em; }
.prose h2 { font-size: var(--text-2xl); margin-top: 2em; }
.prose h3 { font-size: var(--text-xl); margin-top: 1.6em; }
.prose h4 { font-size: var(--text-lg); margin-top: 1.4em; }
.prose h1:first-child, .prose h2:first-child, .prose h3:first-child { margin-top: 0; }
.prose ul, .prose ol { padding-left: 1.4em; }
.prose li + li { margin-top: 0.35em; }
.prose a { color: var(--primary); text-decoration: underline; text-underline-offset: 2px; }
.prose strong { color: var(--foreground); font-weight: 600; }
.prose blockquote { border-left: 3px solid var(--primary); padding-left: 1em; color: var(--muted-foreground); }
.prose code { font-family: var(--font-mono); font-size: 0.9em; background: var(--muted); padding: 0.1em 0.35em; border-radius: 4px; }
.prose img { border-radius: var(--radius-lg); }
.prose hr { border: 0; border-top: 1px solid var(--border); }

/* ══════════════════════════════════════════════════════════════════ */
/* Brand motion language                                               */
/* Cammunity's metaphor is the handover: things arrive, settle and     */
/* light up. Every animation respects prefers-reduced-motion.          */
/* ══════════════════════════════════════════════════════════════════ */

/* Scroll reveal — sections fade up as they enter the viewport. */
.scroll-reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.6s var(--ease-out), transform 0.6s var(--ease-out);
}
.scroll-reveal.is-visible { opacity: 1; transform: translateY(0); }

/* The entrance animations fill `backwards`, never `both`: a filled end
   state keeps a transform on the element for life and re-anchors every
   position:fixed descendant (a dialog) to its box. */
@keyframes rise {
  0% { opacity: 0; transform: translateY(10px); }
  100% { opacity: 1; transform: none; }
}
.animate-rise { animation: rise var(--duration-slow) var(--ease-out) backwards; }
.animate-rise-slow { animation: rise var(--duration-slower) var(--ease-out) backwards; }

@keyframes pop {
  0% { opacity: 0; transform: scale(0.96) translateY(6px); }
  100% { opacity: 1; transform: none; }
}
.animate-pop { animation: pop var(--duration-base) var(--ease-spring) backwards; }

@keyframes slideup {
  0% { opacity: 0; transform: translateY(100%); }
  100% { opacity: 1; transform: none; }
}
.animate-slideup { animation: slideup var(--duration-slow) var(--ease-out) backwards; }

@keyframes headshake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-7px); }
  40% { transform: translateX(6px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(2px); }
}
.animate-shake { animation: headshake 380ms var(--ease-in-out); }

@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.animate-fade { animation: fadeIn var(--duration-slow) ease both; }

@keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
.animate-spin { animation: spin 0.9s linear infinite; }

/* The brand pulse: a soft warm glow breathing on the mark. */
@keyframes glowpulse {
  0%, 100% { box-shadow: 0 0 12px var(--primary-glow); }
  50% { box-shadow: 0 0 30px var(--primary-glow), 0 0 60px rgba(253, 224, 71, 0.35); }
}
.animate-glow { animation: glowpulse 3.2s var(--ease-in-out) infinite; }

/* Spinner ring: the one way a button or panel says "working". */
.spinner {
  display: inline-block;
  width: 1.125rem;
  height: 1.125rem;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  flex-shrink: 0;
}
.spinner-lg { width: 2rem; height: 2rem; border-width: 3px; }

/* ══════════════════════════════════════════════════════════════════ */
/* Surfaces and effects                                                */
/* The "bells and whistles" layer: glass, gradient edges, tickers,     */
/* reveals and tilts. Every one is a class, never an inline style, so  */
/* a page opts in by naming it.                                        */
/* ══════════════════════════════════════════════════════════════════ */

/* Glass: a translucent white surface for things that float over
   imagery — chips on the hero collage, the sticky filter bar, the
   header once the page has scrolled. */
.glass {
  background-color: rgba(255, 255, 255, 0.74);
  -webkit-backdrop-filter: blur(18px) saturate(1.6);
  backdrop-filter: blur(18px) saturate(1.6);
  border: 1px solid rgba(255, 255, 255, 0.65);
  box-shadow: var(--shadow-md), inset 0 1px 0 rgba(255, 255, 255, 0.8);
}

/* A 1px brand-gradient border on any radius: a masked pseudo-element
   rather than border-image, which cannot follow rounded corners. */
.border-gradient { position: relative; isolation: isolate; }
.border-gradient::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: var(--gradient-brand);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
  z-index: 1;
}

/* Ink section: the app's black, used for one dramatic band per page.
   Warm glows keep it from reading as a void. */
.section-ink {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(ellipse 60% 50% at 12% 0%, rgba(255, 79, 1, 0.35), transparent 60%),
    radial-gradient(ellipse 50% 45% at 90% 100%, rgba(253, 224, 71, 0.22), transparent 60%),
    var(--ink);
  color: #fff;
}
.section-ink .text-muted-foreground { color: rgba(255, 255, 255, 0.66); }

/* Dot grid: a quiet technical texture behind marketing sections. */
.bg-dots {
  background-image: radial-gradient(rgba(17, 17, 17, 0.09) 1px, transparent 1.2px);
  background-size: 22px 22px;
}
.bg-dots-fade {
  -webkit-mask-image: radial-gradient(ellipse 70% 70% at 50% 40%, #000 30%, transparent 75%);
  mask-image: radial-gradient(ellipse 70% 70% at 50% 40%, #000 30%, transparent 75%);
}

/* The gradient headline word, breathing: the brand swirl sliding
   through the letters. */
.text-gradient-animated {
  background-image: linear-gradient(90deg, var(--primary) 0%, var(--accent-2) 30%, var(--accent-3) 50%, var(--accent-2) 70%, var(--primary) 100%);
  background-size: 250% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  animation: gradient-slide 7s var(--ease-in-out) infinite;
}
@keyframes gradient-slide {
  0%, 100% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
}

/* Shine: a highlight sweeps across the two solid buttons on hover. */
.btn-brand, .btn-primary { position: relative; overflow: hidden; }
.btn-brand::after, .btn-primary::after {
  content: "";
  position: absolute;
  top: -20%;
  bottom: -20%;
  left: -70%;
  width: 45%;
  background: linear-gradient(100deg, transparent 0%, rgba(255, 255, 255, 0.38) 50%, transparent 100%);
  transform: skewX(-20deg);
  transition: left 0.75s var(--ease-out);
  pointer-events: none;
}
.btn-brand:hover:not(:disabled)::after, .btn-primary:hover:not(:disabled)::after { left: 130%; }
/* The arrow glyph in a button nudges forward on hover. */
.btn-arrow { transition: transform var(--duration-base) var(--ease-out); }
.btn:hover:not(:disabled) .btn-arrow { transform: translateX(4px); }

/* Scroll reveal: an element enters as it scrolls into view. The Page
   shell observes [data-reveal] and adds .is-visible once; --i staggers
   siblings. Variants pick the direction. */
[data-reveal] {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.8s var(--ease-out), transform 0.8s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 90ms);
}
[data-reveal="scale"] { transform: scale(0.94) translateY(14px); }
[data-reveal="left"] { transform: translateX(-36px); }
[data-reveal="right"] { transform: translateX(36px); }
[data-reveal].is-visible { opacity: 1; transform: none; }

/* Ticker: a strip of items sliding forever. The track holds the items
   twice so the loop is seamless; hover pauses it. */
.marquee {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.marquee-track {
  display: flex;
  align-items: center;
  gap: 2.75rem;
  width: max-content;
  padding-right: 2.75rem;
  animation: marquee var(--marquee-duration, 48s) linear infinite;
}
.marquee:hover .marquee-track { animation-play-state: paused; }
@keyframes marquee { to { transform: translate3d(-50%, 0, 0); } }

/* Tilt: a card that leans toward the pointer. lib/tilt.ts writes --rx
   and --ry; the class does the rest. */
.tilt {
  transform: perspective(1000px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateZ(0);
  transition: transform 0.45s var(--ease-out), box-shadow 0.45s var(--ease-out);
  transform-style: preserve-3d;
  will-change: transform;
}
.tilt:hover { transform: perspective(1000px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateY(-4px) translateZ(0); }
.tilt.is-tilting { transition: transform 0.08s linear, box-shadow 0.45s var(--ease-out); }

/* Avatar stack: overlapping heads with a white keyline. */
.avatar-stack { display: inline-flex; align-items: center; }
.avatar-stack .avatar { box-shadow: 0 0 0 2px #fff; }
.avatar-stack .avatar + .avatar { margin-left: -0.55rem; }

/* Avatar ring: the brand gradient around a profile photo. */
.avatar-ring {
  display: inline-flex;
  padding: 3px;
  border-radius: 50%;
  background-image: var(--gradient-brand);
  box-shadow: var(--shadow-brand);
}
.avatar-ring .avatar { box-shadow: 0 0 0 3px #fff; }

/* Live dot: the green pulse beside "live" copy. */
.live-dot {
  position: relative;
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--success);
  flex-shrink: 0;
}
.live-dot::after {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: 50%;
  border: 2px solid var(--success);
  opacity: 0.7;
  animation: ping 1.8s var(--ease-out) infinite;
}
@keyframes ping {
  0% { transform: scale(0.6); opacity: 0.8; }
  100% { transform: scale(1.9); opacity: 0; }
}

/* Pill: the glass kicker above a hero headline. */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.45rem 1rem 0.45rem 0.8rem;
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, 0.78);
  border: 1px solid var(--border);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--foreground);
  box-shadow: var(--shadow-sm);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.pill-ink { background: var(--ink); color: #fff; border-color: var(--ink); }

/* Floaty: things that bob, out of phase with each other. */
@keyframes floaty {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-10px); }
}
.floaty { animation: floaty 5.5s var(--ease-in-out) infinite; }
.floaty-b { animation: floaty 6.5s var(--ease-in-out) -2.2s infinite; }
.floaty-c { animation: floaty 7s var(--ease-in-out) -4.1s infinite; }

/* Numeral: the giant gradient step number. */
.numeral {
  font-size: clamp(3rem, 5.5vw, 4.75rem);
  line-height: 0.9;
  font-weight: 800;
  letter-spacing: -0.06em;
  background-image: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

/* Watermark: the brand mark, huge and faint, behind a section. */
.watermark {
  position: absolute;
  pointer-events: none;
  user-select: none;
  opacity: 0.08;
}

/* Glow tile: the icon tile that lights up when its card is hovered. */
.panel-interactive:hover .icon-tile { box-shadow: var(--shadow-glow); }
.icon-tile { transition: box-shadow var(--duration-base) var(--ease-out), transform var(--duration-base) var(--ease-out); }
.panel-interactive:hover .icon-tile { transform: translateY(-2px) scale(1.04); }

/* Shimmer border: an animated gradient outline for the one thing on the
   page that should draw the eye (the hero search). */
.shimmer-edge { position: relative; }
.shimmer-edge::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 1.5px;
  background: linear-gradient(110deg, var(--primary-border), var(--accent-3-border), rgba(255, 255, 255, 0), var(--primary-border));
  background-size: 300% 100%;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  animation: gradient-slide 9s linear infinite;
  pointer-events: none;
}

/* ══════════════════════════════════════════════════════════════════ */
/* Misc                                                                */
/* ══════════════════════════════════════════════════════════════════ */

::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: var(--radius-sm); }
::-webkit-scrollbar-thumb:hover { background: var(--primary); }

:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.btn:focus-visible, .btn-icon:focus-visible { outline-offset: 3px; }

::selection { background: var(--accent-3); color: var(--ink); }

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}

.no-scrollbar { scrollbar-width: none; }
.no-scrollbar::-webkit-scrollbar { display: none; }

.line-clamp-1, .line-clamp-2, .line-clamp-3 { display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; }
.line-clamp-1 { -webkit-line-clamp: 1; }
.line-clamp-2 { -webkit-line-clamp: 2; }
.line-clamp-3 { -webkit-line-clamp: 3; }

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .spinner, .animate-spin { animation-duration: 0.8s !important; animation-iteration-count: infinite !important; }
}
