every namethatui element, padded only at the leaves

containers arrange with flex / grid + gap, bg, radius, border, overflow-hidden. only leaves (text, buttons, inputs, badges, icon wrappers) own px / py. sibling spacing is parent gap. fills, dividers, sticky headers, and hover states therefore reach every edge with zero negative margins. toggle the inspector to see which nodes own padding. each element is shown twice: side a commits the classic mistake (the container pads, or margins replace gap) and side b is the leaf-only build. the sample under each pair is short enough to copy.

alert

namethatui.com/macos/alert

the action row is a sibling band: the alert arranges, the cells pad themselves. pad the alert and the hover cells stop at the inset, never reaching the rounded edge.

a: the alert pads

delete "notes"?

this cannot be undone.

b: the leaves pad

delete "notes"?

this cannot be undone.

b markup + css
<div class="gm-alert">
<span class="gm-alert-icon">!</span>
<strong class="gm-alert-q">delete "notes"?</strong>
<div class="gm-alert-actions">cancel / delete</div>
</div>
.gm-alert { display:flex; flex-direction:column; gap:8px; overflow:hidden; border-radius:12px; }
.gm-alert-actions { display:grid; grid-template-columns:1fr 1fr; border-top:1px solid; }
.gm-alert-actions button { padding:8px 0; } /* cells pad; row is full-bleed */

color well

namethatui.com/macos/color-well

the swatch is the shape; its box and caret are padded leaves sharing one border. pad the swatch and the halves drift off the shared edge.

a: the swatch pads

accent

b: the leaves pad

accent
b markup + css
<label class="gm-swatch">
<span class="gm-swatch-box"><input type="color"></span>
<span class="gm-swatch-caret"><svg></svg></span>
</label>
.gm-swatch { display:flex; overflow:hidden; border-radius:6px; border:1px solid; }
.gm-swatch-box { padding:4px; } /* each half pads itself */
.gm-swatch-caret { padding:6px 8px; border-left:1px solid; }

column view

namethatui.com/macos/column-view

columns arrange; file rows pad themselves so selection reaches each divider. pad the window and every selection stops short of the column line.

a: the window pads

finder
  • apps
  • docs
  • music
  • work
  • taxes
  • plan.md
  • notes.md

b: the leaves pad

finder
  • apps
  • docs
  • music
  • work
  • taxes
  • plan.md
  • notes.md
b markup + css
<div class="gm-window">
<div class="gm-titlebar">lights + title</div>
<div class="gm-columns">
<ul class="gm-filelist"><li class="gm-file">docs</li>…</ul>
…
</div>
</div>
.gm-columns { display:grid; grid-template-columns:1fr 1fr 1fr; divide-x; }
.gm-file { display:flex; justify-content:space-between; padding:4px 12px; } /* selection reaches the divider */

combo button

namethatui.com/macos/combo-button

two button leaves and a rule sibling; hover fills run to the rounded corners. pad the combo and both halves hover inside an inset.

a: the combo pads

b: the leaves pad

b markup + css
<div class="gm-combo">
<button class="gm-combo-main">share</button>
<div class="gm-combo-rule"></div>
<button class="gm-combo-caret"><svg></svg></button>
</div>
.gm-combo { display:flex; overflow:hidden; border-radius:6px; }
.gm-combo-main { padding:4px 12px; } /* hover fills to the rounded corner */
.gm-combo-rule { width:1px; }

context menu

namethatui.com/macos/context-menu

menu items pad themselves so the highlight runs edge to edge; a real mac inset would be a leaf margin, never parent padding. pad the menu and the highlights float inside it.

a: the menu pads

b: the leaves pad

b markup + css
<div class="gm-menu">
<button class="gm-menu-item">open<span class="gm-key">⌘O</span></button>
<div class="gm-menu-rule"></div>
…
</div>
.gm-menu { display:flex; flex-direction:column; overflow:hidden; border-radius:8px; }
.gm-menu-item { display:flex; justify-content:space-between; padding:4px 12px; } /* highlight is edge to edge */

disclosure triangle

namethatui.com/macos/disclosure-triangle

the summary row and option rows pad themselves; depth comes from the leaf's own padding-left. pad the details and child rows can no longer highlight edge to edge.

a: the details pads

advanced

b: the leaves pad

advanced
b markup + css
<details class="gm-disclose">
<summary class="gm-disclose-head">▸ advanced</summary>
<label class="gm-disclose-opt"><input type="checkbox"> verbose logs</label>
</details>
.gm-disclose-head { display:flex; gap:4px; padding:4px 8px; }
.gm-disclose-opt { display:flex; gap:8px; padding:4px 0 4px 28px; } /* indent is leaf padding-left */

dock badge

namethatui.com/macos/dock-badge

