A cookie banner that unfolds into its own settings, and answers in place.
The prompt29,524 characters
Add the "Consent" component from notboring to my project.
It is licensed for use in my projects — notboring.dev/license. Please:
1. Create the component at a sensible path for this
project, named Consent, from the source below.
2. It needs nothing beyond React.
3. Add the CSS to the project's stylesheet.
4. THE PART THAT NEEDS YOUR JUDGMENT. The CSS reads
these custom properties and does not define them:
--card
--font-ui
--ink
--ink-3
--ink-4
--ink-rgb
They are notboring's design tokens. Map each one to
whatever this project already uses for the same
job — its own ink, ground, surface and UI font —
rather than defining them as new globals. If the
project has no equivalent, define it locally on
the component's own root so nothing leaks out.
Anything ending -rgb wants three bare numbers,
because the CSS builds rgba() from it.
Keep the comments. They say why the numbers are what
they are, and they are most of what makes this worth
copying rather than rewriting.
--- Consent.tsx ---
import { useEffect, useLayoutEffect, useRef, useState } from "react";
/* ══ Consent ══════════════════════════════════════════════
A cookie banner, and the settings it usually hides behind
a link.
IT UNFOLDS IN PLACE. The common build sends "Customize" to
a second page, or to a modal over the first, and the person
who wanted to turn off one tracker is now three surfaces
deep in a dialog about it. Here the banner IS the settings:
press Customize and the card grows upward to hold three
rows, the two buttons that were already under your pointer
change what they say, and they do not move a pixel. Fold it
back and it is the banner again.
THE HEIGHT IS ONE NUMBER. The rows sit in a box whose
height is tweened between nothing and what the rows
measure, and the card is sized by its content — so the card
grows by exactly the rows' height, and because it stands on
the bottom of its block the growth goes up, away from the
buttons. A card whose height was animated separately from
the rows it was making room for would be two numbers
agreeing by luck, and one frame apart is a visible gap.
The rest — the source and its comments — is what you are buying.