  /* The words: ONE calm column laid over the field — the only thing that scrolls.
     data-chrome (set in the field) means the engine leaves its touches alone, so
     native scroll glides over the live dust and taps on the words don't stir it. */
  #words-scroll, .words-document-scroll {
    position: absolute; inset: 0; z-index: 5;
    overflow-y: auto; overflow-x: hidden;
    -webkit-overflow-scrolling: touch; touch-action: auto;
    /* Restoring a reader's position after a redraw must finish before paint. */
    scroll-behavior: auto;
  }
  /* PHONES: the words dissolve before they reach the footer.
     The shell's footer links (© Mike Monday / Here's how I made this…) are fixed
     in the bottom corners. On a wide screen this column is centred well inside
     them and they never meet. On a phone the column is nearly the whole viewport,
     so lines ran straight through both links — at rest on the first screen, not
     only while scrolling (seen live at 360px and 390px, 29 July 2026), which is
     why nothing tied to scrolling could have cleared them.
     So the column's own bottom edge dissolves: the last words fade to nothing
     across --s-10 and are completely gone for the --s-8 above the safe area where
     the links live. Nothing is ever printed over anything, at any scroll position,
     with no hard cut line and no chrome that comes and goes. It reads as an edge,
     and it tells a reader on the first screen that there is more below.
     The black in the gradient is an alpha stop, not a colour: a mask reads only
     the alpha channel, so there is no design-system colour to take from a token.
     The page's own 24vh of bottom padding still keeps the closing words, the
     signup beat and its note well clear of this band when the column is at rest
     at its end. */
  @media (max-width: 600px) {
    #words-scroll, .words-document-scroll {
      --words-footer-clearance: calc(env(safe-area-inset-bottom, 0px) + var(--s-8));
      -webkit-mask-image: linear-gradient(to bottom, rgb(0 0 0 / 100%) calc(100% - var(--words-footer-clearance) - var(--s-10)), rgb(0 0 0 / 0%) calc(100% - var(--words-footer-clearance)));
      mask-image: linear-gradient(to bottom, rgb(0 0 0 / 100%) calc(100% - var(--words-footer-clearance) - var(--s-10)), rgb(0 0 0 / 0%) calc(100% - var(--words-footer-clearance)));
    }
  }
  /* --words-scale / --words-weight / --words-measure are set live by the field
     from the Look chip's Type controls (with sane fallbacks here).
     A declaring canvas may supply --words-render-scale when its enclosing frame
     scales these screen-sized values; an ordinary page retains a divisor of 1. */
  #words-col, .words-document-column {
    --words-scale: 1;
    --words-weight: 460;
    --words-measure: 74ch;
	--words-button-alignment: left;
	--words-button-scale: 1;
	--words-block-space: 1;
	--words-paragraph-rhythm: calc(1.6 * clamp(16px, 1.7vw, 18px) * var(--words-scale) / var(--words-render-scale, 1));
    max-width: var(--words-measure);
	/* A visitor's button is an inline block directly inside this column, so the
	   column is its honest alignment owner. Every words block below keeps its own
	   left-set copy; only buttons read this alignment. */
	text-align: var(--words-button-alignment, left);
    /* The opening space was 26vh, a quarter of the screen before the first word.
       It read as luxury on a page of nothing but words, and it cost a page with a
       video the one thing that page is for: at 26vh the video's bottom fell below
       the fold on an ordinary laptop, so a reader had to scroll before they could
       see there was anything to play. 8vh puts the whole video on the first screen
       at that height and still leaves the heading air, because the chrome sits out
       in the corner rather than in this column. The closing space is unchanged —
       nothing was wrong with the end of the page. Mike chose the number on the
       three versions side by side, 2026-08-10.

       The 104px floor is the chrome. On a wide screen this column sits well to the
       right of the corner block, so it can start as high as it likes; on a phone the
       column is the full width and 8vh put the heading at 61px, straight through the
       FIELD and BUILD rows, which end at 90px. The chrome's height is fixed type, so
       the floor has to be pixels — a percentage cannot know how tall it is. Seen on a
       phone-width screenshot; every measurement of that same frame said the heading
       was neither clipped nor overflowing, because neither of those is what was
       wrong. */
    margin: 0 auto; padding: max(8vh, 104px) 32px 24vh;
    box-sizing: border-box;
  }
  /* Heading, opening line, paragraph and list blocks have no natural top margin.
     When Above is set, use one shared length calculated from the page's 1.6em
     paragraph rhythm so the same value creates comparable space on each; the
     zero fallback keeps an unset block's existing top margin exactly unchanged.
     Blocks with a natural top margin keep scaling their own margin below. */
  .words-h {
    font-family: var(--font-display); font-weight: 700;
    line-height: 1.05; letter-spacing: -0.02em; color: var(--fg);
  }
  /* A heading-first entry keeps the heading's outer spacing and type size even
     when its following lines are rendered as separate paragraph/list children. */
  .words-h, .words-mixed:has(> .words-h:first-child) {
    font-size: calc(clamp(34px, 6vw, 60px) * var(--words-scale) / var(--words-render-scale, 1));
    margin: 0 0 calc(calc(0.6em * var(--words-block-space, 1)) * var(--words-block-space-below, 1));
    margin-top: calc(calc(var(--words-paragraph-rhythm) * var(--words-block-space, 1)) * var(--words-block-space-above, 0));
  }
  .words-lead {
    font-family: var(--font-sans); font-weight: var(--words-weight);
    font-size: calc(clamp(19px, 2.4vw, 24px) * var(--words-scale) / var(--words-render-scale, 1));
    line-height: 1.55; color: var(--fg-soft); margin: 0 0 calc(calc(2em * var(--words-block-space, 1)) * var(--words-block-space-below, 1));
    margin-top: calc(calc(var(--words-paragraph-rhythm) * var(--words-block-space, 1)) * var(--words-block-space-above, 0));
  }
  .words-p {
    font-family: var(--font-sans); font-weight: var(--words-weight);
    font-size: calc(clamp(16px, 1.7vw, 18px) * var(--words-scale) / var(--words-render-scale, 1));
    line-height: var(--words-line-height, 1.85); color: var(--fg); margin: 0 0 calc(calc(1.6em * var(--words-block-space, 1)) * var(--words-block-space-below, 1));
    margin-top: calc(calc(var(--words-paragraph-rhythm) * var(--words-block-space, 1)) * var(--words-block-space-above, 0));
  }
  .words-h2 {
    font-family: var(--font-display); font-weight: 400; /* Hedvig is single-weight; never faux-bold the display serif */
    line-height: 1.15; letter-spacing: -0.01em; color: var(--fg);
  }
  .words-h2, .words-mixed:has(> .words-h2:first-child) {
    font-size: calc(clamp(24px, 3.4vw, 34px) * var(--words-scale) / var(--words-render-scale, 1));
    margin: calc(calc(2.2em * var(--words-block-space, 1)) * var(--words-block-space-above, 1)) 0 calc(calc(0.7em * var(--words-block-space, 1)) * var(--words-block-space-below, 1));
  }
  .words-list {
    font-family: var(--font-sans); font-weight: var(--words-weight);
    font-size: calc(clamp(16px, 1.7vw, 18px) * var(--words-scale) / var(--words-render-scale, 1));
    line-height: var(--words-line-height, 1.85); color: var(--fg);
    margin: 0 0 calc(calc(1.6em * var(--words-block-space, 1)) * var(--words-block-space-below, 1)); padding-left: 1.1em;
    margin-top: calc(calc(var(--words-paragraph-rhythm) * var(--words-block-space, 1)) * var(--words-block-space-above, 0));
  }
  ul.words-list { list-style: disc outside; }
  ol.words-list { list-style: decimal outside; }
  .words-mixed > .words-p, .words-mixed > .words-list,
  .words-mixed > .words-h, .words-mixed > .words-h2 {
    text-align: inherit;
    --words-block-space: 1;
    --words-block-space-above: initial;
    --words-block-space-below: 1;
  }
  .words-mixed > :last-child { margin-bottom: 0; }
  .words-mixed > :is(.words-h, .words-h2):first-child { margin-top: 0; }
  .words-li { margin: 0 0 0.5em; }
  /* body emphasis is real Libre Franklin bold; the display serif never faux-bolds —
     its emphasis is size and the marker (the design-system decision) */
  .words-p strong, .words-li strong, .words-lead strong { font-weight: 700; }
  .words-h strong, .words-h2 strong, .words-close strong { font-weight: inherit; }
  /* the marker highlight — the brand thread (matches patterns/slides.css .mark) */
  #words-col .mark, .words-document-column .mark {
    background: var(--marker);
    color: var(--marker-ink);
    padding: 0.02em 0.18em;
    border-radius: 1px;
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
  }
  .words-close {
    font-family: var(--font-display); font-weight: 600;
    font-size: calc(clamp(20px, 2.6vw, 26px) * var(--words-scale) / var(--words-render-scale, 1));
    line-height: 1.3; color: var(--fg); margin: calc(calc(2.6em * var(--words-block-space, 1)) * var(--words-block-space-above, 1)) 0 calc(calc(1.6em * var(--words-block-space, 1)) * var(--words-block-space-below, 1));
  }
  .words-btn {
	display: inline-block;
	margin-top: calc(2.6em * var(--words-block-space, 1));
	margin-top: calc(calc(2.6em * var(--words-block-space, 1)) * var(--words-block-space-above, 1));
	margin-bottom: calc(calc(1.6em * var(--words-block-space, 1)) * var(--words-block-space-below, 1));
	/* Readable body text in the words the Author wrote (Mike, 27 September 2026:
	   anything a visitor has to read or press is the normal body text, not small
	   typewriter capitals). The Author's Button size dial still scales it. */
	font-family: var(--font-sans); font-size: calc(var(--t-base) * var(--words-button-scale, 1) / var(--words-render-scale, 1)); line-height: var(--lh-normal);
    text-decoration: none;
    color: var(--button-ink, var(--accent-ink)); background: var(--button-bg, var(--accent));
	padding: calc(12px * var(--words-button-scale, 1) / var(--words-render-scale, 1)) calc(20px * var(--words-button-scale, 1) / var(--words-render-scale, 1)); border-radius: 3px;
  }
  .words-btn:hover { background: var(--button-hover, var(--accent)); }

  /* Things that arrive after the page does fade up instead of snapping in. Written
     as an ANIMATION rather than a transition out of a hidden base state, and that
     choice is the whole safety of it: an element that never gets this class is
     simply visible. A fade that fails to start can leave a visitor looking at a
     late image, never at nothing. */
  @keyframes words-arrive { from { opacity: 0; } to { opacity: 1; } }
  /* The author's dial, stamped on the column as --words-arrive before it is placed.
     The design system's panel duration is the fallback, so a page whose value has
     not landed yet still fades rather than snapping. */
  .words-arrives { animation: words-arrive var(--words-arrive, var(--dur-panel)) var(--ease); }
  .words-awaits-arrival { opacity: 0; }
  /* The poster is the biggest late arrival and the one worth easing, so it takes
     twice as long as the words — one dial moves both, keeping their relationship. */
  .words-video-poster-image.words-arrives { animation-duration: calc(var(--words-arrive, var(--dur-panel)) * 2); }
  @media (prefers-reduced-motion: reduce) { .words-arrives { animation: none; } }

  /* A video is a full-column 16:9 block. The same frame holds the poster control,
     the real YouTube iframe after activation, or the visible no-video-yet state,
     so replacement never moves the page and a bad address never becomes a gap. */
  .words-video-frame {
	position: relative; width: 100%; aspect-ratio: 16 / 9;
	margin: calc(2.6em * var(--words-block-space, 1)) 0 calc(2.6em * var(--words-block-space, 1));
	margin-top: calc(calc(2.6em * var(--words-block-space, 1)) * var(--words-block-space-above, 1));
	margin-bottom: calc(calc(2.6em * var(--words-block-space, 1)) * var(--words-block-space-below, 1));
    overflow: hidden; box-sizing: border-box;
    border: var(--b-hair) solid var(--rule); border-radius: var(--r-md);
    background: color-mix(in oklab, var(--panel) 92%, var(--bg));
  }
  .words-video-poster {
	position: absolute; inset: 0; width: 100%; height: 100%;
	margin: 0; padding: 0; overflow: hidden; border: 0; cursor: pointer;
	background: color-mix(in oklab, var(--panel) 82%, var(--bg));
  }
  .words-video-poster:focus-visible { outline: var(--b-stroke) solid var(--accent); outline-offset: calc(-1 * var(--b-stroke)); }
  .words-video-poster-image {
	position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block;
  }
  .words-video-play-mark {
	position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
	display: grid; place-items: center; width: var(--s-16); height: var(--s-16);
	border-radius: var(--r-pill); color: var(--accent-ink); background: var(--accent);
	font-family: var(--font-sans); font-size: var(--s-6); line-height: 1;
  }
  .words-video-iframe {
    position: absolute; inset: 0; width: 100%; height: 100%; border: 0;
  }
  .words-video-placeholder {
    display: grid; place-items: center; width: 100%; height: 100%;
    padding: var(--s-4); box-sizing: border-box; text-align: center;
    color: var(--muted); font-family: var(--font-mono); font-size: calc(11px / var(--words-render-scale, 1));
    letter-spacing: 0.04em; text-transform: uppercase;
  }

  /* The signup beat — an author-declared final beat: email in, submit, then the
     author's success words. Styled only with design-system tokens so it wears the
     page's surface, calm and native rather than a bolted-on form. */
  .words-signup { margin-top: calc(calc(2.6em * var(--words-block-space, 1)) * var(--words-block-space-above, 1)); margin-bottom: calc(calc(1.6em * var(--words-block-space, 1)) * var(--words-block-space-below, 1)); }
  .words-signup-prompt {
    font-family: var(--font-sans); font-weight: var(--words-weight);
    font-size: calc(clamp(16px, 1.7vw, 18px) * var(--words-scale) / var(--words-render-scale, 1));
    line-height: 1.7; color: var(--fg); margin: 0 0 1em;
  }
  .words-signup-row {
    display: flex; flex-wrap: wrap; align-items: stretch; gap: var(--s-3);
  }
  /* A box a thumb can see. This was a single hairline rule under transparent
     text: over the field's moving dust, at a phone width, it read as a line of
     grey words with nowhere to type, and a visitor could not tell there was an
     input there at all (seen live at 360px and 390px, 29 July 2026). It is a
     bordered, filled, rounded box now — every value a design token, and the pad
     deep enough that the box clears the 44px a thumb needs. The button beside it
     is unchanged; the row stretches both to the same height. */
  .words-signup-input {
    flex: 1 1 260px; min-width: 0;
    font-family: var(--font-sans);
    font-size: calc(clamp(16px, 1.7vw, 18px) * var(--words-scale) / var(--words-render-scale, 1));
    color: var(--fg);
    background: color-mix(in oklab, var(--bg) 88%, transparent);
    border: var(--b-hair) solid var(--muted); border-radius: var(--r-md);
    padding: calc(var(--s-3) / var(--words-render-scale, 1)) calc(var(--s-4) / var(--words-render-scale, 1)); outline: none;
    transition: border-color var(--dur-hover) var(--ease), background-color var(--dur-hover) var(--ease);
  }
  .words-signup-input::placeholder { color: var(--muted); }
  .words-signup-input:focus {
    border-color: var(--accent);
    background: color-mix(in oklab, var(--bg) 96%, transparent);
  }
  .words-signup-submit {
    flex: 0 0 auto; cursor: pointer; border: 0;
    /* Readable body text, the same size as the email box beside it, in the words
       the Author wrote (Mike, 27 September 2026). */
    font-family: var(--font-sans); font-size: calc(clamp(16px, 1.7vw, 18px) * var(--words-scale) / var(--words-render-scale, 1)); line-height: var(--lh-normal);
    color: var(--button-ink, var(--accent-ink)); background: var(--button-bg, var(--accent));
    padding: calc(12px / var(--words-render-scale, 1)) calc(20px / var(--words-render-scale, 1)); border-radius: var(--r-sm);
    transition: background-color 140ms ease, opacity 140ms ease;
  }
  .words-signup-submit:hover { background: var(--button-hover, var(--accent-hover)); }
  .words-signup-submit:disabled { opacity: 0.6; cursor: default; }
  .words-signup-note {
    min-height: 1.2em; margin: 0.9em 0 0;
    font-family: var(--font-sans); font-size: calc(14px / var(--words-render-scale, 1)); line-height: 1.5;
    color: var(--muted);
  }
  .words-signup-note.is-warn { color: var(--fg-soft); }
  .words-signup-note.is-alert { color: var(--status-alert); }
  .words-signup-done { margin-top: 0.2em; }
  .words-signup-success { margin: 0; }
	.words-signup-done .words-btn { margin-top: calc(1.4em * var(--words-block-space, 1)); }
  /* author edit affordance (only meaningful in author mode) */
  :where(#words-col, .words-document-column) [data-copy] { border-radius: 2px; }
  :where(#words-col, .words-document-column) [data-copy].editing { outline: none; background: color-mix(in srgb, var(--accent) 18%, transparent); }

  /* Author-only block chrome: drag, add directly after this block, or remove it.
     The field builds .words-block / .words-block-tools ONLY when the author module is
     present, so a visitor's column never carries them. The controls are absolutely
     placed and appear on hover, so the words sit exactly where they will publish.
     .is-first is the emptied-body case: nothing to hover, so it stays in the flow. */
	.words-block { position: relative; }
	/* In author mode the block wrapper owns the button and its editable address
	   line. Grid alignment moves both as one without changing the inline button.
	   The signup success block is the same shape for a visitor. */
	.words-button-block { display: grid; justify-items: var(--words-button-alignment, left); }
	.words-signup-done { display: grid; justify-items: var(--words-button-alignment, left); }
	.words-signup-success { justify-self: stretch; text-align: var(--words-text-alignment, left); }
	.words-video-block { text-align: var(--words-text-alignment, left); }
	.words-h, .words-h2, .words-lead, .words-p, .words-list, .words-close, .words-signup { text-align: var(--words-text-alignment, left); }
	/* Per-block alignment is stamped on the content node itself. That is
	   load-bearing: visitors have no .words-block wrapper. Text blocks align their
	   words; a button also has to move its inline-block box, so it becomes a
	   width-to-content block and uses its own margins. In author mode justify-self
	   puts that same button and its address ahead of the wrapper's page-wide
	   button alignment. With no data-block-alignment attribute, every old rule
	   above remains untouched. */
	:where(#words-col, .words-document-column) [data-block-alignment="left"] { text-align: left; }
	:where(#words-col, .words-document-column) [data-block-alignment="centre"] { text-align: center; }
	:where(#words-col, .words-document-column) [data-block-alignment="right"] { text-align: right; }
	.words-btn[data-block-alignment],
	.words-btn-link[data-block-alignment] {
		display: block; width: fit-content; max-width: 100%;
	}
	.words-btn[data-block-alignment="left"],
	.words-btn-link[data-block-alignment="left"] {
		justify-self: start; margin-left: 0; margin-right: auto;
	}
	.words-btn[data-block-alignment="centre"],
	.words-btn-link[data-block-alignment="centre"] {
		justify-self: center; margin-left: auto; margin-right: auto;
	}
	.words-btn[data-block-alignment="right"],
	.words-btn-link[data-block-alignment="right"] {
		justify-self: end; margin-left: auto; margin-right: 0;
	}
	.words-signup[data-block-alignment="left"] .words-signup-done { justify-items: start; }
	.words-signup[data-block-alignment="centre"] .words-signup-done { justify-items: center; }
	.words-signup[data-block-alignment="right"] .words-signup-done { justify-items: end; }
	.words-signup[data-block-alignment="left"] .words-signup-success { text-align: left; }
	.words-signup[data-block-alignment="centre"] .words-signup-success { text-align: center; }
	.words-signup[data-block-alignment="right"] .words-signup-success { text-align: right; }
  .words-block-tools {
    position: absolute; bottom: 100%; right: 0; z-index: 6;
    display: flex; gap: 4px;
    opacity: 0; visibility: hidden;
    transition: opacity 120ms ease 300ms, visibility 0s linear 420ms;
    /* Invisible is not the same as gone: a faded-out control still catches the
       pointer, so a neighbouring block's + sat on top of an open add menu and
       swallowed the press (seen driving the page, 28 July 2026). Nothing the
       author cannot see may take a click. */
  }
  .words-block:hover > .words-block-tools,
  .words-block:focus-within > .words-block-tools { opacity: 1; visibility: visible; transition-delay: 0s; }
  .words-block-tools:has(> :is(.words-block-add-menu, .words-block-alignment-menu, .words-block-spacing-menu)) { z-index: 8; }
  .words-block-tools.is-first { position: static; opacity: 1; visibility: visible; pointer-events: auto; margin: 0 0 1.6em; }
	.words-block-tool {
    appearance: none; cursor: pointer;
    width: 20px; height: 20px; padding: 0; line-height: 1;
    border: 1px solid var(--rule); border-radius: var(--r-sm);
    background: color-mix(in oklab, var(--bg) 84%, transparent);
    color: var(--muted); font-family: var(--font-mono); font-size: 12px;
	}
	.words-block-tool[data-block-tool="add-above"] { width: auto; flex-shrink: 0; padding: 0 var(--s-1); }
	.words-block-tool[data-block-tool="spacing"] { width: auto; padding: 0 5px; font-size: 9px; }
  .words-block-tool:hover,
  .words-block-tool:focus-visible { border-color: var(--accent); color: var(--accent); }

	/* The +, alignment and spacing gestures use the same small-menu idiom. They are
		 author-only, hang under the control that opened them, and a press anywhere
		 else on the page puts them away. */
	.words-block-add-menu,
	.words-block-alignment-menu,
	.words-block-spacing-menu {
    position: absolute; top: 24px; right: 0; z-index: 7;
    display: flex; flex-direction: column; gap: 2px;
    padding: 4px; border: 1px solid var(--rule); border-radius: var(--r-sm);
    background: color-mix(in oklab, var(--panel) 96%, var(--bg));
    box-shadow: var(--shadow-md);
  }
  .words-block-add-choice,
  .words-block-alignment-choice {
    appearance: none; cursor: pointer; white-space: nowrap; text-align: left;
    padding: 5px 9px; border: 1px solid transparent; border-radius: var(--r-sm);
    background: transparent; color: var(--fg);
    font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.04em;
  }
	.words-block-add-choice:hover,
  .words-block-add-choice:focus-visible,
  .words-block-alignment-choice:hover,
	.words-block-alignment-choice:focus-visible { border-color: var(--accent); color: var(--accent); }
	.words-block-spacing-row { display: grid; grid-template-columns: 42px auto minmax(58px, auto) auto; gap: 2px; align-items: center; }
	.words-block-spacing-label {
		padding: 0 4px; color: var(--muted);
		font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.04em;
	}
	.words-block-spacing-choice {
		appearance: none; cursor: pointer; white-space: nowrap;
		padding: 5px 7px; border: 1px solid transparent; border-radius: var(--r-sm);
		background: transparent; color: var(--fg);
		font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.04em;
	}
	.words-block-spacing-choice:hover,
	.words-block-spacing-choice:focus-visible { border-color: var(--accent); color: var(--accent); }
  .words-block-tools.is-first { position: relative; bottom: auto; }

  /* AUTHOR ONLY: the address a button goes to, written under it so it can be
     Alt-clicked and typed like every other word on the page. A visitor's column
     never carries this line, so it never moves the words a visitor reads. */
  .words-btn-link {
    margin: 0.5em 0 0;
    font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.04em;
    color: var(--muted); word-break: break-all;
  }
  .words-btn-link:empty::before { content: "no address yet"; color: var(--whisper); }

  /* AUTHOR ONLY: a video's stored YouTube id, written under the frame so an
     address can be pasted into it. Visitors never carry this line. */
  .words-video-link {
    margin: 0.5em 0 0;
    font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.04em;
    color: var(--muted); word-break: break-all;
  }
  .words-video-link:empty::before { content: "no video address yet"; color: var(--whisper); }

  /* AUTHOR ONLY: drag a block up or down the page. The handle takes the pointer
     for the whole drag (touch-action: none, or a touch would scroll the column
     instead of moving the block), and a line laid OVER the page says where the
     block will land — nothing about the words moves while the author decides. */
  .words-block-tool[data-block-tool="drag"] { cursor: grab; touch-action: none; }
  .words-block-tool[data-block-tool="drag"]:active { cursor: grabbing; }
  .words-block-drop {
    position: fixed; z-index: 8; height: 2px; margin-top: -1px;
    background: var(--accent); pointer-events: none;
  }

/* Tabs share the document's blocks, type and block tools. */
.words-tabs {
  min-width: 0;
  margin-top: calc(var(--s-6) * var(--words-block-space, 1) * var(--words-block-space-above, 1));
  margin-bottom: calc(var(--s-6) * var(--words-block-space, 1) * var(--words-block-space-below, 1));
}
.words-tab-panel { min-width: 0; padding-block: var(--s-3); }
.words-tab-panel[hidden] { display: none; }
.words-tab-panel > .words-block-tools.is-first { position: relative; opacity: 1; margin-block: var(--s-2); }
.words-tab-panel > .words-object { min-width: 0; }

.words-block:has(> .words-tabs) > .words-block-tools { position: relative; bottom: auto; right: auto; justify-content: flex-end; }

/* Usage — retained appearance, scoped to its declaring page.
   :where() adds no selector weight; values and rule order are preserved. */
:where(body.usage-page) #mai-usage {
	background:
		linear-gradient(90deg, color-mix(in oklch, var(--cyan) 8%, transparent) 1px, transparent 1px),
		linear-gradient(0deg, color-mix(in oklch, var(--fg) 5%, transparent) 1px, transparent 1px);
	background-size: 48px 48px;
	color: var(--fg);
}

:where(body.usage-page) .mu-wrap {
	box-sizing: border-box;
	width: min(1380px, calc(100% - 32px));
	min-height: 100%;
	margin: 0 auto;
	padding: 92px 16px 26px;
	display: grid;
	grid-template-rows: auto auto auto auto;
	align-content: start;
	gap: 8px;
}

:where(body.usage-page) .mu-head {
	display: flex;
	align-items: end;
	justify-content: space-between;
	gap: 16px;
}

:where(body.usage-page) .mu-kicker,
:where(body.usage-page) .mu-title {
	margin: 0;
}

:where(body.usage-page) .mu-title {
	color: var(--fg);
	font-size: 24px;
	line-height: 1;
}

:where(body.usage-page) .mu-refresh {
	min-width: 86px;
	border: 1px solid color-mix(in oklch, var(--accent) 38%, transparent);
	background: color-mix(in oklch, var(--accent) 12%, transparent);
	color: var(--fg);
	border-radius: 4px;
	padding: 8px 10px;
	cursor: pointer;
}

:where(body.usage-page) .mu-refresh:hover {
	border-color: var(--accent);
}

:where(body.usage-page) .mu-refresh:disabled {
	opacity: 0.58;
	cursor: default;
}

:where(body.usage-page) .mu-compact {
	border-top: 1px solid color-mix(in oklch, var(--fg) 16%, transparent);
	border-bottom: 1px solid color-mix(in oklch, var(--fg) 16%, transparent);
	padding: 6px 0 7px;
	color: var(--accent);
	font-size: 22px;
	line-height: 1.15;
	letter-spacing: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: normal;
	overflow-wrap: anywhere;
}

:where(body.usage-page) .mu-capacity {
	display: flex;
	flex-wrap: wrap;
	gap: var(--s-1) var(--s-2);
	margin-top: var(--s-1);
}

:where(body.usage-page) .mu-capacity[hidden],
:where(body.usage-page) .mu-capacity [hidden] { display: none; }

:where(body.usage-page) .mu-capacity[data-usable="true"] { color: var(--status-ok); }

:where(body.usage-page) .mu-main-grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(380px, 0.38fr);
	gap: 8px;
	align-items: start;
}

:where(body.usage-page) .mu-main-grid > *,
:where(body.usage-page) .mu-meter-grid > *,
:where(body.usage-page) .mu-meter,
:where(body.usage-page) .mu-cost,
:where(body.usage-page) .mu-window,
:where(body.usage-page) .mu-window-main,
:where(body.usage-page) .mu-analysis,
:where(body.usage-page) .mu-insight {
	min-width: 0;
}

:where(body.usage-page) .mu-meter-grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 8px;
	align-items: start;
}

:where(body.usage-page) .mu-meter,
:where(body.usage-page) .mu-cost {
	border: 1px solid color-mix(in oklch, var(--fg) 14%, transparent);
	background: color-mix(in oklch, var(--panel) 72%, transparent);
	border-radius: 5px;
	padding: 8px;
	display: flex;
	flex-direction: column;
	gap: 7px;
	box-shadow: var(--shadow-md);
}

:where(body.usage-page) .mu-cost {
	max-height: 188px;
	overflow: auto;
}

:where(body.usage-page) .mu-meter-top,
:where(body.usage-page) .mu-analysis-head,
:where(body.usage-page) .mu-analysis-row {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 12px;
}

:where(body.usage-page) .mu-badge {
	color: var(--muted);
	text-align: right;
}

:where(body.usage-page) .mu-window-list {
	display: grid;
	gap: 7px;
}

:where(body.usage-page) .mu-window {
	display: grid;
	gap: 6px;
}

:where(body.usage-page) .mu-window-main {
	display: grid;
	grid-template-columns: 54px minmax(54px, 0.7fr) minmax(78px, 1fr);
	align-items: baseline;
	gap: 8px;
	min-height: 21px;
}

:where(body.usage-page) .mu-window-label {
	color: var(--fg-soft);
}

:where(body.usage-page) .mu-window-value {
	font-size: 20px;
	line-height: 1;
	font-weight: 700;
	color: var(--fg);
	letter-spacing: 0;
}

:where(body.usage-page) .mu-window-reset {
	color: var(--muted);
	text-align: right;
	white-space: nowrap;
}

:where(body.usage-page) .mu-track {
	width: 100%;
	min-width: 0;
	height: 6px;
	border: 1px solid color-mix(in oklch, var(--fg) 12%, transparent);
	background: color-mix(in oklch, var(--fg) 5%, transparent);
	border-radius: 4px;
	overflow: hidden;
}

:where(body.usage-page) .mu-track span {
	display: block;
	width: 0%;
	height: 100%;
	background: linear-gradient(90deg, var(--sage), var(--accent));
	transition: width 220ms var(--ease);
}

:where(body.usage-page) .mu-peak .mu-track span {
	background: linear-gradient(90deg, var(--amber), var(--marker));
}

:where(body.usage-page) .mu-value-row {
	display: flex;
	align-items: baseline;
	min-height: 22px;
}

:where(body.usage-page) .mu-value {
	color: var(--fg);
	font-size: 20px;
	line-height: 1;
}

:where(body.usage-page) .mu-note {
	min-height: 0;
	margin: 0;
	color: var(--fg-soft);
	overflow: hidden;
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
}

:where(body.usage-page) .mu-analysis {
	border: 1px solid color-mix(in oklch, var(--fg) 14%, transparent);
	background: color-mix(in oklch, var(--bg) 78%, transparent);
	border-radius: 5px;
	padding: 8px;
	display: grid;
	gap: 6px;
}

:where(body.usage-page) .mu-analysis-head h2 {
	margin: 0;
}

:where(body.usage-page) .mu-analysis-grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 6px;
}

:where(body.usage-page) .mu-analysis-row {
	display: grid;
	grid-template-columns: 54px minmax(0, 1fr);
	justify-content: start;
	border: 1px solid color-mix(in oklch, var(--fg) 10%, transparent);
	border-radius: 4px;
	padding: 6px 7px;
	color: var(--fg-soft);
	min-height: 34px;
}

:where(body.usage-page) .mu-controls {
	display: grid;
	grid-template-columns: 0.8fr 1.3fr 0.68fr;
	gap: 6px;
}

:where(body.usage-page) .mu-controls label {
	display: grid;
	gap: 4px;
	color: var(--fg-soft);
}

:where(body.usage-page) .mu-controls select {
	min-width: 0;
	width: 100%;
	border: 1px solid color-mix(in oklch, var(--fg) 14%, transparent);
	background: color-mix(in oklch, var(--bg) 84%, transparent);
	color: var(--fg);
	border-radius: 3px;
	padding: 5px 6px;
	font: inherit;
}

:where(body.usage-page) .mu-cost-main {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	gap: 2px 10px;
	align-items: baseline;
	padding: 5px 6px;
	border: 1px solid color-mix(in oklch, var(--accent) 18%, transparent);
	border-radius: 4px;
	background: color-mix(in oklch, var(--accent) 7%, transparent);
}

:where(body.usage-page) .mu-cost-main strong {
	font-family: var(--font-mono);
	font-size: 18px;
	line-height: 1;
	color: var(--marker);
}

:where(body.usage-page) .mu-cost-main span,
:where(body.usage-page) .mu-cost-main small {
	color: var(--fg-soft);
}

:where(body.usage-page) .mu-cost-main small {
	grid-column: 1 / -1;
}

:where(body.usage-page) .mu-token-grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 5px;
}