icons are leaves margining themselves inside the dock fill (leaf margin allowed); badges anchor to the icon corner. pad the dock and the icon row drifts off the dock frame.

a: the dock pads

3
12

b: the leaves margin themselves

3
12
b markup + css
<div class="gm-dock">
<div class="gm-dock-app">
<span class="gm-dock-icon"></span>
<span class="gm-dock-badge">3</span>
</div>
…
</div>
.gm-dock { display:flex; align-items:flex-end; gap:12px; border-radius:16px; }
.gm-dock-icon { margin:8px; width:48px; height:48px; border-radius:12px; } /* leaf margin allowed */
.gm-dock-badge { position:absolute; top:0; right:0; border-radius:9999px; padding:0 6px; }

focus ring

namethatui.com/macos/focus-ring

the ring is drawn outside each leaf, and the gap reserves its room. swap the gap for per-child margins and the rhythm drifts; take the room away and rings overlap the neighbor.

a: margins replace the gap

b: gap reserves the ring's room

b markup + css
<div class="gm-focus">
<input class="gm-focus-input" placeholder="click">
<button class="gm-focus-btn">default</button>
</div>
.gm-focus { display:flex; align-items:center; gap:16px; } /* gap = room for the ring */
.gm-focus-input:focus { outline:none; box-shadow:0 0 0 4px sky; } /* drawn outside the leaf */

insertion caret

namethatui.com/macos/insertion-caret

the caret is a zero-padding sibling between two padded text leaves, so the text hugs the border. pad the field and the text floats off it.

a: the field pads

hello world

b: the leaves pad

hello world
b markup + css
<div class="gm-caret-field">
<span class="gm-caret-before">hello wor</span>
<span class="gm-caret"></span>
<span class="gm-caret-after">ld</span>
</div>
.gm-caret-field { display:flex; align-items:center; border:1px solid; border-radius:6px; }
.gm-caret-before { padding:4px 0 4px 8px; } /* text hugs the border */
.gm-caret { width:1px; height:16px; }

inspector

namethatui.com/macos/inspector

section bands are self-padding regions and the input is inset by a gutter track, not a right margin. pad the window and the bands stop short of the frame.

a: the window pads

inspector
layout
fill

b: the leaves pad

inspector
layout
fill
b markup + css
<label class="gm-inspector-row">
<span class="gm-inspector-key">width</span>
<input class="gm-inspector-input" value="320">
</label>
.gm-inspector-band { padding:4px 12px; border-bottom:1px solid; } /* band spans the panel */
.gm-inspector-row { display:grid; grid-template-columns:1fr 1fr 12px; } /* 3rd track = gutter, no mr */

level indicator

namethatui.com/macos/level-indicator

segments are gap-separated siblings and the capacity track has no inset, so the fill reaches its rounded ends. pad the track and the fill falls short of them.

a: the capacity track pads

★★★☆☆

b: the leaves pad

★★★☆☆
b markup + css
<div class="gm-capacity">
<span class="gm-seg is-full"></span> …
</div>
.gm-capacity { display:flex; gap:2px; overflow:hidden; border-radius:2px; } /* no inset */
.gm-seg { width:16px; height:12px; } /* fixed-size siblings, gap-spaced */

outline view

namethatui.com/macos/outline-view

depth is each row's own padding-left, so the selected fill still spans the full width. pad the list and selection stops short of the edges.

a: the list pads

  • src
  • components
  • button.tsx
  • card.tsx
  • public

b: the leaves pad

  • src
  • components
  • button.tsx
  • card.tsx
  • public
b markup + css
<ul class="gm-outline">
<li class="gm-outline-row is-d1">▸ src</li>
<li class="gm-outline-row is-d3 is-active">button.tsx</li>
</ul>
.gm-outline-row { padding:4px 8px 4px 8px; } /* base inset on the leaf */
.gm-outline-row.is-d3 { padding-left:36px; } /* depth = leaf padding-left, fill still spans */

panel

namethatui.com/macos/panel

the title strip and list rows pad themselves; the frame only arranges. pad the panel and the title fill stops short of the frame.

a: the panel pads

fonts
  • helvetica
  • monolisa
  • sf pro

b: the leaves pad

fonts
  • helvetica
  • monolisa
  • sf pro
b markup + css
<div class="gm-panel">
<div class="gm-panel-head">title + close</div>
<ul class="gm-panel-list"><li class="gm-panel-row is-active">monolisa</li>…</ul>
</div>
.gm-panel-head { display:flex; justify-content:space-between; } /* strip is flush */
.gm-panel-title { padding:4px 8px; }
.gm-panel-close { padding:4px 8px; } /* hover fills to the frame edge */

pointer

namethatui.com/macos/pointer

each cell is a padded leaf and a cursor target; the grid spaces them with one gap value. swap gap for per-child margins and the rhythm drifts cell by cell.

a: margins replace the gap

