@import 'katex/dist/katex.min.css'; @tailwind base; @tailwind components; @tailwind utilities; :root { --font-scale: 1; --safe-bottom: env(safe-area-inset-bottom, 0px); --safe-top: env(safe-area-inset-top, 0px); --uqo: #0f6180; --uqo-dark: #0a4a63; --uqo-light: #e6f0f4; } html, body, #root { height: 100%; } html { -webkit-text-size-adjust: 100%; } body { @apply bg-neutral-bg text-neutral-text font-sans antialiased; font-size: calc(16px * var(--font-scale)); overscroll-behavior-y: none; -webkit-tap-highlight-color: transparent; text-rendering: optimizeLegibility; } ::selection { background: rgba(15, 97, 128, 0.18); } input, textarea, select, button { font: inherit; } /* Anti-zoom iOS: never below 16 px in inputs */ input, textarea { font-size: max(16px, 1em); } button, a { touch-action: manipulation; } *:focus-visible { outline: 2px solid var(--uqo); outline-offset: 2px; border-radius: 6px; } .scroll-thin { scrollbar-width: thin; scrollbar-color: #c5d0db transparent; } .scroll-thin::-webkit-scrollbar { width: 6px; height: 6px; } .scroll-thin::-webkit-scrollbar-thumb { background: #c5d0db; border-radius: 3px; } .no-scrollbar { scrollbar-width: none; } .no-scrollbar::-webkit-scrollbar { display: none; } /* Brand gradients */ .bg-uqo-gradient { background: linear-gradient(135deg, #0f6180 0%, #0a4a63 60%, #083a4f 100%); } .bg-uqo-soft { background: radial-gradient(1200px 400px at 20% -20%, rgba(15, 97, 128, 0.10), transparent 60%), #f4f7f9; } .shadow-soft { box-shadow: 0 1px 2px rgba(10, 74, 99, 0.05), 0 6px 20px rgba(10, 74, 99, 0.07); } .shadow-float { box-shadow: 0 2px 6px rgba(10, 74, 99, 0.08), 0 14px 34px rgba(10, 74, 99, 0.14); } /* Markdown (prose-like, mobile first) */ .md { line-height: 1.62; word-wrap: break-word; } .md > * + * { margin-top: 0.75em; } .md h1, .md h2, .md h3, .md h4 { @apply font-semibold text-uqo-blue-dark; line-height: 1.3; margin-top: 1.15em; letter-spacing: -0.01em; } .md h1 { font-size: 1.32em; } .md h2 { font-size: 1.18em; } .md h3 { font-size: 1.06em; } .md h4 { font-size: 1em; } .md p { margin: 0; } .md ul { list-style: disc; padding-left: 1.35em; } .md ol { list-style: decimal; padding-left: 1.35em; } .md li + li { margin-top: 0.3em; } .md li::marker { color: var(--uqo); } .md a { @apply text-uqo-blue underline underline-offset-2 decoration-uqo-blue/40; } .md blockquote { @apply border-l-4 border-uqo-blue/30 pl-3 text-neutral-muted bg-uqo-blue-light/40 rounded-r-lg py-1; } .md code:not(pre code) { @apply font-mono text-[0.88em] bg-neutral-surface px-1.5 py-0.5 rounded-md text-uqo-blue-dark; } .md pre { @apply font-mono text-[0.86em] rounded-xl overflow-x-auto; } .md table { display: block; overflow-x: auto; max-width: 100%; border-collapse: separate; border-spacing: 0; font-size: 0.93em; border: 1px solid theme('colors.neutral.line'); border-radius: 10px; } .md thead th { @apply bg-uqo-blue-light text-uqo-blue-dark font-semibold text-left; padding: 7px 10px; white-space: nowrap; } .md td { padding: 7px 10px; border-top: 1px solid theme('colors.neutral.line'); white-space: nowrap; } .md tbody tr:nth-child(even) td { background: #fafbfc; } .md hr { @apply border-neutral-line my-3; } .md .katex-display { overflow-x: auto; overflow-y: hidden; padding: 6px 2px; margin: 0.5em 0; } .md .katex { font-size: 1.05em; } .md img { max-width: 100%; border-radius: 10px; } .md strong { color: theme('colors.uqo.blue-dark'); } .shiki { padding: 12px 14px; margin: 0; background: #0e1f2b !important; color: #e6edf3; } .shiki code { counter-reset: line; } .streaming-cursor::after { content: '▍'; @apply text-uqo-blue; animation: blink 1s steps(2) infinite; margin-left: 1px; } @keyframes blink { 50% { opacity: 0; } } .progress-bar { position: relative; height: 3px; overflow: hidden; background: var(--uqo-light); } .progress-bar::after { content: ''; position: absolute; left: -40%; width: 40%; height: 100%; background: linear-gradient(90deg, transparent, var(--uqo), #78be20); animation: slide 1.2s ease-in-out infinite; } @keyframes slide { to { left: 100%; } } .skeleton { @apply bg-neutral-surface rounded-xl; position: relative; overflow: hidden; } .skeleton::after { content: ''; position: absolute; inset: 0; transform: translateX(-100%); background: linear-gradient(90deg, transparent, rgba(255,255,255,.7), transparent); animation: shimmer 1.4s infinite; } @keyframes shimmer { to { transform: translateX(100%); } } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } }