/* ============================================================================================
   THE PARTS — one stylesheet, every site, every theme.

   A theme sets the TOKENS below and nothing else. It does not restyle a row, a card or a field:
   if it did, we would be back to five implementations of the same thing drifting apart, which is
   what made a page rounded at the top and square underneath.

   Everything here is written in tokens. There is no pixel value in a component rule that is not
   derived from `--c-u`, the type scale, or the radius. That is the rule that makes the whole site
   feel composed rather than assembled.

   TWO HOSTS, ONE STYLESHEET. Every rule is `:is(#clay-page,#design-sheets)`, because the overlays
   are a SIBLING of the page, not a child of it. Written for the page alone — which is how this
   file started — the basket, a product and the photo viewer got no tokens and no components at
   all: the way out came out as a bordered link, the two-column basket stacked, and the whole
   overlay looked like a stylesheet had failed to load, which is exactly what had happened.
   Nothing about a sheet is a different design, so nothing about it is a second stylesheet.
   ========================================================================================== */

/**
 * EVERY BOX IS A BORDER BOX — and this was missing, which is the most expensive single line in
 * this stylesheet.
 *
 * Without it a card is `content-box`: its padding and its border sit OUTSIDE the width and height
 * the layout gave it. A card with 20px of padding and a 5px border renders 50px taller than the
 * grid track holding it, so on a phone the third way-in overlapped the first — and every column
 * sum, every `minmax`, every `100% - gap` in this file was quietly out by the same amount.
 *
 * It looks like a dozen unrelated layout faults, which is exactly how it was reported. It is one.
 *
 * Scoped to our two hosts like everything else here, so it cannot reach the editor's own chrome.
 */
