Pure TailwindMIT licensed

Tailwind Whitespace That Groups Instead of Separates

Two identical checkout forms. The left one uses gap-4 everywhere, so label, field and next section are all equally far apart and nothing groups. The right one uses gap-1.5 inside a field, gap-2 inside a fieldset and gap-8 between fieldsets — a 1:4 ratio that makes the structure legible with no rules, boxes or colour.

Live Demo
Plain CSSTailwind v4
Try it

Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time

Untitled UI React · Affiliate link

Get Untitled UI Pro

The code

<section class="tmu-06 relative w-full min-h-svh bg-tmu06-bg font-tmu06-ui text-tmu06-ink antialiased" aria-labelledby="tmu06-title">
  <div class="absolute top-4 right-4 z-10">
    <input id="tmu06-theme" type="checkbox" class="peer sr-only">
    <label for="tmu06-theme" class="grid size-11 cursor-pointer place-items-center rounded-full border border-tmu06-line bg-tmu06-surface text-tmu06-ink-2 shadow-[0_1px_2px_rgb(0_0_0/0.06)] transition-[color,rotate] duration-300 hover:text-tmu06-ink peer-checked:rotate-180 peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-tmu06-acc motion-reduce:transition-none">
      <svg class="size-5" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="8" fill="none" stroke="currentColor" stroke-width="1.6"/><path d="M12 4a8 8 0 0 0 0 16Z" fill="currentColor"/></svg>
      <span class="sr-only">Switch colour theme</span>
    </label>
  </div>
  <div class="mx-auto grid max-w-[72rem] gap-12 px-6 pt-20 pb-20 md:px-12">
    <header class="grid max-w-[62ch] gap-3">
      <p class="inline-flex items-center gap-2.5 font-tmu06-mono text-xs font-medium uppercase tracking-[0.14em] text-tmu06-ink-2"><span class="tabular-nums text-tmu06-acc">06</span><span aria-hidden="true" class="h-px w-6 bg-tmu06-line"></span>Proximity</p>
      <h2 id="tmu06-title" class="text-[clamp(1.75rem,1.2rem+2vw,2.75rem)] font-semibold leading-[1.08] tracking-[-0.03em] text-balance">Space that groups, not space that separates</h2>
      <p class="text-[1.0625rem] leading-relaxed text-tmu06-ink-2 text-pretty">Same fields, same order. Equal spacing makes everything a neighbour; unequal spacing tells you which label owns which field.</p>
    </header>
    <div class="grid gap-6 md:grid-cols-2">
      <article aria-labelledby="tmu06-a" class="relative grid min-w-0 content-start gap-6 overflow-hidden rounded-xl bg-tmu06-surface p-6 md:p-8">
        <header class="grid min-w-0 gap-0.5">
          <h3 id="tmu06-a" class="text-[0.8125rem] font-bold uppercase tracking-[0.1em]">Equal spacing</h3>
          <p class="font-tmu06-mono text-xs tabular-nums text-tmu06-ink-2">16px everywhere &middot; ratio 1:1</p>
        </header>
        <div class="grid min-w-0 gap-4">
          <fieldset class="grid min-w-0 gap-4">
            <legend class="mb-1 text-xs font-bold uppercase tracking-[0.08em] text-tmu06-ink-2">Billing contact</legend>
            <div class="grid min-w-0 gap-4">
              <label for="tmu06-a-name" class="text-sm font-medium">Full name</label>
              <input id="tmu06-a-name" type="text" autocomplete="name" value="Sam Rivera" class="min-h-11 w-full min-w-0 rounded-md border border-tmu06-line bg-tmu06-field px-3 text-[0.9375rem] text-tmu06-ink shadow-[inset_0_1px_1px_rgb(0_0_0/0.06)] transition-[border-color] duration-150 hover:border-tmu06-ink-2 focus-visible:border-tmu06-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tmu06-acc motion-reduce:transition-none">
            </div>
            <div class="grid min-w-0 gap-4">
              <label for="tmu06-a-mail" class="text-sm font-medium">Work email</label>
              <input id="tmu06-a-mail" type="email" autocomplete="email" value="sam@vale.co" class="min-h-11 w-full min-w-0 rounded-md border border-tmu06-line bg-tmu06-field px-3 text-[0.9375rem] text-tmu06-ink shadow-[inset_0_1px_1px_rgb(0_0_0/0.06)] transition-[border-color] duration-150 hover:border-tmu06-ink-2 focus-visible:border-tmu06-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tmu06-acc motion-reduce:transition-none">
            </div>
          </fieldset>
          <fieldset class="grid min-w-0 gap-4">
            <legend class="mb-1 text-xs font-bold uppercase tracking-[0.08em] text-tmu06-ink-2">Card</legend>
            <div class="grid min-w-0 gap-4">
              <label for="tmu06-a-card" class="text-sm font-medium">Card number</label>
              <input id="tmu06-a-card" type="text" inputmode="numeric" value="4242 4242 4242 4242" class="min-h-11 w-full min-w-0 rounded-md border border-tmu06-line bg-tmu06-field px-3 text-[0.9375rem] text-tmu06-ink shadow-[inset_0_1px_1px_rgb(0_0_0/0.06)] transition-[border-color] duration-150 hover:border-tmu06-ink-2 focus-visible:border-tmu06-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tmu06-acc motion-reduce:transition-none">
            </div>
            <div class="grid min-w-0 gap-4">
              <label for="tmu06-a-exp" class="text-sm font-medium">Expiry</label>
              <input id="tmu06-a-exp" type="text" inputmode="numeric" value="09 / 29" class="min-h-11 w-full min-w-0 rounded-md border border-tmu06-line bg-tmu06-field px-3 text-[0.9375rem] text-tmu06-ink shadow-[inset_0_1px_1px_rgb(0_0_0/0.06)] transition-[border-color] duration-150 hover:border-tmu06-ink-2 focus-visible:border-tmu06-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tmu06-acc motion-reduce:transition-none">
            </div>
          </fieldset>
        </div>
      </article>
      <article aria-labelledby="tmu06-b" class="relative grid min-w-0 content-start gap-6 overflow-hidden rounded-xl bg-tmu06-surface p-6 md:p-8 before:absolute before:inset-y-0 before:left-0 before:w-[3px] before:bg-tmu06-acc">
        <header class="grid min-w-0 gap-0.5">
          <h3 id="tmu06-b" class="text-[0.8125rem] font-bold uppercase tracking-[0.1em]">Proximity applied</h3>
          <p class="font-tmu06-mono text-xs tabular-nums text-tmu06-ink-2">6px &middot; 8px &middot; 32px &middot; ratio 1:4</p>
        </header>
        <div class="grid min-w-0 gap-8">
          <fieldset class="grid min-w-0 gap-2">
            <legend class="mb-1 text-xs font-bold uppercase tracking-[0.08em] text-tmu06-ink-2">Billing contact</legend>
            <div class="grid min-w-0 gap-1.5">
              <label for="tmu06-b-name" class="text-sm font-medium">Full name</label>
              <input id="tmu06-b-name" type="text" autocomplete="name" value="Sam Rivera" class="min-h-11 w-full min-w-0 rounded-md border border-tmu06-line bg-tmu06-field px-3 text-[0.9375rem] text-tmu06-ink shadow-[inset_0_1px_1px_rgb(0_0_0/0.06)] transition-[border-color] duration-150 hover:border-tmu06-ink-2 focus-visible:border-tmu06-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tmu06-acc motion-reduce:transition-none">
            </div>
            <div class="grid min-w-0 gap-1.5">
              <label for="tmu06-b-mail" class="text-sm font-medium">Work email</label>
              <input id="tmu06-b-mail" type="email" autocomplete="email" value="sam@vale.co" class="min-h-11 w-full min-w-0 rounded-md border border-tmu06-line bg-tmu06-field px-3 text-[0.9375rem] text-tmu06-ink shadow-[inset_0_1px_1px_rgb(0_0_0/0.06)] transition-[border-color] duration-150 hover:border-tmu06-ink-2 focus-visible:border-tmu06-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tmu06-acc motion-reduce:transition-none">
            </div>
          </fieldset>
          <fieldset class="grid min-w-0 gap-2">
            <legend class="mb-1 text-xs font-bold uppercase tracking-[0.08em] text-tmu06-ink-2">Card</legend>
            <div class="grid min-w-0 gap-1.5">
              <label for="tmu06-b-card" class="text-sm font-medium">Card number</label>
              <input id="tmu06-b-card" type="text" inputmode="numeric" value="4242 4242 4242 4242" class="min-h-11 w-full min-w-0 rounded-md border border-tmu06-line bg-tmu06-field px-3 text-[0.9375rem] text-tmu06-ink shadow-[inset_0_1px_1px_rgb(0_0_0/0.06)] transition-[border-color] duration-150 hover:border-tmu06-ink-2 focus-visible:border-tmu06-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tmu06-acc motion-reduce:transition-none">
            </div>
            <div class="grid min-w-0 gap-1.5">
              <label for="tmu06-b-exp" class="text-sm font-medium">Expiry</label>
              <input id="tmu06-b-exp" type="text" inputmode="numeric" value="09 / 29" class="min-h-11 w-full min-w-0 rounded-md border border-tmu06-line bg-tmu06-field px-3 text-[0.9375rem] text-tmu06-ink shadow-[inset_0_1px_1px_rgb(0_0_0/0.06)] transition-[border-color] duration-150 hover:border-tmu06-ink-2 focus-visible:border-tmu06-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tmu06-acc motion-reduce:transition-none">
            </div>
          </fieldset>
          <button type="button" class="inline-flex min-h-11 min-w-11 items-center justify-self-start rounded-md border border-tmu06-acc bg-tmu06-acc px-5 text-[0.9375rem] font-semibold text-tmu06-acc-ink cursor-pointer transition-[filter,translate] duration-150 hover:brightness-110 active:translate-y-px focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tmu06-ink motion-reduce:transition-none">Continue to payment</button>
        </div>
      </article>
    </div>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-tmu06-bg: light-dark(#f6f4f1, #1c1a18);
  --color-tmu06-bg: light-dark(oklch(96.5% 0.006 70), oklch(23% 0.008 60));
  --color-tmu06-surface: light-dark(#ffffff, #262320);
  --color-tmu06-surface: light-dark(oklch(100% 0 0), oklch(27.5% 0.009 60));
  --color-tmu06-field: light-dark(#ffffff, #322e2a);
  --color-tmu06-field: light-dark(oklch(100% 0 0), oklch(32% 0.01 60));
  --color-tmu06-ink: light-dark(#1c1a18, #f6f3f0);
  --color-tmu06-ink: light-dark(oklch(23% 0.008 60), oklch(96.5% 0.006 70));
  --color-tmu06-ink-2: light-dark(#55504a, #b6afa7);
  --color-tmu06-ink-2: light-dark(oklch(45% 0.012 65), oklch(77% 0.012 70));
  --color-tmu06-line: light-dark(#d5cfc7, #45403a);
  --color-tmu06-line: light-dark(oklch(85.5% 0.012 70), oklch(37% 0.011 65));
  --color-tmu06-acc: light-dark(#8a4a06, #f0a35c);
  --color-tmu06-acc: light-dark(oklch(45% 0.12 58), oklch(78% 0.13 62));
  --color-tmu06-acc-ink: light-dark(#ffffff, #201408);
  --color-tmu06-acc-ink: light-dark(oklch(100% 0 0), oklch(18% 0.03 60));
  --font-tmu06-ui: "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
  --font-tmu06-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
}
/* Root rule: the full-bleed contract, restated so the stage is sized before the browser build
   compiles. color-scheme drives every light-dark() token above. */

.tmu-06 {
  width: 100%;
  min-height: 100vh;
  min-height: 100svh;
  color-scheme: light dark;
}
/* Theme toggle: flip the scheme and every token follows. Mirrored for a dark OS. */

.tmu-06:has(#tmu06-theme:checked) {
  color-scheme: dark;
}

@media (prefers-color-scheme: dark) {
  .tmu-06:has(#tmu06-theme:checked) {
    color-scheme: light;
  }
}

Setup — do this once per project

Skip this if your project already runs Tailwind v4.

1Load Tailwind
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>

Compiles in the browser — perfect for a CodePen or a quick test, not for production.

2Add the stylesheetRequiredthe @theme block is what makes the custom utilities exist
@import "tailwindcss";

@theme {
  --color-tmu06-bg: light-dark(#f6f4f1, #1c1a18);
  --color-tmu06-bg: light-dark(oklch(96.5% 0.006 70), oklch(23% 0.008 60));
  --color-tmu06-surface: light-dark(#ffffff, #262320);
  --color-tmu06-surface: light-dark(oklch(100% 0 0), oklch(27.5% 0.009 60));
  --color-tmu06-field: light-dark(#ffffff, #322e2a);
  --color-tmu06-field: light-dark(oklch(100% 0 0), oklch(32% 0.01 60));
  --color-tmu06-ink: light-dark(#1c1a18, #f6f3f0);
  --color-tmu06-ink: light-dark(oklch(23% 0.008 60), oklch(96.5% 0.006 70));
  --color-tmu06-ink-2: light-dark(#55504a, #b6afa7);
  --color-tmu06-ink-2: light-dark(oklch(45% 0.012 65), oklch(77% 0.012 70));
  --color-tmu06-line: light-dark(#d5cfc7, #45403a);
  --color-tmu06-line: light-dark(oklch(85.5% 0.012 70), oklch(37% 0.011 65));
  --color-tmu06-acc: light-dark(#8a4a06, #f0a35c);
  --color-tmu06-acc: light-dark(oklch(45% 0.12 58), oklch(78% 0.13 62));
  --color-tmu06-acc-ink: light-dark(#ffffff, #201408);
  --color-tmu06-acc-ink: light-dark(oklch(100% 0 0), oklch(18% 0.03 60));
  --font-tmu06-ui: "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
  --font-tmu06-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
}
/* Root rule: the full-bleed contract, restated so the stage is sized before the browser build
   compiles. color-scheme drives every light-dark() token above. */

.tmu-06 {
  width: 100%;
  min-height: 100vh;
  min-height: 100svh;
  color-scheme: light dark;
}
/* Theme toggle: flip the scheme and every token follows. Mirrored for a dark OS. */

.tmu-06:has(#tmu06-theme:checked) {
  color-scheme: dark;
}

@media (prefers-color-scheme: dark) {
  .tmu-06:has(#tmu06-theme:checked) {
    color-scheme: light;
  }
}

What changed in the port

Which parts became utilities, which stayed CSS, and why.

  • .form--grouped .set { gap } descendant overrides disappear: each side's gaps are written on its own elements, so the comparison is a diff of class names.
  • The inset box-shadow bar became a before: pseudo-element — it no longer collides with the card's own shadow.
  • UI upgrade: inputs gained a 1px inset shadow and a hover border, so they read as fields on the warm charcoal ground; the submit gained active:translate-y-px press feedback and a brightness hover.
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Whitespace That Groups Instead of Separates
Source: https://codefronts.com/design-styles/tailwind-css-minimalist-ui/tailwind-whitespace-grouping-form-proximity/

Two identical checkout forms. The left one uses gap-4 everywhere, so label, field and next section are all equally far apart and nothing groups. The right one uses gap-1.5 inside a field, gap-2 inside a fieldset and gap-8 between fieldsets &mdash; a 1:4 ratio that makes the structure legible with no rules, boxes or colour.
## HTML
```html
<section class="tmu-06 relative w-full min-h-svh bg-tmu06-bg font-tmu06-ui text-tmu06-ink antialiased" aria-labelledby="tmu06-title">
  <div class="absolute top-4 right-4 z-10">
    <input id="tmu06-theme" type="checkbox" class="peer sr-only">
    <label for="tmu06-theme" class="grid size-11 cursor-pointer place-items-center rounded-full border border-tmu06-line bg-tmu06-surface text-tmu06-ink-2 shadow-[0_1px_2px_rgb(0_0_0/0.06)] transition-[color,rotate] duration-300 hover:text-tmu06-ink peer-checked:rotate-180 peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-tmu06-acc motion-reduce:transition-none">
      <svg class="size-5" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="8" fill="none" stroke="currentColor" stroke-width="1.6"/><path d="M12 4a8 8 0 0 0 0 16Z" fill="currentColor"/></svg>
      <span class="sr-only">Switch colour theme</span>
    </label>
  </div>
  <div class="mx-auto grid max-w-[72rem] gap-12 px-6 pt-20 pb-20 md:px-12">
    <header class="grid max-w-[62ch] gap-3">
      <p class="inline-flex items-center gap-2.5 font-tmu06-mono text-xs font-medium uppercase tracking-[0.14em] text-tmu06-ink-2"><span class="tabular-nums text-tmu06-acc">06</span><span aria-hidden="true" class="h-px w-6 bg-tmu06-line"></span>Proximity</p>
      <h2 id="tmu06-title" class="text-[clamp(1.75rem,1.2rem+2vw,2.75rem)] font-semibold leading-[1.08] tracking-[-0.03em] text-balance">Space that groups, not space that separates</h2>
      <p class="text-[1.0625rem] leading-relaxed text-tmu06-ink-2 text-pretty">Same fields, same order. Equal spacing makes everything a neighbour; unequal spacing tells you which label owns which field.</p>
    </header>
    <div class="grid gap-6 md:grid-cols-2">
      <article aria-labelledby="tmu06-a" class="relative grid min-w-0 content-start gap-6 overflow-hidden rounded-xl bg-tmu06-surface p-6 md:p-8">
        <header class="grid min-w-0 gap-0.5">
          <h3 id="tmu06-a" class="text-[0.8125rem] font-bold uppercase tracking-[0.1em]">Equal spacing</h3>
          <p class="font-tmu06-mono text-xs tabular-nums text-tmu06-ink-2">16px everywhere &middot; ratio 1:1</p>
        </header>
        <div class="grid min-w-0 gap-4">
          <fieldset class="grid min-w-0 gap-4">
            <legend class="mb-1 text-xs font-bold uppercase tracking-[0.08em] text-tmu06-ink-2">Billing contact</legend>
            <div class="grid min-w-0 gap-4">
              <label for="tmu06-a-name" class="text-sm font-medium">Full name</label>
              <input id="tmu06-a-name" type="text" autocomplete="name" value="Sam Rivera" class="min-h-11 w-full min-w-0 rounded-md border border-tmu06-line bg-tmu06-field px-3 text-[0.9375rem] text-tmu06-ink shadow-[inset_0_1px_1px_rgb(0_0_0/0.06)] transition-[border-color] duration-150 hover:border-tmu06-ink-2 focus-visible:border-tmu06-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tmu06-acc motion-reduce:transition-none">
            </div>
            <div class="grid min-w-0 gap-4">
              <label for="tmu06-a-mail" class="text-sm font-medium">Work email</label>
              <input id="tmu06-a-mail" type="email" autocomplete="email" value="sam@vale.co" class="min-h-11 w-full min-w-0 rounded-md border border-tmu06-line bg-tmu06-field px-3 text-[0.9375rem] text-tmu06-ink shadow-[inset_0_1px_1px_rgb(0_0_0/0.06)] transition-[border-color] duration-150 hover:border-tmu06-ink-2 focus-visible:border-tmu06-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tmu06-acc motion-reduce:transition-none">
            </div>
          </fieldset>
          <fieldset class="grid min-w-0 gap-4">
            <legend class="mb-1 text-xs font-bold uppercase tracking-[0.08em] text-tmu06-ink-2">Card</legend>
            <div class="grid min-w-0 gap-4">
              <label for="tmu06-a-card" class="text-sm font-medium">Card number</label>
              <input id="tmu06-a-card" type="text" inputmode="numeric" value="4242 4242 4242 4242" class="min-h-11 w-full min-w-0 rounded-md border border-tmu06-line bg-tmu06-field px-3 text-[0.9375rem] text-tmu06-ink shadow-[inset_0_1px_1px_rgb(0_0_0/0.06)] transition-[border-color] duration-150 hover:border-tmu06-ink-2 focus-visible:border-tmu06-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tmu06-acc motion-reduce:transition-none">
            </div>
            <div class="grid min-w-0 gap-4">
              <label for="tmu06-a-exp" class="text-sm font-medium">Expiry</label>
              <input id="tmu06-a-exp" type="text" inputmode="numeric" value="09 / 29" class="min-h-11 w-full min-w-0 rounded-md border border-tmu06-line bg-tmu06-field px-3 text-[0.9375rem] text-tmu06-ink shadow-[inset_0_1px_1px_rgb(0_0_0/0.06)] transition-[border-color] duration-150 hover:border-tmu06-ink-2 focus-visible:border-tmu06-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tmu06-acc motion-reduce:transition-none">
            </div>
          </fieldset>
        </div>
      </article>
      <article aria-labelledby="tmu06-b" class="relative grid min-w-0 content-start gap-6 overflow-hidden rounded-xl bg-tmu06-surface p-6 md:p-8 before:absolute before:inset-y-0 before:left-0 before:w-[3px] before:bg-tmu06-acc">
        <header class="grid min-w-0 gap-0.5">
          <h3 id="tmu06-b" class="text-[0.8125rem] font-bold uppercase tracking-[0.1em]">Proximity applied</h3>
          <p class="font-tmu06-mono text-xs tabular-nums text-tmu06-ink-2">6px &middot; 8px &middot; 32px &middot; ratio 1:4</p>
        </header>
        <div class="grid min-w-0 gap-8">
          <fieldset class="grid min-w-0 gap-2">
            <legend class="mb-1 text-xs font-bold uppercase tracking-[0.08em] text-tmu06-ink-2">Billing contact</legend>
            <div class="grid min-w-0 gap-1.5">
              <label for="tmu06-b-name" class="text-sm font-medium">Full name</label>
              <input id="tmu06-b-name" type="text" autocomplete="name" value="Sam Rivera" class="min-h-11 w-full min-w-0 rounded-md border border-tmu06-line bg-tmu06-field px-3 text-[0.9375rem] text-tmu06-ink shadow-[inset_0_1px_1px_rgb(0_0_0/0.06)] transition-[border-color] duration-150 hover:border-tmu06-ink-2 focus-visible:border-tmu06-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tmu06-acc motion-reduce:transition-none">
            </div>
            <div class="grid min-w-0 gap-1.5">
              <label for="tmu06-b-mail" class="text-sm font-medium">Work email</label>
              <input id="tmu06-b-mail" type="email" autocomplete="email" value="sam@vale.co" class="min-h-11 w-full min-w-0 rounded-md border border-tmu06-line bg-tmu06-field px-3 text-[0.9375rem] text-tmu06-ink shadow-[inset_0_1px_1px_rgb(0_0_0/0.06)] transition-[border-color] duration-150 hover:border-tmu06-ink-2 focus-visible:border-tmu06-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tmu06-acc motion-reduce:transition-none">
            </div>
          </fieldset>
          <fieldset class="grid min-w-0 gap-2">
            <legend class="mb-1 text-xs font-bold uppercase tracking-[0.08em] text-tmu06-ink-2">Card</legend>
            <div class="grid min-w-0 gap-1.5">
              <label for="tmu06-b-card" class="text-sm font-medium">Card number</label>
              <input id="tmu06-b-card" type="text" inputmode="numeric" value="4242 4242 4242 4242" class="min-h-11 w-full min-w-0 rounded-md border border-tmu06-line bg-tmu06-field px-3 text-[0.9375rem] text-tmu06-ink shadow-[inset_0_1px_1px_rgb(0_0_0/0.06)] transition-[border-color] duration-150 hover:border-tmu06-ink-2 focus-visible:border-tmu06-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tmu06-acc motion-reduce:transition-none">
            </div>
            <div class="grid min-w-0 gap-1.5">
              <label for="tmu06-b-exp" class="text-sm font-medium">Expiry</label>
              <input id="tmu06-b-exp" type="text" inputmode="numeric" value="09 / 29" class="min-h-11 w-full min-w-0 rounded-md border border-tmu06-line bg-tmu06-field px-3 text-[0.9375rem] text-tmu06-ink shadow-[inset_0_1px_1px_rgb(0_0_0/0.06)] transition-[border-color] duration-150 hover:border-tmu06-ink-2 focus-visible:border-tmu06-acc focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tmu06-acc motion-reduce:transition-none">
            </div>
          </fieldset>
          <button type="button" class="inline-flex min-h-11 min-w-11 items-center justify-self-start rounded-md border border-tmu06-acc bg-tmu06-acc px-5 text-[0.9375rem] font-semibold text-tmu06-acc-ink cursor-pointer transition-[filter,translate] duration-150 hover:brightness-110 active:translate-y-px focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tmu06-ink motion-reduce:transition-none">Continue to payment</button>
        </div>
      </article>
    </div>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tmu06-bg: light-dark(#f6f4f1, #1c1a18);
  --color-tmu06-bg: light-dark(oklch(96.5% 0.006 70), oklch(23% 0.008 60));
  --color-tmu06-surface: light-dark(#ffffff, #262320);
  --color-tmu06-surface: light-dark(oklch(100% 0 0), oklch(27.5% 0.009 60));
  --color-tmu06-field: light-dark(#ffffff, #322e2a);
  --color-tmu06-field: light-dark(oklch(100% 0 0), oklch(32% 0.01 60));
  --color-tmu06-ink: light-dark(#1c1a18, #f6f3f0);
  --color-tmu06-ink: light-dark(oklch(23% 0.008 60), oklch(96.5% 0.006 70));
  --color-tmu06-ink-2: light-dark(#55504a, #b6afa7);
  --color-tmu06-ink-2: light-dark(oklch(45% 0.012 65), oklch(77% 0.012 70));
  --color-tmu06-line: light-dark(#d5cfc7, #45403a);
  --color-tmu06-line: light-dark(oklch(85.5% 0.012 70), oklch(37% 0.011 65));
  --color-tmu06-acc: light-dark(#8a4a06, #f0a35c);
  --color-tmu06-acc: light-dark(oklch(45% 0.12 58), oklch(78% 0.13 62));
  --color-tmu06-acc-ink: light-dark(#ffffff, #201408);
  --color-tmu06-acc-ink: light-dark(oklch(100% 0 0), oklch(18% 0.03 60));
  --font-tmu06-ui: "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
  --font-tmu06-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
}
/* Root rule: the full-bleed contract, restated so the stage is sized before the browser build
   compiles. color-scheme drives every light-dark() token above. */

.tmu-06 {
  width: 100%;
  min-height: 100vh;
  min-height: 100svh;
  color-scheme: light dark;
}
/* Theme toggle: flip the scheme and every token follows. Mirrored for a dark OS. */

.tmu-06:has(#tmu06-theme:checked) {
  color-scheme: dark;
}

@media (prefers-color-scheme: dark) {
  .tmu-06:has(#tmu06-theme:checked) {
    color-scheme: light;
  }
}
```

How this works

Proximity is the strongest grouping signal in interface design, and it costs nothing. Things that sit close together are read as related before a single word is processed. That means spacing is not decoration — it is the mechanism by which a reader learns your form’s structure. Get it wrong and no amount of borders, headings or colour will fully repair it.

The failure is almost always equal spacing. A designer picks 16px and applies it everywhere: label to input, input to next label, section to section. The result looks tidy in a screenshot and is genuinely ambiguous to use, because a label is equidistant from the field it names and the field below it. Users guess. On a long form, they guess wrong.

State the rule as a ratio. The gap between groups must clearly exceed the gap inside them — at least double, and on a dense form, closer to triple. Here that is --mu-06-gap-in: 8px against --mu-06-gap-out: 32px: a 4× ratio, which reads unambiguously at 320px and at 1440px. Anything below about 2× and the eye cannot resolve which side the label belongs to.

Whitespace can also separate the wrong things. Generous space around every element individually — the classic misreading of minimalism — dissolves structure just as effectively as equal spacing does. A label 4px from its input inside a group that sits 40px from the next group is calm and legible. The same total whitespace distributed evenly is a list of unrelated fragments. Space is a relationship, not an amount.

Make it yours

  • Tighten the good form to 1:3 with gap-8 → gap-6 between fieldsets.
  • Move the bar to the top with before:inset-x-0 before:top-0 before:h-[3px].
  • Retheme through --color-tmu06-acc; the submit, focus ring and bar all read it.

Gotchas — read before shipping

  • Equal spacing everywhere is the default failure. It reads as tidy and behaves as ambiguous, because every label is equidistant from two fields.
  • A group gap under about twice the internal gap does not register as a group boundary at all, so the extra space is spent with no return.
  • Generous space around every element individually destroys grouping just as thoroughly as equal spacing. Space is a relationship, not an amount.
  • Relying on space alone with no <label> leaves screen-reader users with no grouping at all — proximity is a visual signal, and <fieldset> plus <legend> is its programmatic equivalent.

Browser support

ChromeSafariFirefoxEdge
123+17.5+128+123+

The floor is set by light-dark() on the colour tokens (Chrome 123 / Safari 17.5 / Firefox 120) and by Tailwind v4's own generated sheet (cascade layers, @property, color-mix()). The technique itself works far further back.

Techniques used in this demo

Utilitiesfirst-class utility or variant

Arbitraryneeds bracket syntax

Search CodeFronts

Loading…