-----

## name: responsive-html
description: >
Apply this skill whenever creating or updating an HTML deliverable that will be
viewed on any device — desktop, tablet, or mobile/iOS. Triggers include: any HTML
artifact, landing page, card, dashboard, report, interactive tool, or data
visualisation. Mandatory when the user mentions “mobile”, “iOS”, “iPhone”,
“responsive”, or “works on phone”. Also apply proactively to ALL HTML files
regardless of whether responsiveness is explicitly requested — it is the default
production standard.

# Responsive HTML — Production Standard

Every HTML file ships mobile-first, iOS-safe, and progressively enhanced for
larger screens. This skill encodes the exact patterns to use. Read all sections
before writing a single line of HTML.

-----

## 1. Document Shell — Always Use This Exact Head

```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- viewport-fit=cover brings content under iOS notch/Dynamic Island.
     Compensate with env(safe-area-inset-*) CSS variables below. -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<meta name="theme-color" content="#YOUR_BG_COLOR">
<!-- PWA / iOS home-screen additions (add when relevant) -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<title>Page Title</title>

<!-- Bootstrap 5.3 (CDN — always use jsDelivr for reliability) -->
<link rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">

<!-- Google Fonts — preconnect first to avoid render blocking -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=YOUR+FONT&display=swap" rel="stylesheet">

<style>
  /* Paste token block + responsive CSS here (see sections 2–7) */
</style>
</head>
<body>
  <!-- content -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
```

**Rules:**

- `viewport-fit=cover` is REQUIRED. Without it, iOS notch clips content.
- Bootstrap JS goes at the **bottom** of `<body>`, never in `<head>`.
- Never use `<script>` in `<head>` without `defer` or `async`.

-----

## 2. CSS Design Tokens — Always Define These First

```css
:root {
  /* ── Brand palette ────────────────────────────────── */
  --color-primary:   #YOUR_PRIMARY;
  --color-accent:    #YOUR_ACCENT;
  --color-bg:        #YOUR_BG;
  --color-surface:   #YOUR_SURFACE;
  --color-text:      #YOUR_TEXT;
  --color-text-dim:  #YOUR_DIM;

  /* ── Fluid type scale (clamp: min | fluid | max) ─── */
  /* Adjust min/max to suit the design; the fluid mid uses vw */
  --t-2xs: clamp(0.55rem, 1.5vw,  0.65rem);
  --t-xs:  clamp(0.65rem, 1.8vw,  0.75rem);
  --t-sm:  clamp(0.75rem, 2vw,    0.9rem);
  --t-base:clamp(0.9rem,  2.2vw,  1rem);
  --t-lg:  clamp(1rem,    2.8vw,  1.3rem);
  --t-xl:  clamp(1.2rem,  3.5vw,  1.8rem);
  --t-2xl: clamp(1.5rem,  4.5vw,  2.4rem);
  --t-3xl: clamp(1.8rem,  6vw,    3.2rem);

  /* ── iOS safe-area insets (0px fallback for non-notch) ── */
  --sat: env(safe-area-inset-top,    0px);
  --sar: env(safe-area-inset-right,  0px);
  --sab: env(safe-area-inset-bottom, 0px);
  --sal: env(safe-area-inset-left,   0px);

  /* ── Spacing tokens ──────────────────────────────── */
  --space-xs:  clamp(4px,  1vw,  8px);
  --space-sm:  clamp(8px,  2vw,  16px);
  --space-md:  clamp(12px, 3vw,  24px);
  --space-lg:  clamp(16px, 4vw,  32px);
  --space-xl:  clamp(24px, 5vw,  48px);

  /* ── Border-radius tokens ────────────────────────── */
  --radius-sm: clamp(4px,  1vw,  8px);
  --radius-md: clamp(8px,  2vw,  14px);
  --radius-lg: clamp(12px, 3vw,  20px);
}
```

**Rules:**

- Every font-size in the page uses `var(--t-*)`. Never use hardcoded `px` for text.
- Every spacing value uses `var(--space-*)` or `clamp()`. Never hardcode `px` padding on layout elements.
- Colors always reference a token. Never repeat hex values in rules.

-----

## 3. Body — iOS-Safe Padding & Scroll Behaviour

```css
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%; /* prevent iOS font inflation on orientation change */
  scroll-behavior: smooth;
}

body {
  background: var(--color-bg);
  font-family: 'YOUR FONT', system-ui, sans-serif;
  color: var(--color-text);
  overflow-x: hidden;

  /* Safe-area padding: max() ensures at least 16px even on notch-less devices */
  padding-top:    max(16px, var(--sat));
  padding-right:  max(16px, var(--sar));
  padding-bottom: max(24px, var(--sab));  /* extra for home indicator bar */
  padding-left:   max(16px, var(--sal));

  overscroll-behavior-y: contain;   /* prevent rubber-band scroll fighting layout */
  -webkit-tap-highlight-color: transparent; /* remove grey tap flash on iOS */
}
```

