Skip to main content

Design Guidelines

Table of Contents

  1. Typography
  2. Color System
  3. Spacing System
  4. Layout & Containers
  5. Component Standards
  6. Component Classes
  7. Responsive Design
  8. Accessibility Guidelines
  9. Icon System

Typography

Font Family

  • Primary Font: Inter
  • Fallback: system-ui, sans-serif

Font Sizes

Size ClassValueUsage
text-xs12px / 0.75remHelper text, captions
text-sm14px / 0.875remLabels, secondary text, small UI elements
text-base16px / 1remBody text (all devices)
text-lg18px / 1.125remEmphasized text, subsection headers
text-xl20px / 1.25remCard/section headers
text-2xl24px / 1.5remMajor section headers
text-3xl30px / 1.875remPage titles

Font Weights

Weight ClassValueUsage
font-normal400Regular body text
font-medium500Medium emphasis, labels
font-semibold600Section headers, emphasis
font-bold700Strong emphasis, page headers

Line Heights

ClassValueUsage
leading-none1Headings, where tight spacing is needed
leading-tight1.25Compact text areas
leading-normal1.5Body text (default)
leading-relaxed1.625Extended reading text

Color System

OX Agry uses a nature-inspired color palette that reflects agricultural themes.

Base Colors

VariableLight ModeDark ModeUsage
backgroundhsl(60, 33%, 98%)hsl(123, 15%, 12%)Page background
foregroundhsl(147, 30%, 12%)hsl(83, 24%, 95%)Primary text
primaryhsl(123, 35%, 35%)hsl(123, 35%, 45%)Primary actions, branding
secondaryhsl(83, 24%, 95%)hsl(147, 20%, 20%)Secondary elements
mutedhsl(83, 24%, 95%)hsl(147, 20%, 20%)Subdued UI elements
accenthsl(76, 39%, 90%)hsl(147, 20%, 20%)Highlights, accents
destructivehsl(0, 74%, 42%)hsl(0, 62.8%, 40.6%)Destructive actions

Agricultural Semantic Colors

VariableValue (Light Mode)Purpose
growthhsl(123, 42%, 35%)Plant growth indicators
soilhsl(27, 65%, 45%)Soil-related data
harvesthsl(45, 85%, 50%)Harvest/yield information
waterhsl(195, 45%, 45%)Water/irrigation data
leafhsl(96, 40%, 45%)Foliage health indicators

Status Colors

VariableValue (Light Mode)Purpose
successhsl(145, 50%, 40%)Success states, healthy growth
warninghsl(35, 95%, 50%)Warning states, drought alerts
errorhsl(0, 75%, 42%)Error states, disease/pest alerts
infohsl(195, 45%, 45%)Information states, weather alerts

State Colors

StateVariablesUsage
Focus--ring: hsl(123, 35%, 45%),Interactive element focus
--ring-width: 2px
Hover--hover-opacity: 0.9,Element hover states
--hover-brightness: 1.05
Active--active-opacity: 0.8,Element active/pressed states
--active-brightness: 0.95
Disabled--disabled-bg: hsl(83, 10%, 95%),Disabled elements appearance
--disabled-text: hsl(147, 10%, 60%),
--disabled-opacity: 0.6

Spacing System

OX Agry uses a consistent spacing scale based on 4px increments.

Spacing Scale

ClassSizeUsage
p-1, m-14pxMinimal spacing, icons
p-2, m-28pxTight spacing, compact elements
p-3, m-312pxDefault inner padding
p-4, m-416pxStandard content spacing
p-6, m-624pxSection spacing
p-8, m-832pxLarge section spacing
p-12, m-1248pxMajor section divisions
p-16, m-1664pxPage level spacing

Form Field Spacing

  • Field to field spacing: 24px (m-6)
  • Label to input spacing: 8px (m-2)
  • Input to error area: 4px (m-1)
  • Reserved error text space: 20px (min-height)

Implementation Example

<div className="space-y-6">
{" "}
{/* 24px between form groups */}
<div className="form-group">
<label className="block text-sm font-medium mb-2">Field Label</label>
<input className="w-full px-3 h-11 rounded-md border border-input" />
<div className="min-h-5">
{" "}
{/* Reserved error space */}
{error && <p className="text-destructive text-sm mt-1">{error}</p>}
</div>
</div>
{/* Next form group */}
</div>

Layout & Containers

Container Widths

BreakpointContainer SizeSidebar WidthContent Width
Mobile (768px and below)100% with 16px marginsOff-canvas100% when sidebar hidden
Tablet (768px to 1279px)100% with 24px margins240-280pxRemaining space
Desktop (1280px and up)Max-width 1280-1440px280-320pxRemaining space

Layout Structure

+--------------------------------------------+
| <header> |
+--------+-----------------------------------+
| | |
| | |
| | |
| Sidebar| Content Area |
| | |
| | |
| | |
+--------+-----------------------------------+

