| name | ipad-pro-design |
| description | CSS and UX patterns for iPad Pro 12.9" development. Covers viewport configuration, touch optimization, safe areas, ProMotion animations, and child-friendly design patterns. Use when building educational apps targeting iPad Pro. |
| allowed-tools | Read, Write, Edit, Glob, Grep |
iPad Pro 12.9" Design Skill
Comprehensive CSS and UX patterns for building educational web applications optimized for iPad Pro 12.9" (M1/M2/M4). This skill integrates with the project's Utopia fluid scales and web components architecture.
Related Skills
utopia-fluid-scales: Fluid typography and spacing tokens (cqi-based)utopia-container-queries: Container setup for fluid scalesweb-components: Component architecture patternsux-accessibility: Focus management and WCAG complianceux-animation-motion: Animation timing and reduced motionanimejs-v4: Hardware-accelerated animations
iPad Pro 12.9" Technical Specifications
Display Specifications
| Property | Value |
|---|---|
| Screen Resolution | 2732 x 2048 pixels |
| Points Resolution | 1366 x 1024 points |
| Device Pixel Ratio | 2x (@2x Retina) |
| PPI | 264 pixels per inch |
| Display Type | Liquid Retina XDR |
| Refresh Rate | ProMotion 24-120Hz adaptive |
| Color | P3 wide color gamut |
| Peak Brightness | 1600 nits HDR, 1000 nits full-screen |
Viewport Calculations
CSS Pixels (Landscape): 1366 x 1024
CSS Pixels (Portrait): 1024 x 1366
Device Pixels (Landscape): 2732 x 2048
Device Pixels (Portrait): 2048 x 2732
Safe Areas
| Edge | Safe Inset (Points) |
|---|---|
| Top (Portrait, no notch) | 24pt status bar |
| Top (Landscape, no notch) | 24pt status bar |
| Bottom (all orientations) | 20pt home indicator |
| Left/Right (Landscape) | 0pt (no notch on 12.9") |
Viewport Configuration
Required Meta Tag
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
| Attribute | Purpose |
|---|---|
width=device-width |
Match CSS viewport to device width |
initial-scale=1 |
Prevent default zoom, 1:1 scale |
viewport-fit=cover |
Extend content to screen edges (enables safe area insets) |
AVOID These Viewport Settings
<!-- DON'T: Disabling zoom breaks accessibility -->
<meta name="viewport" content="... user-scalable=no">
<meta name="viewport" content="... maximum-scale=1">
<!-- DON'T: Fixed width creates horizontal scroll -->
<meta name="viewport" content="width=1024">
PWA Optimizations
<!-- Full-screen web app (home screen) -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<!-- Prevent text size adjustment -->
<meta name="apple-mobile-web-app-title" content="Fantasy Phonics">
<!-- Theme color for Safari UI -->
<meta name="theme-color" content="#252119">
Safe Area Handling
CSS Environment Variables
Safari on iPadOS provides safe area values via env():
:root {
/* Safe area fallbacks for non-Safari browsers */
--safe-area-inset-top: env(safe-area-inset-top, 0px);
--safe-area-inset-right: env(safe-area-inset-right, 0px);
--safe-area-inset-bottom: env(safe-area-inset-bottom, 0px);
--safe-area-inset-left: env(safe-area-inset-left, 0px);
}
Applying Safe Areas
/* Full-screen layout with safe areas */
.app-container {
padding-top: var(--safe-area-inset-top);
padding-right: var(--safe-area-inset-right);
padding-bottom: var(--safe-area-inset-bottom);
padding-left: var(--safe-area-inset-left);
}
/* Fixed bottom navigation */
.bottom-nav {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding-bottom: calc(var(--space-s) + var(--safe-area-inset-bottom));
}
/* Fixed header */
.header {
position: fixed;
top: 0;
left: 0;
right: 0;
padding-top: calc(var(--space-s) + var(--safe-area-inset-top));
}
Home Indicator Avoidance
The home indicator appears at the bottom of screen. Avoid placing interactive elements in this zone:
.interactive-bottom-zone {
/* Ensure 20pt clearance from bottom */
margin-bottom: max(20px, var(--safe-area-inset-bottom));
}
Touch Target Optimization
Apple Human Interface Guidelines
| Guideline | Value | Project Token |
|---|---|---|
| Minimum touch target | 44pt x 44pt | --min-touch-target |
| Recommended touch target | 48pt x 48pt | Use --space-xl |
| Child-friendly target | 56pt+ | Use --space-2xl |
| Spacing between targets | 8pt minimum | Use --space-2xs |
Touch Target Patterns
/* Standard touch target (adults) */
.touch-target {
min-width: var(--min-touch-target);
min-height: var(--min-touch-target);
}
/* Large touch target (children 3-8 years) */
.touch-target-child {
min-width: var(--space-2xl); /* 72-80px */
min-height: var(--space-2xl);
}
/* Extra-large target (toddlers/accessibility) */
.touch-target-xl {
min-width: var(--space-3xl); /* 108-120px */
min-height: var(--space-3xl);
}
/* Expanded hit area for small visual elements */
.touch-expand::before {
content: '';
position: absolute;
inset: -8px;
/* Or for child-friendly: */
inset: calc(-1 * var(--space-s));
}
Button Sizing for Children
/* Primary game button - child-friendly */
.game-button {
min-width: var(--space-3xl);
min-height: var(--space-2xl);
padding: var(--space-m) var(--space-xl);
font-size: var(--step-1);
border-radius: var(--space-s);
}
/* Card selection - large tap area */
.word-card {
min-width: 120px;
min-height: 120px;
padding: var(--space-m);
}
Media Queries for iPad Pro
Device-Specific Targeting
/* iPad Pro 12.9" Landscape */
@media screen and (min-width: 1024px) and (max-width: 1366px) and (orientation: landscape) {
/* Landscape-specific styles */
}
/* iPad Pro 12.9" Portrait */
@media screen and (min-width: 1024px) and (max-width: 1366px) and (orientation: portrait) {
/* Portrait-specific styles */
}
/* iPad Pro 12.9" - Any orientation */
@media screen and (min-width: 1024px) and (max-width: 1366px) {
/* Tablet-specific styles */
}
/* High-DPI screens (Retina) */
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
/* High-DPI assets and adjustments */
}
Pointer and Hover Detection
iPadOS supports both touch and Apple Pencil/trackpad. Detect input type:
/* Touch-only devices */
@media (hover: none) and (pointer: coarse) {
.tooltip-trigger:hover .tooltip {
/* Don't show hover tooltips on touch */
display: none;
}
}
/* Devices with fine pointer (trackpad/mouse) */
@media (hover: hover) and (pointer: fine) {
.interactive:hover {
/* Show hover states */
background: var(--color-hover-overlay);
}
}
/* Devices with coarse pointer (finger/stylus) */
@media (pointer: coarse) {
.interactive {
/* Larger touch targets */
min-height: var(--min-touch-target);
min-width: var(--min-touch-target);
}
}
Container Queries (Preferred)
Container queries are preferred over viewport queries for component responsiveness:
/* Set container on parent */
.game-board {
container-type: inline-size;
}
/* Component responds to container, not viewport */
@container (inline-size > 800px) {
.word-card {
flex-direction: row;
padding: var(--space-l);
}
}
@container (inline-size <= 600px) {
.word-card {
flex-direction: column;
padding: var(--space-m);
}
}
ProMotion (120Hz) Animation Optimization
Hardware Acceleration
Safari on iPadOS uses hardware acceleration for specific CSS properties. Always animate these properties for smooth 120Hz performance:
| Property | Hardware Accelerated |
|---|---|
transform |
Yes - always use |
opacity |
Yes - always use |
filter |
Yes (simple filters) |
backdrop-filter |
Yes |
will-change |
Promotes to GPU layer |
| Property | NOT Hardware Accelerated |
|---|---|
width, height |
Triggers layout |
margin, padding |
Triggers layout |
top, left, right, bottom |
Triggers layout |
border-width |
Triggers layout |
font-size |
Triggers layout |
box-shadow |
CPU intensive |
Animation Timing for 120Hz
At 120Hz, each frame is 8.33ms. Animation timing feels different:
:root {
/* Snappy micro-interactions */
--duration-instant: 100ms; /* 12 frames at 120Hz */
--duration-quick: 150ms; /* 18 frames at 120Hz */
--duration-normal: 200ms; /* 24 frames at 120Hz */
--duration-slow: 350ms; /* 42 frames at 120Hz */
/* Ease curves for natural feel */
--ease-out: cubic-bezier(0.0, 0.0, 0.2, 1); /* Decelerate */
--ease-in-out: cubic-bezier(0.4, 0.0, 0.2, 1); /* Standard */
--ease-spring: cubic-bezier(0.175, 0.885, 0.32, 1.275); /* Overshoot */
}
CSS Transitions (ProMotion Optimized)
.card {
/* Use transform instead of position */
transform: translateY(0) scale(1);
opacity: 1;
transition:
transform var(--duration-normal) var(--ease-out),
opacity var(--duration-quick) var(--ease-out);
}
.card:active {
/* Press feedback - instant response */
transform: scale(0.97);
transition-duration: var(--duration-instant);
}
.card.selected {
transform: translateY(-8px) scale(1.02);
}
Anime.js 4.0 for Complex Animations
Use Anime.js for multi-property animations:
import { animate, createSpring } from 'animejs';
// Check reduced motion preference first
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
function cardSelectAnimation(element) {
if (prefersReducedMotion) {
element.classList.add('selected');
return;
}
return animate(element, {
scale: [1, 1.05, 1],
translateY: [0, -8, -4],
duration: 250,
ease: 'outBack'
});
}
// Spring physics for natural feel
function dragDropAnimation(element) {
return animate(element, {
x: 0,
y: 0,
ease: createSpring({ stiffness: 400, damping: 25 }),
});
}
will-change Usage
Use will-change sparingly - only on elements that will animate:
/* Apply before animation starts */
.card {
will-change: transform;
}
/* Remove after animation completes (via JavaScript) */
.card.animation-complete {
will-change: auto;
}
// Anime.js lifecycle hooks
animate(element, {
scale: [1, 1.1, 1],
onBegin: () => {
element.style.willChange = 'transform';
},
onComplete: () => {
element.style.willChange = 'auto';
}
});
Touch Interaction Patterns
Pointer Events (Unified API)
Use Pointer Events API for unified touch/mouse/stylus handling:
class DraggableCard extends HTMLElement {
#isDragging = false;
#startX = 0;
#startY = 0;
connectedCallback() {
this.addEventListener('pointerdown', this);
this.addEventListener('pointermove', this);
this.addEventListener('pointerup', this);
this.addEventListener('pointercancel', this);
// Prevent default touch behaviors
this.style.touchAction = 'none';
}
disconnectedCallback() {
this.removeEventListener('pointerdown', this);
this.removeEventListener('pointermove', this);
this.removeEventListener('pointerup', this);
this.removeEventListener('pointercancel', this);
}
handleEvent(e) {
switch (e.type) {
case 'pointerdown':
this.#handlePointerDown(e);
break;
case 'pointermove':
this.#handlePointerMove(e);
break;
case 'pointerup':
case 'pointercancel':
this.#handlePointerUp(e);
break;
}
}
#handlePointerDown(e) {
this.#isDragging = true;
this.#startX = e.clientX;
this.#startY = e.clientY;
// Capture pointer for reliable tracking
this.setPointerCapture(e.pointerId);
// Visual feedback
this.setAttribute('aria-grabbed', 'true');
}
#handlePointerMove(e) {
if (!this.#isDragging) return;
const deltaX = e.clientX - this.#startX;
const deltaY = e.clientY - this.#startY;
// Direct transform for 120Hz smoothness - no animate() during drag
this.style.transform = `translate(${deltaX}px, ${deltaY}px)`;
}
#handlePointerUp(e) {
if (!this.#isDragging) return;
this.#isDragging = false;
this.releasePointerCapture(e.pointerId);
this.removeAttribute('aria-grabbed');
// Animate back with physics
this.#animateDrop();
}
#animateDrop() {
animate(this, {
x: 0,
y: 0,
duration: 300,
ease: 'outBack'
});
}
}
CSS touch-action Control
/* Allow vertical scroll only */
.scrollable-list {
touch-action: pan-y;
}
/* Disable all touch behaviors (for custom drag) */
.draggable {
touch-action: none;
}
/* Allow pinch-zoom but not pan */
.zoomable-image {
touch-action: pinch-zoom;
}
/* Default - allow all */
.interactive {
touch-action: manipulation; /* Disables double-tap zoom delay */
}
Tap vs Long-Press
class TappableElement extends HTMLElement {
#longPressTimeout = null;
#longPressTriggered = false;
static LONG_PRESS_DURATION = 500; // ms
connectedCallback() {
this.addEventListener('pointerdown', this);
this.addEventListener('pointerup', this);
this.addEventListener('pointercancel', this);
}
handleEvent(e) {
switch (e.type) {
case 'pointerdown':
this.#longPressTriggered = false;
this.#longPressTimeout = setTimeout(() => {
this.#longPressTriggered = true;
this.#handleLongPress(e);
}, TappableElement.LONG_PRESS_DURATION);
break;
case 'pointerup':
clearTimeout(this.#longPressTimeout);
if (!this.#longPressTriggered) {
this.#handleTap(e);
}
break;
case 'pointercancel':
clearTimeout(this.#longPressTimeout);
break;
}
}
#handleTap(e) {
this.dispatchEvent(new CustomEvent('tap', {
bubbles: true,
detail: { x: e.clientX, y: e.clientY }
}));
}
#handleLongPress(e) {
// Haptic feedback if available
if (navigator.vibrate) navigator.vibrate(10);
this.dispatchEvent(new CustomEvent('longpress', {
bubbles: true,
detail: { x: e.clientX, y: e.clientY }
}));
}
}
Hover State Handling
iPadOS triggers :hover on first tap, then :active on second. Handle this:
/* Default: no hover effects for touch */
@media (hover: none) {
.button:hover {
/* Reset hover styles for touch devices */
background: var(--button-bg);
}
}
/* Only apply hover for devices that support it */
@media (hover: hover) {
.button:hover {
background: var(--color-hover-overlay);
transform: translateY(-1px);
}
}
/* Active state works on both */
.button:active {
background: var(--color-active-overlay);
transform: scale(0.98);
}
Layout Patterns for 12.9" Display
Grid for Large Tablets
/* Game board - uses full width */
.game-board {
container-type: inline-size;
display: grid;
gap: var(--grid-gutter);
padding: var(--space-m);
}
/* Landscape: 4 columns */
@container (inline-size >= 1024px) {
.card-grid {
grid-template-columns: repeat(4, 1fr);
}
}
/* Portrait: 3 columns */
@container (inline-size >= 768px) and (inline-size < 1024px) {
.card-grid {
grid-template-columns: repeat(3, 1fr);
}
}
/* Small containers: 2 columns */
@container (inline-size < 768px) {
.card-grid {
grid-template-columns: repeat(2, 1fr);
}
}
Avoiding "Blown-Up Phone" Layouts
/* DON'T: Single column on large screens */
.page-content {
max-width: 100%; /* Content stretches uncomfortably */
}
/* DO: Constrain content width, use whitespace */
.page-content {
max-width: var(--grid-max-width); /* 1240px */
margin-inline: auto;
padding-inline: var(--space-l);
}
/* DO: Multi-column layouts on large screens */
.main-layout {
display: grid;
grid-template-columns: 1fr 2fr 1fr; /* Sidebar | Main | Aside */
gap: var(--grid-gutter);
}
Orientation Change Handling
/* Landscape-specific adjustments */
@media (orientation: landscape) {
.game-ui {
flex-direction: row;
.sidebar {
width: 280px;
flex-shrink: 0;
}
.main-content {
flex: 1;
}
}
}
/* Portrait-specific adjustments */
@media (orientation: portrait) {
.game-ui {
flex-direction: column;
.sidebar {
width: 100%;
height: auto;
}
.main-content {
flex: 1;
}
}
}
JavaScript Orientation Detection
class OrientationAware extends HTMLElement {
#mediaQuery = window.matchMedia('(orientation: landscape)');
connectedCallback() {
this.#mediaQuery.addEventListener('change', this);
this.#updateOrientation();
}
disconnectedCallback() {
this.#mediaQuery.removeEventListener('change', this);
}
handleEvent(e) {
if (e.type === 'change') {
this.#updateOrientation();
}
}
#updateOrientation() {
const isLandscape = this.#mediaQuery.matches;
this.setAttribute('data-orientation', isLandscape ? 'landscape' : 'portrait');
this.dispatchEvent(new CustomEvent('orientation-change', {
bubbles: true,
detail: { isLandscape }
}));
}
}
Child-Friendly UX Patterns
Design Principles for Children (Ages 3-8)
| Principle | Implementation |
|---|---|
| Large tap targets | Minimum 56pt (prefer 72pt+) |
| Clear visual feedback | Immediate bounce/glow on tap |
| Simple navigation | Max 2-3 choices visible |
| Forgiving interactions | Accept imprecise taps, allow undo |
| Consistent layout | Same button positions across screens |
| No time pressure | Avoid timers for young children |
| Positive reinforcement | Celebrate success, gentle error handling |
Visual Feedback for Children
// Immediate, exaggerated feedback
function childFriendlyTapFeedback(element) {
// Instant scale down
animate(element, {
scale: 0.9,
duration: 80,
ease: 'linear'
}).then(() => {
// Bouncy return
animate(element, {
scale: [0.9, 1.15, 1],
duration: 300,
ease: 'outBack'
});
});
}
// Success celebration
function celebrateSuccess(element) {
return animate(element, {
scale: [1, 1.3, 1],
rotate: [0, -8, 8, -4, 4, 0],
duration: 500,
ease: 'outElastic(1, 0.5)'
});
}
// Gentle error shake (not scary)
function gentleErrorShake(element) {
return animate(element, {
x: [0, -4, 4, -2, 2, 0],
duration: 300,
ease: 'linear'
});
}
Progressive Disclosure
<!-- Show only essential options initially -->
<nav class="game-nav" aria-label="Game navigation">
<button class="nav-item nav-item--current" aria-current="page">
<span class="icon" aria-hidden="true">play_arrow</span>
<span class="label">Play</span>
</button>
<!-- Advanced options hidden until needed -->
<button class="nav-item" hidden data-requires-progress="5">
<span class="icon" aria-hidden="true">settings</span>
<span class="label">Settings</span>
</button>
</nav>
Forgiving Touch Zones
/* Extra-large interactive cards for children */
.word-card-child {
min-width: 140px;
min-height: 140px;
padding: var(--space-l);
/* Expanded hit area beyond visual bounds */
position: relative;
}
.word-card-child::before {
content: '';
position: absolute;
inset: calc(-1 * var(--space-m)); /* 27-30px expansion */
}
/* Wide spacing between cards to prevent mis-taps */
.card-grid-child {
gap: var(--space-l); /* 36-40px */
}
Audio Feedback (Optional)
class AudioFeedback {
#audioContext = null;
#enabled = true;
constructor() {
// Initialize on first user interaction
document.addEventListener('pointerdown', () => {
if (!this.#audioContext) {
this.#audioContext = new AudioContext();
}
}, { once: true });
}
playTap() {
if (!this.#enabled || !this.#audioContext) return;
this.#playTone(800, 50); // Short, high beep
}
playSuccess() {
if (!this.#enabled || !this.#audioContext) return;
this.#playMelody([523, 659, 784], 100); // C-E-G chord
}
playError() {
if (!this.#enabled || !this.#audioContext) return;
this.#playTone(200, 150); // Low, longer tone
}
#playTone(frequency, duration) {
const oscillator = this.#audioContext.createOscillator();
const gainNode = this.#audioContext.createGain();
oscillator.connect(gainNode);
gainNode.connect(this.#audioContext.destination);
oscillator.frequency.value = frequency;
gainNode.gain.setValueAtTime(0.1, this.#audioContext.currentTime);
gainNode.gain.exponentialRampToValueAtTime(0.01, this.#audioContext.currentTime + duration / 1000);
oscillator.start();
oscillator.stop(this.#audioContext.currentTime + duration / 1000);
}
#playMelody(frequencies, noteDuration) {
frequencies.forEach((freq, i) => {
setTimeout(() => this.#playTone(freq, noteDuration), i * noteDuration);
});
}
toggle(enabled) {
this.#enabled = enabled;
}
}
Safari/WebKit Considerations
Supported CSS Features (iPadOS 17+)
| Feature | Support | Notes |
|---|---|---|
| Container Queries | Full | Use cqi units |
:has() selector |
Full | Use for complex states |
| Subgrid | Full | Use for nested grids |
view-transitions |
Partial | Same-document only |
field-sizing |
Yes | Auto-sizing textareas |
@layer |
Full | CSS cascade layers |
color-mix() |
Full | Dynamic color blending |
| Backdrop filter | Full | With -webkit- prefix |
Safari-Specific CSS
/* Backdrop blur - requires prefix */
.modal-backdrop {
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
}
/* Prevent iOS font boosting */
body {
-webkit-text-size-adjust: 100%;
text-size-adjust: 100%;
}
/* Smooth scrolling with momentum */
.scrollable {
-webkit-overflow-scrolling: touch;
overflow-y: auto;
}
/* Hide scrollbar but keep functionality */
.scrollable::-webkit-scrollbar {
display: none;
}
Known Safari Limitations
| Issue | Workaround |
|---|---|
No popover attribute |
Use <dialog> or custom implementation |
| Limited Fullscreen API | Works in standalone PWA mode only |
| No Web MIDI | Use Web Audio API instead |
| IndexedDB storage limits | 1GB quota, request via Storage API |
No beforeinstallprompt |
Manual PWA install instructions |
PWA Capabilities
// manifest.json
{
"name": "Fantasy Phonics",
"short_name": "Phonics",
"display": "standalone",
"orientation": "any",
"background_color": "#252119",
"theme_color": "#252119",
"icons": [
{ "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png" }
],
"start_url": "/",
"scope": "/"
}
Performance Checklist
Rendering Performance
- Use
transformandopacityfor animations (GPU accelerated) - Apply
will-changebefore animations, remove after - Use
contain: layouton fixed-size containers - Avoid animating during scroll (use
scroll-behavior: smoothinstead) - Batch DOM reads and writes (avoid layout thrashing)
Touch Performance
- Use
touch-action: manipulationto remove 300ms tap delay - Apply
pointer-events: noneto elements during drag - Use
pointerdown/pointermove/pointerup(not touch events) - Set
passive: trueon scroll/touch listeners when not preventing default
Memory Management
- Clean up event listeners in
disconnectedCallback - Cancel animations when component unmounts
- Use
AbortControllerfor cancellable fetch requests - Avoid creating objects in animation loops
Asset Optimization
- Use
srcsetfor images at 1x and 2x resolutions - Lazy load images below the fold with
loading="lazy" - Preload critical fonts with
<link rel="preload"> - Use WebP/AVIF images where supported
Quick Reference
Viewport & Safe Areas
/* Essential meta tag */
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
/* Safe area padding */
padding: env(safe-area-inset-top) env(safe-area-inset-right)
env(safe-area-inset-bottom) env(safe-area-inset-left);
Touch Targets
/* Adults */ min-width: 44px; min-height: 44px;
/* Children */ min-width: 72px; min-height: 72px;
Media Queries
/* iPad Pro 12.9" specific */
@media (min-width: 1024px) and (max-width: 1366px) { }
/* Touch-only */
@media (hover: none) and (pointer: coarse) { }
/* Orientation */
@media (orientation: landscape) { }
Animation Timing (120Hz)
--duration-instant: 100ms; /* Tap feedback */
--duration-quick: 150ms; /* State changes */
--duration-normal: 200ms; /* Transitions */
Integration with Project Tokens
/* Use Utopia space tokens for consistent sizing */
.touch-target-child {
min-width: var(--space-2xl); /* 72-80px */
min-height: var(--space-2xl);
padding: var(--space-m); /* 27-30px */
gap: var(--space-s); /* 18-20px */
}
/* Use Utopia type tokens for readable text */
.game-label {
font-size: var(--step-1); /* 21.6-25px */
}
Files
This skill references and integrates with:
css/styles/accessibility.css- Touch target tokens, focus ringscss/styles/space.css- Utopia spacing scalecss/styles/typography.css- Utopia type scalecss/styles/transitions.css- Animation timing tokens