-----

## 4. Bootstrap Grid — Responsive Breakpoint Patterns

### Two-column → stacked (most common card/panel layout)

```html
<div class="container-fluid px-0">
  <div class="row g-3 g-lg-4 justify-content-center mx-0">

    <!-- Full width on xs–md, half on lg+ -->
    <div class="col-12 col-lg-6">
      <!-- Panel A -->
    </div>

    <div class="col-12 col-lg-6">
      <!-- Panel B -->
    </div>

  </div>
</div>
```

### Three-column grid

```html
<div class="row g-3">
  <div class="col-12 col-sm-6 col-lg-4">...</div>
  <div class="col-12 col-sm-6 col-lg-4">...</div>
  <div class="col-12 col-sm-6 col-lg-4">...</div>
</div>
```

### Dashboard (sidebar + main)

```html
<div class="row g-0">
  <div class="col-12 col-md-3 col-xl-2"><!-- Sidebar --></div>
  <div class="col-12 col-md-9 col-xl-10"><!-- Main --></div>
</div>
```

**Bootstrap breakpoints reference:**

|Prefix|Min-width|Typical target|
|------|---------|--------------|
|(none)|0px      |All phones    |
|`sm`  |576px    |Large phones  |
|`md`  |768px    |Tablets       |
|`lg`  |992px    |Laptops       |
|`xl`  |1200px   |Desktops      |
|`xxl` |1400px   |Wide screens  |

-----

## 5. Touch Target & Interaction Rules

All interactive elements must meet Apple HIG minimum: **44×44 CSS pixels**.

```css
/* Apply to any button, link, or interactive element */
.btn-touch {
  min-height: 44px;
  min-width:  44px;
  padding: 0 var(--space-md);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  touch-action: manipulation;   /* eliminates 300ms click delay on iOS */
  -webkit-user-select: none;
  user-select: none;
}

/* Always provide visible focus ring for accessibility */
.btn-touch:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* Subtle press feedback */
.btn-touch:active { transform: scale(0.97); }
```

Never use `pointer-events: none` on interactive elements.
Never put tap targets closer than 8px apart.

-----

## 6. Scrollable Containers — iOS Momentum Scroll

Any overflow container must include momentum scrolling for iOS:

```css
.scroll-container {
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;  /* momentum scroll on iOS Safari */
  overscroll-behavior: contain;       /* prevent scroll chain to parent */
}

/* Textarea and code blocks */
textarea, pre, code {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  /* Prevent iOS from zooming on focus (font-size must be ≥16px to suppress) */
  font-size: max(16px, var(--t-xs));
}
```

> **iOS zoom prevention:** Any `<input>`, `<textarea>`, or `<select>` with
> `font-size` below 16px triggers auto-zoom on iOS Safari. Always use
> `font-size: max(16px, ...)` or set `font-size: 16px` explicitly on these
> elements, then use `transform: scale()` if you need them visually smaller.

-----

## 7. Fluid Images & Media

```css
img, svg, video, canvas {
  max-width: 100%;
  height: auto;
  display: block;
}

/* SVG illustrations used as layout elements */
.svg-responsive {
  width: 100%;
  height: auto;
  /* Prevents layout shift — set viewBox on the SVG element */
}
```

Always set `viewBox` on inline `<svg>`. Never hardcode `width` / `height`
attributes on layout SVGs — use CSS instead.

-----

## 8. Fluid Aspect Ratios

Use CSS `aspect-ratio` instead of the padding-top hack:

```css
/* Trading card */
.card { aspect-ratio: 2.5 / 3.5; }

/* 16:9 video/panel */
.panel-video { aspect-ratio: 16 / 9; }

/* Square thumbnail */
.thumb { aspect-ratio: 1; }
```

For containers that should match a sibling’s height on large screens but
be natural height on mobile:

```css
.equal-height-lg {
  /* Mobile: natural height */
  min-height: clamp(300px, 60vw, 500px);
}
@media (min-width: 992px) {
  .equal-height-lg { min-height: unset; height: 100%; }
}
```

-----

## 9. Animation — Performance & Reduced Motion

Only animate `transform`, `opacity`, and `filter`. Never animate `width`,
`height`, `top`, `left`, `margin`, or `padding` (triggers layout reflow).

```css
.animated-element {
  will-change: transform, opacity; /* hint browser to composite on GPU */
  animation: myAnim 3s ease-in-out infinite;
}

/* REQUIRED: respect user accessibility preference */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
```

-----

## 10. Typography — Responsive Rules

