TLDR: If your CSS variables use cqi units, never apply them to html — even inside a shared html, body {} rule. Set font-size on body only. One misplaced selector can push your root font-size 2–3× too large and silently break every rem-based clamp in your stylesheet.

The Setup

I was building a presentation site for a marketing client AI workshop — full-screen 16:9 stages, snapping panels, a fluid type system built on a single --body CSS variable using clamp() with cqi (container query inline units) to scale text to the stage.

Looked clean in dev.

Then I opened it on a big monitor.

The Wall

Every slide overflowed.

Not a little — 100–200px past the bottom edge of the 16:9 frame. Cards too tall. Body text enormous. H2 wrapping to two lines when it had no business doing so.

I assumed it was the card padding. Trimmed it. Still broken.

Tightened the type maxes. Rewrote the gallery layout. Cut a panel. Reduced clamp ceilings. Twelve commits. Still broken "in multiple places" — but the places kept shifting.

That's when I knew it wasn't a content problem.

What I Should Have Done First

I was debugging symptoms. The root was somewhere else entirely.

So I finally measured.

arc-cdp eval 'JSON.stringify({
  rootFs: getComputedStyle(document.documentElement).fontSize,
  bodyFs: getComputedStyle(document.body).fontSize
})'

(arc-cdp is my Arc browser automation tool — lets me eval JavaScript in the live page from the terminal.)

The result: rootFs: "36px".

Thirty-six. Browser default is 16px.

The Actual Bug

Here's the CSS:

:root {
  --body: clamp(0.95rem, 1.7cqi, 2.25rem);
}

html, body {
  font-size: var(--body);   /* ← the bug */
}

The --body variable uses 1.7cqi — 1.7% of the container's inline width.

html has no container. When you use cqi on a containerless element, it falls back to the viewport.

On a 2540px-wide viewport: 1.7% × 2540 = 43px. The clamp (15.2px, 43px, 36px) returns 36px. Root html font-size = 36px.

Now every rem downstream resolves against 36px instead of 16px. So this innocent rule:

.card p { font-size: clamp(0.85rem, 1.3cqi, 1.7rem); }

…suddenly had a 30.6px floor. On a normal viewport the cqi midrange was only ~21px — so the rem floor won every time. Responsive sizing: completely broken, everywhere, all at once.

One selector. Everything downstream: wrong.

The Fix

html {
  scroll-snap-type: y mandatory;
  scroll-behavior: smooth;
  /* everything EXCEPT font-size */
}

body {
  font-size: var(--body);   /* body only */
}

That's it. One line moved from html, body to body alone.

Root html stays at the browser default 16px. Every rem-based clamp inside the stage elements now computes correctly — and the cqi midrange wins as designed.

Single commit. Every overflow: gone.

Why This Matters

Any container-relative unit (cqi, cqb, cqmin, cqmax) applied to a containerless element falls back to the viewport. And html is always containerless.

If you've ever set font-size on html using a variable that contains a container unit — directly or through a shared html, body {} selector — your rem scale is probably wrong on large screens and you don't know it yet.

The debugging move I wish I'd made on commit one:

getComputedStyle(document.documentElement).fontSize

If that's not 16px (or whatever you intended), STOP. That's the bug. Don't trim card padding. Don't touch type scales. Measure first.

I lost an afternoon chasing symptoms. You don't have to.

P.S. This is now the first thing I check when CSS overflows don't respond to the obvious fixes. Measure the root before you touch anything else.