Implementation Example

<div className="min-h-screen bg-background">
{/* Main container */}
<div className="mx-auto w-full max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="flex flex-col md:flex-row">
{/* Sidebar */}
<aside className="w-full md:w-72 lg:w-80 bg-sidebar text-sidebar-foreground">
{/* Sidebar content */}
</aside>

{/* Main content */}
<main className="flex-1 p-4 md:p-6">{/* Page content */}</main>
</div>
</div>
</div>

Component Standards

Form Controls

Heights

  • Standard height: 44px (h-11)
  • Use consistently for all interactive elements that appear in the same row

Text Inputs

StateStyling
Defaultborder-input bg-background
Focusring-2 ring-primary border-primary
Errorborder-destructive
Disabledopacity-60 bg-muted

Buttons

TypeStyling
Primarybg-primary text-primary-foreground
Secondarybg-secondary text-secondary-foreground
Outlineborder border-input bg-background hover:bg-accent
Destructivebg-destructive text-destructive-foreground
Ghosthover:bg-accent hover:text-accent-foreground
Disabledopacity-60 cursor-not-allowed

Form Structure Example

<form className="space-y-6">
{/* Form field */}
<div>
<label className="text-sm font-medium mb-2 block">Field Label</label>
<input className="w-full h-11 px-3 rounded-md border border-input" />
<div className="min-h-5">{/* Error message placeholder */}</div>
</div>

{/* Actions */}
<div className="flex gap-3 pt-2">
<button className="h-11 px-4 bg-primary text-primary-foreground rounded-md">
Submit
</button>
<button className="h-11 px-4 border border-input bg-background rounded-md">
Cancel
</button>
</div>
</form>

Cards & Panels

  • Standard padding: 16px (p-4) to 24px (p-6)
  • Rounded corners: 8px (rounded-lg)
  • Consistent border: border border-border
  • Optional shadow: shadow-sm to shadow-md
<div className="bg-card text-card-foreground p-6 rounded-lg border border-border shadow-sm">
<h3 className="text-xl font-semibold mb-4">Card Title</h3>
<div className="text-base">Card content goes here</div>
</div>

Component Classes

To maintain consistent styling while improving development efficiency, OX Agry uses reusable component classes with Tailwind CSS. This approach avoids repetitive inline styles while maintaining the flexibility of Tailwind.

Implementation Approach

Create a components.css file with reusable classes:

/* components.css */
@layer components {
/* Form Elements */
.ox-input {
@apply w-full px-3 h-11 rounded-md border border-input bg-background text-foreground;
}

.ox-input:focus {
@apply ring-2 ring-primary border-primary outline-none;
}

.ox-input:disabled {
@apply opacity-60 bg-muted cursor-not-allowed;
}

.ox-input-error {
@apply border-destructive focus:border-destructive focus:ring-destructive;
}

.ox-label {
@apply block text-sm font-medium mb-2;
}

.ox-error {
@apply text-destructive text-sm mt-1;
}

.ox-helper {
@apply text-muted-foreground text-xs mt-1;
}

.ox-form-group {
@apply mb-6;
}

.ox-error-container {
@apply min-h-5;
}

/* Buttons */
.ox-btn {
@apply h-11 px-4 rounded-md inline-flex items-center justify-center whitespace-nowrap text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-60;
}

.ox-btn-primary {
@apply bg-primary text-primary-foreground hover:bg-primary/90;
}

.ox-btn-secondary {
@apply bg-secondary text-secondary-foreground hover:bg-secondary/80;
}

.ox-btn-outline {
@apply border border-input bg-background hover:bg-accent hover:text-accent-foreground;
}

.ox-btn-destructive {
@apply bg-destructive text-destructive-foreground hover:bg-destructive/90;
}

/* Cards */
.ox-card {
@apply bg-card text-card-foreground p-6 rounded-lg border border-border shadow-sm;
}

.ox-card-title {
@apply text-lg font-semibold leading-none tracking-tight mb-3;
}

.ox-card-description {
@apply text-sm text-muted-foreground mb-4;
}

/* Agricultural-specific components */
.ox-field-data {
@apply bg-secondary p-3 rounded-md;
}

.ox-crop-badge {
@apply inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold;
}

.ox-growth-indicator {
@apply text-growth;
}

.ox-harvest-indicator {
@apply text-harvest;
}
}

Form Element Classes

ClassPurposeApplied Styles
ox-inputBase input stylingw-full px-3 h-11 rounded-md border border-input bg-background text-foreground
ox-labelForm labelsblock text-sm font-medium mb-2
ox-errorError messagestext-destructive text-sm mt-1
ox-helperHelper texttext-muted-foreground text-xs mt-1
ox-form-groupForm group wrappermb-6
ox-error-containerError containermin-h-5

Button Classes

