Files
Ready-to-Planner-Tour/.agents/skills/ui-design/SKILL.md
T
2026-08-27 19:45:15 +07:00

6.6 KiB

name, description
name description
ui-design Panduan design system, CSS variables, layout, dan visual styling untuk Tour Planner App. Gunakan skill ini ketika menulis CSS, membangun layout, atau memastikan konsistensi visual antar halaman.

Skill: UI Design — Tour Planner App

Design System Lengkap

Semua token harus didefinisikan di src/index.css di dalam :root.

/* === src/index.css === */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Outfit:wght@400;500;600;700;800&family=Playfair+Display:ital,wght@0,600;1,600&display=swap');

:root {
  /* Colors */
  --color-primary: hsl(220, 90%, 56%);
  --color-primary-dark: hsl(220, 90%, 42%);
  --color-primary-light: hsl(220, 90%, 70%);
  --color-primary-glow: hsl(220, 90%, 56%, 0.3);
  
  --color-accent: hsl(38, 95%, 55%);
  --color-accent-dark: hsl(38, 95%, 40%);
  --color-accent-light: hsl(38, 95%, 70%);
  
  --color-bg-base: hsl(222, 28%, 8%);
  --color-bg-surface: hsl(222, 22%, 13%);
  --color-bg-elevated: hsl(222, 18%, 18%);
  --color-bg-overlay: hsla(222, 28%, 5%, 0.8);
  
  --color-text-primary: hsl(210, 40%, 96%);
  --color-text-secondary: hsl(210, 20%, 65%);
  --color-text-muted: hsl(210, 15%, 45%);
  
  --color-border: hsl(220, 15%, 22%);
  --color-border-light: hsl(220, 15%, 28%);
  
  --color-success: hsl(142, 70%, 45%);
  --color-success-bg: hsl(142, 70%, 45%, 0.15);
  --color-warning: hsl(38, 95%, 55%);
  --color-warning-bg: hsl(38, 95%, 55%, 0.15);
  --color-danger: hsl(0, 75%, 55%);
  --color-danger-bg: hsl(0, 75%, 55%, 0.15);
  
  /* Typography */
  --font-body: 'Inter', -apple-system, sans-serif;
  --font-display: 'Outfit', sans-serif;
  --font-hero: 'Playfair Display', serif;
  
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.25rem;
  --text-2xl: 1.5rem;
  --text-3xl: 1.875rem;
  --text-4xl: 2.25rem;
  --text-5xl: 3rem;
  
  /* Spacing */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;
  --space-20: 5rem;
  
  /* Border Radius */
  --radius-sm: 0.375rem;
  --radius-md: 0.5rem;
  --radius-lg: 0.75rem;
  --radius-xl: 1rem;
  --radius-2xl: 1.5rem;
  --radius-full: 9999px;
  
  /* Shadows */
  --shadow-sm: 0 1px 3px hsla(0,0%,0%,0.3);
  --shadow-md: 0 4px 16px hsla(0,0%,0%,0.35);
  --shadow-lg: 0 8px 32px hsla(0,0%,0%,0.4);
  --shadow-glow: 0 0 24px var(--color-primary-glow);
  
  /* Transitions */
  --transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
  --transition-base: 300ms cubic-bezier(0.4, 0, 0.2, 1);
  --transition-slow: 500ms cubic-bezier(0.4, 0, 0.2, 1);
  
  /* Z-Index */
  --z-dropdown: 100;
  --z-modal: 200;
  --z-toast: 300;
  --z-tooltip: 400;
}

CSS Utility Classes Wajib

/* Base reset */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
  font-family: var(--font-body);
  background-color: var(--color-bg-base);
  color: var(--color-text-primary);
  line-height: 1.6;
}

/* Glassmorphism */
.glass {
  background: hsla(222, 22%, 18%, 0.7);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
}

/* Gradient text */
.text-gradient {
  background: linear-gradient(135deg, var(--color-primary-light), var(--color-accent));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

/* Layout container */
.container {
  width: 100%;
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 var(--space-4);
}

/* Grid layouts */
.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-4); }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4); }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-4); }

/* Responsive grid */
@media (max-width: 1024px) {
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
  .grid-3 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
  .grid-4, .grid-3, .grid-2 { grid-template-columns: 1fr; }
}

Pola Layout Halaman

// Setiap page menggunakan struktur ini:
<div className="page-wrapper">
  <div className="page-header">
    <h1 className="page-title">Judul</h1>
    <p className="page-subtitle">Deskripsi</p>
  </div>
  <div className="page-content">
    {/* konten */}
  </div>
</div>

Komponen Hero (Home Page)

.hero {
  min-height: 100vh;
  background: 
    radial-gradient(ellipse at 20% 50%, hsl(220, 90%, 20%, 0.4) 0%, transparent 60%),
    radial-gradient(ellipse at 80% 20%, hsl(38, 95%, 20%, 0.3) 0%, transparent 60%),
    var(--color-bg-base);
  display: flex;
  align-items: center;
  position: relative;
  overflow: hidden;
}

.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml,..."); /* subtle grid pattern */
  opacity: 0.03;
}

Warna Kategori Aktivitas

export const CATEGORY_COLORS = {
  wisata: 'hsl(220, 90%, 56%)',
  makan: 'hsl(142, 70%, 45%)',
  transportasi: 'hsl(280, 70%, 60%)',
  'check-in': 'hsl(38, 95%, 55%)',
  lainnya: 'hsl(210, 20%, 55%)',
};

Warna Kategori Budget

export const BUDGET_CATEGORY_COLORS = {
  transportasi: '#4f8ef7',
  akomodasi: '#a78bfa',
  makan: '#34d399',
  aktivitas: '#fbbf24',
  'oleh-oleh': '#f87171',
  lainnya: '#94a3b8',
};

Breakpoints

/* Mobile first */
/* xs: 0+ (default) */
/* sm: 640+ */
@media (min-width: 640px) { }
/* md: 768+ */
@media (min-width: 768px) { }
/* lg: 1024+ */
@media (min-width: 1024px) { }
/* xl: 1280+ */
@media (min-width: 1280px) { }

Animasi Framer Motion Standar

// Import di setiap komponen yang butuh animasi
import { motion, AnimatePresence } from 'framer-motion';

// Fade in dari bawah (item list, card)
export const fadeInUp = {
  initial: { opacity: 0, y: 24 },
  animate: { opacity: 1, y: 0 },
  exit: { opacity: 0, y: -12 },
  transition: { duration: 0.3 }
};

// Stagger container
export const staggerContainer = {
  animate: {
    transition: { staggerChildren: 0.08, delayChildren: 0.1 }
  }
};

// Scale pop (modal, tooltip)
export const scalePop = {
  initial: { opacity: 0, scale: 0.92 },
  animate: { opacity: 1, scale: 1 },
  exit: { opacity: 0, scale: 0.92 },
  transition: { type: 'spring', stiffness: 300, damping: 24 }
};

// Slide in dari kiri (sidebar)
export const slideInLeft = {
  initial: { x: -300, opacity: 0 },
  animate: { x: 0, opacity: 1 },
  exit: { x: -300, opacity: 0 },
  transition: { type: 'spring', stiffness: 260, damping: 28 }
};