```css
/* Headings: fluid + line-height tightens at large sizes */
h1 { font-size: var(--t-3xl); line-height: clamp(1.05, 1.1, 1.2); }
h2 { font-size: var(--t-2xl); line-height: 1.2; }
h3 { font-size: var(--t-xl);  line-height: 1.3; }

/* Body: comfortable reading measure */
p, li, td {
  font-size: var(--t-base);
  line-height: 1.65;
  max-width: 70ch; /* optimal reading width */
}

/* Letter-spacing: use clamp so large tracking doesn't break on small screens */
.display-heading {
  letter-spacing: clamp(1px, 0.5vw, 4px);
}
```

-----

## 11. iOS Copy-Paste (Clipboard API Fallback)

The standard `navigator.clipboard.writeText()` requires a secure context and
fails silently on some iOS Safari versions. Always implement the fallback:

```javascript
function copyToClipboard(text, onSuccess) {
  if (navigator.clipboard && navigator.clipboard.writeText) {
    navigator.clipboard.writeText(text).then(onSuccess).catch(() => legacyCopy(text, onSuccess));
  } else {
    legacyCopy(text, onSuccess);
  }
}

function legacyCopy(text, cb) {
  /* iOS Safari requires a range selection on a rendered DOM element */
  const el = document.createElement('textarea');
  el.value = text;
  el.style.cssText = 'position:fixed;top:-9999px;left:-9999px;opacity:0;';
  document.body.appendChild(el);
  /* iOS: must use createRange + setSelectionRange */
  const range = document.createRange();
  range.selectNodeContents(el);
  const sel = window.getSelection();
  sel.removeAllRanges();
  sel.addRange(range);
  el.setSelectionRange(0, 99999);
  try { document.execCommand('copy'); if (cb) cb(); } catch (e) { console.warn('Copy failed', e); }
  sel.removeAllRanges();
  document.body.removeChild(el);
}
```

-----

## 12. Quick-Reference Checklist

Before shipping any HTML file, verify all boxes:

**Head:**

- [ ] `viewport-fit=cover` present in viewport meta
- [ ] Bootstrap 5.3 CSS linked via jsDelivr CDN
- [ ] Google Fonts loaded with `preconnect` before the font `<link>`

**CSS:**

- [ ] Design token block defined at `:root` (colors, type scale, spacing, safe-area vars)
- [ ] Body has `max(16px, env(safe-area-inset-*))` padding on all four sides
- [ ] Body has `overflow-x: hidden`, `overscroll-behavior-y: contain`, `-webkit-tap-highlight-color: transparent`
- [ ] All font sizes use `var(--t-*)` or `clamp()`
- [ ] All layout spacing uses `var(--space-*)` or `clamp()`
- [ ] `@media (prefers-reduced-motion: reduce)` block included

**Layout:**

- [ ] Bootstrap `container-fluid` + `row` + `col-12 col-{bp}-{n}` grid used
- [ ] No fixed pixel widths on layout containers
- [ ] `aspect-ratio` used instead of padding-top hack
- [ ] SVGs have `viewBox` set, width/height in CSS only

**Interactivity:**

- [ ] All buttons/links have `min-height: 44px`, `touch-action: manipulation`
- [ ] Focus styles visible (`:focus-visible` ring)
- [ ] Clipboard uses API + `legacyCopy` fallback
- [ ] Scrollable containers have `-webkit-overflow-scrolling: touch`, `overscroll-behavior: contain`
- [ ] Input/textarea font-size ≥ 16px (prevents iOS zoom)
- [ ] Bootstrap JS at bottom of `<body>`

-----

## 13. Common Anti-Patterns to Avoid

|❌ Don’t                            |✅ Do instead                                          |
|-----------------------------------|------------------------------------------------------|
|`font-size: 12px` on inputs        |`font-size: max(16px, ...)`                           |
|`width: 800px` on containers       |`width: 100%; max-width: 800px`                       |
|Hardcoded `height: 400px`          |`min-height: clamp(...)` or `aspect-ratio`            |
|`padding: 20px` (fixed)            |`padding: var(--space-md)`                            |
|`onClick` on a `<div>`             |Use `<button>` or add `role="button"` + `tabindex="0"`|
|`position: fixed` without safe-area|Add `bottom: max(16px, var(--sab))`                   |
|Animate `width`/`height`           |Animate `transform: scaleX()` / `transform: scaleY()` |
|`letter-spacing: 6px` (fixed)      |`letter-spacing: clamp(1px, 0.5vw, 6px)`              |
|Bootstrap JS in `<head>`           |Bootstrap JS at bottom of `<body>`                    |
|`navigator.clipboard` only         |Always add `legacyCopy` fallback                      |

-----

*Skill authored by ACRA Insight LLC · gemclaw.click · @bretkerr*
*Responsive HTML Standard v1.0 · May 17, 2026*