:where(body.usage-page) .mu-token-cell {
	display: grid;
	gap: 3px;
	padding: 4px 5px;
	border: 1px solid color-mix(in oklch, var(--fg) 10%, transparent);
	border-radius: 4px;
	color: var(--fg-soft);
}

:where(body.usage-page) .mu-token-cell strong {
	font-family: var(--font-mono);
	font-size: 14px;
	color: var(--fg);
}

:where(body.usage-page) .mu-token-cell small {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

:where(body.usage-page) .mu-compare {
	display: grid;
	gap: 5px;
	max-height: 74px;
	overflow: auto;
}

:where(body.usage-page) .mu-compare-row {
	display: grid;
	grid-template-columns: 68px 72px minmax(0, 1fr);
	gap: 6px;
	align-items: baseline;
	border: 1px solid color-mix(in oklch, var(--fg) 10%, transparent);
	background: color-mix(in oklch, var(--bg) 80%, transparent);
	color: var(--fg-soft);
	border-radius: 3px;
	padding: 4px 5px;
	text-align: left;
	cursor: pointer;
}

:where(body.usage-page) .mu-compare-row strong {
	color: var(--fg);
	font-family: var(--font-mono);
}

:where(body.usage-page) .mu-compare-row small {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

:where(body.usage-page) .mu-compare-row.active {
	border-color: color-mix(in oklch, var(--marker) 42%, transparent);
	background: color-mix(in oklch, var(--marker) 10%, transparent);
}

:where(body.usage-page) .mu-insights {
	display: grid;
	grid-template-columns: 1fr;
	gap: 5px;
}

:where(body.usage-page) .mu-insight {
	display: grid;
	grid-template-columns: minmax(0, 1.1fr) minmax(110px, 0.34fr) minmax(220px, 0.78fr);
	gap: 6px 10px;
	min-height: 0;
	border: 1px solid color-mix(in oklch, var(--fg) 10%, transparent);
	border-left-width: 3px;
	border-radius: 4px;
	padding: 7px 9px;
	color: var(--fg-soft);
	background: color-mix(in oklch, var(--panel) 55%, transparent);
	align-items: start;
}

:where(body.usage-page) .mu-insight div {
	display: grid;
	grid-template-columns: minmax(140px, 0.42fr) minmax(0, 1fr);
	gap: 8px;
	align-items: baseline;
}

:where(body.usage-page) .mu-insight strong {
	color: var(--fg);
	font-size: 13px;
	line-height: 1.12;
}

:where(body.usage-page) .mu-insight p {
	margin: 0;
	font-size: 13px;
	line-height: 1.18;
}

:where(body.usage-page) .mu-insight small {
	color: var(--muted);
	font-size: 12px;
	line-height: 1.2;
}

:where(body.usage-page) .mu-insight[data-severity="high"] {
	border-color: color-mix(in oklch, var(--amber) 42%, transparent);
}

:where(body.usage-page) .mu-insight[data-severity="good"] {
	border-color: color-mix(in oklch, var(--sage) 38%, transparent);
}

:where(body.usage-page) .mu-warnings {
	color: var(--muted);
}

@media (max-width: 1040px) {
:where(body.usage-page) .mu-main-grid {
		grid-template-columns: 1fr;
	}
}

@media (max-width: 860px) {
:where(body.usage-page) .mu-wrap {
		width: min(calc(100% - 24px), 720px);
		padding: 88px 12px 40px;
	}
:where(body.usage-page) .mu-head {
		align-items: start;
		flex-direction: column;
	}
:where(body.usage-page) .mu-title {
		font-size: 22px;
	}
:where(body.usage-page) .mu-refresh {
		min-width: 0;
		padding: 7px 10px;
	}
:where(body.usage-page) .mu-meter-grid {
		grid-template-columns: 1fr;
	}
:where(body.usage-page) .mu-compact {
		font-size: 18px;
		line-height: 1.18;
		white-space: normal;
	}
:where(body.usage-page) .mu-window-main {
		grid-template-columns: 68px minmax(68px, 1fr) minmax(86px, auto);
	}
:where(body.usage-page) .mu-window-value {
		font-size: 22px;
	}
:where(body.usage-page) .mu-analysis-grid {
		grid-template-columns: 1fr;
	}
:where(body.usage-page) .mu-controls,
:where(body.usage-page) .mu-token-grid,
:where(body.usage-page) .mu-insights {
		grid-template-columns: 1fr;
	}
:where(body.usage-page) .mu-cost {
		max-height: 300px;
		overflow: auto;
	}
:where(body.usage-page) .mu-insight,
:where(body.usage-page) .mu-insight div {
		grid-template-columns: 1fr;
	}
:where(body.usage-page) .mu-compare-row {
		grid-template-columns: 64px 72px minmax(0, 1fr);
	}
}