defaultpointertextgrabcrosshairnot-allowedcol-resizewait

b: gap on the grid

defaultpointertextgrabcrosshairnot-allowedcol-resizewait
b markup + css
<div class="gm-pointers">
<span class="gm-pointer is-pointer">pointer</span> …
</div>
.gm-pointers { display:grid; grid-template-columns:repeat(4,1fr); gap:8px; }
.gm-pointer { padding:16px 12px; text-align:center; border-radius:4px; } /* cell is the cursor target */

popover

namethatui.com/macos/popover

the arrow overlaps with translate, not negative margin, and the action row is a full-width band. pad the body and the action stops short of the rounded edge.

a: the body pads

sep 28standup 10:00

b: the leaves pad

sep 28standup 10:00
b markup + css
<div class="gm-pop">
<div class="gm-pop-arrow"></div>
<div class="gm-pop-body">title / sub / action</div>
</div>
.gm-pop-arrow { translate:0 6px; rotate:45deg; } /* overlap by transform, never negative margin */
.gm-pop-action { padding:8px 0; border-top:1px solid; } /* full-width band */

save panel

namethatui.com/macos/save-panel

rows arrange on a gutter-track grid, and the button band keeps its inset with min-height plus an after spacer. no field or button margins anywhere. pad the window and every band stops short of the sheet.

a: the window pads

save

b: the leaves pad

save
b markup + css
<div class="gm-save-body">
<label class="gm-save-row"><span class="gm-save-key">save as:</span>
<Input className="gm-save-input h-8 rounded-md px-2 text-xs" defaultValue="report.pdf" /></label>
<div class="gm-save-actions">cancel / save</div>
</div>
.gm-save-body { display:flex; flex-direction:column; gap:12px; } /* rows space on gap */
.gm-save-row { display:grid; grid-template-columns:5rem 1fr 1rem; gap:8px; } /* 3rd track = gutter */
.gm-save-actions { min-height:48px; align-items:center; justify-content:flex-end; gap:8px; }
.gm-save-actions::after { content:""; width:12px; } /* band inset by spacer, never mr */

scroll view

namethatui.com/macos/scroll-view

row fills run under the scrollbar track with no gutter inset. pad the scroller and the stripes stop short of the frame.

a: the scroller pads

row 1

row 2

row 3

row 4

row 5

row 6

row 7

row 8

row 9

row 10

row 11

row 12

b: the leaves pad

row 1

row 2

row 3

row 4

row 5

row 6

row 7

row 8

row 9

row 10

row 11

row 12

b markup + css
<div class="gm-scrollview">
<p class="gm-scrollrow">row 1</p> …
</div>
.gm-scrollview { height:128px; overflow-y:scroll; border-radius:8px; } /* no gutter inset */
.gm-scrollrow { padding:6px 12px; }
.gm-scrollrow:nth-child(odd) { background:subtle; } /* stripes run under the track */

search field

namethatui.com/macos/search-field

icon, input and clear are padded leaves; the field shape is the parent's radius. pad the field and the content floats off the shape.

a: the field pads

b: the leaves pad

b markup + css
<label class="gm-search">
<span class="gm-search-icon">🔍</span>
<input class="gm-search-el" placeholder="search">
<button class="gm-search-clear">✕</button>
</label>
.gm-search { display:flex; align-items:center; overflow:hidden; border-radius:6px; }
.gm-search-icon { padding-left:8px; } /* leaves pad; the shape is the parent's radius */

segmented control

namethatui.com/macos/segmented-control

the thumb is the checked leaf's fill and the track has no padding; a real macos inset would be a leaf margin, never parent padding. pad the track and the thumb stops acting like a full-bleed segment.

a: the track pads

b: the leaves pad

b markup + css
<div class="gm-segmented">
<label class="gm-segment"><input type="radio" checked> week</label> …
</div>
.gm-segmented { display:flex; gap:2px; border-radius:8px; } /* track has no padding */
.gm-segment:has(:checked) { background:fill; box-shadow:shadow; } /* thumb = checked leaf */

sheet

namethatui.com/macos/sheet

the sheet hangs flush from the title bar; text and button cells are self-padding regions. pad the sheet and the action band stops short of the bottom edge.

a: the sheet pads

document

save changes before closing?

b: the leaves pad

document

save changes before closing?

b markup + css
<div class="gm-sheet">
<p class="gm-sheet-text">save changes before closing?</p>
<div class="gm-sheet-actions">don't save / save</div>
</div>
.gm-sheet { border:1px solid; border-top:0; border-radius:0 0 8px 8px; } /* hangs flush */
.gm-sheet-text { padding:12px 16px; }
.gm-sheet-btn { padding:8px 0; } /* cells pad; band is full-bleed */

slider

namethatui.com/macos/slider

