@tailwind base; @tailwind components; @tailwind utilities; /* Self-hosted fonts (no external CDN). Inter = body/UI, Fraunces = display headings. */ @font-face { font-family: "Inter"; font-weight: 400; font-display: swap; src: url("/fonts/inter-400.woff2") format("woff2"); } @font-face { font-family: "Inter"; font-weight: 500; font-display: swap; src: url("/fonts/inter-500.woff2") format("woff2"); } @font-face { font-family: "Inter"; font-weight: 600; font-display: swap; src: url("/fonts/inter-600.woff2") format("woff2"); } @font-face { font-family: "Inter"; font-weight: 700; font-display: swap; src: url("/fonts/inter-700.woff2") format("woff2"); } @font-face { font-family: "Fraunces"; font-weight: 600; font-display: swap; src: url("/fonts/fraunces-600.woff2") format("woff2"); } @font-face { font-family: "Fraunces"; font-weight: 700; font-display: swap; src: url("/fonts/fraunces-700.woff2") format("woff2"); } @layer base { /* Warm cream page with a faint paper grain so the background doesn't read as flat/sterile. The grain is a self-contained inline SVG fractal-noise (no external asset), fixed to the viewport so it stays put while content scrolls. Cards sit opaque on top of it. */ body { @apply bg-gray-50 text-gray-900; /* Paper grain — bumped to be clearly visible (coarser + higher opacity than before). */ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='p'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.7' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23p)' opacity='0.12'/%3E%3C/svg%3E"); background-attachment: fixed; } } @layer components { .btn { @apply inline-flex items-center justify-center rounded-md px-4 py-2 text-sm font-medium transition disabled:opacity-50 disabled:cursor-not-allowed; /* Finer grain than the page background (higher frequency, lower opacity) so buttons pick up the same paper feel without looking rough. Layers over each variant's background color below. */ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='b'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23b)' opacity='0.09'/%3E%3C/svg%3E"); } .btn-primary { @apply btn bg-brand-600 text-white hover:bg-brand-700; } .btn-secondary { @apply btn bg-white text-gray-800 border border-gray-300 hover:bg-gray-50; } .btn-danger { @apply btn bg-red-600 text-white hover:bg-red-700; } .input { @apply w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-brand-500 focus:ring-1 focus:ring-brand-500 outline-none; } .label { @apply block text-sm font-medium text-gray-700 mb-1; } .card { @apply rounded-lg border border-gray-200 bg-white p-4 shadow-sm; } .badge { @apply inline-block rounded-full px-2 py-0.5 text-xs font-medium; } /* Inline citation links (Credits). Tailwind's preflight resets anchors to `color: inherit; text-decoration: inherit`, so without this every renders as plain body text and reads as if the link were never added. */ .link { @apply text-leaf-700 underline underline-offset-2 hover:text-leaf-800; } } /* Scanning line that sweeps down a photo while it's being embedded/searched. */ @keyframes scan-sweep { 0% { top: 4%; opacity: 0; } 15% { opacity: 1; } 85% { opacity: 1; } 100% { top: 96%; opacity: 0; } } .scan-sweep { animation: scan-sweep 1.15s ease-in-out infinite; } @media (prefers-reduced-motion: reduce) { .scan-sweep { animation: none; top: 50%; } }