@import '@fontsource-variable/inter'; @import '@fontsource-variable/fraunces'; @import 'tailwindcss'; @import 'tw-animate-css'; @import './theme/tokens.css'; @import './theme/accents.css'; @import './theme/radius.css'; @import './theme/bridge.css'; @import './theme/cover-effects.css'; @custom-variant dark (&:is(.dark *)); .pattern-preview { position: relative; overflow: hidden; } .pattern-preview[class*='pattern-']::before { position: absolute; z-index: 1; } .pattern-dots { background-image: radial-gradient(circle, var(--dot-color) 1px, transparent 1px); background-size: 24px 24px; } .pattern-cross { background-image: radial-gradient(circle, var(--dot-color) 1px, transparent 1px), radial-gradient(circle, var(--dot-color) 1px, transparent 1px); background-size: 24px 24px; background-position: 0 0, 12px 12px; } .pattern-aurora { background-image: radial-gradient(ellipse 60% 45% at 0% 50%, color-mix(in oklch, var(--primary) 15%, transparent), transparent 100%), radial-gradient(ellipse 50% 40% at 100% 50%, color-mix(in oklch, var(--primary) 10%, transparent), transparent 100%), radial-gradient(ellipse 40% 35% at 50% 0%, color-mix(in oklch, var(--primary) 8%, transparent), transparent 100%); } .pattern-horizon { background-image: linear-gradient(180deg, transparent 0%, color-mix(in oklch, var(--primary) 8%, transparent) 50%, transparent 100%); } .pattern-topo { background-image: repeating-radial-gradient( circle at 0% 0%, transparent 0, transparent 40px, color-mix(in oklch, var(--dot-color) 50%, transparent) 40px, color-mix(in oklch, var(--dot-color) 50%, transparent) 41px, transparent 41px, transparent 80px ), repeating-radial-gradient( circle at 100% 100%, transparent 0, transparent 40px, color-mix(in oklch, var(--dot-color) 50%, transparent) 40px, color-mix(in oklch, var(--dot-color) 50%, transparent) 41px, transparent 41px, transparent 80px ); } .pattern-mesh { background-image: radial-gradient(at 0% 0%, color-mix(in oklch, var(--primary) 20%, transparent) 0px, transparent 50%), radial-gradient(at 100% 0%, color-mix(in oklch, var(--primary) 15%, transparent) 0px, transparent 50%), radial-gradient(at 100% 100%, color-mix(in oklch, var(--primary) 20%, transparent) 0px, transparent 50%), radial-gradient(at 0% 100%, color-mix(in oklch, var(--primary) 15%, transparent) 0px, transparent 50%), radial-gradient(at 50% 50%, color-mix(in oklch, var(--primary) 10%, transparent) 0px, transparent 50%); } .pattern-glow { background-image: radial-gradient(ellipse 80% 50% at 50% -10%, color-mix(in oklch, var(--primary) 20%, transparent) 0%, transparent 100%); } .pattern-brushed { background-image: repeating-linear-gradient( 45deg, transparent, transparent 1px, color-mix(in oklch, var(--primary) 6%, transparent) 1px, color-mix(in oklch, var(--primary) 6%, transparent) 2px ); } .pattern-prism::before { content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none; background-image: linear-gradient(135deg, rgba(255, 0, 0, 0.03) 0%, transparent 50%), linear-gradient(225deg, rgba(0, 0, 255, 0.03) 0%, transparent 50%), linear-gradient(45deg, rgba(0, 255, 0, 0.03) 0%, transparent 50%); filter: contrast(150%) brightness(110%); } .pattern-spectrum::before { content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none; background-image: linear-gradient(135deg, oklch(0.7 0.15 var(--tint-h) / 0.08) 0%, transparent 50%), linear-gradient(225deg, oklch(0.7 0.15 calc(var(--tint-h) + 120) / 0.08) 0%, transparent 50%), linear-gradient(45deg, oklch(0.7 0.15 calc(var(--tint-h) + 240) / 0.08) 0%, transparent 50%); filter: contrast(160%) brightness(110%); } .pattern-spectrum-x::before { content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none; background-image: linear-gradient(135deg, oklch(0.7 0.15 var(--tint-h) / 0.08) 0%, transparent 50%), linear-gradient(225deg, oklch(0.7 0.15 calc(var(--tint-h) + 90) / 0.08) 0%, transparent 50%), linear-gradient(315deg, oklch(0.7 0.15 calc(var(--tint-h) + 180) / 0.08) 0%, transparent 50%), linear-gradient(45deg, oklch(0.7 0.15 calc(var(--tint-h) + 270) / 0.08) 0%, transparent 50%); filter: contrast(160%) brightness(110%); } .pattern-spectrum-plus::before { content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none; background-image: linear-gradient(to bottom, oklch(0.7 0.15 var(--tint-h) / 0.08) 0%, transparent 50%), linear-gradient(to left, oklch(0.7 0.15 calc(var(--tint-h) + 90) / 0.08) 0%, transparent 50%), linear-gradient(to top, oklch(0.7 0.15 calc(var(--tint-h) + 180) / 0.08) 0%, transparent 50%), linear-gradient(to right, oklch(0.7 0.15 calc(var(--tint-h) + 270) / 0.08) 0%, transparent 50%); filter: contrast(160%) brightness(110%); } .pattern-eclipse::before { content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none; background-image: radial-gradient(at 0% 0%, oklch(0.7 0.15 var(--tint-h) / 0.12) 0%, transparent 65%), radial-gradient(at 100% 100%, oklch(0.7 0.15 calc(var(--tint-h) + 180) / 0.12) 0%, transparent 65%); filter: contrast(150%) brightness(110%); } .pattern-millimeter::before { content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none; background-image: linear-gradient(to right, color-mix(in oklch, var(--primary) 5%, transparent) 1px, transparent 1px), linear-gradient(to bottom, color-mix(in oklch, var(--primary) 5%, transparent) 1px, transparent 1px); background-size: 2px 2px; } .pattern-elevation::before { content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none; background-image: linear-gradient(to bottom, color-mix(in oklch, var(--primary) 5%, transparent), transparent 40%), linear-gradient(to top, color-mix(in oklch, var(--primary) 3%, transparent), transparent 30%); } .pattern-terminal::before { content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none; opacity: 0.05; background-image: repeating-linear-gradient(90deg, var(--primary), var(--primary) 1px, transparent 1px, transparent 40px); } .pattern-scanlines::before { content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none; background: linear-gradient(to bottom, transparent 50%, color-mix(in oklch, var(--primary) 5%, transparent) 50%); background-size: 100% 4px; } .pattern-vinyl::before { content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none; background-image: repeating-radial-gradient( circle at 50% -25%, transparent, transparent 3px, color-mix(in oklch, var(--primary) 8%, transparent) 3.75px, transparent 4.5px ); } .pattern-carbon::before { content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none; background-image: linear-gradient(45deg, color-mix(in oklch, var(--primary) 5%, transparent) 25%, transparent 25%), linear-gradient(-45deg, color-mix(in oklch, var(--primary) 5%, transparent) 25%, transparent 25%), linear-gradient(45deg, transparent 75%, color-mix(in oklch, var(--primary) 5%, transparent) 75%), linear-gradient(-45deg, transparent 75%, color-mix(in oklch, var(--primary) 5%, transparent) 75%); background-size: 8px 8px; } .pattern-perforated::before { content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none; background-image: radial-gradient(circle at center, color-mix(in oklch, var(--primary) 8%, transparent) 1.5px, transparent 2px); background-size: 12px 12px; } .pattern-blueprint::before { content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none; background-image: linear-gradient(to right, color-mix(in oklch, var(--primary) 4%, transparent) 1px, transparent 1px), linear-gradient(to bottom, color-mix(in oklch, var(--primary) 4%, transparent) 1px, transparent 1px); background-size: 4px 4px; } .pattern-wireframe::before { content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none; opacity: 0.1; background-color: var(--primary); -webkit-mask-image: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 50l50-50 50 50-50 50z' fill='none' stroke='black' stroke-width='0.5'/%3E%3Cpath d='M50 0v100M0 50h100' stroke='black' stroke-width='0.5'/%3E%3Ccircle cx='50' cy='50' r='2' fill='black'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 50l50-50 50 50-50 50z' fill='none' stroke='black' stroke-width='0.5'/%3E%3Cpath d='M50 0v100M0 50h100' stroke='black' stroke-width='0.5'/%3E%3Ccircle cx='50' cy='50' r='2' fill='black'/%3E%3C/svg%3E"); mask-size: 150px 150px; } .glow-wrapper { background-image: radial-gradient(50% 50% at center -25px, color-mix(in oklch, var(--primary) 35%, transparent) 0%, transparent 100%); background-blend-mode: hard-light, color-dodge; background-position: top; background-repeat: no-repeat; background-size: auto 12rem; } @layer base { * { @apply border-border outline-ring/50; scrollbar-color: var(--scrollbar-thumb) transparent; } html, body, #app, .app-shell, .app-shell-inset, .app-shell-scroll { max-width: 100%; overflow-x: clip; overscroll-behavior-x: none; } @supports not (overflow: clip) { html, body, #app, .app-shell, .app-shell-inset, .app-shell-scroll { overflow-x: hidden; } } body { @apply bg-background text-foreground font-sans antialiased; } @supports (-webkit-touch-callout: none) { @media (pointer: coarse) { /* iOS Safari auto-zooms focused inputs below 16px. Keep editable controls at 16px on touch devices. */ input:not([type='checkbox']):not([type='radio']):not([type='range']):not([type='color']):not([type='file']):not([type='button']):not( [type='submit'] ):not([type='reset']):not([data-ios-zoom-exempt]), textarea:not([data-ios-zoom-exempt]), select:not([data-ios-zoom-exempt]) { font-size: 16px; } } } @media (pointer: coarse) { .app-shell-inset, .app-shell-scroll { touch-action: pan-y; } /* Prevent double-tap zoom on tappable controls while preserving normal taps. */ a, button, [role='button'] { touch-action: manipulation; } } /* Webkit scrollbar styles */ ::-webkit-scrollbar { width: 10px; height: 10px; } ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { background: var(--scrollbar-thumb); border: 2px solid transparent; background-clip: padding-box; border-radius: 10px; } ::-webkit-scrollbar-thumb:hover { background: var(--scrollbar-thumb-hover); border: 2px solid transparent; background-clip: padding-box; } } @layer components { .viewer-btn { @apply flex items-center justify-center w-8 h-8 rounded text-foreground/60 hover:text-foreground hover:bg-muted transition-colors shrink-0 disabled:opacity-30 disabled:cursor-not-allowed; } .viewer-sep { @apply w-px h-5 mx-1 bg-border shrink-0; } /* ── Settings typography scale ────────────────────────────── Change these once to update every settings panel at once. ────────────────────────────────────────────────────────────── */ .settings-title { @apply font-serif font-semibold text-foreground text-2xl tracking-tight; } .settings-subtitle { @apply text-sm text-muted-foreground mt-1; } .settings-group-label { @apply text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-3; } .settings-label { @apply text-sm font-medium text-foreground; } .settings-hint { @apply text-xs text-muted-foreground mt-0.5; } .settings-value { @apply text-sm font-medium tabular-nums text-foreground; } /* ── Settings form controls ───────────────────────────────── Use .input-field on and .select-field on