the track fills its flex slot and the icons are padded leaves spaced by one gap. swap gap for margins and the row's rhythm becomes per-child edits.

a: margins replace the gap

60

b: gap on the row

60
b markup + css
<div class="gm-slider">
<span class="gm-slider-icon">♪</span>
<input type="range" value="60">
<span class="gm-slider-value">60</span>
</div>
.gm-slider { display:flex; align-items:center; gap:8px; }
.gm-slider-el { flex:1; } /* track fills its slot; only leaves pad */

split view

namethatui.com/macos/split-view

the divider is a full-height sibling line and the panes only arrange. pad the split and the divider no longer reaches the frame.

a: the split pads

list
detail

b: the leaves pad

list
detail
b markup + css
<div class="gm-split">
<div class="gm-split-side">list</div>
<div class="gm-split-divider"></div>
<div class="gm-split-main">detail</div>
</div>
.gm-split { display:flex; overflow:hidden; border-radius:8px; }
.gm-split-divider { width:1px; cursor:col-resize; } /* full-height sibling line */
.gm-split-label { padding:8px 12px; }

stepper

namethatui.com/macos/stepper

the readout pads itself and the button halves hover to their own rounded corners. pad the stack and the hover fills stop inside it.

a: the button stack pads

b: the leaves pad

b markup + css
<div class="gm-stepper">
<input class="gm-stepper-readout" value="12">
<div class="gm-stepper-buttons">▲ | ▼</div>
</div>
.gm-stepper-buttons { display:flex; flex-direction:column; overflow:hidden; border-radius:4px; }
.gm-stepper-btn { padding:2px 4px; } /* each half hovers to its rounded corner */

token field

namethatui.com/macos/token-field

tokens wrap on gap and the field border hugs them with zero inset. pad the field and the tokens float off the border.

a: the field pads

to:adalin

b: the leaves pad

to:adalin
b markup + css
<div class="gm-tokens">
<span class="gm-tokens-key">to:</span>
<span class="gm-token">ada</span>
<input class="gm-tokens-el">
</div>
.gm-tokens { display:flex; flex-wrap:wrap; align-items:center; gap:4px; border-radius:6px; }
.gm-token { padding:2px 8px; border-radius:9999px; } /* tokens wrap on gap; border hugs them */

toolbar

namethatui.com/macos/toolbar

toolbar items pad themselves, so hover fills run the full toolbar height. pad the toolbar and every hover fill stops short.

a: the toolbar pads

documents

b: the leaves pad

documents
b markup + css
<div class="gm-toolbar">
<button class="gm-toolbar-btn">‹</button>
<span class="gm-toolbar-title">documents</span>
<button class="gm-toolbar-btn">🔍</button>
</div>
.gm-toolbar { display:flex; align-items:stretch; overflow:hidden; border-radius:12px 12px 0 0; }
.gm-toolbar-btn { padding:8px 12px; } /* hover fills run the full toolbar height */

traffic lights

namethatui.com/macos/traffic-lights

no padding anywhere: fixed-size shapes spaced by the parent's one gap value. swap gap for per-child margins and the cluster's rhythm becomes three edits instead of one.

a: margins replace the gap

×−+

b: gap on the row

×−+
b markup + css
<div class="gm-traffic">
<span class="gm-traffic-light is-rose">✕</span> …
</div>
.gm-traffic { display:flex; gap:8px; } /* no padding anywhere */
.gm-traffic-light { width:12px; height:12px; border-radius:9999px; } /* fixed-size shapes */

vibrancy

namethatui.com/macos/vibrancy

the blur material reaches the window edge and selection rows tint on top of it. pad the material and the tint stops short of the frame.

a: the material pads

b: the leaves pad

b markup + css
<div class="gm-vibrancy">
<nav class="gm-vibrancy-nav">
<a class="gm-vibrancy-item is-active">airdrop</a> …
</nav>
</div>
.gm-vibrancy { overflow:hidden; border-radius:12px; } /* material reaches the window edge */
.gm-vibrancy-nav { backdrop-filter:blur(24px); }
.gm-vibrancy-item { padding:6px 12px; } /* selection tints on top of the material */

window

namethatui.com/macos/window

titlebar and status bar are bands that run edge to edge; the content region is the only padded leaf. pad the window and both bands stop short.

a: the window pads

untitled

content region

12 items2 gb free

b: the leaves pad

untitled

content region

12 items2 gb free
b markup + css
<div class="gm-window">
<div class="gm-titlebar">lights + title</div>
<div class="gm-window-body">
<p class="gm-window-content">content region</p>
<div class="gm-window-status">12 items / 2 gb free</div>
</div>
</div>
.gm-titlebar, .gm-window-status { border-*:1px solid; } /* bands run edge to edge */
.gm-window-content { padding:12px 16px; } /* the only padded region */

search pages

go to any page