:is(#clay-page,#design-sheets),
:is(#clay-page,#design-sheets) *,
:is(#clay-page,#design-sheets) *::before,
:is(#clay-page,#design-sheets) *::after{box-sizing:border-box}

:is(#clay-page,#design-sheets){
  /* ── ink and ground ───────────────────────────────────────────────────────────────────── */
  --c-paper:#ffffff;
  --g:var(--c-paper);            /* what I am sitting on */
  --c-ink:#0d0d0f;
  --c-faint:var(--c-soft);
  --c-accent:#C87F5E;
  --c-on:#ffffff;                       /* what sits on the accent — see below, it is derived */

  /**
   * ── THE ACCENT'S OWN PALETTE ── one hue, eleven steps, and every dark thing on the page is one
   * of them.
   *
   * A theme needs more than an accent: it needs the room the accent lives in. Before this there
   * were SIX different near-blacks between the two themes — `#0b0b0d`, `#191920`, `#0d0d0f`,
   * `#141210`, `#241E18`, `#151515` — each hand-picked, none related to the business's colour and
   * none related to each other. A footer, a contrast band and a photo scrim on the same site were
   * three unrelated dark greys, and the accent sat on top of them looking like it had been dropped
   * in from somewhere else.
   *
   * So: mix the accent toward white for the light end and toward BLACK for the dark end. Mixing
   * toward black drops the chroma as it drops the lightness, which is exactly what a near-black
   * wants to be — a very dark version of their colour rather than a dark version of their colour,
   * which would be a neon in a dark room.
   *
   * NOT A NEW DECISION PER THEME. A theme names a step; it does not mix its own. What it may still
   * do is choose WHICH step — a light theme's contrast band is 950, a dark theme's is 900, because
   * the same darkness reads differently depending on what it is next to.
   *
   * `color-mix` rather than `oklch(from …)`: it needs no `@supports` guard, and toward black the
   * two are indistinguishable at these strengths.
   */
  --c-a-50: color-mix(in oklab, var(--c-accent)  6%, #fff);
  --c-a-100:color-mix(in oklab, var(--c-accent) 12%, #fff);
  --c-a-200:color-mix(in oklab, var(--c-accent) 22%, #fff);
  --c-a-300:color-mix(in oklab, var(--c-accent) 40%, #fff);
  --c-a-400:color-mix(in oklab, var(--c-accent) 68%, #fff);
  --c-a-500:var(--c-accent);
  --c-a-600:color-mix(in oklab, var(--c-accent) 82%, #000);
  --c-a-700:color-mix(in oklab, var(--c-accent) 62%, #000);
  --c-a-800:color-mix(in oklab, var(--c-accent) 42%, #000);
  --c-a-900:color-mix(in oklab, var(--c-accent) 26%, #000);
  --c-a-950:color-mix(in oklab, var(--c-accent) 15%, #000);

  /**
   * THE NEUTRALS CARRY THE BRAND — this is the one number that decides how much.
   *
   * Every grey on the page was mixed from ink and paper alone, so two businesses with two very
   * different colours got the same rules, the same tints and the same grey text: the accent showed
   * up on a button and nowhere else, and a site read as our design with their colour dropped into
   * it. A brand is not one button.
   *
   * So every neutral is pulled a little way toward the accent. A LITTLE: the rule under a heading
   * is still a rule, the body text is still readable, and nothing here is the accent itself — it
   * is the accent's shadow in the greys, which is what makes a page look like it was made for one
   * business rather than tinted after the fact.
   *
   * One token, so a theme that wants more of it or none of it says so once, and a dark page can
   * carry more than a light one (a dark ground takes colour without losing contrast).
   */
  --c-brand:7%;                         /* how much of the accent is in the neutrals */
  /* TEXT TAKES LESS OF IT THAN A SURFACE DOES, and it is measured rather than guessed: the
     surfaces lift toward the accent and the secondary text is pulled toward it, so at equal
     strength the two close on each other and a line under a heading drops below AA. A quarter,
     and a little more ink in it, keeps every secondary line over 4.5:1 in both modes. */
  --c-soft:color-mix(in oklab, var(--c-accent) calc(var(--c-brand) / 4),
                     color-mix(in oklab, var(--c-ink) 66%, var(--c-paper)));
  --c-line:color-mix(in oklab, var(--c-accent) var(--c-brand),
                     color-mix(in oklab, var(--c-ink) 14%, var(--c-paper)));
  --c-fill:color-mix(in oklab, var(--c-accent) var(--c-brand),
                     color-mix(in oklab, var(--c-ink) 5%, var(--c-paper)));
  /**
   * THE FILL AS A GROUND — the same colour, and it has to be a SECOND token.
   *
   * `--c-fill` is redefined on every band (see the ground-aware block below), because a box drawn
   * inside a dark band must be a lifted dark rather than the pale one mixed for the page. But the
   * `fill` GROUND is `--g: var(--c-fill)`, and a `--c-fill` derived from `--g` makes those two
   * definitions a cycle: the browser throws both away, the band paints no background at all, and
   * the ink derived from the missing ground falls back to the page's — near-white text on a cream
   * page. Every `c-g-fill` band on every site, invisible.
   *
   * So the ground reads THIS, which is stated once here and never derived from a ground.
   */
  --c-ground-fill:color-mix(in oklab, var(--c-accent) var(--c-brand),
                            color-mix(in oklab, var(--c-ink) 5%, var(--c-paper)));

  /**
   * THE TWO GROUNDS THAT ARE NOT PAPER — named, so a dark page can answer them differently.
   *
   * `ink` and `accent` used to BE `--c-ink` and `--c-accent`, which is right on paper and wrong in
   * the dark: a dark page's ink is nearly white, so the one band meant to be the darkest thing on
   * the page came out as the only white one on it. And a full-strength accent that is a warm
   * ground under black type on paper is a floodlight in a dark room.
   *
   * So both are tokens of their own. A light theme leaves them exactly as they were; a dark one
   * answers "the contrast band is a LIFTED dark" and "the accent band is a DEEPER accent", and
   * every band on the page is dark, which is the whole of what dark mode means.
   */
  /* THE DEEPEST STEP, not the ink. The contrast band and the footer were `--c-ink` — a neutral
     near-black nobody chose — beside an accent band of the business's colour. Same hue now. */
  --c-flip:var(--c-a-950);              /* the contrast band's ground */
  --c-flip-ink:var(--c-paper);          /* and what is written on it */
  --c-band-accent:var(--c-accent);      /* the accent AS A GROUND — a whole band of it */
  --c-band-accent-safe:var(--c-band-accent);   /* …the same, held apart from the paper — see above */
  --c-on-band:var(--c-on);              /* and what is written on that */

  /**
   * THE GRADE EVERY PHOTOGRAPH TAKES — the one answer that repairs a bad picture.
   *
   * Most owners upload a badly-lit photograph of their room, and no arrangement fixes that. A
   * grade does: black and white hides a colour cast, a warm low-key curve makes an ordinary
   * candlelit shot look intentional. It was `saturate(1.05)`, hard-coded, on photo GROUNDS only —
   * so every theme got the same taste and no theme could have its own.
   *
   * `none` is the default and a real answer: a theme that wants the owner's photograph exactly as
   * they took it says nothing. One token, applied to every photograph the page draws — a card, a
   * strip, a hero — because a grade that applies to half of them is worse than no grade at all.
   */
  --c-photo:none;
  /* THE ACCENT DOES NOT TOUCH PHOTOGRAPHS. It tinted every picture toward the owner's colour,
     which is a lovely idea and looks terrible the moment somebody picks green, blue or yellow —
     and it painted a coloured wash over any picture that failed to load, since a broken <img> is
     still an <img>. A grade is the DESIGNER's decision and it is the same for every business:
     black and white, warm, cool, or nothing. It all lives in `--c-photo` above. */
  /* how dark it gets under the type on a photo band, top and bottom */
  --c-scrim-a:.15;
  --c-scrim-b:.55;
  /**
   * THE NOTIONAL GROUND BEHIND A PHOTOGRAPH — what type ON a picture is computed against.
   *
   * Ink is derived from `--g`, "what am I sitting on", and over a photograph the honest answer is
   * "a dark room with a scrim in it" rather than any colour the theme owns: `--c-flip` is LIGHT in
   * a dark theme, so deriving from it puts dark type on a photograph. This was a literal written
   * into the rule below and repeated by every design that puts words on a picture; it is a token
   * now so a theme with a very light grade can lift it rather than every one of them being stuck.
   */
  /* the deepest step, so a photograph's scrim is the same dark as the footer under it */
  --c-over:var(--c-a-950);

  /* ── type ─────────────────────────────────────────────────────────────────────────────── */
  --c-display:system-ui,sans-serif;
  --c-body:system-ui,sans-serif;
  --c-weight:700;                       /* headings */
  --c-case:none;                        /* uppercase for a theme that shouts */
  --c-track:-.01em;
  --c-lead-h:1.02;                      /* leading on a heading */
  --c-body-h:1.5;                       /* …and on a line of text */

  /**
   * THE SAME NUMBER IS NOT THE SAME SIZE IN TWO DIFFERENT FACES.
   *
   * The scale is in pixels and a face's PERCEIVED size is its x-height, not its point size. Inter
   * has a very large x-height; a Didone has a small one. So a dish name set in the display face at
   * `--c-t2` sat beside its description set in the body face at `--c-t1` — one step smaller by the
   * scale — and read as visibly SMALLER than it: the title looked like the caption.
   *
   * This only bites where the two faces meet at body size — a row's name over its line, a card's
   * name over its note, a question over its answer. A heading has no body text beside it to be
   * measured against, so the design's own numbers stand.
   *
   * 1 is no correction, which is right for any theme whose two faces are close.
   */
  --c-display-adj:1;

  /**
   * THE THIRD TYPE ROLE — the small tracked capitals a page labels things with.
   *
   * There were two roles, display and body, and one `--c-case` applied to headings. So a theme was
   * all-uppercase or all-sentence-case, and a design that wants sentence-case serif headings AND
   * tracked capitals on its addresses, its eyebrows and its facts could not say so: it had to pick
   * one and lose the other.
   *
   * An eyebrow, a field's label, a tag and a line of facts are all the same voice. It is named
   * once here, so a theme answers it once.
   */
  --c-label:var(--c-body);
  --c-label-weight:600;
  --c-label-case:uppercase;
  --c-label-track:.18em;
  --c-eyebrow-deco:none;                /* underline, for a theme that rules its eyebrows */

  /**
   * HOW FAR THE NAVIGATION'S LINKS STAND BACK — and nothing else in the bar.
   *
   * A bar holds three different things: the business's MARK, a row of LINKS, and the one ACTION.
   * Only the links stand back; the mark is the business and the action is the point of the page.
   * This is a number rather than a rule so a theme states how much and never how — a theme that
   * wrote the rule itself wrote it against the tag (`nav a`) and dimmed all three, which put a
   * business's own black logo and its only button on the page at 72% on every page of the site.
   *
   * `1` is no dim at all, which is the right default: a theme opts into the effect.
   */
  --c-nav-dim:1;

  /* the button's own voice, because it is not always the heading's */
  --c-act-font:var(--c-display);
  --c-act-weight:var(--c-weight);
  --c-act-case:var(--c-case);
  --c-act-bg:var(--c-ink);              /* on paper */
  --c-act-ink:var(--c-paper);
  /**
   * …AND THE ONE THE PAGE ACTUALLY PAINTS WITH, which is not always the one the theme asked for.
   *
   * A theme states the accent as a button's ground because that is the theme's taste. Whether the
   * owner's colour can be TOLD APART from the paper it is standing on is not a matter of taste,
   * and it is not something a theme can answer: the theme is written before anybody picks a
   * colour. Measured on chunky, whose button ground IS the accent — an owner picking black got a
   * black button on black paper at a contrast of 1.00, and one picking white got 1.06 in light
   * mode. The buttons were still there; there was simply nothing to see.
   *
   * So the theme keeps stating its taste and the CONTRACT holds the floor: `-safe` is the same
   * colour, at a lightness this paper can be told from, and the rules below paint with it. A
   * theme that never picks an extreme never notices, and a theme written tomorrow is safe without
   * knowing this exists. The guard itself is a few lines further down, beside the other things
   * derived from a ground.
   *
   * Pass-through here so a browser without relative colour syntax gets exactly what it got before.
   */
  --c-act-bg-safe:var(--c-act-bg);
  /**
   * A BUTTON ON AN INVERTED GROUND IS NOT "THE OTHER WAY ROUND" — it is whatever contrasts with
   * the ground it is standing on, and those are different things.
   *
   * This pair used to be `--c-paper` on `--c-ink`, which reads correctly and is wrong half the
   * time: an inverted ground is `--c-flip`, and `--c-flip` is DARK on a dark page as well as on a
   * light one. So in dark mode the band was near-black and the button took `--c-paper`, which is
   * also near-black — measured on the reviews band, a button at lightness 0.08 on a ground at
   * 0.14. A dark button on a dark band, with the contrast rules watching.
   *
   * So the default is derived per ground, beside the other ground-aware neutrals — see
   * `--c-on-g`.
   *
   * `--c-act-on` and `--c-act-on-ink` are what a THEME says when it wants its own, and they are
   * DELIBERATELY NOT DECLARED here. `var(--c-act-on, …)` reaches its fallback only when the
   * property is guaranteed-invalid, which means never set — declaring it empty (`--c-act-on:;`)
   * sets it to an EMPTY value, which is perfectly valid, substitutes nothing, and makes the
   * `background` that reads it invalid instead. It reads as "the default is unset" and behaves as
   * "the button has no colour": measured, that took every button on an inverted band to pure
   * black on a dark ground, which is the same bug with an extra step. Unstated means UNSTATED.
   */
  /* THE SAME FOR A BUTTON'S EDGE, and the same default: a theme whose buttons sit on a hard offset
     shadow had to write its own `.c-act` rule to get one. `none` changes nothing. */
  --c-act-shadow:none;

  /**
   * ONE SCALE, AND IT IS COMPUTED — a base and a ratio, not seven numbers.
   *
   * Seven independent sizes can contradict each other, and they did: a theme set a dish's name one
   * step above its description on the scale and it came out visibly SMALLER, because the name is in
   * the display face and the description is in the body face, and a face's perceived size is its
   * x-height rather than its point size.
   *
   * Two things fix that for good. The steps are DERIVED from one ratio, so they are ordered by
   * construction and a theme cannot make step 4 smaller than step 3 by editing a number. And any
   * role set in the display face reads `--c-d…` instead of `--c-t…` — the same step, corrected for
   * that face's x-height — so "one step bigger" is one step bigger on the page and not just in the
   * stylesheet.
   *
   * A theme states TWO values, `--c-base` and `--c-ratio`, and gets a scale. It may still overrule
   * a single step where a design genuinely wants one; it just no longer has to write seven.
   */
  --c-base:16px;                        /* body — the one size everything else is measured from */
  --c-ratio:1.28;                       /* 1.2 is a quiet design, 1.4 shouts */
  /**
   * THE SMALL END HAS ITS OWN RATIO, and this is why every theme's captions were unreadable.
   *
   * One ratio drove the scale in BOTH directions: a design that wants a headline five steps up
   * needs a big ratio, and the same number then divided the small end twice. Bold shouts at 1.42,
   * so its eyebrows, tags and compact buttons came out at 16 / 1.42 / 1.42 = 7.9px — smaller than
   * anything a person reads on a phone, on every band of every site it draws.
   *
   * Going up and coming down are not the same decision. `--c-ratio` stays the shout; this is the
   * step between body, a note and a caption, and it is gentle because those three are all read.
   * A theme that genuinely wants a tighter or wider small end says so in one number.
   */
  --c-ratio-sm:1.18;
  --c-t0:calc(var(--c-t2) / var(--c-ratio-sm) / var(--c-ratio-sm)); /* eyebrow, tag, caption */
  --c-t1:calc(var(--c-t2) / var(--c-ratio-sm));                     /* note, secondary */
  --c-t2:var(--c-base);                 /* body */
  /**
   * FLUID AS WELL AS ORDERED — and `min()` was the wrong tool.
   *
   * Taking the SMALLER of the step and a width made the scale stop growing: a hero capped at the
   * ratio's own answer, so on a 2000px band the name of the business was 87px in a room built for
   * three times that, and the design read as timid rather than large.
   *
   * `clamp()` instead, with the step as the FLOOR. Each size is at least one ratio above the one
   * under it — which is what keeps the order guaranteed, at any width, in any face — and is free
   * to grow with the band up to a ceiling three steps higher.
   */
  --c-t3:clamp(calc(var(--c-t2) * var(--c-ratio)), 1.8cqw, calc(var(--c-t2) * var(--c-ratio) * var(--c-ratio)));
  --c-t4:clamp(calc(var(--c-t3) * var(--c-ratio)), 2.8cqw, calc(var(--c-t3) * var(--c-ratio) * var(--c-ratio)));
/* THE TOP OF THE SCALE IS DRIVEN BY WIDTH AND THE BOTTOM IS NOT, so on a wide screen a heading
   ran away from its own paragraph — 78px over 16px, which is not emphasis, it is two unrelated
   designs sharing a band. The width terms are pulled back so a heading stays under four times its
   body at 1400px, which is where `sizes.test.js` measures it. */
  --c-t5:clamp(calc(var(--c-t4) * var(--c-ratio)), 4.2cqw, calc(var(--c-t4) * var(--c-ratio) * var(--c-ratio) * var(--c-ratio)));
  --c-t6:clamp(calc(var(--c-t5) * var(--c-ratio)), 7.8cqw, calc(var(--c-t5) * var(--c-ratio) * var(--c-ratio) * var(--c-ratio)));

  /* THE SAME STEPS IN THE DISPLAY FACE. One correction, applied once, so every display role is
     optically the size its step says it is. `--c-display-adj` is 1 when the two faces match. */
  --c-d1:calc(var(--c-t1) * var(--c-display-adj));
  --c-d2:calc(var(--c-t2) * var(--c-display-adj));
  --c-d4:calc(var(--c-t4) * var(--c-display-adj));

  /* ── space, shape, measure ────────────────────────────────────────────────────────────── */
  --c-u:8px;                            /* the unit. Nothing is spaced by anything else. */
  --c-density:1;                        /* a theme that breathes: 1.25. A dense one: .85 */
  --c-r:0px;                            /* radius — ONE value, used by every part */
  --c-bw:1px;                           /* border width */
  --c-gap:calc(var(--c-u) * 3 * var(--c-density));   /* between cells. 0 = they share edges. */
  /**
   * THE MOST COLUMNS THIS THEME WILL EVER ALLOW.
   *
   * A block says how many columns its content wants; nothing said how many the DESIGN wants, so
   * the answer came from `auto-fit` — "as many as fit" — and on a wide screen six questions became
   * four columns one line tall. Nobody chose four. Nobody could have.
   *
   * A ceiling is a theme decision: a design of big deliberate tiles caps at 3 and one of small
   * cards caps at 4. It is a maximum, never a count — three products in a cap of four are three.
   */
  --c-cap-max:4;
  --c-band-rule:var(--c-bw);            /* the line between bands. 0 = grounds do the separating. */
  --c-band-min:0px;                     /* a picture band may be the whole screen: 100svh */
  --c-measure:1180px;                   /* nothing text-bearing is ever wider than this */
  /**
   * THE PAGE'S OWN COLUMN — the widest anything on it ever is, and where its edges are.
   *
   * The bands sat in it, the navigation used the full gutter as PADDING (so twice the inset the
   * bands had), and the footer used the text measure (so a third edge again). Three insets down
   * one page: at 1920 the mark was at 64, the hero at 220 and the footer at 260, and every one of
   * them was somebody's idea of "the edge". Reported as "top bar menu is not aligned with the
   * page", which is exactly what it was.
   *
   * Declared once here so the furniture and the bands cannot disagree about it.
   */
  --c-page:min(1480px, 100% - var(--c-gut));

  /**
   * …AND NOTHING IS EVER WIDER THAN ITS OWN READING LENGTH, which is a count of CHARACTERS and
   * not a number of pixels. `--c-measure` is the band's ceiling; these are each ROLE's.
   *
   * Measured, the pages were already inside the band — 64 characters of body, 19 of headline — but
   * by accident: only `.c-line` and `.c-prose` said so, and everything else was short because its
   * container happened to be narrow. A wider band, a denser theme or a longer sentence puts any of
   * them out and nothing says a word. `ch` is the unit that cannot drift: it is the width of a
   * digit in the element's OWN face and size, so a cap written here holds at every step of the
   * scale and in every theme.
   *
   * The numbers are the ordinary ones: prose is comfortable to about 65, a headline wants 20–40
   * (it is read in one glance, not scanned), and a note beside something else wants less again.
   */
  --c-cap-body:64ch;                    /* running prose */
  --c-cap-title:40ch;                   /* a headline is read in a glance */
  --c-cap-note:55ch;                    /* a line under a row, a card, or a button */

  /**
   * WHAT A CARD IS — a box, an outline, or nothing at all.
   *
   * `.c-card` was one treatment for every theme that will ever exist: no ground, no border, no
   * padding, a photograph on top of a name. That is a fine card and it is not the only one. A
   * filled block with the type inside it and the picture bleeding to its edges is a different
   * design, and no amount of colour makes the first one into the second.
   *
   * Nothing changes by default: transparent, no border, no padding, exactly as it was.
   */
  --c-card-bw:0px;
  --c-card-pad:0px;
  /**
   * AND WHETHER ITS EDGE CASTS. A shadow is paint — it says nothing about where a card is — but
   * there was no token for one, so a theme built on a hard offset edge had nowhere to put it and
   * the only way to get it was a component rule of its own, which is the thing this file exists to
   * stop. `none` is the default, so nothing that was drawn yesterday moves.
   */
  --c-card-shadow:none;
  /* …AND ITS SECONDARY TEXT. `--c-soft` is mixed for the PAGE's paper, so the moment a card has a
     ground of its own the line under its name is a grey chosen for a surface it is no longer on —
     which on a dark card is unreadable, on a light band, with nothing about the band wrong. */
  /* a card with no ground of its own is simply the band's, so its ink needs no answer */
  /**
   * AND `transparent` IS NOT HOW YOU SAY THAT — it is how you say "white type on cream paper".
   *
   * `--g` is what the ink is derived from, and `transparent` has a lightness of 0, so a theme
   * writing `--c-card-bg:transparent` to mean "no fill, please" was telling the derivation it was
   * on black: every name and price inside every card came out white, on paper. Nothing looked
   * broken — the words were simply not there, and the card read as a photograph with a gap under
   * it. A theme that wants no fill writes `--c-card-bg:var(--c-card-g)`, "whatever the band is",
   * or writes nothing at all and gets the same. There is a test that no theme writes the other. */

  /**
   * A QUOTATION IS ALWAYS A CARD WITH A GROUND — the rule, not a taste.
   *
   * It used to be bare words on the band, which is typographically the honest drawing of a
   * quotation and is wrong here for one reason: a review is PROOF, and proof that looks like the
   * paragraph above it reads as the business talking about itself. Three of them in a row with
   * nothing around them is a column of text nobody stops at.
   *
   * So a quotation has a ground, an edge and room, on every theme — and unlike a card, whose
   * ground defaults to the band's, this one is always a real colour. That is why its ink can be
   * DERIVED (below) rather than inherited: a light quote card on a black proof band gets black
   * type without any theme having to remember.
   */
  --c-quote-bg:var(--c-fill);
  --c-quote-ink:var(--c-ink);
  --c-quote-bw:var(--c-card-bw);
  --c-quote-pad:calc(var(--c-u) * 3 * var(--c-density));

  /* a field: a box, or a rule under it and nothing else */
  --c-field-bg:var(--c-paper);
  --c-field-bw:var(--c-bw);             /* all four sides… */
  --c-field-bw-b:var(--c-bw);           /* …and the bottom, which may be the only one */
  /* SPLIT, because the button standing beside a field has to be as tall as one and the only way
     to be sure of that is to be padded by the same value — a shorthand pair cannot be half-read. */
  --c-field-pad-y:calc(var(--c-u) * 2);
  --c-field-pad-x:calc(var(--c-u) * 2);
  --c-field-pad:var(--c-field-pad-y) var(--c-field-pad-x);
  --c-rhythm:clamp(40px,6cqw,96px);     /* the air above and below a band */
  --c-gut:clamp(20px,5cqw,64px);        /* the page gutter */
  --c-bar:64px;                         /* how tall the sticky bar is — chips clear it */
}

/**
 * EVERY INK IS DERIVED FROM THE GROUND IT IS ON. Nothing on this page names a colour.
 *
 * THE BUG THIS ENDS. A theme used to set a ground here and an ink there, independently, and
 * nothing connected the two — so a panel could paint itself cream inside a dark band and keep the
 * band's cream text, a fact's number could be pinned to the page's ink and vanish on a dark band,
 * a card could take a grey mixed for paper it was no longer on, and a pale accent could keep the
 * white ink computed for a dark one. Four separate reports, one cause: an element naming a colour
 * instead of asking what it is sitting on.
 *
 * `--g` IS THE ANSWER TO "WHAT AM I ON". Every surface sets it — a band, a card, a panel — and
 * every ink below is mixed from it. Change the ground and the type follows, automatically, at any
 * depth, because a card inside a dark band inside a light page is just another `--g`.
 *
 *   --c-on-g   pure black or pure white, whichever the ground can carry
 *   --c-ink    text. 92% of that toward the ground, so it is warm rather than absolute
 *   --c-soft   the secondary line. Measured: 66% holds above 4.5:1 on any ground.
 *   --c-faint  a caption, a timestamp
 *   --c-line   a rule
 *
 * These keep their old names ON PURPOSE. Every rule in this file already asks for `--c-soft` and
 * `--c-line`, so redefining what they MEAN makes the whole stylesheet ground-aware without a
 * single rule changing — and it deletes the override list that used to re-colour eight classes by
 * hand on every inverted band.
 *
 * A theme states GROUNDS. It does not state inks, and there is no longer anywhere to put one.
 */
/* DECLARED WHEREVER `--g` CAN CHANGE, because a custom property resolves once on the element that
   declares it and its children inherit the ANSWER, not the sum. Stated only on the page, every
   band inherited the ink computed for paper — which is dark text on the dark bands. Each surface
   that sets a ground therefore restates the derivation, and only those. */
@supports (color: oklch(from red l c h)){
  :is(#clay-page,#design-sheets), :is(#clay-page,#design-sheets) .c-band, :is(#clay-page,#design-sheets) .c-card, :is(#clay-page,#design-sheets) .c-tone-tint .c-in,
  :is(#clay-page,#design-sheets) .c-bleed-t, :is(#clay-page,#design-sheets) [data-g],
  /* THE FURNITURE SETS A GROUND TOO — the bar and the foot. The foot paints the CONTRAST ground,
     which on a light page is nearly black, and without this every neutral in it stayed the one
     mixed for the page: dark text on a dark footer, on every page of every light site. */
  /* …AND A QUOTATION, which states its own ground the same way a card does. */
  :is(#clay-page,#design-sheets) .c-quote,
  :is(#clay-page,#design-sheets) .l-nav, :is(#clay-page,#design-sheets) .l-foot{
    --c-on-g:oklch(from var(--g) clamp(0, (.62 - l) * 1000, 1) 0 h);
    --c-ink:color-mix(in oklab, var(--c-on-g) 92%, var(--g));
    /* AND THE BRAND IS IN THEM, which is the whole point of `--c-brand` and was lost right here.
       The definitions at the top of this file mix the accent into the neutrals — that is what
       makes a rule on a sage site sage and a rule on a rust site rust. These override them on
       every ground, and they were derived from pure black or pure white alone, so the accent was
       thrown away on the page itself and on every band: measured on a green site, `--c-line` came
       out at a chroma of 0.003, which is grey. A rule and a fill carry the full measure; the
       secondary line carries the same quarter the top of the file measured for it. */
    --c-soft:color-mix(in oklab, var(--c-accent) calc(var(--c-brand) / 4),
                       color-mix(in oklab, var(--c-on-g) 66%, var(--g)));
    --c-faint:color-mix(in oklab, var(--c-accent) calc(var(--c-brand) / 4),
                        color-mix(in oklab, var(--c-on-g) 48%, var(--g)));
    --c-line:color-mix(in oklab, var(--c-accent) var(--c-brand),
                       color-mix(in oklab, var(--c-on-g) 16%, var(--g)));
    /* AND THE FILL, which was not restated here at all — so an inverted band's fill was the one
       computed for the page's paper: a pale grey box on a black band. */
    --c-fill:color-mix(in oklab, var(--c-accent) var(--c-brand),
                       color-mix(in oklab, var(--c-on-g) 5%, var(--g)));
    /* AND THE BUTTON ON THIS GROUND. `--c-on-g` is already the pure colour that contrasts with
       whatever this band is wearing, which is exactly what a solid button wants to be; the words
       on it are the ground itself. A theme that has said its own (`--c-act-on`) keeps it — this
       is the answer for a theme that has not, and until now that answer was a fixed `--c-paper`
       which is only the opposite of the ground on a light page. */
    --c-act-bg-on:var(--c-act-on, var(--c-on-g));
    --c-act-ink-on:var(--c-act-on-ink, var(--g));
  }
}

/**
 * CONTRAST IS DERIVED, NOT CHOSEN — and it went missing when the parts contract arrived.
 *
 * The theme's own chrome has computed this for a long time: `--on-accent` reads the accent's
 * LIGHTNESS and hands back black or white, so a lime or a pale yellow is as safe as a navy and
 * nobody has to remember to check. The parts contract did not: `--c-on` and `--c-on-band` were a
 * hex each theme wrote by hand, always white, because every theme was tried with a dark accent.
 * An owner picking a pale yellow got white type on it — in the one place their own colour appears.
 *
 * So it is computed here, for every theme at once, from the only thing that decides it. `.564` is
 * the lightness where black overtakes white; the `clamp` turns the comparison into 0 or 1 and the
 * chroma goes to 0, so the answer is always pure black or pure white and never a tinted grey.
 *
 * THAT NUMBER IS SEARCHED, NOT GUESSED. It was `.68`, which is where a mid grey stops LOOKING
 * dark — not where the contrast crosses over. Between the two an accent got the weaker of the two
 * poles and nobody read it as a bug because the type stayed legible-ish: measured then, an accent
 * at l .65 was given white at 3.23:1 with black available on the same button at 6.49:1.
 *
 * For a GREY the crossover is exactly where `(Y + .05)² = 1.05 × .05`, at l .5637. Colour is not
 * that tidy — lightness is not luminance, and a vivid violet at l .58 carries less light than a
 * grey at .50 — so no single lightness gets the stronger pole onto every colour. `.58` is the one
 * that leaves the WORST colour best off, at 4.16:1; picking by luminance instead, which no
 * stylesheet can be asked to do, would top out at 4.58:1. The contract test re-runs that search
 * and fails if this drifts off it.
 *
 * A theme may still write its own — a design whose accent is only ever its own colour can say so —
 * but it no longer has to, and the default is right rather than lucky. Without `oklch(from …)` the
 * hex above stands, which is what every browser did until now.
 */
@supports (color: oklch(from red l c h)){
  :is(#clay-page,#design-sheets){
    --c-on:oklch(from var(--c-accent) clamp(0, (.58 - l) * 1000, 1) 0 h);
    --c-on-band:oklch(from var(--c-band-accent-safe) clamp(0, (.58 - l) * 1000, 1) 0 h);
    /* and the same for a button that IS the accent, which is the commonest one of all */
    --c-act-ink:oklch(from var(--c-act-bg-safe) clamp(0, (.58 - l) * 1000, 1) 0 h);
    /* AND THE QUOTATION, which is the case the card cannot have: its ground is always a real
       colour, never `transparent`, so deriving from it is safe — and it is the whole reason a
       light quote card on a dark proof band needs no theme to think about it. */
    --c-quote-ink:oklch(from var(--c-quote-bg) clamp(0, (.58 - l) * 1000, 1) 0 h);
  }
  /* NOT THE CARD. Its ground defaults to `transparent`, whose lightness is 0 — deriving from it
     would hand every theme that has not set one white type on white paper. A card with no ground
     of its own inherits the band's ink, which is already the right answer. */
}

/**
 * A GROUND MADE OF THE OWNER'S COLOUR STAYS TELLABLE FROM THE PAPER.
 *
 * Contrast has two questions in it and the block above only answers one. "What is written ON this
 * colour" is derived and has been for a while. "Can this colour be SEEN against the page" was
 * nobody's — the theme picks the accent as a ground before it knows what the accent is, and the
 * owner picks the accent without being told what it will be standing on. Measured on chunky, over
 * every accent and both modes: black in dark mode gave a button-to-paper contrast of 1.00, white
 * in light mode 1.06, pale yellow 1.20. Three cards on the board are that one number.
 *
 * The fix is a LIGHTNESS FLOOR, not a colour swap: `min()`/`max()` on the l channel with the hue
 * and the chroma untouched, so a navy stays navy and a yellow stays yellow — they only stop being
 * as pale, or as deep, as the paper behind them. For an accent already on the right side of the
 * floor this is arithmetically a no-op, which is why every existing site looks the same.
 * A pure black or a pure white has no hue to keep, and comes out the grey the floor names.
 *
 * `.60` and `.55` are SOLVED, over every colour an owner can pick — swept in the contract test,
 * with the chroma gamut-mapped the way a browser maps it and the dark paper coupled to the accent
 * it is mixed from. They are not the lightnesses a grey would need: a saturated cyan at l .62
 * carries far more luminance than a grey at .62 and clears only 2.93:1, which is why the numbers
 * are lower than the grey maths alone would suggest. At these two the worst colour there is
 * clears 3.17:1 light and 3.62:1 dark.
 *
 * KEYED ON `data-mode`, which is the attribute a theme's own mode control writes (it is named in
 * the control the theme hands the panel, so the two cannot drift). A theme with no mode gets the
 * light rule, which is the right answer for paper. Both hosts, and both the page's own attribute
 * and the root's, because a mode can be set live on either.
 */
@supports (color: oklch(from red l c h)){
  :is(#clay-page,#design-sheets){
    --c-act-bg-safe:oklch(from var(--c-act-bg) min(l, .60) c h);
    --c-band-accent-safe:oklch(from var(--c-band-accent) min(l, .60) c h);
  }
  :is(#clay-page,#design-sheets)[data-mode="dark"],
  :root[data-mode="dark"] :is(#clay-page,#design-sheets){
    --c-act-bg-safe:oklch(from var(--c-act-bg) max(l, .55) c h);
    --c-band-accent-safe:oklch(from var(--c-band-accent) max(l, .55) c h);
  }
}

/* ============================================================================================
   THE OWNER'S GEAR — the same on every theme, because it is not a theme's to design.

   It is the editor's control, not part of the page: an owner moving between designs should not
   have to find a different button each time. It was styled per theme, which is how one theme's
   gear ended up a cream slab with a hard shadow while another's was a plain disc.

   AND IT MUST NOT COST THE BAR ITS STICKINESS. A gear needs a positioned ancestor, so both themes
   that have shipped wrote `position:relative` on the band — and the navigation IS a band, so the
   later rule beat `position:sticky` and the bar stopped sticking the moment an owner looked at it.
   Bold found it and fixed it in Bold. `.c-band` is already `position:relative` (below), so every
   band the parts draw needs nothing; a theme's own furniture must scope its rule away from the bar.
   ========================================================================================== */
:is(#clay-page,#design-sheets) .band-gear{display:none}
/* THE ONE THAT WAS THERE: a solid disc in the page's contrast colour with a soft drop shadow, so
   it reads on a photograph, on paper and on a black band without being part of any of them. It is
   Bold's, unchanged, moved here — an owner has been finding this button for months and a redesign
   of it is a redesign of their muscle memory. */
body[data-owner] :is(#clay-page,#design-sheets) .band-gear{display:grid;position:absolute;top:14px;right:14px;z-index:20;
  width:38px;height:38px;place-items:center;padding:0;cursor:pointer;border:0;
  border-radius:999px;background:var(--c-flip);color:var(--c-flip-ink);
  box-shadow:0 6px 18px rgba(0,0,0,.18);transition:opacity .15s}
/* AN OUTLINE ICON MUST NOT BE FILLED. The shared library serves the cog as a STROKED path with
   `fill="none"`, and forcing `fill:currentColor` on every svg in here turned it into a solid blob
   — a flower, not a gear. Only a theme that inlines its own filled svg gets the fill, and the
   library's slot is merely sized. */
body[data-owner] :is(#clay-page,#design-sheets) .band-gear > svg{width:18px;height:18px;fill:currentColor}
body[data-owner] :is(#clay-page,#design-sheets) .band-gear .ico{width:19px;height:19px;display:grid;place-items:center}
body[data-owner] :is(#clay-page,#design-sheets) .band-gear .ico svg{width:100%;height:100%}
body[data-owner] :is(#clay-page,#design-sheets) nav .band-gear{top:50%;transform:translateY(-50%)}
body.preview :is(#clay-page,#design-sheets) .band-gear{display:none!important}

/* WHO MADE THIS SITE — and not while its owner is working on it.
   The badge belongs to a VISITOR's page. In the editor it is one more thing fixed to the bottom of
   the screen, over the dock, saying something the owner already knows — and it was there because
   whether to draw it was a decision each theme made in its own stylesheet: Chunky hid it, Bold
   never did, so half the sites had a badge in the workspace and the difference was which theme
   they were on. One rule, here, for every theme. Preview is a visitor's view, so it comes back. */
body[data-owner]:not(.preview) :is(#clay-page,#design-sheets) .qck-badge{display:none}

/* ── the shell ─────────────────────────────────────────────────────────────────────────── */
:is(#clay-page,#design-sheets) .c-band{
  --c-card-g:var(--g);
  padding:calc(var(--c-rhythm) * var(--c-density)) 0;
  container-type:inline-size;position:relative;isolation:isolate;
  background:var(--g);color:var(--c-ink);
}
/* A LINE BETWEEN BANDS IS ONE WAY TO SEPARATE THEM, not the only one. A design that alternates
   ground every band is already saying "you have moved", and a hairline on top of that is a seam
   drawn over a seam. `--c-band-rule:0` takes it away. */
:is(#clay-page,#design-sheets) .c-band + .c-band{border-top:var(--c-band-rule) solid var(--c-line)}
/* THE MEASURE. At 2560 the words are still 1180 and centred — a line of text that grows with the
   window is unreadable, and a photograph that grows with it is stretched. */
/**
 * THE PAGE HAS ONE COLUMN, and the bar, the bands and the footer all stand on it.
 *
 * This was `min(--c-measure, 100% - gut)` while `.l-nav-in` and `.l-foot-in` were `--c-page`. Two
 * different edges, and which one you SAW depended on an accident: bold's measure (1400) is wider
 * than its page at ordinary widths, so bold happened to line up and chunky's (1240) did not.
 * Measured at 1440: chunky's bar and footer ran 28..1412 and every band inside them 100..1340 —
 * 72px of daylight on both sides, on all ten pages. Bold has the same bug from 1544px up.
 *
 * `--c-measure` is a LINE-LENGTH ceiling and it goes back to being only that. It caps text by role
 * in `ch` (R4) and it clamps a set of one or two so a pair does not spread — a cap on the reading,
 * not on where the page's edge is. Putting it on the band's container capped the photographs too,
 * and gave the page a second left edge to explain.
 *
 * `.c-in-wide` still exists for a band that means to run wider than the page column.
 */
:is(#clay-page,#design-sheets) .c-in{width:var(--c-page);margin-inline:auto}
:is(#clay-page,#design-sheets) .c-in-mid{max-width:min(720px, 100% - var(--c-gut));text-align:center;margin-inline:auto}
:is(#clay-page,#design-sheets) .c-in-wide{width:var(--c-page)}
:is(#clay-page,#design-sheets) .c-behind{position:absolute;inset:0;z-index:-1;overflow:hidden}
:is(#clay-page,#design-sheets) .c-behind img{width:100%;height:100%;object-fit:cover;display:block}

/* grounds a theme can ask for. The ONLY four. */
:is(#clay-page,#design-sheets) .c-g-fill{--g:var(--c-ground-fill)}
:is(#clay-page,#design-sheets) .c-g-ink{--g:var(--c-flip)}
:is(#clay-page,#design-sheets) .c-g-accent{--g:var(--c-band-accent-safe)}
/* A PICTURE BAND MAY BE THE SCREEN. `--c-band-min:100svh` and it is; the default is 0 and it is
   as tall as what is in it. Content centres itself in whatever height it ends up with. */
:is(#clay-page,#design-sheets) .c-g-photo{--g:var(--c-over);min-height:var(--c-band-min);
  display:grid;align-content:center}
:is(#clay-page,#design-sheets) .c-g-photo .c-behind::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(0,0,0,var(--c-scrim-a)),rgba(0,0,0,var(--c-scrim-b)))}
:is(#clay-page,#design-sheets) .c-g-glass .c-in{background:color-mix(in oklab,var(--c-paper) 62%,transparent);
  -webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);
  padding:calc(var(--c-u) * 4 * var(--c-density));border-radius:var(--c-r)}

/**
 * ON AN INVERTED GROUND THE SECONDARY TEXT INVERTS TOO.
 *
 * `--c-soft` is a mid grey mixed for PAPER. On the black band it was a dark grey on near-black —
 * "from Google" under the reviews measured 2.6:1, which is not readable, and it is the one line on
 * that band whose whole job is saying where the score came from.
 *
 * Every small text class belongs here, not two of them: a card's line, a row's line and a fine
 * print line are the same kind of thing as the ones that were already listed.
 */
/* the list that used to re-colour eight classes by hand on every inverted band is gone:
   they all ask for --c-soft, and --c-soft is now mixed from the ground they are on. */

/**
 * THE CORNER — the header that is not a stack.
 *
 * Every other header arrangement is a column that varies where it sits. This one holds the name
 * in one corner of the screen and the line, the button and the proof in the other, with the
 * photograph as the whole room between them. On a phone there are no corners, so it closes back
 * into a column and keeps the height.
 */
/**
 * BLEED — a panel of words against a picture, edge to edge, no gutter between them.
 *
 * The two halves touch: there is no measure, no gap and no radius between them, which is the one
 * geometry the page could not previously make. The WORDS still sit in a readable column inside
 * their half, because a panel is not an excuse for a 700px line of text.
 */
:is(#clay-page,#design-sheets) .c-bleed{display:grid;grid-template-columns:1fr 1fr;min-height:var(--c-band-min);
  padding:0}
:is(#clay-page,#design-sheets) .c-bleed > .c-bleed-t{display:grid;align-content:center;
  padding:calc(var(--c-rhythm) * var(--c-density)) var(--c-gut)}
:is(#clay-page,#design-sheets) .c-bleed > .c-bleed-t > div{max-width:46ch}
:is(#clay-page,#design-sheets) .c-bleed > .c-bleed-m{position:relative;overflow:hidden;min-height:52svh}
:is(#clay-page,#design-sheets) .c-bleed > .c-bleed-m img{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;filter:var(--c-photo)}

@container (max-width:820px){:is(#clay-page,#design-sheets) .c-bleed{grid-template-columns:1fr}}

/* BESIDE — the heading in a narrow column and the content in a wide one next to it. This is the
   shape a design uses when it wants a page to read as a document rather than a stack of posters. */
/* every recipe carries this, so a stylesheet has one place to reach a composed band */
:is(#clay-page,#design-sheets) .c-plate{min-width:0}
:is(#clay-page,#design-sheets) .c-aside-b{min-width:0}
:is(#clay-page,#design-sheets) .c-aside{display:grid;grid-template-columns:minmax(0,var(--c-aside-w,.28fr)) minmax(0,1fr);
  gap:calc(var(--c-u)*4*var(--c-density)) calc(var(--c-u)*7*var(--c-density));align-items:start}
:is(#clay-page,#design-sheets) .c-aside-h{position:sticky;top:calc(var(--c-bar) + var(--c-u)*3)}
@container (max-width:820px){
  :is(#clay-page,#design-sheets) .c-aside{grid-template-columns:1fr}
  :is(#clay-page,#design-sheets) .c-aside-h{position:static}
}

:is(#clay-page,#design-sheets) .c-corner{display:grid}
:is(#clay-page,#design-sheets) .c-corner > .c-in{display:grid;grid-template-rows:1fr auto;gap:calc(var(--c-u)*4);
  width:min(1480px, 100% - var(--c-gut));padding-block:calc(var(--c-u)*5)}
/* WIDE ENOUGH TO BE A TITLE. At 14ch a 124px face put one word on each of eight lines, which is
   a column of words rather than a name. It takes most of the room and the type shrinks with the
   band, so a long title stays a title instead of becoming a list. */
:is(#clay-page,#design-sheets) .c-corner-a{align-self:start;max-width:min(76%, 22ch)}
:is(#clay-page,#design-sheets) .c-corner-a .c-title{font-size:var(--c-t6);line-height:var(--c-lead-h)}
:is(#clay-page,#design-sheets) .c-corner-b{align-self:end;justify-self:end;text-align:right;max-width:46ch}
:is(#clay-page,#design-sheets) .c-corner-b .c-line{max-width:none;margin-left:auto}
:is(#clay-page,#design-sheets) .c-corner-b .c-acts,:is(#clay-page,#design-sheets) .c-corner-b .c-proof{justify-content:flex-end}
@container (max-width:760px){
  :is(#clay-page,#design-sheets) .c-corner-a{max-width:none}
  :is(#clay-page,#design-sheets) .c-corner-b{justify-self:start;text-align:left}
  :is(#clay-page,#design-sheets) .c-corner-b .c-line{margin-left:0}
  :is(#clay-page,#design-sheets) .c-corner-b .c-acts,:is(#clay-page,#design-sheets) .c-corner-b .c-proof{justify-content:flex-start}
}

/* ── head ──────────────────────────────────────────────────────────────────────────────── */
:is(#clay-page,#design-sheets) .c-head{display:flex;flex-direction:column;gap:calc(var(--c-u) * 1.5)}
:is(#clay-page,#design-sheets) .c-head.c-mid{align-items:center;text-align:center}
:is(#clay-page,#design-sheets) .c-eyebrow{font:var(--c-label-weight) var(--c-t0)/1 var(--c-label);
  letter-spacing:var(--c-label-track);text-transform:var(--c-label-case);color:var(--c-soft);
  margin:0;text-decoration:var(--c-eyebrow-deco);text-underline-offset:.4em}
:is(#clay-page,#design-sheets) .c-title{font-family:var(--c-display);font-weight:var(--c-weight);
  letter-spacing:var(--c-track);line-height:var(--c-lead-h);font-size:var(--c-t5);margin:0;
  text-transform:var(--c-case);text-wrap:balance;max-width:var(--c-cap-title)}
:is(#clay-page,#design-sheets) .c-title.c-big{font-size:var(--c-t6)}
:is(#clay-page,#design-sheets) h1.c-title{font-size:var(--c-t6)}
/**
 * BODY TEXT IS SET AT THE BODY STEP. It was `--c-t3` — the step ABOVE body, which is where a lead
 * paragraph under a headline lives — and `.c-line` is not only the lead: it is every line of prose
 * on the site, under every heading, in every card and on every page. So body copy came out at 23px
 * against a 14px button and a 12px overline, and the whole page read as though the type had been
 * set by three different people. Every theme has had this.
 */
:is(#clay-page,#design-sheets) .c-line{font:var(--c-t2)/var(--c-body-h) var(--c-body);color:var(--c-soft);margin:0;
  max-width:var(--c-cap-body)}
/* …and a LEAD is still a lead: the one directly under a page's own heading keeps the step up. */
:is(#clay-page,#design-sheets) .c-head > .c-line:first-of-type{font-size:var(--c-t3)}
/* A CAPPED BLOCK THAT IS CENTRED STILL CENTRES. Without this a 40ch heading in a centred band
   sits hard against the left edge of the band and the text inside it is centred within that —
   which reads as a mistake, because it is one. */
:is(#clay-page,#design-sheets) .c-mid .c-line,
:is(#clay-page,#design-sheets) .c-mid .c-title,
:is(#clay-page,#design-sheets) .c-head.c-mid .c-line,
:is(#clay-page,#design-sheets) .c-head.c-mid .c-title{margin-inline:auto}
/* the gap between a head and whatever it introduces — ONE value, everywhere */
:is(#clay-page,#design-sheets) .c-head + *{margin-top:calc(var(--c-u) * 4 * var(--c-density))}

/* ── action ────────────────────────────────────────────────────────────────────────────── */
/* A BUTTON IS NOT ALWAYS THE HEADING'S VOICE. It was locked to the display family and to
   `--c-case`, so a design with sentence-case serif headings could not have small sans buttons
   without giving up one or the other. Three tokens, all defaulting to what they were. */
/* A BUTTON IS SET AT READING SIZE. It was one step BELOW body, so the single thing a page asks
   anybody to do was the smallest text on it — 14px under a 16px paragraph, on every theme. */
:is(#clay-page,#design-sheets) .c-act{display:inline-flex;align-items:center;justify-content:center;
  font:var(--c-act-weight) var(--c-t2)/1 var(--c-act-font);letter-spacing:.02em;
  text-transform:var(--c-act-case);text-decoration:none;border-radius:var(--c-r);
  white-space:nowrap;cursor:pointer;transition:opacity .14s ease,transform .14s ease}
:is(#clay-page,#design-sheets) .c-act:active{transform:translateY(1px)}
:is(#clay-page,#design-sheets) .c-act-inline{padding:calc(var(--c-u)*2) calc(var(--c-u)*3);
  background:var(--c-act-bg-safe);color:var(--c-act-ink);box-shadow:var(--c-act-shadow)}
:is(#clay-page,#design-sheets) .c-act-block{padding:calc(var(--c-u)*2) calc(var(--c-u)*4);font-size:var(--c-t2);
  background:var(--c-act-bg-safe);color:var(--c-act-ink);box-shadow:var(--c-act-shadow)}
:is(#clay-page,#design-sheets) .c-act-compact{padding:calc(var(--c-u)*1.5) calc(var(--c-u)*2);font-size:var(--c-t0);
  background:var(--c-act-bg-safe);color:var(--c-act-ink);box-shadow:var(--c-act-shadow)}
:is(#clay-page,#design-sheets) .c-act.c-quiet{background:none;color:inherit;
  box-shadow:inset 0 0 0 calc(var(--c-bw)*2) currentColor}
:is(#clay-page,#design-sheets) .c-g-ink .c-act-inline,:is(#clay-page,#design-sheets) .c-g-ink .c-act-block,
:is(#clay-page,#design-sheets) .c-g-ink .c-act-compact,:is(#clay-page,#design-sheets) .c-g-accent .c-act-compact,
:is(#clay-page,#design-sheets) .c-g-photo .c-act-compact,
:is(#clay-page,#design-sheets) .c-g-accent .c-act-inline,:is(#clay-page,#design-sheets) .c-g-accent .c-act-block,
:is(#clay-page,#design-sheets) .c-g-photo .c-act-inline,:is(#clay-page,#design-sheets) .c-g-photo .c-act-block{
  background:var(--c-act-bg-on);color:var(--c-act-ink-on)}
:is(#clay-page,#design-sheets) .c-acts{display:flex;gap:calc(var(--c-u)*1.5);flex-wrap:wrap;
  margin-top:calc(var(--c-u)*4*var(--c-density))}
:is(#clay-page,#design-sheets) .c-mid .c-acts,:is(#clay-page,#design-sheets) .c-acts.c-mid{justify-content:center}

/* ── row ───────────────────────────────────────────────────────────────────────────────── */
:is(#clay-page,#design-sheets) .c-rows{list-style:none;margin:0;padding:0}
:is(#clay-page,#design-sheets) .c-row{display:flex;gap:calc(var(--c-u)*2);align-items:flex-start;
  padding:calc(var(--c-u)*2*var(--c-density)) 0;border-bottom:var(--c-bw) solid var(--c-line)}
:is(#clay-page,#design-sheets) .c-row:last-child{border-bottom:0}
/* A ROW THAT IS A CHOICE says which one is chosen — the booking's services are rows rather than
   chips, because a service has a line and a chip has no room for one. */
:is(#clay-page,#design-sheets) .c-row.on{box-shadow:inset 3px 0 0 var(--c-accent);padding-left:calc(var(--c-u)*1.5)}
:is(#clay-page,#design-sheets) .c-row-t{display:flex;flex-direction:column;gap:calc(var(--c-u)*.5);min-width:0;flex:1}
:is(#clay-page,#design-sheets) .c-row-n{font:var(--c-weight) var(--c-d2)/1.2 var(--c-display);
  text-transform:var(--c-case);letter-spacing:var(--c-track)}
/* A ROW THAT LEADS SOMEWHERE IS A HEADING, not a line item. A menu category is a destination —
   "Kitchen", "Coffee", "Breakfast" — and it was set at body size under a band heading four times
   its height, which read as a list of labels somebody forgot to style. A dish stays a dish. */
:is(#clay-page,#design-sheets) .c-row-l{text-decoration:none;color:inherit;font-size:var(--c-d4)}
:is(#clay-page,#design-sheets) .c-row-l:hover{text-decoration:underline;text-underline-offset:.22em}
:is(#clay-page,#design-sheets) .c-row-s{font:var(--c-t1)/1.45 var(--c-body);color:var(--c-soft);
  max-width:var(--c-cap-note)}
:is(#clay-page,#design-sheets) .c-row-m{font:var(--c-weight) var(--c-d2)/1.2 var(--c-display);font-style:normal;
  font-variant-numeric:tabular-nums;white-space:nowrap}
:is(#clay-page,#design-sheets) .c-row-a{flex:0 0 auto}
:is(#clay-page,#design-sheets) .c-row.c-dim{opacity:.5}
/**
 * `hidden` MEANS HIDDEN — and a layout class was quietly beating it.
 *
 * The browser hides `[hidden]` with a `display:none` in its own stylesheet, which ANY rule of ours
 * that sets `display` overrides. `.l-basket` is `display:grid`, so the full basket stayed on screen
 * next to "Nothing in the cart yet": both states of the same panel at once, and the client that
 * set `.hidden = true` looked like the thing that was broken.
 *
 * It is `!important` because that is the only weight that survives a rule written later by
 * somebody who does not know this one exists — which is exactly how it happened the first time.
 */
:is(#clay-page,#design-sheets) [hidden]{display:none !important}

:is(#clay-page,#design-sheets) .c-thumb{flex:0 0 calc(var(--c-u)*7);width:calc(var(--c-u)*7)}
/* a thumbnail that opens the picture says so before it is pressed */
:is(#clay-page,#design-sheets) .c-thumb-go{cursor:zoom-in}

/* ── card ──────────────────────────────────────────────────────────────────────────────── */
/* A CARD IS A BOX, AN OUTLINE OR NOTHING — the theme says which, and nothing is the default.
   When it IS a filled box, the photograph belongs to the box: it bleeds to the box's own edges
   rather than sitting inside the padding with a frame of ground around it. */
:is(#clay-page,#design-sheets) .c-card{display:flex;flex-direction:column;gap:calc(var(--c-u)*1);
  align-items:flex-start;min-width:0;--g:var(--c-card-bg, var(--c-card-g));
  background:var(--g);color:var(--c-ink);box-shadow:var(--c-card-shadow);
  border:var(--c-card-bw) solid var(--c-line);border-radius:var(--c-r);padding:var(--c-card-pad)}
:is(#clay-page,#design-sheets) .c-card .c-media{width:100%;margin-bottom:calc(var(--c-u)*1.5)}
/**
 * …AND IT TAKES THE CARD'S INNER CURVE WHERE IT TOUCHES IT.
 *
 * The photograph is pulled out to the card's own edges by those negative margins, and it was then
 * squared off — which is right on a square theme and wrong on every rounded one: a hard corner
 * sitting inside a 20px curve pokes through it, so the card looks like a photograph with a frame
 * drawn slightly wrong around it. Measured on chunky: a card at radius 20 with a 5px border,
 * holding a picture at radius 0.
 *
 * The value is the card's INNER radius — the outer curve less the border it sits inside, which is
 * what makes two curves nest instead of crossing. `max(0px, …)` because a theme may have a border
 * thicker than its radius, and a negative radius is not a thing.
 *
 * Only the TOP two corners: the picture bleeds up, left and right and stops before the bottom of
 * the card, so those are the only corners it shares with the frame.
 */
:is(#clay-page,#design-sheets) .c-card .c-media:first-child{margin:calc(var(--c-card-pad) * -1)
  calc(var(--c-card-pad) * -1) calc(var(--c-u)*1.5);width:auto;align-self:stretch;
  border-radius:max(0px, calc(var(--c-r) - var(--c-card-bw)))
                max(0px, calc(var(--c-r) - var(--c-card-bw))) 0 0}
/* A CARD WITH NO PHOTOGRAPH IS NOT A CARD WITH A HOLE IN IT — `card()` has said so since it was
   written and marked the case, and no rule has ever answered the mark. It closes up, and it takes
   the room the picture would have had as air above the name, so a row of cards where one has no
   photograph does not read as one that failed to load. */
:is(#clay-page,#design-sheets) .c-card.c-nopic{padding-top:calc(var(--c-u)*1.5)}
/**
 * A CARD WITH NO PICTURE IS BIG ONLY WHEN NONE OF THEM HAVE ONE.
 *
 * The name was promoted to hero size on every picture-less card, which is right for a set that has
 * no photographs at all — a list of categories, a menu — and badly wrong for the ordinary case: a
 * shop of eight products where the tote bag was never shot. That one tile came out with its name
 * four times the size of the two beside it, in the same row, which reads as a mistake because it
 * is one. It was also the "some cards have different heights" report: one giant name in a row of
 * small ones is what made the row uneven.
 *
 * `grid()` marks the set when EVERY cell in it lacks a picture, so the promotion happens for the
 * set and never for the odd one out. A lone picture-less card keeps its siblings' type and simply
 * closes up, which is what the rule above always said it did.
 */
:is(#clay-page,#design-sheets) .c-grid-bare .c-card.c-nopic .c-card-n{font-size:var(--c-t5)}
/* AND THE BUTTONS LINE UP ACROSS THE ROW. A card is a column; its action is pushed to the bottom
   of whatever height the row settled on, so four products with descriptions of different lengths
   do not put four Add buttons at four heights. This is the whole of "cards have equal heights" —
   the boxes were always equal, it was the contents that floated. */
:is(#clay-page,#design-sheets) .c-grid > .c-card{height:100%}
:is(#clay-page,#design-sheets) .c-card > .c-act{margin-top:auto}
:is(#clay-page,#design-sheets) .c-card-n{font:var(--c-weight) var(--c-d4)/1.05 var(--c-display);
  text-transform:var(--c-case);letter-spacing:var(--c-track)}
/**
 * A CARD'S NOTE IS BODY COPY, AND IT IS SET AT THE BODY SIZE (R9).
 *
 * It was one step down, which put two sizes of prose in the same band: the band's own line at step
 * 2 and every card's note at step 1, describing the same things at two scales for no reason
 * anybody could name. Five type sizes in one band is what R9 exists to stop, and this was the
 * fifth in the two bands that broke it. It is still SOFT, which is what tells a note from a line.
 */
:is(#clay-page,#design-sheets) .c-card-s{font:var(--c-t2)/1.45 var(--c-body);color:var(--c-soft);
  max-width:var(--c-cap-note)}
:is(#clay-page,#design-sheets) .c-card-m{font:var(--c-weight) var(--c-d4)/1 var(--c-display);
  font-variant-numeric:tabular-nums}
:is(#clay-page,#design-sheets) .c-card .c-act{margin-top:calc(var(--c-u)*1.5)}
:is(#clay-page,#design-sheets) .c-grid > .c-card > .c-act{margin-top:auto;margin-block-start:auto}
:is(#clay-page,#design-sheets) .c-card.c-dim{opacity:.55}
/**
 * A CARD THAT GOES SOMEWHERE — the whole card is the target, and the markup stays one link.
 *
 * `card()` makes the NAME the anchor when it has a destination, and this stretches that anchor
 * over the card. That is why the card is not an `<a>` with an Add button inside it: a button
 * inside a link is invalid and taps unpredictably on a phone, which is the one place it matters.
 * Anything else in the card that is itself pressable is raised above the sheet.
 */
:is(#clay-page,#design-sheets) .c-card:has(.c-card-l){position:relative}
:is(#clay-page,#design-sheets) .c-card-l{color:inherit;text-decoration:none}
:is(#clay-page,#design-sheets) .c-card-l::after{content:"";position:absolute;inset:0;border-radius:var(--c-r)}
:is(#clay-page,#design-sheets) .c-card-l:focus-visible::after{outline:2px solid var(--c-accent);outline-offset:2px}
:is(#clay-page,#design-sheets) .c-card > .c-act,
:is(#clay-page,#design-sheets) .c-card > .c-tag{position:relative;z-index:1}

/* ── media ─────────────────────────────────────────────────────────────────────────────── */
/**
 * NO PHOTOGRAPH DECIDES HOW TALL A BAND IS — R3 and R5, in one line.
 *
 * The ratio was already the drawing's rather than the file's, which is half the rule: a `4/5` hero
 * beside a narrow column of words is a portrait box as wide as half a desktop, so on a 2000px
 * screen it came out 1250px tall and the business's own NAME was below the fold. Nothing was
 * "wrong": the ratio was honoured exactly, and a ratio with no ceiling is a height the window
 * decides.
 *
 * So a box may not be taller than most of the screen. It keeps its width, the ratio gives way, and
 * `object-fit: cover` means the photograph fills whatever is left — which is why this cannot crop
 * badly enough to matter and why it is safe to apply to every picture on the site. A card 300px
 * wide is nowhere near the cap, so this is a no-op everywhere except the places that were broken.
 *
 * `svh`, not `vh`: on a phone `vh` is the window with the browser's chrome pretending not to be
 * there, which is the one measurement that is wrong on the device this is for.
 */
:is(#clay-page,#design-sheets) .c-media{aspect-ratio:var(--c-ar,4/3);overflow:hidden;background:var(--c-fill);
  border-radius:var(--c-r);position:relative;max-height:var(--c-shot-max,78svh)}
:is(#clay-page,#design-sheets) .c-media img{width:100%;height:100%;object-fit:cover;display:block}

/**
 * THE GRADE — every photograph on the page, in two layers.
 *
 * The CURVE is a filter and belongs to the theme. The TINT is a colour in `color` blend mode and
 * belongs to the owner: `mix-blend-mode:color` keeps the picture's own light and dark and replaces
 * only its hue, which is what a duotone is and what `sepia()` cannot be talked into doing.
 *
 * Both default to nothing, so a theme that says neither draws the owner's photograph exactly as
 * they took it. A band's background picture takes the same two, in the same order, or a hero would
 * be graded differently from the card three bands below it.
 */
:is(#clay-page,#design-sheets) .c-media img,:is(#clay-page,#design-sheets) .c-behind img{filter:var(--c-photo)}


/* ── quote ─────────────────────────────────────────────────────────────────────────────── */
:is(#clay-page,#design-sheets) .c-quote{margin:0;display:flex;flex-direction:column;gap:calc(var(--c-u)*1.5);
  --g:var(--c-quote-bg);background:var(--g);color:var(--c-quote-ink);
  border:var(--c-quote-bw) solid var(--c-line);border-radius:var(--c-r);
  padding:var(--c-quote-pad);box-shadow:var(--c-card-shadow)}
/**
 * A REVIEW IS READ, SO IT IS SET AT READING SIZE.
 *
 * It was `--c-t3` — a HEADING step — from back when a quotation was bare words on a band and the
 * only thing making it carry was its size. Now that it is a card with a ground, the card does that
 * work, and a heading step inside a narrow column is a billboard: four of them side by side came
 * out as four walls of shouting text, eight words to a line, with the shortest review a third
 * empty. Body size, and the ground carries it.
 */
:is(#clay-page,#design-sheets) .c-quote blockquote{margin:0;font:var(--c-t2)/1.5 var(--c-body)}
/* THE NAME UNDER IT IS THE CARD'S OWN INK, QUIETENED — never `--c-soft`, which is mixed for the
   PAGE's paper and is therefore a grey chosen for a surface the quotation is no longer on. On a
   light card over a dark band that grey came out very nearly the colour of the card. */
/* THE ATTRIBUTION IS A BLOCK AT THE FOOT, and `margin-top:auto` is what puts it there: the cards
   in a row are one height, so every name lines up across the set however long the quotations are.
   Beside the words it read as part of them; under them, it is the signature. */
:is(#clay-page,#design-sheets) .c-quote figcaption{display:flex;flex-direction:column;gap:calc(var(--c-u)*.5);
  margin-top:auto;padding-top:calc(var(--c-u)*2)}
/* THE CARD'S OWN INK, QUIETENED — never `--c-soft`, which is mixed for the PAGE's paper and is
   therefore a grey chosen for a surface the quotation is no longer sitting on. On a light quote
   card over a dark proof band it came out very nearly the colour of the card. */
:is(#clay-page,#design-sheets) .c-quote .c-who{font:var(--c-weight) var(--c-t1)/1.2 var(--c-display);
  letter-spacing:var(--c-track);color:inherit}
/**
 * FIVE STARS, DRAWN — not a font's glyph and not an image.
 *
 * A star is a shape, so it is a shape: one background image in the ink of whatever it sits on, and
 * a half score is the same shape clipped down the middle. Nothing to load, nothing to line up, and
 * it takes the colour of its surroundings on every theme without any of them saying so.
 */
:is(#clay-page,#design-sheets) .c-stars{display:inline-flex;gap:2px;align-items:center;
  line-height:1;flex:0 0 auto}
/* A STAR IS A DRAWN SHAPE — `stars()` in parts.js emits the SVG and the path lives there. All this
   owns is the size and how much of the ink an unfilled one keeps, which is paint. The half star
   clips itself inside the SVG, so nothing here stacks a second layer on a first. */
:is(#clay-page,#design-sheets) .c-star{width:1em;height:1em;display:block;opacity:.22}
:is(#clay-page,#design-sheets) .c-star-on,
:is(#clay-page,#design-sheets) .c-star-half{opacity:1}
:is(#clay-page,#design-sheets) .c-when{font:var(--c-label-weight) var(--c-t0)/1.2 var(--c-body);
  text-transform:var(--c-label-case);letter-spacing:var(--c-label-track);color:inherit;opacity:.6}

/* ── field ─────────────────────────────────────────────────────────────────────────────── */
:is(#clay-page,#design-sheets) .c-form{display:grid;gap:calc(var(--c-u)*2);
  grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}
:is(#clay-page,#design-sheets) .c-field{display:flex;flex-direction:column;gap:calc(var(--c-u)*1)}
:is(#clay-page,#design-sheets) .c-field.c-wide{grid-column:1/-1}
:is(#clay-page,#design-sheets) .c-lab{font:var(--c-label-weight) var(--c-t0)/1 var(--c-label);
  letter-spacing:var(--c-label-track);text-transform:var(--c-label-case);color:var(--c-soft)}
/* A FIELD IS A BOX OR A RULE. Four borders and a fill is one answer; a single hairline under the
   line you type on, with the label sitting on it, is another — and a form is the most theme-
   visible machine we have, so it cannot be the only part of the page with no say in it. */
:is(#clay-page,#design-sheets) .c-field input,:is(#clay-page,#design-sheets) .c-field select,:is(#clay-page,#design-sheets) .c-field textarea{
  font:var(--c-t2)/1.4 var(--c-body);color:var(--c-ink);background:var(--c-field-bg);
  border:var(--c-field-bw) solid var(--c-line);border-bottom-width:var(--c-field-bw-b);
  border-radius:var(--c-r);padding:var(--c-field-pad);width:100%}
:is(#clay-page,#design-sheets) .c-field textarea{min-height:calc(var(--c-u)*14);resize:vertical}
:is(#clay-page,#design-sheets) .c-field :is(input,select,textarea):focus{outline:0;border-color:var(--c-accent)}
/* a capture: the fields, the button on its own row, and the line that says what happened */
:is(#clay-page,#design-sheets) .c-form-go{grid-column:1/-1;display:flex;justify-content:flex-start}
/**
 * A FORM WITH ONE OR TWO FIELDS IS ONE LINE, not a grid the width of the page.
 *
 * `auto-fit` spread a single email field across a fifth of an 1180px measure and dropped the
 * button onto a row of its own, centred, a hand's width away from the box it belongs to — which
 * is a sign-up nobody reads as a sign-up. The field and its button travel together, at a width a
 * person can take in, and centred under a centred heading.
 */
:is(#clay-page,#design-sheets) .c-form.c-form-row{display:flex;flex-wrap:wrap;align-items:flex-end;
  gap:calc(var(--c-u)*1.5);max-width:min(620px,100%)}
/* …and it follows its heading: centred under a centred one, at the margin under a left one */
:is(#clay-page,#design-sheets) .c-in-mid .c-form.c-form-row{margin-inline:auto}
:is(#clay-page,#design-sheets) .c-form.c-form-row .c-field{flex:1 1 200px;min-width:0;text-align:left}
:is(#clay-page,#design-sheets) .c-form.c-form-row .c-form-go{flex:0 0 auto;grid-column:auto;justify-content:flex-start}
/* and a stacked one keeps a measure too — a message box 1180px wide is a page, not a field */
:is(#clay-page,#design-sheets) .c-form:not(.c-form-row){max-width:min(720px,100%)}
:is(#clay-page,#design-sheets) .c-in-mid .c-form:not(.c-form-row){margin-inline:auto;text-align:left}
/* the line about the form travels with the form, at the form's own width and alignment */
:is(#clay-page,#design-sheets) .c-capture{display:grid;gap:calc(var(--c-u)*2)}
:is(#clay-page,#design-sheets) .c-form-note{max-width:min(620px,100%)}
:is(#clay-page,#design-sheets) .c-in-mid .c-form-note{margin-inline:auto;text-align:center}
:is(#clay-page,#design-sheets) .c-fine{grid-column:1/-1;margin:0;font:var(--c-t1)/1.5 var(--c-body);color:var(--c-soft);
  max-width:var(--c-cap-note)}
/* A PANEL THAT PAINTS ITS OWN GROUND MUST PAINT ITS OWN INK. `--c-fill` is mixed from PAPER, so
   inside a dark band - where the text colour is the band's cream - the sign-up form came out as a
   cream heading on a cream panel, invisible, with only the field labels and the button (which set
   their own colours) still readable. */
:is(#clay-page,#design-sheets) .c-tone-tint .c-in{--g:var(--c-fill);background:var(--g);color:var(--c-ink);border-radius:var(--c-r);
  padding-block:calc(var(--c-u)*7);padding-inline:calc(var(--c-u)*4)}

/* ── chip ──────────────────────────────────────────────────────────────────────────────── */
/**
 * A FILTER STRIP IS ONE LINE, AND IT SCROLLS.
 *
 * Wrapping put eight categories on three lines above a menu, which pushes the food off the screen
 * and reads as a paragraph of buttons. One line, sideways, snapping — the gesture a phone already
 * means, and on a desktop it simply never wraps.
 */
:is(#clay-page,#design-sheets) .c-chips{display:flex;gap:var(--c-u);flex-wrap:nowrap;overflow-x:auto;
  overscroll-behavior-x:contain;scrollbar-width:none;scroll-snap-type:x proximity;
  margin-inline:calc(var(--c-gut) / -2);padding-inline:calc(var(--c-gut) / 2);
  /* AND THE SNAP IS PADDED TOO — see the rails below. This one snaps by `proximity` rather than
     `mandatory`, so it does not lose the gutter sitting still the way they did; it loses it the
     first time somebody scrolls and lets go. Same token, so the chip the strip settles on lines
     up with the heading under it however it got there. */
  scroll-padding-inline:calc(var(--c-gut) / 2)}
:is(#clay-page,#design-sheets) .c-chips::-webkit-scrollbar{display:none}
:is(#clay-page,#design-sheets) .c-chips > *{flex:0 0 auto;scroll-snap-align:start}
:is(#clay-page,#design-sheets) .c-chip{font:var(--c-weight) var(--c-t1)/1 var(--c-display);text-transform:var(--c-case);
  padding:calc(var(--c-u)*1.5) calc(var(--c-u)*2);border-radius:var(--c-r);cursor:pointer;
  border:calc(var(--c-bw)*2) solid var(--c-line);background:var(--c-paper);color:var(--c-ink);
  display:inline-flex;gap:calc(var(--c-u));align-items:center}
:is(#clay-page,#design-sheets) .c-chip.c-on{background:var(--c-ink);color:var(--c-paper);border-color:var(--c-ink)}
:is(#clay-page,#design-sheets) .c-chip-m{font-weight:400;opacity:.6;font-variant-numeric:tabular-nums}

/* A FILTER STICKS, AND IT CLEARS THE BAR. It used to stick at 0 and sit UNDER the navigation, so
   the chips were visible and unclickable. Both numbers come from the same token. */
/* PADDING-BLOCK, NOT `padding`. The rule above bleeds the strip to the edge of the screen with a
   negative margin and puts the chips back on the column with an equal padding — and this was
   written as the SHORTHAND, which sets all four sides, so it kept the bleed and threw the
   compensation away. Every filtered page had its first chip hard against the edge of the glass
   while the heading under it started at the gutter, and the last one clipped by the other edge.
   Only the vertical is this rule's business. */
:is(#clay-page,#design-sheets) .c-chips.c-stick{position:sticky;top:var(--c-bar);z-index:3;background:var(--c-paper);
  padding-block:calc(var(--c-u)*1.5)}
:is(#clay-page,#design-sheets) [id]{scroll-margin-top:calc(var(--c-bar) + var(--c-u)*2)}

/* ── grid and strip ────────────────────────────────────────────────────────────────────── */
/* THE THEME'S CEILING APPLIES EVEN WHEN THE BLOCK NAMES NO CAP. `auto-fit` alone answers "as many
   as fit", which is the browser deciding a composition. `--c-cap-max` is the design's most. */
:is(#clay-page,#design-sheets) .c-grid{display:grid;gap:var(--c-gap);
  grid-template-columns:repeat(auto-fit,minmax(max(var(--c-min,220px),
    calc((100% - var(--c-gap) * (var(--c-cap-max) - 1)) / var(--c-cap-max))),1fr))}
/**
 * TWO THINGS DO NOT SPREAD ACROSS THE WHOLE MEASURE with a chasm between them — but they are not
 * two columns AT EVERY WIDTH either.
 *
 * `repeat(2, minmax(0,1fr))` is a hard two: two cards on a 390px phone were two 170px slivers,
 * whatever minimum the block asked for. The cap was written looking at a desk.
 *
 * IT HAS TO CAP THE COUNT, THOUGH. `minmax(min(100%, --c-min), 1fr)` caps nothing at all: it is
 * `auto-fit` with a 260px floor, so on Bold's 1400px measure a cap of two came out as THREE
 * columns — which is how four reviews, deliberately re-columned to two so they would tile, drew
 * as three and one on its own. The floor has to be a HALF of the row, exactly the way the caps of
 * three and four below are written. Where half is narrower than the block's own minimum, the
 * minimum wins and they stack, which is the phone case the hard two got wrong.
 *
 * The max-width is the other half of what a cap of two is for: two things do not spread across
 * the whole measure with a chasm between them.
 *
 * (Quotations are not this case — they scroll sideways under 560px, on purpose, and that rule
 * takes over before this one matters. This is for everything else that comes in twos.)
 */
:is(#clay-page,#design-sheets) .c-grid[style*="--c-cap:2"]{
  grid-template-columns:repeat(auto-fit,minmax(max(var(--c-min,220px),calc((100% - var(--c-gap)) / 2)),1fr))}
/* …AND THE NARROWING IS FOR TWO THINGS, not for two COLUMNS. Four reviews are two columns because
   four in three is one on its own — but four is a block, not a pair, and clamping it to 62% of the
   measure left a third of the band empty beside it. The clamp is what stops a PAIR spreading with
   a chasm between them, so it belongs to a set of exactly two. */
:is(#clay-page,#design-sheets) .c-grid[style*="--c-cap:2"]:not(:has(> :nth-child(3))){
  max-width:calc(var(--c-measure) * .62)}
:is(#clay-page,#design-sheets) .c-grid[style*="--c-cap:1"]{grid-template-columns:minmax(0,1fr);
  max-width:calc(var(--c-measure) * .42)}
/* A CAP OF THREE OR FOUR IS ALSO A CAP. Only 1 and 2 were written, so a block asking for at most
   three got `auto-fit` — which on a 1400px measure is five columns of four words each, and that is
   exactly what a page of reviews came out as. `auto-fit` still applies underneath: these are the
   most it may have, never the number it must have. */
/* …and the theme's ceiling still applies on top: a wider minimum means fewer columns, so taking
   the LARGER of the block's minimum and the design's honours both without either overruling the
   other. A block asking for four in a design that caps at three gets three. */
:is(#clay-page,#design-sheets) .c-grid[style*="--c-cap:3"]{grid-template-columns:repeat(auto-fit,minmax(max(var(--c-min,220px),calc((100% - var(--c-gap)*2) / 3),calc((100% - var(--c-gap) * (var(--c-cap-max) - 1)) / var(--c-cap-max))),1fr))}
:is(#clay-page,#design-sheets) .c-grid[style*="--c-cap:4"]{grid-template-columns:repeat(auto-fit,minmax(max(var(--c-min,220px),calc((100% - var(--c-gap)*3) / 4),calc((100% - var(--c-gap) * (var(--c-cap-max) - 1)) / var(--c-cap-max))),1fr))}
/* THE COUNT DECIDES THE COLUMNS. `auto-fit` fills the row with as many minimum-width cells as go
   in it, so two photographs sat small and left-packed with the rest of the row empty. `strip()`
   works out how many there are and caps it; two photographs are two halves. */
:is(#clay-page,#design-sheets) .c-strip{display:grid;gap:calc(var(--c-u)*.5);
  grid-template-columns:repeat(var(--c-cols,3),minmax(0,1fr))}
:is(#clay-page,#design-sheets) .c-strip .c-media{border-radius:var(--c-r)}
/* AND THE PICTURE INSIDE IT TAKES THE BOX'S CORNERS, NOT ITS OWN. `media()` writes an <img class="img">
   and a theme with an older `.img` rule of its own — Bold had one, at 18px — was rounding every
   photograph on every page while the box around it stayed square. The box decides; the token
   decides the box. */
:is(#clay-page,#design-sheets) .c-media{border-radius:var(--c-r);overflow:hidden}
:is(#clay-page,#design-sheets) .c-media > .img{border-radius:0}

/**
 * THE MOSAIC — which, until now, was a class name and no rule at all.
 *
 * `blocks.js` has asked for `c-mosaic` since the gallery was written and nothing has ever drawn
 * one, so "mosaic" and "grid" were the same auto-fit row: seven photographs came out as five and
 * then two, with three holes beside them.
 *
 * A FIXED NUMBER OF COLUMNS, not auto-fit, and every cell the same. A feature cell twice the size
 * was tried first and it only tiles for counts nobody has: at seven it left two holes AND stood a
 * screen and a half tall. Four equal squares, three at tablet, two on a phone — a short last row
 * reads as a grid; a row of five beside a row of two reads as a mistake.
 */
:is(#clay-page,#design-sheets) .c-mosaic .c-strip{gap:calc(var(--c-u)*1)}
/**
 * TWO UP ON A PHONE, WHEREVER IT IS CARDS.
 *
 * `auto-fit` at 390px gives one column, so three products were a 1900px column of pictures — a
 * screen and a half of scrolling to get past a teaser of three things. Two of them side by side is
 * what every shop on a phone does, and it is the difference between a page you flick through and
 * one you give up on.
 *
 * Cards only: a grid of quotations at two-up on a phone is two columns of one word each, and the
 * facts strip is already narrow enough to sit two across on its own.
 */
@container (max-width:560px){
  :is(#clay-page,#design-sheets) .c-grid:has(> .c-card){grid-template-columns:repeat(2,minmax(0,1fr));
    gap:calc(var(--c-u)*1.5)}
  :is(#clay-page,#design-sheets) .c-grid:has(> .c-card) .c-card-n{font-size:var(--c-t2)}
}

/**
 * ON A PHONE A ROW OF PHOTOGRAPHS SCROLLS SIDEWAYS.
 *
 * Four squares stacked into a column of four is a screen and a half of scrolling to get past the
 * pictures — and the pictures are the one part of a page nobody needs to read. A snapping strip
 * shows the first and says there are more, in the gesture a phone already means.
 *
 * `overflow-x` on the strip only: the PAGE must never scroll sideways (scripts/check-overflow).
 */
/* HOW WIDE A CARD IS IN THE RAIL — the rail itself is stated once, at the foot of this file. */
:is(#clay-page,#design-sheets) .c-strip{--c-rail:72%}

/**
 * THE WAYS IN — as many columns as there are, across the WHOLE band.
 *
 * `grid`'s `cap` narrows the measure as well as the columns, which is right for two quotations
 * and wrong for two ways in: they came out in two thirds of the band with the last third empty.
 * These fill it, whatever there are of them.
 */
:is(#clay-page,#design-sheets) .c-does{--c-rail:78%;display:grid;gap:calc(var(--c-u)*3*var(--c-density));
  grid-template-columns:repeat(var(--c-cols,3),minmax(0,1fr));margin-top:calc(var(--c-u)*4*var(--c-density));
  /* FOUR ROWS, SHARED — picture, name, line, way in. Without this a card with a photograph and one
     without were two different cards at two different heights with their buttons on two different
     lines, which is exactly how a row of ways in reads as broken. */
  grid-template-rows:auto auto auto auto;align-items:start}
:is(#clay-page,#design-sheets) .c-does > .c-does-c{display:grid;grid-row:span 4;grid-template-rows:subgrid;
  gap:calc(var(--c-u)*1.5);align-content:start}
/* the picture row is empty for a card that has none — empty, never a grey box (R1) */
:is(#clay-page,#design-sheets) .c-does .c-does-pic:empty{display:none}
:is(#clay-page,#design-sheets) .c-does .c-does-pic .c-media{border-radius:var(--c-r)}
/* AN EMPTY LINE STILL HOLDS ITS ROW. Hiding it took the card out of step with its neighbours by
   one row, so the card with no line had its button where the others had their line. Empty is
   zero-height; the row is as tall as the tallest line across the three, and the buttons agree. */
:is(#clay-page,#design-sheets) .c-does .c-card-s:empty{min-height:0}
:is(#clay-page,#design-sheets) .c-does .c-does-a{display:flex;align-items:end}
@container (max-width:900px){:is(#clay-page,#design-sheets) .c-does{grid-template-columns:repeat(2,minmax(0,1fr))}}
/**
 * ON A PHONE THEY GO SIDEWAYS, like the photographs do.
 *
 * Stacked, four ways in is four screens of scrolling before the page even starts — and the point
 * of this band is to be read at a glance. One row, snapping, the next card peeking so the gesture
 * is obvious. `overflow-x` on the row only: the PAGE never scrolls sideways (scripts/check-overflow).
 */
@container (max-width:560px){
  /* SIDEWAYS, so the shared rows go — a scroller is one row of cards and each is its own height */
  :is(#clay-page,#design-sheets) .c-does > .c-does-c{grid-row:auto;grid-template-rows:none}
}
/* a capped grid under a CENTRED heading is centred too — the reviews sat hard left under a
   heading in the middle of the band, which reads as two bands that happened to touch */
:is(#clay-page,#design-sheets) .c-grid.c-mid{margin-inline:auto}
/* A LINE THAT SAYS IT IS CENTRED IS CENTRED. The rule was written for a line INSIDE something
   centred (`.c-mid .c-line`), so the one place that puts the class on the line itself — the
   reviews' own sentence, under a heading in the middle of the band — sat hard against the left
   edge, on every site with a line on its reviews. */
:is(#clay-page,#design-sheets) .c-line.c-mid{margin-inline:auto;text-align:center}

/**
 * ON A PHONE THE QUOTATIONS SCROLL SIDEWAYS, like the ways in and the photographs.
 *
 * Four reviews stacked is four screens of somebody else's words between a visitor and the rest of
 * the page. One at a time, snapping, the next peeking — the gesture a phone already means.
 *
 * `overflow-x` on the row only: the PAGE must never scroll sideways (scripts/check-overflow).
 */
:is(#clay-page,#design-sheets) .c-grid.c-quotes{--c-rail:82%}
@container (max-width:560px){
  /* a quotation reads left even where the band is centred, and one on its own is the band again */
  :is(#clay-page,#design-sheets) .c-grid.c-quotes{text-align:left}
  :is(#clay-page,#design-sheets) .c-grid.c-quotes:not(:has(> * + *)){text-align:center}
}

/* A CAPPED GRID IS CAPPED, NOT FIXED. `--c-cap:2` names the most columns it may have, and the
   rule set exactly two at every width — so a pair of quotations on a 390px phone came out as two
   columns three words wide. Anything that is not a card goes to one. */
/**
 * …AND A RAIL HAS NO COLUMNS TO CAP, which is not a detail — it was a review nobody could see.
 *
 * The note on the cap-of-two above says quotations are not its case, because "they scroll sideways
 * under 560px and that rule takes over before this one matters". It does not take over: the rail
 * is `.c-grid.c-quotes` (two classes) and this is a class plus an attribute plus a `:not(:has())`,
 * so THIS wins, and it hands a horizontal rail one explicit `minmax(0,1fr)` track.
 *
 * In a rail the implicit tracks are 82% each and overflow on purpose, so the free space is
 * negative and `1fr` resolves to ZERO. The first quotation went into that track and came out 0px
 * wide: on every phone, the home page's reviews band silently dropped its first review and opened
 * on the second.
 *
 * So the caps stand aside for the things that become rails — by the same names the rail rule uses.
 */
@container (max-width:560px){
  :is(#clay-page,#design-sheets) .c-grid[style*="--c-cap:2"]:not(:has(> .c-card)):not(:is(.c-strip,.c-does,.c-quotes,.l-faces)){grid-template-columns:minmax(0,1fr)}
}

/**
 * AND A CARD IS NOT A COLUMN ON A PHONE — docs/design-rules.md R12.
 *
 * "No two-column anything below 560px unless both columns are genuinely narrow." A card carries a
 * photograph, a name, a line and a button: at 179px that is a picture the size of a stamp over
 * three words a line with a button that wraps. The set stacks, which is the arrangement's own
 * declared collapse rather than a breakpoint someone reached for.
 *
 * A STRIP of photographs is the exception and keeps its columns — pictures ARE narrow, and a wall
 * of them two across is the point of the wall.
 */
@container page (max-width:560px){
  :is(#clay-page,#design-sheets) .c-grid:has(> .c-card){grid-template-columns:minmax(0,1fr)}
}

/* ── two up ────────────────────────────────────────────────────────────────────────────── */
:is(#clay-page,#design-sheets) .c-two{display:grid;gap:calc(var(--c-u)*4*var(--c-density));align-items:center;
  grid-template-columns:minmax(0,1fr) minmax(0,.8fr)}
/* …and top-aligned where one side is a tall photograph and the other is three lines: centred put
   a screen of air above the writing and lined its middle up with nothing. */
:is(#clay-page,#design-sheets) .c-two.c-top{align-items:start}
/* ONE WAY IN is a portrait beside the words, not a card in a row of one. It sat in a third of the
   band with air above and below it; the picture takes its half floor to ceiling and the writing
   sits in the middle of the other. */
:is(#clay-page,#design-sheets) .c-two.c-does-one{grid-template-columns:minmax(0,1fr) minmax(0,.92fr);
  gap:calc(var(--c-u)*7*var(--c-density))}
/* THE COLLAPSE COMES LAST, so every variant above it stacks on a phone. It was written first and
   the one-card split kept its two columns at 390px — a portrait squeezed into a third of the
   screen with a headline crushed beside it. */
@container (max-width:640px){:is(#clay-page,#design-sheets) .c-two,:is(#clay-page,#design-sheets) .c-two.c-does-one{grid-template-columns:1fr}}
:is(#clay-page,#design-sheets) .c-cols{columns:2;column-gap:calc(var(--c-u)*5)}
@container (max-width:640px){:is(#clay-page,#design-sheets) .c-cols{columns:1}}
:is(#clay-page,#design-sheets) .c-cols > *{break-inside:avoid}

/* ── tags ──────────────────────────────────────────────────────────────────────────────── */
:is(#clay-page,#design-sheets) .c-tags{display:flex;gap:calc(var(--c-u)*1);flex-wrap:wrap;margin-top:calc(var(--c-u)*.5)}
:is(#clay-page,#design-sheets) .c-tag{font:var(--c-label-weight) var(--c-t0)/1 var(--c-label);font-style:normal;
  letter-spacing:var(--c-label-track);text-transform:var(--c-label-case);color:var(--c-soft);
  border:var(--c-bw) solid var(--c-line);
  padding:calc(var(--c-u)*.5) calc(var(--c-u));border-radius:var(--c-r)}

/* ── the booking flow ──────────────────────────────────────────────────────────────────────
   Not a component of its own: steps, chips, fields and actions, with a calendar. The calendar is
   the only geometry here that nothing else needs. It scrolls with the PAGE — the version before
   this scrolled inside itself, so the page stood still while the form moved. */
:is(#clay-page,#design-sheets) .c-book{margin-top:calc(var(--c-u)*4*var(--c-density))}
:is(#clay-page,#design-sheets) .c-step{border-top:var(--c-bw) solid var(--c-line)}
:is(#clay-page,#design-sheets) .c-step:last-child{border-bottom:var(--c-bw) solid var(--c-line)}
:is(#clay-page,#design-sheets) .c-step-h{display:flex;align-items:center;gap:calc(var(--c-u)*2);width:100%;
  padding:calc(var(--c-u)*3) 0;background:none;border:0;cursor:pointer;text-align:left;
  color:inherit;font:inherit}
:is(#clay-page,#design-sheets) .c-step-n{width:calc(var(--c-u)*4);height:calc(var(--c-u)*4);flex:0 0 auto;
  border-radius:var(--c-r);border:calc(var(--c-bw)*2) solid var(--c-line);display:grid;
  place-items:center;font:var(--c-weight) var(--c-t0)/1 var(--c-display)}
:is(#clay-page,#design-sheets) .c-step.on .c-step-n{background:var(--c-ink);color:var(--c-paper);border-color:var(--c-ink)}
:is(#clay-page,#design-sheets) .c-step-t{font:var(--c-weight) var(--c-t2)/1 var(--c-display);
  text-transform:var(--c-case);letter-spacing:var(--c-track)}
:is(#clay-page,#design-sheets) .c-step-v{margin-left:auto;font:var(--c-t1)/1 var(--c-body);color:var(--c-soft)}
/* THE RUNTIME OWNS THIS STATE. It toggles `on` and `done`; a component that invents `c-on` for
   the same thing is a component nothing can open, which is a booking page of four closed boxes. */
:is(#clay-page,#design-sheets) .c-step-b{display:none;padding:0 0 calc(var(--c-u)*4)}
:is(#clay-page,#design-sheets) .c-step.on .c-step-b{display:block}
:is(#clay-page,#design-sheets) .c-step-b > * + *{margin-top:calc(var(--c-u)*3)}
:is(#clay-page,#design-sheets) .c-step-b2{width:calc(var(--c-u)*5);height:calc(var(--c-u)*5);border-radius:var(--c-r);
  border:calc(var(--c-bw)*2) solid var(--c-line);background:var(--c-paper);color:inherit;
  font:var(--c-weight) var(--c-t2)/1 var(--c-display);cursor:pointer}

:is(#clay-page,#design-sheets) .c-cal-h{display:flex;align-items:center;justify-content:space-between;
  gap:calc(var(--c-u)*2);margin-bottom:calc(var(--c-u)*2)}
:is(#clay-page,#design-sheets) .c-cal-m{font:var(--c-weight) var(--c-t2)/1 var(--c-display);text-transform:var(--c-case)}
:is(#clay-page,#design-sheets) .c-cal-b{width:calc(var(--c-u)*5);height:calc(var(--c-u)*5);border-radius:var(--c-r);
  border:calc(var(--c-bw)*2) solid var(--c-line);background:var(--c-paper);color:inherit;
  font-size:var(--c-t3);cursor:pointer;line-height:1}
/**
 * A CALENDAR IS A SMALL OBJECT.
 *
 * `max-width` alone did not hold it: in a column a third of a wide page, seven `1fr` tracks with
 * `aspect-ratio:1` cells gave squares the size of a thumbnail each and a month the height of the
 * screen. The CELL is what has a size — 44px, which is the smallest a thumb can hit, up to 56 —
 * and the grid is however wide seven of those are. Nothing about it grows with the window.
 */
:is(#clay-page,#design-sheets) .c-cal{display:grid;
  grid-template-columns:repeat(7,minmax(0,clamp(38px,7.2cqw,54px)));
  gap:calc(var(--c-u)*.5);justify-content:start;width:max-content;max-width:100%}
/* THE WEEKDAY ROW IS A LABEL, so it is the height of a label. It had a pad on every side and sat
   in a grid whose other rows are square, which left a band of nothing between the days of the week
   and the first day of the month. */
:is(#clay-page,#design-sheets) .c-cal .head{font:600 var(--c-t0)/1 var(--c-body);letter-spacing:.06em;
  text-transform:uppercase;color:var(--c-soft);display:grid;place-items:center;
  height:calc(var(--c-u)*3)}
/* A CELL WITH NOTHING IN IT IS NOT A CELL. The days before the 1st are spacers; giving them the
   square the real days have is what put a blank row above every month starting late in the week. */
:is(#clay-page,#design-sheets) .c-cal > span:not([data-day]):not(.head){aspect-ratio:1}
:is(#clay-page,#design-sheets) .c-cal [data-day]{aspect-ratio:1;display:grid;place-items:center;cursor:pointer;
  border-radius:var(--c-r);border:var(--c-bw) solid transparent;
  font:var(--c-t1)/1 var(--c-body);font-variant-numeric:tabular-nums}
:is(#clay-page,#design-sheets) .c-cal [data-day]:hover{border-color:var(--c-line)}
:is(#clay-page,#design-sheets) .c-cal .on,:is(#clay-page,#design-sheets) .c-cal .sel{background:var(--c-ink);color:var(--c-paper)}
:is(#clay-page,#design-sheets) .c-cal .off,:is(#clay-page,#design-sheets) .c-cal .out{opacity:.28;pointer-events:none}
:is(#clay-page,#design-sheets) .c-cal .pad{visibility:hidden}
/**
 * THE TIMES ARE A LIST, NOT A STRIP.
 *
 * They were chips in a horizontal scroller: on a desk that ran the free times off the side of the
 * column and under the calendar next to it, and a person comparing 09:00 with 15:15 had to swipe
 * between them. A day has eight or ten of these and they are the column's whole content — so they
 * stack, each one the width of the column, each one a target.
 */
:is(#clay-page,#design-sheets) .c-times{display:grid;gap:calc(var(--c-u));
  max-height:calc(var(--c-u)*52);overflow-y:auto;overscroll-behavior:contain}
:is(#clay-page,#design-sheets) .c-times span{font:var(--c-weight) var(--c-t1)/1 var(--c-display);
  padding:calc(var(--c-u)*1.5) calc(var(--c-u)*2);border-radius:var(--c-r);cursor:pointer;
  border:calc(var(--c-bw)*2) solid var(--c-line);text-align:center;min-height:calc(var(--c-u)*5);
  font-variant-numeric:tabular-nums}
:is(#clay-page,#design-sheets) .c-times span.on{background:var(--c-ink);color:var(--c-paper);border-color:var(--c-ink)}
:is(#clay-page,#design-sheets) .c-times p{font:var(--c-t1)/1.45 var(--c-body);color:var(--c-soft);margin:0}
/**
 * WHAT THEY PICKED, AND THE WAY BACK — the times' replacement, so it stands where they were.
 *
 * A choice you cannot see is a choice you cannot check, and one you cannot undo is a page people
 * leave rather than risk. Both, in one control.
 */
:is(#clay-page,#design-sheets) .c-chosen{display:flex;align-items:baseline;justify-content:space-between;
  gap:calc(var(--c-u)*2);width:100%;text-align:left;cursor:pointer;
  padding:calc(var(--c-u)*1.5) calc(var(--c-u)*2);border-radius:var(--c-r);
  border:calc(var(--c-bw)*2) solid var(--c-line);background:none;color:inherit;
  margin-bottom:calc(var(--c-u)*3)}
:is(#clay-page,#design-sheets) .c-chosen b{font:var(--c-weight) var(--c-t2)/1.2 var(--c-display)}
:is(#clay-page,#design-sheets) .c-chosen span{font:var(--c-t1)/1 var(--c-body);color:var(--c-soft);
  text-decoration:underline;flex:0 0 auto}
/* THE LINE UNDER A FIELD — an explanation, which is why it is not the placeholder. See `field()`. */
:is(#clay-page,#design-sheets) .c-field .c-note{font:var(--c-t1)/1.45 var(--c-body);color:var(--c-soft);
  margin-top:calc(var(--c-u)*.5)}
/* THE LABEL SITS OVER THE ANSWERS, not beside them. Beside them, in a column a third of a page
   wide, "How many" breaks onto two lines and the chips lose a third of their room to it. */
:is(#clay-page,#design-sheets) .c-party{display:flex;align-items:center;gap:calc(var(--c-u)*1.5)}
:is(#clay-page,#design-sheets) .c-party:has(.c-party-n){display:grid;justify-items:start;
  gap:calc(var(--c-u))}
/* the chips do not scroll — under eight of them there is nothing to scroll to, and a strip that
   scrolls when it does not need to is a strip somebody swipes at and nothing happens */
:is(#clay-page,#design-sheets) .c-party-n{overflow:visible;flex-wrap:wrap;margin-inline:0;padding-inline:0}
/* THE DAY OVER THE TIMES. Its own line, because it is the answer to "which day am I looking at". */
:is(#clay-page,#design-sheets) [data-daylabel]:empty{display:none}
:is(#clay-page,#design-sheets) [data-daylabel]{margin:0 0 calc(var(--c-u)*1.5)}
:is(#clay-page,#design-sheets) .c-party b{font:var(--c-weight) var(--c-t3)/1 var(--c-display);min-width:calc(var(--c-u)*3);
  text-align:center;font-variant-numeric:tabular-nums}
:is(#clay-page,#design-sheets) .c-quote-line{font:var(--c-t2)/1.5 var(--c-body);color:var(--c-soft);margin:0}
:is(#clay-page,#design-sheets) .c-book-two{align-items:start}
@container (max-width:640px){:is(#clay-page,#design-sheets) .c-book-two{grid-template-columns:1fr}}

/* ── pages ─────────────────────────────────────────────────────────────────────────────── */
:is(#clay-page,#design-sheets) .c-page{padding-top:calc(var(--c-u)*5)}
:is(#clay-page,#design-sheets) .c-group{margin-top:calc(var(--c-u)*7*var(--c-density))}
:is(#clay-page,#design-sheets) .c-group[hidden]{display:none}
:is(#clay-page,#design-sheets) .c-prose{font:var(--c-t3)/1.65 var(--c-body);max-width:62ch;margin:0}
:is(#clay-page,#design-sheets) .c-shot{padding:0;border:0;background:none;cursor:pointer;display:block}
:is(#clay-page,#design-sheets) .c-week{max-width:calc(var(--c-u)*52)}

/* ── the owner's way in ────────────────────────────────────────────────────────────────── */
:is(#clay-page,#design-sheets) .c-doc{display:block}
/* the band is the positioning context; the gear itself is the editor's control and the editor
   styles it — a second set of rules for the same button is two buttons drifting apart */
:is(#clay-page,#design-sheets) .c-own{position:relative}

/* ── questions ─────────────────────────────────────────────────────────────────────────────
   A feature's own, answered on its page. One open at a time is the browser's job, not ours. */
/* the proof line under a header's button: the faces, then the words */
:is(#clay-page,#design-sheets) .c-proof{display:flex;align-items:center;gap:calc(var(--c-u)*1.5);
  margin-top:calc(var(--c-u)*3);font:var(--c-t1)/1.4 var(--c-body);color:var(--c-soft)}
:is(#clay-page,#design-sheets) .c-proof.c-mid{justify-content:center}
:is(#clay-page,#design-sheets) .c-faces{display:flex}
:is(#clay-page,#design-sheets) .c-faces i{width:calc(var(--c-u)*4);height:calc(var(--c-u)*4);border-radius:999px;
  background-size:cover;background-position:center;border:2px solid var(--c-paper);margin-left:-8px}
:is(#clay-page,#design-sheets) .c-faces i:first-child{margin-left:0}
:is(#clay-page,#design-sheets) .c-proof-t b{color:var(--c-ink);font-weight:700}
:is(#clay-page,#design-sheets) .c-g-photo .c-proof,:is(#clay-page,#design-sheets) .c-g-ink .c-proof{color:rgba(255,255,255,.8)}
:is(#clay-page,#design-sheets) .c-g-photo .c-proof-t b,:is(#clay-page,#design-sheets) .c-g-ink .c-proof-t b{color:#fff}

/* a fact: the number that carries, and what it is underneath */
/* the facts strip: a year, a count, a thing that is true and short. It is a second thought after
   the paragraph, not the next line of it, so it stands off from what it follows. */
:is(#clay-page,#design-sheets) .c-facts{margin-top:calc(var(--c-u)*4);margin-bottom:calc(var(--c-u)*4)}
/* a single photograph on a page of prose: a figure, not a billboard the width of the measure */
:is(#clay-page,#design-sheets) .c-shots-one{margin-top:calc(var(--c-u)*5);max-width:min(720px,100%)}
/* a page heading and the block it introduces are one thing: no seam, no second rhythm */
:is(#clay-page,#design-sheets) .c-page-lead{padding-bottom:0}

/* ── the page header ───────────────────────────────────────────────────────────────────────
   One band at the top of every page: the overline, the heading, the line under it, and the
   feature's first photograph beside them. It pays its own rhythm above and none below, because
   the band under it is the thing this page is — and the DESCENDERS get room: with no bottom
   padding at all the tail of a "Q" was painted over by the next band's ground. */
:is(#clay-page,#design-sheets) .c-page-head{padding-bottom:calc(var(--c-u)*2)}
:is(#clay-page,#design-sheets) .c-page-head + .c-band{border-top:0}
:is(#clay-page,#design-sheets) .c-page-head .c-two{gap:calc(var(--c-u)*5*var(--c-density))}
:is(#clay-page,#design-sheets) .c-page-head .c-media{border-radius:var(--c-r)}
/* the page's own heading is the biggest type on it, and it needs the leading a display face with
   descenders actually occupies */
:is(#clay-page,#design-sheets) .c-page-head h1.c-title{padding-bottom:.06em}

/* ── a place ───────────────────────────────────────────────────────────────────────────────
   The visit page: one panel per address — its picture or its map, then its overline, its street,
   whether it is open right now, every way to reach it, and the week it keeps. */
:is(#clay-page,#design-sheets) .c-place{display:grid;gap:calc(var(--c-u)*3)}
:is(#clay-page,#design-sheets) .c-place + .c-place{margin-top:calc(var(--c-u)*7*var(--c-density));
  padding-top:calc(var(--c-u)*7*var(--c-density));border-top:var(--c-bw) solid var(--c-line)}
:is(#clay-page,#design-sheets) .c-place .c-media{border-radius:var(--c-r)}
:is(#clay-page,#design-sheets) .c-place-t{display:grid;gap:calc(var(--c-u)*2)}
:is(#clay-page,#design-sheets) .c-place-t .c-week{max-width:none;margin-top:calc(var(--c-u)*1)}
/* one place has the room for the two columns; several are a grid of panels and each is one column */
:is(#clay-page,#design-sheets) .c-place-one{grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);align-items:start}
@container (max-width:720px){:is(#clay-page,#design-sheets) .c-place-one{grid-template-columns:1fr}}
:is(#clay-page,#design-sheets) .c-places{align-items:start}

/* the street itself — a fact under the heading, at the size of a line and the weight of a name */
/* AN ADDRESS IS A FACT, NOT A HEADING. Set in the display face one step under the title it sat
   directly below, a long street ran to three lines of serif and came out larger than the
   description above it - the hierarchy exactly inverted. It is the label voice: small, tracked,
   quiet, and the same voice the footer says it in. */
:is(#clay-page,#design-sheets) .c-place-a{font:var(--c-label-weight) var(--c-t1)/1.5 var(--c-label);
  letter-spacing:var(--c-label-track);text-transform:var(--c-label-case);margin:0;
  letter-spacing:var(--c-track);max-width:34ch}
/* open right now — a dot and the sentence, the same answer the footer gives */
:is(#clay-page,#design-sheets) .c-now{display:flex;align-items:center;gap:calc(var(--c-u)*1.5);margin:0;
  font:600 var(--c-t1)/1.4 var(--c-body);color:var(--c-soft)}
:is(#clay-page,#design-sheets) .c-now i{width:8px;height:8px;border-radius:999px;flex:0 0 auto;
  background:color-mix(in oklab,currentColor 45%,transparent)}
:is(#clay-page,#design-sheets) .c-now.c-on{color:var(--c-ink)}
:is(#clay-page,#design-sheets) .c-now.c-on i{background:#2fbf6b}
:is(#clay-page,#design-sheets) .c-g-ink .c-now.c-on,:is(#clay-page,#design-sheets) .c-g-accent .c-now.c-on{color:inherit}
:is(#clay-page,#design-sheets) .c-page-lead + .c-band{border-top:0}
:is(#clay-page,#design-sheets) .c-fact{display:flex;flex-direction:column;gap:calc(var(--c-u)*.5)}
/* `inherit`, NOT `--c-ink`. A fact's number was pinned to the page's ink, so on the one band a
   design turns dark it was near-black on near-black — the number invisible and its label under it
   readable, which reads as a layout that failed to load. Everything else on a band takes the
   band's colour; this was the one thing that did not. */
:is(#clay-page,#design-sheets) .c-fact b{font:var(--c-weight) var(--c-t4)/1 var(--c-display);color:inherit}
:is(#clay-page,#design-sheets) .c-fact span{font:var(--c-t1)/1.3 var(--c-body);color:var(--c-soft)}
:is(#clay-page,#design-sheets) .c-sub{font:600 var(--c-t3)/1.2 var(--c-display);margin:calc(var(--c-u)*5) 0 calc(var(--c-u)*2)}
:is(#clay-page,#design-sheets) .c-fine{font:var(--c-t1)/1.5 var(--c-body);color:var(--c-soft);margin:calc(var(--c-u)*2) 0 0}
/* a small line under a centred band — the attribution on the reviews, sitting with the button
   rather than hanging off the left edge under whichever quote came first */
:is(#clay-page,#design-sheets) .c-fine.c-mid{text-align:center}

/* A CENTRED BAND CENTRES ITS HEADING. The questions are read, not admired: `c-in-mid` sets
   `text-align:center` on the whole band, so every answer came out centred under a left-aligned
   question — which is what "some faqs are centered text..?" is. */
:is(#clay-page,#design-sheets) .c-asks{margin-top:calc(var(--c-u)*3);text-align:left}
/**
 * ENOUGH OF THEM AND THEY READ AS TWO COLUMNS — TWO, which is what this has always claimed.
 *
 * `auto-fit` with a 280px minimum is not two columns, it is "as many as fit", and on a 1400px
 * measure that is four: six questions came out as four columns one line tall, which reads as a
 * row of labels rather than a set of questions. The block asked for two and the browser answered.
 *
 * The same shape as the capped grid — the larger of the minimum and half the measure — so two is
 * the most it can ever be, and one is what it becomes when there is not room for two.
 */
:is(#clay-page,#design-sheets) .c-asks-two{display:grid;column-gap:calc(var(--c-u)*5);
  grid-template-columns:repeat(auto-fit,minmax(max(280px,calc((100% - var(--c-u)*5) / 2)),1fr))}
:is(#clay-page,#design-sheets) .c-ask{border-bottom:var(--c-bw) solid var(--c-line)}
:is(#clay-page,#design-sheets) .c-ask summary{cursor:pointer;list-style:none;padding:calc(var(--c-u)*2) 0;
  font:var(--c-weight) var(--c-d2)/1.3 var(--c-display);text-transform:var(--c-case);
  letter-spacing:var(--c-track);display:flex;justify-content:space-between;gap:var(--c-u)}
:is(#clay-page,#design-sheets) .c-ask summary::-webkit-details-marker{display:none}
:is(#clay-page,#design-sheets) .c-ask summary::after{content:"+";font-weight:400;opacity:.5}
:is(#clay-page,#design-sheets) .c-ask[open] summary::after{content:"–"}
:is(#clay-page,#design-sheets) .c-ask .c-line{padding-bottom:calc(var(--c-u)*3);max-width:64ch}
/* A RUN OF QUESTIONS ABOUT ONE THING — the questions page, under the feature each set belongs to.
   The heading uses the same `c-sub` every other run-of-writing does; what this adds is the space
   between one run and the next, and no space above the first (the band's head already paid it). */
:is(#clay-page,#design-sheets) .c-ask-set{text-align:left}
:is(#clay-page,#design-sheets) .c-ask-set + .c-ask-set{margin-top:calc(var(--c-u)*5)}
:is(#clay-page,#design-sheets) .c-ask-set > .c-sub{margin-top:calc(var(--c-u)*4)}
:is(#clay-page,#design-sheets) .c-ask-set:first-child > .c-sub{margin-top:calc(var(--c-u)*3)}
:is(#clay-page,#design-sheets) .c-ask-set .c-asks{margin-top:calc(var(--c-u)*1.5)}

/* ============================================================================================
   THE LIBRARY'S SHAPES — `l-…`

   Every rule here belongs to a shape in lib/designs/library.js, which is the /wireframe catalogue
   ported to real data. They are LAYOUT: where things go, in tokens, with no colour and no size of
   their own. A theme reaches them by stating a taste, never by naming them.

   `c-…` is a component — a row, a card, a field — shared by every shape. `l-…` is one shape's own
   arrangement of them.

   AND THE GRID GOES ON `> .c-in`. `band()` wraps what it is given in `.c-in` (the measure and the
   gutter) unless the shape asked to be bare, so a grid written on the shape itself lays out ONE
   child and every column silently collapses to a stack. It looks exactly like the shape ignoring
   its own rule.
   ========================================================================================== */

/**
 * AND THE SHEET IS A CONTAINER OF ITS OWN.
 *
 * `#design-sheets` is a sibling of the page, fixed over the whole window, so a shape inside it
 * measured the WINDOW and a basket in an 980px sheet on a 1600px screen never reached its narrow
 * arrangement — the two columns stayed side by side in a box half that wide. The sheet itself is
 * the container, named `page` like the page is, so every `@container page` rule in this file means
 * the same thing in both places and no shape needs a second answer for being in an overlay.
 */
:is(#clay-page,#design-sheets) .sheet{container-type:inline-size;container-name:page}

/* ── the sheet layer ── it comes UP from the bottom, like every sheet on a phone ────────────
 *
 * A SHEET IS NOT A DIALOG. Both themes positioned their own: fixed, centred, floating in the
 * middle of the screen — which is a desktop alert box, and it is what everything that is not a
 * phone app looks like. A sheet slides up from the edge your thumb is already at, it is as wide as
 * the screen, and it stays attached to that edge. The editor's own panels do exactly this; the
 * sites they build did not.
 *
 * IT IS HERE, ONCE. Geometry is never a theme's — a theme states paper, ink, border and shadow, and
 * two themes each positioning the same overlay is two descriptions of one behaviour, which is the
 * whole disease this layer was rebuilt to end.
 */
/**
 * THE PAGE UNDER IT DOES NOT MOVE.
 *
 * A sheet takes the screen, and a screen that still scrolls behind it is two things moving at once
 * under one finger: you drag the basket and the shop slides past behind it. `overscroll-behavior`
 * on the sheet stops the CHAIN once the sheet has been scrolled to its end; it does nothing about
 * a drag that starts on the veil, which is most of the screen.
 *
 * `overflow:hidden` ALONE IS NOT A LOCK. It is the answer on a desktop and it is ignored on a
 * phone: iOS Safari scrolls the document anyway, so on the device where a sheet is most of the
 * product, the whole page went on sliding under it. The lock that actually holds is taking the
 * body out of the flow — and that loses your place, so the client puts the offset on as `top` and
 * scrolls back to it on the way out. See `lock()` in design-client.js; without it this rule is
 * still correct, it simply pins the page at the top instead of where you were.
 */
body.sheet-open{position:fixed;left:0;right:0;width:100%;overflow:hidden;overscroll-behavior:none}
/* THE EDITOR'S PANEL TAKES THE RIGHT OF THE SCREEN, and a fixed layer has to move out of its way
   or it opens underneath it. One theme knew this and the other did not — which is exactly the kind
   of thing a layer is for. Owner-only: `panel-open` is the editor's class and no visitor has it. */
body.panel-open :is(#clay-page,#design-sheets) .sheet-host{right:min(380px,92vw)}
:is(#clay-page,#design-sheets) .sheet-host{position:fixed;inset:0;z-index:80}
:is(#clay-page,#design-sheets) .sheet-veil{position:fixed;inset:0;display:flex;align-items:flex-end;
  justify-content:center;overflow:hidden;padding:0}
/* ONE PADDING, NAMED, because the sticky head has to cancel it to reach both edges and a second
   copy of the number is a head that stops short of the corner on one screen size. */
:is(#clay-page,#design-sheets) .sheet{--c-sheet-pad:var(--c-gut);
  width:100%;max-width:min(920px, 100%);margin:0;
  max-height:92svh;overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;
  border-radius:var(--c-r) var(--c-r) 0 0;
  padding:0 var(--c-sheet-pad) calc(var(--c-u)*4);
  animation:c-sheet-up .26s cubic-bezier(.22,.8,.3,1)}
/* THE GRAB HANDLE — it says which way this thing moves before anybody touches it. Drawn by the
   layer rather than by any sheet, so no drawing has to remember it. */
:is(#clay-page,#design-sheets) .sheet::before{content:"";display:block;width:calc(var(--c-u)*5);height:4px;
  border-radius:999px;background:var(--c-line);margin:calc(var(--c-u)*1.5) auto 0}
/**
 * THE WAY OUT NEVER SCROLLS AWAY.
 *
 * A basket with nine things in it, or a menu with sixty, put the Close button a screen and a half
 * above wherever you were reading — so the way out of a thing that covers the screen was the one
 * thing you could not see. The editor's own panels have always pinned their head; the sites they
 * build did not.
 *
 * `background:inherit` rather than a colour: the sheet is painted by the theme (and the photo
 * viewer is painted differently from the rest), so the head takes whatever the sheet it is in is
 * wearing and no theme has to state this twice.
 */
:is(#clay-page,#design-sheets) .sheet-head{position:sticky;top:0;z-index:3;background:inherit;
  margin-inline:calc(var(--c-sheet-pad) * -1);
  padding:calc(var(--c-u)*2) var(--c-sheet-pad)}
@keyframes c-sheet-up{from{transform:translateY(12%);opacity:.6}to{transform:none;opacity:1}}
/* ON A WIDE SCREEN it still comes from the bottom and still touches it — it simply stops being
   the whole width, because a form 1600px wide is a form nobody can read a line of. */
@media (min-width:940px){
  :is(#clay-page,#design-sheets) .sheet{--c-sheet-pad:calc(var(--c-u)*5)}
}
@media (prefers-reduced-motion:reduce){
  :is(#clay-page,#design-sheets) .sheet{animation:none}
}

/* ── header/beside ── words on the floor of the narrow column, the picture beside them ────── */
:is(#clay-page,#design-sheets) .l-hero > .c-in{display:grid;grid-template-columns:5fr 7fr;
  gap:calc(var(--c-u)*5);align-items:stretch}
/**
 * THE WORDS ARE CENTRED AGAINST THE PICTURE — R10, and this is the example the rule was written
 * from: text one side, image the other, the text block always centred vertically against it.
 *
 * They stood on the floor of the column. Beside a picture that is most of the screen tall, "on the
 * floor" is at the bottom of the screen: the name of the business was the last thing on the first
 * screenful instead of the first. The alignment belongs to the arrangement — no theme can move it,
 * so no theme can break it.
 */
:is(#clay-page,#design-sheets) .l-hero-w{display:flex;flex-direction:column;justify-content:center;
  padding-block:calc(var(--c-u)*3)}
/* AND A CEILING OF ITS OWN, lower than the page's. A hero is the one band where the whole point is
   that the words next to it are read without scrolling, so it stops short of a screenful rather
   than filling one. `height:100%` alone let the row — which this box was itself setting — decide. */
/* AND IT IS THE COLUMN. `aspect-ratio` with a definite height gives a definite WIDTH, so the
   picture came out narrower than the half of the page it was in and sat against the words with a
   third of the band empty to the right of it — the band is drawn edge to edge and the photograph
   stopped 290px short of the edge. Both dimensions definite means the ratio steps aside and
   `object-fit:cover` does the cropping, which is what it is there for. */
:is(#clay-page,#design-sheets) .l-hero-p .c-media{width:100%;height:100%;
  min-height:min(48svh,520px);max-height:min(68svh,720px)}
:is(#clay-page,#design-sheets) .l-hero-solo > .c-in{grid-template-columns:1fr}
@container (max-width:820px){
  :is(#clay-page,#design-sheets) .l-hero > .c-in{grid-template-columns:1fr}
  :is(#clay-page,#design-sheets) .l-hero-p .c-media{min-height:0}
}

/* ── does/cards ── one way in is a split: its words one half, its picture the other ────── */
:is(#clay-page,#design-sheets) .l-does-one > .c-in{display:grid;grid-template-columns:1fr 1fr;
  gap:calc(var(--c-u)*5);align-items:center}
@container page (max-width:760px){
  :is(#clay-page,#design-sheets) .l-does-one > .c-in{grid-template-columns:1fr} }

/* ── menu/courses ── the strip, then the courses two across ─────────────────────────────────
   COLUMNS, NOT A GRID. Two grid columns put each course in a cell of the same height as the one
   beside it, so Wine (two lines) held a hole open the depth of Mains (six) and a menu read as a
   page with things missing from it. A menu is a column of courses that happens to be poured into
   two — which is what `columns` is, and what every printed menu does. */
:is(#clay-page,#design-sheets) .l-courses{columns:2;column-gap:calc(var(--c-u)*5);
  margin-top:calc(var(--c-u)*3)}
/* a course is never split across the fold of the two columns */
:is(#clay-page,#design-sheets) .l-course{break-inside:avoid;-webkit-column-break-inside:avoid;
  margin-bottom:calc(var(--c-u)*4)}
:is(#clay-page,#design-sheets) .l-course .c-head{margin-bottom:calc(var(--c-u)*1.5)}
/**
 * A COURSE HEADING IS A HEADING.
 *
 * It was set at step 2 — the same size as the dish names under it and as their descriptions — so
 * "Mains" and "Nasi Campur" were the same size and the menu read as one long list with the odd
 * word in it. Two steps down from a page heading, one step up from a dish: it is smaller than the
 * page's own title because it is inside it, and bigger than a row because it names a set of them.
 */
:is(#clay-page,#design-sheets) .l-course .c-title{font-size:var(--c-t4)}
@container (max-width:760px){ :is(#clay-page,#design-sheets) .l-courses{columns:1} }

/* ── reviews/proof ── the score one side, the way out the other, quotes beneath ───────────── */
:is(#clay-page,#design-sheets) .l-proof > .c-in{display:block}
:is(#clay-page,#design-sheets) .l-proof-h{display:flex;justify-content:space-between;align-items:flex-end;
  gap:calc(var(--c-u)*3);flex-wrap:wrap;margin-bottom:calc(var(--c-u)*3)}
:is(#clay-page,#design-sheets) .l-proof-h .c-title{margin:0;font-size:var(--c-t4)}
/* the score is the FACT beside the heading, not the heading — see reviews/proof */
:is(#clay-page,#design-sheets) .l-proof-s{margin:calc(var(--c-u)*1) 0 0;
  font:var(--c-weight) var(--c-d4)/1 var(--c-display);color:var(--c-ink);
  display:flex;align-items:center;gap:calc(var(--c-u)*1.5)}
/* the stars beside a display-sized number are set to the type, not to it */
:is(#clay-page,#design-sheets) .l-proof-s .c-stars{font-size:var(--c-t3)}
:is(#clay-page,#design-sheets) .l-proof-h .c-line{margin:calc(var(--c-u)*.5) 0 0}

/* ── about/beside ── half words, half picture, centred against each other ─────────────────── */
:is(#clay-page,#design-sheets) .l-about > .c-in{display:grid;grid-template-columns:1fr 1fr;
  gap:calc(var(--c-u)*5);align-items:center}
:is(#clay-page,#design-sheets) .l-facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(110px,1fr));
  gap:calc(var(--c-u)*3);margin-top:calc(var(--c-u)*3)}
:is(#clay-page,#design-sheets) .l-facts .c-fact .c-title{margin:0;font-size:var(--c-t3)}
@container (max-width:760px){ :is(#clay-page,#design-sheets) .l-about > .c-in{grid-template-columns:1fr} }

/* ── aboutPage/story ── the story beside one picture, the writing, the people ───────────────
   The parts stack down the page with air between them; only the top half is two columns, and the
   writing keeps the MEASURE rather than the band's width — a paragraph the width of a desk is a
   paragraph nobody reaches the end of a line of. */
:is(#clay-page,#design-sheets) .l-story{display:grid;grid-template-columns:1fr 1fr;
  gap:calc(var(--c-u)*5);align-items:center}
:is(#clay-page,#design-sheets) .l-story-w{max-width:var(--c-measure)}
:is(#clay-page,#design-sheets) .l-story-more{display:grid;grid-template-columns:4fr 8fr;
  gap:calc(var(--c-u)*5);align-items:start;margin-top:calc(var(--c-u)*7)}
:is(#clay-page,#design-sheets) .l-story-t{max-width:var(--c-measure);display:grid;
  gap:calc(var(--c-u)*1.5)}
:is(#clay-page,#design-sheets) .l-story-t .c-title + .c-line{margin-top:0}
:is(#clay-page,#design-sheets) .l-story-t .c-line + .c-title{margin-top:calc(var(--c-u)*2)}
:is(#clay-page,#design-sheets) .l-story-p{margin-top:calc(var(--c-u)*7)}
:is(#clay-page,#design-sheets) .l-faces{--c-min:180px;--c-rail:62%;margin-top:calc(var(--c-u)*2)}
:is(#clay-page,#design-sheets) .l-story-pics{display:grid;
  grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:calc(var(--c-u)*2);
  margin-top:calc(var(--c-u)*7)}
@container page (max-width:760px){
  :is(#clay-page,#design-sheets) .l-story,
  :is(#clay-page,#design-sheets) .l-story-more{grid-template-columns:1fr}
}


/* ── asks/beside ── the heading narrow, the answers wide ──────────────────────────────────── */
:is(#clay-page,#design-sheets) .l-asks > .c-in{display:grid;grid-template-columns:4fr 8fr;
  gap:calc(var(--c-u)*5);align-items:start}
:is(#clay-page,#design-sheets) .l-asks-h .c-acts{margin-top:calc(var(--c-u)*2)}
/* A RUN WITH NO HEADING KEEPS THE ANSWERS' COLUMN. The questions page leads with the general ones
   — the run that is about the business rather than about one thing it does — and those wear no
   heading. As the only child of the grid they landed in the 4fr column: the first six answers on
   the page were a third the width of the rest of them, and did not line up with any of them. */
:is(#clay-page,#design-sheets) .l-asks > .c-in > :only-child{grid-column:2}
/* CONSECUTIVE RUNS ARE ONE PAGE, NOT SIX SECTIONS. One run is one band so that no band carries
   two headings at the same level — but six bands is six bands' worth of rhythm, which on a
   business with two questions per feature is a screen of air per answer. A run that follows a run
   opens where the last one closed. */
:is(#clay-page,#design-sheets) .l-asks + .l-asks{padding-top:0}
@container (max-width:760px){ :is(#clay-page,#design-sheets) .l-asks > .c-in{grid-template-columns:1fr}
  :is(#clay-page,#design-sheets) .l-asks > .c-in > :only-child{grid-column:auto} }

/* ── capture/beside ── the reason, then the form ──────────────────────────────────────────── */
:is(#clay-page,#design-sheets) .l-capture > .c-in{display:grid;grid-template-columns:5fr 7fr;
  gap:calc(var(--c-u)*5);align-items:start}
@container (max-width:760px){ :is(#clay-page,#design-sheets) .l-capture > .c-in{grid-template-columns:1fr} }

/* ── visit/map ── the map, and where you are ──────────────────────────────────────────────── */
:is(#clay-page,#design-sheets) .l-visit > .c-in{display:grid;grid-template-columns:1fr 1fr;
  gap:calc(var(--c-u)*5);align-items:start}
@container (max-width:760px){ :is(#clay-page,#design-sheets) .l-visit > .c-in{grid-template-columns:1fr} }

/* ── nav/bar ── the mark at one end, everything else clustered at the other ───────────────── */
/* THE BAR SPANS THE SCREEN AND ITS CONTENTS DO NOT. A sticky bar's ground has to reach both
   edges; what is written on it belongs in the same column as the page under it. */
:is(#clay-page,#design-sheets) .l-nav{position:sticky;top:0;z-index:40;--g:var(--c-paper);background:var(--g);color:var(--c-ink);
  border-bottom:var(--c-band-rule,var(--c-bw)) solid var(--c-line);padding:0}
:is(#clay-page,#design-sheets) .l-nav-in{width:var(--c-page);margin-inline:auto;min-height:var(--c-bar);
  display:flex;align-items:center;gap:calc(var(--c-u)*2)}
/* AND ROOM FOR THE GEAR WHILE THEY ARE EDITING. The band's own settings button is pinned to the
   right of the bar, and on a phone that is exactly where the menu control is — so the owner's own
   site had two round buttons on top of each other. Only while they are editing; a visitor's bar
   runs to the edge of the column like everything else. */
/* …AND PREVIEW IS NOT EDITING. `body.preview` takes every gear off the page — the rule beside
   `.band-gear` says so — but the room reserved for one stayed, so the menu, the basket and the
   button sat a gear's width in from the edge with nothing there. Preview is what the owner checks
   their own bar against, and it was the one place the bar was never right. */
body[data-owner]:not(.preview) :is(#clay-page,#design-sheets) .l-nav-in{padding-inline-end:calc(var(--c-u)*7)}
:is(#clay-page,#design-sheets) .l-mark{font:var(--c-weight) var(--c-t2)/1 var(--c-display);
  letter-spacing:var(--c-track);color:inherit;text-decoration:none;white-space:nowrap;
  display:flex;align-items:center}
/**
 * THE MARK PUSHES, AND EVERYTHING ELSE FOLLOWS IT TO THE RIGHT.
 *
 * The auto margin used to be on the LINKS, with a rule taking it off the controls whenever the
 * links were present. On a phone the links are `display:none` — which does not stop them being a
 * sibling — so the controls kept the "links are here" answer, nothing pushed them anywhere, and
 * the basket, the button and the menu all bunched against the logo with the right half of the bar
 * empty. Put on the mark it is true in all three cases: links and controls, controls alone, links
 * alone.
 */
:is(#clay-page,#design-sheets) .l-nav .l-mark{margin-inline-end:auto}
:is(#clay-page,#design-sheets) .l-mark img{height:calc(var(--c-u)*5);width:auto;display:block}
/* THE ROWS AND THE CONTROLS TRAVEL TOGETHER. Loose children of a space-between bar put the gaps
   between THEM, which marooned the basket in the middle of the bar a hand's width from the
   button beside it. */
:is(#clay-page,#design-sheets) .l-nav-l{display:flex;gap:calc(var(--c-u)*3);align-items:center;min-width:0}
:is(#clay-page,#design-sheets) .l-nav-l a{font:600 var(--c-t1)/1 var(--c-body);color:inherit;text-decoration:none;
  white-space:nowrap;padding:calc(var(--c-u)*.5) 0;border-bottom:var(--c-bw) solid transparent;
  /* THE LINKS, and only the links — see --c-nav-dim. The mark and the action are the bar's other
     two things and neither of them stands back. */
  opacity:var(--c-nav-dim);transition:opacity .15s}
:is(#clay-page,#design-sheets) .l-nav-l a:hover{border-bottom-color:var(--c-accent);opacity:1}
:is(#clay-page,#design-sheets) .l-nav-e{display:flex;align-items:center;gap:calc(var(--c-u)*1.5)}
/* ONE HEIGHT FOR EVERYTHING IN THE BAR — the basket was a circle beside a button whose height
   came from its padding, so nothing in the row lined up with anything else. */
:is(#clay-page,#design-sheets) .l-nav .c-act,:is(#clay-page,#design-sheets) .l-cart,:is(#clay-page,#design-sheets) .l-burger{height:42px;min-height:42px;
  box-sizing:border-box}
:is(#clay-page,#design-sheets) .l-cart,:is(#clay-page,#design-sheets) .l-burger{width:42px;display:grid;place-items:center;padding:0;
  background:none;color:inherit;cursor:pointer;border-radius:999px;
  border:var(--c-bw) solid currentColor}
:is(#clay-page,#design-sheets) .l-cart[hidden],:is(#clay-page,#design-sheets) .l-burger[hidden]{display:none}
:is(#clay-page,#design-sheets) .l-cart .ico,:is(#clay-page,#design-sheets) .l-burger .ico{width:18px;height:18px;display:grid;
  place-items:center}
:is(#clay-page,#design-sheets) .l-cart .ico svg,:is(#clay-page,#design-sheets) .l-burger .ico svg{width:100%;height:100%}
:is(#clay-page,#design-sheets) .l-cart b{font:var(--c-weight) var(--c-t0)/1 var(--c-display);margin-inline-start:2px}
:is(#clay-page,#design-sheets) .l-burger{display:none}
/* THE DRAWER IS A SHEET — the layer above says where it sits, how it arrives and what the page
   behind it does. All that is left here is how its rows are set. */
:is(#clay-page,#design-sheets) .l-nav-rows{display:flex;flex-direction:column;gap:calc(var(--c-u)*1.5)}
/* THE ROWS, and only the rows. Written as "every anchor in the drawer" it also caught the site's
   one ACTION at the end of it and set `color:inherit` — so the button kept its own ground and lost
   its own ink, and on a dark theme it was a white block with white writing on it. */
:is(#clay-page,#design-sheets) .l-nav-rows a{font:var(--c-weight) var(--c-t2)/1.1 var(--c-display);
  letter-spacing:var(--c-track);color:inherit;text-decoration:none}
/* FOUR LINKS AT 390px IS FOUR TRUNCATED WORDS. The way around goes behind the menu control and
   the space buys a legible mark and a reachable action. */
@container page (max-width:820px){
  :is(#clay-page,#design-sheets) .l-nav-l{display:none}
  :is(#clay-page,#design-sheets) .l-burger{display:grid}
}

/* ── footer/two ── the business one side, every way to reach them the other ───────────────── */
/* THE FOOTER STATES ITS GROUND, it does not merely paint one.
   It painted `--c-flip` — the contrast ground, which on a light page is nearly black — and left
   every neutral inside it at the page's. So on a light theme the sign-up's overline, its line and
   the copyright were dark text on a dark footer: 1.66:1, on every page of every site on that
   theme. It happened to look right on a dark theme, which is why it survived. `--g` plus the
   selector list above is the whole mechanism; the footer simply was not in it. */
:is(#clay-page,#design-sheets) .l-foot{--g:var(--c-flip);background:var(--g);color:var(--c-flip-ink);
  padding:calc(var(--c-rhythm)*.8) 0 calc(var(--c-u)*4)}
:is(#clay-page,#design-sheets) .l-foot-in{width:var(--c-page);margin:0 auto;display:grid;
  grid-template-columns:5fr 7fr;gap:calc(var(--c-u)*5);align-items:start}
:is(#clay-page,#design-sheets) .l-fcols{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  gap:calc(var(--c-u)*4)}
:is(#clay-page,#design-sheets) .l-fcol{display:flex;flex-direction:column;gap:calc(var(--c-u)*1.5);
  align-items:flex-start}
:is(#clay-page,#design-sheets) .l-fc-t{font:var(--c-label-weight) var(--c-t0)/1 var(--c-display);
  text-transform:var(--c-label-case);letter-spacing:var(--c-label-track);opacity:.62}
:is(#clay-page,#design-sheets) .l-fcol a{font:400 var(--c-t1)/1.3 var(--c-body);color:inherit;text-decoration:none;
  border-bottom:2px solid transparent}
:is(#clay-page,#design-sheets) .l-fcol a:hover{border-bottom-color:var(--c-accent)}
:is(#clay-page,#design-sheets) .l-sign{display:grid;gap:calc(var(--c-u)*1.5);margin-top:calc(var(--c-u)*2);width:100%}
:is(#clay-page,#design-sheets) .l-sign-f{display:flex;flex-wrap:wrap;gap:calc(var(--c-u)*1.5);align-items:end}
:is(#clay-page,#design-sheets) .l-sign-f .c-field{flex:1 1 150px;min-width:0}
/**
 * …AND THE BUTTON IS AS TALL AS THE BOXES IT STANDS IN A ROW WITH.
 *
 * `Subscribe` is a `c-act-compact` — the small button, set at the caption step with tight padding,
 * which is right in a card and wrong here: measured in the footer, two 56px inputs with a 35px
 * button sitting on their baseline, twenty-one pixels short. It is not a small button next to
 * some boxes, it is the third control in a row of three.
 *
 * So it takes the FIELD's measurements rather than a height of its own: the same vertical padding,
 * the same type step, the same line, and a transparent border of the field's own width, because a
 * theme with a 3px field border (chunky) makes its inputs 6px taller than a borderless button
 * padded identically. Nothing here is a number — change the field and the button follows.
 */
:is(#clay-page,#design-sheets) .l-sign-f > .c-act{
  font:var(--c-act-weight) var(--c-t2)/1.4 var(--c-act-font);
  padding-block:var(--c-field-pad-y);
  border:var(--c-field-bw) solid transparent;border-bottom-width:var(--c-field-bw-b)}
/* THE RULE ABOVE THE FINE PRINT IS A RULE, and every rule on this site is `--c-line`. It was
   `currentColor` — full-strength ink — so on a dark page the faintest separator on the page came
   out as the brightest line on it, at the very bottom, on every page. */
:is(#clay-page,#design-sheets) .l-foot-f{width:var(--c-page);margin:calc(var(--c-u)*5) auto 0;
  padding-top:calc(var(--c-u)*3);border-top:var(--c-bw) solid var(--c-line)}
@container page (max-width:760px){ :is(#clay-page,#design-sheets) .l-foot-in{grid-template-columns:1fr} }

/* ── cart/two ── the things one side, what it comes to the other ──────────────────────────── */
/* `l-basket`, not `l-cart` — that one is the BUTTON in the bar, and a class doing two jobs is
   how a rule for one silently reshapes the other. */
:is(#clay-page,#design-sheets) .l-basket{display:grid;grid-template-columns:7fr 5fr;gap:calc(var(--c-u)*4);
  align-items:start}
:is(#clay-page,#design-sheets) .l-basket-s{display:grid;gap:calc(var(--c-u)*1.5)}
@container page (max-width:760px){ :is(#clay-page,#design-sheets) .l-basket{grid-template-columns:1fr} }

/* ── product/pdp ── the pictures one half, what you decide with the other ─────────────────── */
:is(#clay-page,#design-sheets) .l-pdp{display:grid;grid-template-columns:7fr 5fr;gap:calc(var(--c-u)*4);
  align-items:start}
:is(#clay-page,#design-sheets) .l-pdp-w{display:grid;gap:calc(var(--c-u)*2);align-content:start}
:is(#clay-page,#design-sheets) .l-pdp-t{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);
  gap:calc(var(--c-u)*1.5);margin-top:calc(var(--c-u)*1.5)}
/* NO PICTURE, NO COLUMN FOR ONE — a product with no photographs is one column of words, not one
   column of words beside an empty square. */
:is(#clay-page,#design-sheets) .l-pdp-solo{grid-template-columns:1fr}
@container page (max-width:760px){ :is(#clay-page,#design-sheets) .l-pdp{grid-template-columns:1fr} }

/* the rest of the shop under a product — a class, because a shape may not write a size */
:is(#clay-page,#design-sheets) .l-others{--c-min:200px}

/* A THUMBNAIL SWAPS THE BIG PICTURE and says so before it is pressed; the one showing is opaque
   and the rest step back, which is the only state this control has. */
:is(#clay-page,#design-sheets) .l-pdp-t .c-media{cursor:pointer;opacity:.55;transition:opacity .15s}
:is(#clay-page,#design-sheets) .l-pdp-t .c-media.on,
:is(#clay-page,#design-sheets) .l-pdp-t .c-media:hover{opacity:1}
/* ONE CHOICE, ONE ROW. The name of the choice sits over its values rather than beside them, so a
   product with four options is four bands of the same shape and not a table that reflows. */
:is(#clay-page,#design-sheets) .c-opt{display:grid;gap:calc(var(--c-u)*1)}
:is(#clay-page,#design-sheets) .c-opt + .c-opt{margin-top:calc(var(--c-u)*2)}

/* ── viewer/one ── auto · 1fr · auto, and the middle column is the point ──────────────────── */
:is(#clay-page,#design-sheets) .l-view{display:grid;gap:calc(var(--c-u)*2)}
:is(#clay-page,#design-sheets) .l-view-h{display:flex;justify-content:space-between;align-items:center}
:is(#clay-page,#design-sheets) .l-view-r{display:grid;grid-template-columns:auto 1fr auto;gap:calc(var(--c-u)*1.5);
  align-items:center}
:is(#clay-page,#design-sheets) .l-view-t{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);
  gap:calc(var(--c-u)*1)}

/* ── bar/bottom ── a phone design; the desktop bar never left the screen ──────────────────── */
:is(#clay-page,#design-sheets) .l-bar{position:fixed;left:0;right:0;bottom:0;z-index:50;display:none;
  align-items:center;justify-content:space-between;gap:calc(var(--c-u)*1.5);
  padding:calc(var(--c-u)*1.5) calc(var(--c-gut)/2);background:var(--c-paper);color:var(--c-ink);
  border-top:var(--c-bw) solid var(--c-line)}
:is(#clay-page,#design-sheets) .l-bar .c-act{flex:1 1 auto;justify-content:center}
/* nothing to say yet — the client fills it in when the page has a state (a total, a slot) */
:is(#clay-page,#design-sheets) .l-bar .c-fine[hidden]{display:none}
@container page (max-width:820px){
  :is(#clay-page,#design-sheets) .l-bar{display:flex}
  /* AND ROOM UNDER THE PAGE FOR IT. A bar fixed over the last band covers the last band — on
     every page, and the last thing on most of them is the footer's own links. */
  #clay-page:has(.l-bar) .l-foot{padding-bottom:calc(var(--c-u)*11)}
}

/* ── badge ── OUR mark on somebody else's site, and not a theme's to design ───────────────── */
/**
 * THE BADGE IS THE SAME OBJECT ON EVERY THEME, for the same reason the owner's gear is: it is not
 * part of anybody's design. It is Clay saying who made this, on a page that belongs to a business,
 * and it has to be legible and out of the way on every theme that will ever exist — including the
 * ones nobody has written yet.
 *
 * It was described THREE times instead. `site.css` (the bento editor's stylesheet, which a
 * designed page also loads) centres it at the bottom; chunky's theme pins it bottom-right and
 * sizes the mark; bold carries a rule whose whole job is undoing site.css. Three descriptions, and
 * the two faults they produced were exactly the two you get from three descriptions:
 *
 *   · THE WORDMARK WAS SQUASHED. `Clay.site` is a 385×120 drawing and chunky gave it a
 *     `1.15em × 1.15em` box, so it fitted by WIDTH and rendered a third as tall — measured, a 13px
 *     square holding artwork 13 wide and 4 high. Beside "Made with" at 11px it read as a smudge.
 *     Height and auto width: the mark keeps its own proportions and matches the words next to it.
 *
 *   · IT SAT ON TOP OF THE BOTTOM BAR. The bar is fixed to the bottom of a phone and carries the
 *     page's one action; the badge was fixed 14px above the bottom, which is inside it. Measured
 *     on BOTH themes, not just the one the card was written about. The footer already steps aside
 *     for the bar by exactly this much — same number, one place it comes from.
 */
:is(#clay-page,#design-sheets) .qck-badge{position:fixed;z-index:55;
  right:calc(var(--c-gut) / 2);bottom:calc(var(--c-u)*2);left:auto;transform:none;
  display:inline-flex;align-items:center;gap:calc(var(--c-u));width:max-content;
  max-width:calc(100% - var(--c-gut));height:auto;white-space:nowrap;text-decoration:none;
  font:var(--c-label-weight) var(--c-t0)/1 var(--c-body);letter-spacing:0;
  padding:calc(var(--c-u)) calc(var(--c-u)*1.5);border:0;border-radius:999px;
  background:var(--c-flip);color:var(--c-flip-ink);
  -webkit-backdrop-filter:none;backdrop-filter:none;
  box-shadow:0 4px 14px rgba(0,0,0,.2)}
:is(#clay-page,#design-sheets) .qck-badge .qb-tx{opacity:.85}
/* THE MARK KEEPS ITS SHAPE. It arrives as whatever the server hands over — an svg today — so the
   wrapper is told to be a line box and the drawing is told its HEIGHT only. A width as well is how
   a wordmark ends up a third of its size inside a square. */
:is(#clay-page,#design-sheets) .qck-badge .qb-mark{display:inline-flex;align-items:center;flex:0 0 auto}
:is(#clay-page,#design-sheets) .qck-badge .qb-mark svg{height:1.25em;width:auto;display:block}
/* AND IT STEPS OVER THE BAR, by the same allowance the footer uses — see `bar/bottom` above. */
@container page (max-width:820px){
  #clay-page:has(.l-bar) .qck-badge{bottom:calc(var(--c-u)*11 + var(--c-u)*2)}
}
/* …AND OUT FROM UNDER THE OWNER'S PANEL. An editing owner never sees the badge at all (the rule
   beside the gear), but a previewing one can have the Design panel open beside the page — and the
   panel takes the right of the screen, which is the corner the badge is now in. */
body.panel-open :is(#clay-page,#design-sheets) .qck-badge{
  right:calc(min(380px, 92vw) + var(--c-gut) / 2)}

/* ── text/toc ── the contents one side, the writing the other ─────────────────────────────── */
:is(#clay-page,#design-sheets) .l-text > .c-in{display:grid;grid-template-columns:4fr 8fr;gap:calc(var(--c-u)*5);
  align-items:start}
:is(#clay-page,#design-sheets) .l-toc{position:sticky;top:calc(var(--c-bar) + var(--c-u)*2);display:grid;
  gap:calc(var(--c-u)*1.5)}
/* A CONTENTS LIST IS NOT A SET OF HEADINGS. `row()` sets a name at the display size, which is
   right in a menu and wrong here: beside the document it points at, every entry came out as loud
   as the heading it names, and the page read as two columns of headings. It is a list of places to
   go — body size, and the ink says which is a link. */
:is(#clay-page,#design-sheets) .l-toc .c-row-n{font:var(--c-t2)/var(--c-body-h) var(--c-body);
  text-transform:none;letter-spacing:normal;color:var(--c-soft)}
:is(#clay-page,#design-sheets) .l-toc .c-row-n:hover{color:var(--c-ink)}
:is(#clay-page,#design-sheets) .l-toc .c-row{padding-block:calc(var(--c-u))}
@container page (max-width:760px){
  :is(#clay-page,#design-sheets) .l-text > .c-in{grid-template-columns:1fr}
  :is(#clay-page,#design-sheets) .l-toc{position:static}
}

/* ── signin · manage · states ── small, one job each ──────────────────────────────────────── */
:is(#clay-page,#design-sheets) .l-signin,:is(#clay-page,#design-sheets) .l-manage{display:grid;gap:calc(var(--c-u)*2);
  max-width:var(--c-cap-max,46ch)}
:is(#clay-page,#design-sheets) .l-states{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));
  gap:calc(var(--c-u)*3)}
:is(#clay-page,#design-sheets) .l-state{display:grid;gap:calc(var(--c-u)*1.5);align-content:start}
:is(#clay-page,#design-sheets) .l-state .c-title{font-size:var(--c-t3);margin:0}

/* ── visitPage/many ── each branch its own ────────────────────────────────────────────────── */
:is(#clay-page,#design-sheets) .l-places{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));
  gap:calc(var(--c-u)*5)}
:is(#clay-page,#design-sheets) .l-place{display:grid;gap:calc(var(--c-u)*1.5);align-content:start}

/* ── bookingPage/three ── what · when · what time, all at once ────────────────────────────── */
:is(#clay-page,#design-sheets) .l-book{display:grid;grid-template-columns:4fr 5fr 3fr;gap:calc(var(--c-u)*4);
  align-items:start}
:is(#clay-page,#design-sheets) .l-book .l-step{min-width:0}
/**
 * A STEP IN A COLUMN IS ALWAYS OPEN.
 *
 * `.c-step-b` is `display:none` until the client marks its step `.on` — right for the SHEET, where
 * the three are a walk and only one is answered at a time. Side by side they are not a walk: the
 * page opened with a month, a list of times and a form that were all in the document and all
 * hidden, so the whole booking page read as three headings, three rules and nothing under them.
 * The `.on` class still marks where you are; here it no longer decides whether the column exists.
 */
/**
 * NO ECHO WHERE THE ANSWER IS ALREADY ON THE SCREEN.
 *
 * `data-chosen` is what a CLOSED step says about itself — it is how a phone's accordion tells you
 * what you picked three steps ago. Side by side with every step open it printed the chosen service
 * beside the word "Service", the ISO date beside "Day" and the time beside "Time", each of them
 * directly above the thing it was repeating.
 */
:is(#clay-page,#design-sheets) .l-book .c-step-v{display:none}
:is(#clay-page,#design-sheets) .l-book .c-step-h{cursor:default}
:is(#clay-page,#design-sheets) .l-book .c-step-b,
:is(#clay-page,#design-sheets) .l-book-who .c-step-b{display:block}
/* THE DETAILS LIVE IN THE THIRD COLUMN NOW — where the times were, so the flow does not jump
   somewhere else at the last step. It is as wide as its column and no wider. */
:is(#clay-page,#design-sheets) .l-book-who{max-width:100%}
:is(#clay-page,#design-sheets) .l-book-who .c-form{grid-template-columns:1fr}
/* ON A PHONE IT IS A WALK AGAIN. Three columns at 390px is three slivers, and the whole reason
   the walk exists is that a month, forty times and five fields at once is a wall. */
@container page (max-width:900px){ :is(#clay-page,#design-sheets) .l-book{grid-template-columns:1fr} }

/* ── the breadcrumb ── one step back, never a map of a site two levels deep ───────────────── */
/* ITS OWN STRIP, AGAINST THE BAR. A band's rhythm is for a band; the line that says where you are
   is chrome, and it belongs a couple of units under the navigation rather than a screenful. The
   band below it opens as it always did, so the page keeps its rhythm from the heading down. */
:is(#clay-page,#design-sheets) .l-crumbs{padding:calc(var(--c-u)*3) 0 0}
:is(#clay-page,#design-sheets) .l-crumbs + .c-band{padding-top:calc(var(--c-u)*3)}
:is(#clay-page,#design-sheets) .l-crumbs + .c-band{border-top:0}
:is(#clay-page,#design-sheets) .l-crumb{display:flex;gap:calc(var(--c-u));align-items:center;
  margin-bottom:0;font:var(--c-t0)/1 var(--c-body);color:var(--c-soft);
  letter-spacing:var(--c-label-track);text-transform:var(--c-label-case);flex-wrap:wrap}
:is(#clay-page,#design-sheets) .l-crumb a{color:inherit;text-decoration:none;
  border-bottom:var(--c-bw) solid currentColor}
:is(#clay-page,#design-sheets) .l-crumb b{color:var(--c-ink);font-weight:inherit}

/* ── pagehead/beside ── the words, and the feature's own picture beside them ──────────────── */
:is(#clay-page,#design-sheets) .l-phead > .c-in{display:grid;grid-template-columns:7fr 5fr;
  gap:calc(var(--c-u)*5);align-items:center}
@container (max-width:760px){ :is(#clay-page,#design-sheets) .l-phead > .c-in{grid-template-columns:1fr} }

/* the street, under the heading rather than as one — see visit/map in the library */
/* AN ADDRESS IS NEVER SHOUTED. `text-transform` inherits, so a street sitting inside a head that
   uppercases its overline came out as JL. RAYA PENGOSEKAN UBUD NO.108, KECAMATAN UBUD — which is
   two lines of capitals nobody can read and, worse, is not how the street is written. It is said
   explicitly here rather than left to whatever it happens to sit inside. */
:is(#clay-page,#design-sheets) .c-place-a{font:var(--c-t2)/var(--c-body-h) var(--c-body);color:var(--c-ink);
  text-transform:none;letter-spacing:normal;
  margin:calc(var(--c-u)*1) 0 0;max-width:40ch}

/* ── close/centre ── the last thing on the page, and the narrowest ────────────────────────── */
:is(#clay-page,#design-sheets) .l-close > .c-in{max-width:var(--c-cap-max,52ch)}

/**
 * ── THE RAIL ── on a phone, a row of cards scrolls sideways. One rule, four rows.
 *
 * Stacked, four of anything is four screens of scrolling before the page starts again — and the
 * photographs, the ways in, the quotations and the faces are all rows a visitor takes in at a
 * glance rather than reads. One at a time, snapping, the next one peeking so the gesture is
 * obvious: what a phone already means.
 *
 * THREE COPIES OF THIS EXISTED, one under each of the first three rows, and the fourth row (the
 * people, on the story page) had none — so the team stacked into a column of portraits while
 * everything above and below it scrolled. Three hand-written copies of one behaviour do not stay
 * the same: they had three different bleed rules and two of them had no `padding-bottom`.
 *
 * A row states how wide ONE card is (`--c-rail`) and nothing else. Everything here is the rail.
 *
 * `overflow-x` on the row only: the PAGE must never scroll sideways (scripts/check-overflow).
 */
@container (max-width:560px){
  :is(#clay-page,#design-sheets) :is(.c-strip,.c-does,.c-grid.c-quotes,.l-faces){
    display:grid;grid-auto-flow:column;grid-template-columns:none;grid-template-rows:none;
    grid-auto-columns:var(--c-rail,78%);
    overflow-x:auto;overscroll-behavior-x:contain;scroll-snap-type:x mandatory;
    scrollbar-width:none;padding-bottom:var(--c-u);
    margin-inline:calc(var(--c-gut) / -2);padding-inline:calc(var(--c-gut) / 2);
    /**
     * AND THE SNAP RESPECTS THE GUTTER, which is the half that was missing.
     *
     * The bleed and its compensating padding are a pair (see the chips), and on a SNAPPING rail
     * they are not enough on their own: `scroll-snap-align:start` snaps an item to the scrollport,
     * whose start is the padding edge, so the browser quietly scrolled the rail right by exactly
     * the padding it had just been given. Measured: padding 10px, `scrollLeft` 10, first card
     * resting at x=0 with the heading above it at x=10.
     *
     * `scroll-padding` is what moves the snapport itself. Same number as the padding, from the
     * same token, so the card the rail settles on lines up with the words above it.
     */
    scroll-padding-inline:calc(var(--c-gut) / 2)}
  :is(#clay-page,#design-sheets) :is(.c-strip,.c-does,.c-grid.c-quotes,.l-faces)::-webkit-scrollbar{display:none}
  :is(#clay-page,#design-sheets) :is(.c-strip,.c-does,.c-grid.c-quotes,.l-faces) > *{scroll-snap-align:start}
  /* ONE OF ANYTHING HAS NOTHING TO SCROLL TO, so it is simply the width of the band. Stated once
     here rather than three times: one of the three said it with `:has`, one with an attribute
     selector on an inline custom property, and one did not say it at all. */
  :is(#clay-page,#design-sheets) :is(.c-strip,.c-does,.c-grid.c-quotes,.l-faces):not(:has(> * + *)){
    grid-auto-columns:100%}
  /**
   * AND WHERE A SET IS GENUINELY STACKED, AN EMPTY FRAME PROTECTS NOTHING.
   *
   * `card()` keeps the frame of a picture that has not arrived so a row of cards still lines up —
   * see the note beside `slot` in parts.js. That reasoning is about a ROW: the name sits at the
   * top of one card and under a photograph on the two beside it, and the row reads as broken.
   *
   * On a phone a plain grid is one card per row, so there is nothing beside it and nothing to line
   * up with — and the frame becomes a blank block the height of the screen between two products.
   * The rails above are the exception and are excluded by the same names: they put three cards
   * side by side on a phone, which is a row, which is where the frame earns its place.
   *
   * Measured rather than assumed: every grid here is one per row at 560px and two or more at 600.
   */
  :is(#clay-page,#design-sheets) .c-grid:not(:is(.c-strip,.c-does,.c-quotes,.l-faces)) .c-card > .c-media:empty{display:none}
}

/* ── footer/two ── where else this business is, under its name ────────────────────────────── */
/* MARKS, NOT WORDS. Nobody scans "Instagram, Facebook, TikTok" as a list; they look for the mark.
   Sized off the same scale as everything else, and the row wraps rather than pushing the column. */
:is(#clay-page,#design-sheets) .l-social{display:flex;flex-wrap:wrap;gap:calc(var(--c-u)*1.5);
  margin-top:calc(var(--c-u)*2)}
:is(#clay-page,#design-sheets) .l-social a{display:grid;place-items:center;width:calc(var(--c-u)*5);
  height:calc(var(--c-u)*5);border-radius:999px;color:inherit;text-decoration:none;
  border:var(--c-bw) solid var(--c-line);transition:border-color .14s ease,opacity .14s ease}
:is(#clay-page,#design-sheets) .l-social a:hover{border-color:var(--c-accent)}
:is(#clay-page,#design-sheets) .l-social .ico{width:18px;height:18px;display:grid;place-items:center}
:is(#clay-page,#design-sheets) .l-social .ico svg{width:100%;height:100%}
