Files
cloud-host/frontend/src/app/globals.css
T
keyhan aa7ff3d26d Fix mobile select zoom and unify optional-service version pickers.
Form controls smaller than 16px made iOS Safari auto-zoom on focus,
shifting page content upward. Enforce a 16px minimum font-size on
inputs/selects/textareas at mobile widths. Also replace the three tiny,
inconsistently-styled (colored-border, text-xs) version pickers in the
deploy wizard's optional-services cards with a shared .select-compact
style so they match the rest of the form.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 12:33:41 +03:30

240 lines
8.4 KiB
CSS

@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
body {
@apply bg-gray-50 text-gray-900 antialiased;
}
/* Smooth scrollbar */
::-webkit-scrollbar {
@apply w-1.5 h-1.5;
}
::-webkit-scrollbar-track {
@apply bg-transparent;
}
::-webkit-scrollbar-thumb {
@apply bg-gray-300 rounded-full hover:bg-gray-400;
}
}
@layer components {
/* ─── Buttons ──────────────────────────────────────────── */
.btn-primary {
@apply inline-flex items-center justify-center gap-2 bg-primary-600 text-white
px-4 py-2.5 rounded-xl font-semibold text-sm
hover:bg-primary-700 active:scale-[0.98]
focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2
transition-all duration-150 disabled:opacity-50 disabled:cursor-not-allowed
shadow-sm hover:shadow-md;
}
.btn-secondary {
@apply inline-flex items-center justify-center gap-2 bg-white text-gray-700
px-4 py-2.5 rounded-xl font-semibold text-sm border border-gray-300
hover:bg-gray-50 active:scale-[0.98]
focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2
transition-all duration-150 shadow-sm;
}
.btn-danger {
@apply inline-flex items-center justify-center gap-2 bg-red-600 text-white
px-4 py-2.5 rounded-xl font-semibold text-sm
hover:bg-red-700 active:scale-[0.98]
focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2
transition-all duration-150 shadow-sm hover:shadow-md
disabled:opacity-50 disabled:cursor-not-allowed;
}
.btn-ghost {
@apply inline-flex items-center justify-center gap-2 text-gray-600
px-3 py-2 rounded-xl font-medium text-sm
hover:bg-gray-100 active:scale-[0.98]
focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2
transition-all duration-150;
}
.btn-icon {
@apply inline-flex items-center justify-center w-9 h-9 rounded-xl
text-gray-500 hover:bg-gray-100 hover:text-gray-700
active:scale-[0.95] transition-all duration-150;
}
/* ─── Inputs ──────────────────────────────────────────── */
.input-field {
@apply w-full px-3.5 py-2.5 border border-gray-300 rounded-xl shadow-sm text-sm
placeholder-gray-400 bg-white
focus:outline-none focus:ring-2 focus:ring-primary-500/20 focus:border-primary-500
transition-all duration-150;
}
/* Compact, design-consistent select for inline rows (e.g. version pickers). */
.select-compact {
@apply rounded-lg border border-gray-300 bg-white px-2.5 py-1.5 text-sm shadow-sm
text-gray-800 cursor-pointer
focus:outline-none focus:ring-2 focus:ring-primary-500/20 focus:border-primary-500
transition-all duration-150;
}
/* ─── Cards ──────────────────────────────────────────── */
.card {
@apply bg-white rounded-2xl shadow-sm border border-gray-200/80 p-6
transition-shadow duration-200;
}
.card-hover {
@apply card hover:shadow-md hover:border-gray-300;
}
/* ─── Badges ──────────────────────────────────────────── */
.badge {
@apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-semibold;
}
.badge-green { @apply badge bg-emerald-100 text-emerald-700; }
.badge-red { @apply badge bg-red-100 text-red-700; }
.badge-blue { @apply badge bg-blue-100 text-blue-700; }
.badge-yellow { @apply badge bg-amber-100 text-amber-700; }
.badge-gray { @apply badge bg-gray-100 text-gray-600; }
.badge-purple { @apply badge bg-purple-100 text-purple-700; }
/* ─── Stat card ──────────────────────────────────────── */
.stat-card {
@apply bg-white rounded-2xl border border-gray-200/80 p-5 shadow-sm
flex flex-col gap-1;
}
.stat-value {
@apply text-3xl font-bold tracking-tight;
}
.stat-label {
@apply text-sm font-medium text-gray-500;
}
/* ─── Table ──────────────────────────────────────────── */
.table-wrapper {
@apply overflow-hidden rounded-2xl border border-gray-200/80 bg-white shadow-sm;
}
/* ─── Loading skeleton ──────────────────────────────── */
.skeleton {
@apply animate-pulse bg-gray-200 rounded-xl;
}
/* ─── Page header ──────────────────────────────────── */
.page-header {
@apply flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4;
}
.page-title {
@apply text-2xl font-bold text-gray-900 tracking-tight;
}
.page-subtitle {
@apply text-sm text-gray-500 mt-0.5;
}
}
/* ─── Animations ─────────────────────────────────────── */
@keyframes fadeIn {
from { opacity: 0; transform: translateY(8px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes slideUp {
from { opacity: 0; transform: translateY(16px); }
to { opacity: 1; transform: translateY(0); }
}
.animate-fade-in {
animation: fadeIn 0.3s ease-out;
}
.animate-slide-up {
animation: slideUp 0.4s ease-out;
}
/* ─── Modal animations ───────────────────────────────── */
@keyframes modalBackdropIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes modalEnter {
from { opacity: 0; transform: scale(0.95) translateY(8px); }
to { opacity: 1; transform: scale(1) translateY(0); }
}
.animate-modal-backdrop {
animation: modalBackdropIn 0.15s ease-out;
}
.animate-modal-enter {
animation: modalEnter 0.2s ease-out;
}
/* ─── Lenis smooth scroll (only active on the landing page) ─── */
html.lenis,
html.lenis body {
height: auto;
}
.lenis.lenis-smooth {
scroll-behavior: auto !important;
}
.lenis.lenis-smooth [data-lenis-prevent] {
overscroll-behavior: contain;
}
.lenis.lenis-stopped {
overflow: hidden;
}
.lenis.lenis-smooth iframe {
pointer-events: none;
}
/* ─── Landing-only helpers ───────────────────────────── */
@keyframes abrbanFloat {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}
@keyframes abrbanScrollHint {
0% { opacity: 0; transform: translateY(-6px); }
50% { opacity: 1; }
100% { opacity: 0; transform: translateY(8px); }
}
@keyframes abrbanShimmer {
to { background-position: 200% center; }
}
.abrban-float { animation: abrbanFloat 6s ease-in-out infinite; }
.abrban-scroll-hint { animation: abrbanScrollHint 1.8s ease-in-out infinite; }
.abrban-shimmer {
background: linear-gradient(100deg, #93c5fd 0%, #ffffff 25%, #2563eb 50%, #ffffff 75%, #93c5fd 100%);
background-size: 200% auto;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
animation: abrbanShimmer 6s linear infinite;
filter: drop-shadow(0 2px 12px rgba(2, 6, 23, 0.55));
}
/* Strong legibility over the ever-changing sky (bright clouds <-> dark storm). */
.abrban-ink {
text-shadow: 0 1px 2px rgba(2, 6, 23, 0.5), 0 6px 30px rgba(2, 6, 23, 0.45);
}
/* Frosted dark-glass panel so text stays crisp on any weather stage. */
.abrban-panel {
background: rgba(15, 23, 42, 0.46);
backdrop-filter: blur(18px) saturate(125%);
-webkit-backdrop-filter: blur(18px) saturate(125%);
border: 1px solid rgba(255, 255, 255, 0.12);
box-shadow:
0 30px 80px -30px rgba(2, 6, 23, 0.78),
inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
@media (prefers-reduced-motion: reduce) {
.abrban-float,
.abrban-scroll-hint,
.abrban-shimmer {
animation: none;
}
}
/* Mobile: keep form controls at a 16px minimum so iOS Safari doesn't auto-zoom
(and shift the page contents up) when a field/select is focused. */
@media (max-width: 640px) {
input:not([type='checkbox']):not([type='radio']):not([type='range']),
select,
textarea {
font-size: 16px !important;
}
}