ClassPurposeApplied Styles
ox-btnBase buttonh-11 px-4 rounded-md inline-flex items-center justify-center
ox-btn-primaryPrimary actionbg-primary text-primary-foreground hover:bg-primary/90
ox-btn-secondarySecondary actionbg-secondary text-secondary-foreground hover:bg-secondary/80
ox-btn-outlineOutline buttonborder border-input bg-background hover:bg-accent
ox-btn-destructiveDestructive actionbg-destructive text-destructive-foreground hover:bg-destructive/90

Card Classes

ClassPurposeApplied Styles
ox-cardCard containerbg-card text-card-foreground p-6 rounded-lg border border-border shadow-sm
ox-card-titleCard titletext-lg font-semibold leading-none tracking-tight mb-3
ox-card-descriptionCard descriptiontext-sm text-muted-foreground mb-4

Usage Examples

Form group with reusable classes:

<div className="ox-form-group">
<label className="ox-label">Crop Type</label>
<select className="ox-input">
<option value="wheat">Wheat</option>
<option value="corn">Corn</option>
</select>
<div className="ox-error-container">
{error && <p className="ox-error">{error}</p>}
</div>
</div>

Button examples:

<button className="ox-btn ox-btn-primary">Save Changes</button>
<button className="ox-btn ox-btn-outline">Cancel</button>

Card example:

<div className="ox-card">
<h3 className="ox-card-title">Field Report</h3>
<p className="ox-card-description">Summary of current field conditions</p>
<div className="ox-field-data">
<span className="ox-growth-indicator">Healthy growth detected</span>
</div>
</div>

Extending shadcn/UI Components

Create wrapper components that apply OX Agry specific styles:

// components/ui/OxInput.jsx
import { Input } from "@/components/ui/input";

export const OxInput = React.forwardRef((props, ref) => {
const { error, ...rest } = props;
return (
<Input
className={`h-11 ${error ? "ox-input-error" : ""}`}
{...rest}
ref={ref}
/>
);
});

This approach ensures consistent styling while leveraging Tailwind and shadcn/UI.

Responsive Design

Breakpoints

NameWidthCSS
xs< 640px(default)
sm≥ 640pxsm:...
md≥ 768pxmd:...
lg≥ 1024pxlg:...
xl≥ 1280pxxl:...
2xl≥ 1536px2xl:...

Responsive Patterns

  1. Stacking to Side-by-Side

    <div className="flex flex-col md:flex-row gap-4">
    <div className="w-full md:w-1/2">Panel 1</div>
    <div className="w-full md:w-1/2">Panel 2</div>
    </div>
  2. Grid Adaptation

    <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
    <div>Card 1</div>
    <div>Card 2</div>
    <div>Card 3</div>
    </div>
  3. Hidden to Visible Elements

    <button className="md:hidden">Mobile Menu</button>
    <nav className="hidden md:block">
    {/* Navigation items */}
    </nav>

Mobile-First Approach

Always design and implement for mobile first, then enhance for larger screens.

Accessibility Guidelines

Color Contrast

  • Text on backgrounds: Minimum 4.5:1 contrast ratio
  • Large text/headers: Minimum 3:1 contrast ratio
  • UI components/graphics: Minimum 3:1 contrast ratio against adjacent colors

Interactive Elements

  • Focus states: All interactive elements must have visible focus states
  • Touch targets: Minimum 44px × 44px for touch targets on mobile
  • Spacing: Adequate spacing between clickable elements (minimum 8px)

Keyboard Navigation

  • All interactive elements must be keyboard accessible
  • Logical tab order following visual layout
  • Focus visible at all times during keyboard navigation

Assistive Text

  • Form inputs should have associated labels
  • Images should have appropriate alt text
  • Icons used alone should have accessible names

Example Implementation

<button className="ox-btn ox-btn-primary" aria-label="Save field data">
<span>Save</span>
</button>

Icon System

Icon Sizes

SizeDimensionsUsageClass
Small16pxInline with text, dense UIsox-icon-sm
Medium20pxStandard UI elementsox-icon
Large24pxPrimary navigation, emphasisox-icon-lg
XLarge32pxFeature highlightsox-icon-xl

Icon Colors

Icons should use the text color of their context:

  • text-foreground for standard icons
  • text-muted-foreground for secondary icons
  • text-primary for emphasized icons
  • Current color (currentColor) when used within buttons/controls

Implementation Example

<button className="ox-btn ox-btn-primary">
<svg className="w-5 h-5 mr-2" viewBox="0 0 20 20" fill="currentColor">
{/* Icon paths */}
</svg>
<span>Crop Rotation</span>
</button>

Component Classes for Icons

@layer components {
.ox-icon {
@apply w-5 h-5 inline-block;
}

.ox-icon-sm {
@apply w-4 h-4;
}

.ox-icon-lg {
@apply w-6 h-6;
}

.ox-icon-xl {
@apply w-8 h-8;
}
}

Usage example:

<Icon name="crop" className="ox-icon ox-icon-lg text-primary" />