/* ============================================================
   The rest of the chrome, in dialkit's language.

   dialkit is a controls library: sliders, toggles, colours, selects. It has no
   app bar, no dock, no layer list, no gallery — so those cannot *be* dialkit,
   and the panel was ending up as a well-dressed stranger in the middle of a
   window built to other rules. This file settles the argument the other way:
   the chrome takes dialkit's shapes, sizes and fills, so the panel stops being
   the odd one out by everything else joining it.

   Loaded last, after each tool's own stylesheet, because it is deliberately
   overriding decisions those files made.

   The four things that actually differed, measured against
   `vendor/dialkit/dialkit.css`:

     radius   dialkit is 8px everywhere; the chrome was pills (9999px) on every
              button and dock. This is the single loudest difference — a pill
              beside a rounded rectangle reads as two design systems, before
              any colour is considered.
     height   36px rows against the chrome's 40px buttons.
     fill     a translucent wash over the surface (4% black, 5% white) rather
              than an opaque grey step. It is what makes dialkit's rows sit
              *in* the panel rather than on it, and it costs nothing to adopt
              because it works over any background.
     type     13px, and numbers in a monospace so a column of readouts lines
              up on the decimal point.
   ============================================================ */

:root {
  /* dialkit's own, restated in our namespace so the chrome and the panel are
     reading the same numbers rather than two sets that happen to agree. */
  --dk-radius: 8px;
  --dk-row: 36px;
  --dk-gap: 6px;

  --dk-fill: rgba(0, 0, 0, 0.04);
  --dk-fill-hover: rgba(0, 0, 0, 0.08);
  --dk-fill-active: rgba(0, 0, 0, 0.1);
  --dk-line: rgba(0, 0, 0, 0.1);
  --dk-line-hover: rgba(0, 0, 0, 0.15);

  --dk-ink: rgba(0, 0, 0, 0.9);
  --dk-ink-label: rgba(0, 0, 0, 0.6);
  --dk-ink-quiet: rgba(0, 0, 0, 0.35);

  --dk-mono: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --dk-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 6.5 8 10 11.5 6.5'/%3E%3C/svg%3E");
}

/* The dark half, matched to dialkit's own dark values rather than derived from
   the light ones — an inverted alpha is not the same colour and reads muddier. */
:root[data-theme="dark"] {
  --dk-fill: rgba(255, 255, 255, 0.05);
  --dk-fill-hover: rgba(255, 255, 255, 0.1);
  --dk-fill-active: rgba(255, 255, 255, 0.11);
  --dk-line: rgba(255, 255, 255, 0.1);
  --dk-line-hover: rgba(255, 255, 255, 0.15);

  --dk-ink: rgba(255, 255, 255, 0.95);
  --dk-ink-label: rgba(255, 255, 255, 0.7);
  --dk-ink-quiet: rgba(255, 255, 255, 0.4);
}

/* ---------- buttons ---------- */

/* A rounded rectangle, not a pill, and a row tall rather than a chip tall. */
.md-button {
  height: var(--dk-row);
  border-radius: var(--dk-radius);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0;
  padding: 0 12px;
}
.md-button.has-icon { padding-inline: 10px 12px; gap: 6px; }

/* Filled, outlined and tonal collapse into two weights: a quiet wash for
   everything, and ink-on-surface for the one action a bar is actually for.
   Three weights of button in a toolbar is a hierarchy nobody is reading. */
.md-button--outlined,
.md-button--tonal {
  background: var(--dk-fill);
  color: var(--dk-ink);
  box-shadow: none;
}
.md-button--outlined:hover:not(:disabled),
.md-button--tonal:hover:not(:disabled) { background: var(--dk-fill-hover); }

.md-button--filled {
  background: var(--md-sys-color-on-surface);
  color: var(--md-sys-color-surface);
  border-radius: var(--dk-radius);
}

.md-button--text {
  background: none;
  color: var(--dk-ink-label);
  padding: 0 10px;
}
.md-button--text:hover:not(:disabled) { background: var(--dk-fill); color: var(--dk-ink); }

.md-icon-button,
.md-icon-button--small {
  border-radius: var(--dk-radius);
  color: var(--dk-ink-label);
}
.md-icon-button { width: var(--dk-row); height: var(--dk-row); }
.md-icon-button:hover:not(:disabled) { background: var(--dk-fill-hover); color: var(--dk-ink); }

/* The floating action button keeps its own shape: it is the one control that is
   meant to sit above the surface rather than in it. */

/* ---------- segmented controls, and the dock ---------- */

/* dialkit's own segmented control is a wash with a raised current option, so
   ours becomes that: no pill, no hairline, the selection carried by tone. */
.md-segmented,
.segmented {
  border-radius: var(--dk-radius);
  background: var(--dk-fill);
  padding: 3px;
  gap: 2px;
  /* No stroke. dialkit draws a group of options as a fill with the current one
     raised out of it, and never outlines the group — an inset hairline round a
     filled shape is two edges describing the same boundary. */
  box-shadow: none;
}
.md-segmented > button,
.segment {
  border-radius: calc(var(--dk-radius) - 3px);
  height: 30px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--dk-ink-label);
  border: none;
  background: none;
}
.md-segmented > button:hover,
.segment:hover:not(:disabled) { color: var(--dk-ink); }
.md-segmented > button[aria-pressed="true"],
.segment[data-on="true"] {
  background: var(--md-sys-color-surface);
  color: var(--dk-ink);
  box-shadow: none;
}

/* The dock and the hint chip float over the canvas, and both were carrying an
   inset hairline to stand off the picture behind them. The stroke goes with the
   others; what replaces it is a more opaque surface and dialkit's own backdrop
   blur, which separates them from a photograph better than a one-pixel line
   ever did — a hairline over a busy image is itself busy. */
.viewport-dock,
.viewport-hint {
  border-radius: var(--dk-radius);
  background: color-mix(in srgb, var(--md-sys-color-surface) 94%, transparent);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow: none;
}

/* ---------- headings ---------- */

/* dialkit titles a section in sentence case at 13px. The chrome was using 11px
   uppercase with a point of tracking, which is a different voice — louder and
   more clerical — and it was landing directly above dialkit's own titles. */
.group-title,
.field-label {
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--dk-ink-label);
}

/* ---------- numbers ---------- */

/* Monospace, so a column of readouts lines up and a value changing under the
   pointer does not shuffle the ones around it. */
.md-slider output,
.md-colour-value,
.gradient-where,
output {
  font-family: var(--dk-mono);
  font-size: 12px;
  color: var(--dk-ink-label);
}

/* ---------- inputs ---------- */

.md-select,
.md-colour-input {
  border-radius: var(--dk-radius);
  border-color: var(--dk-line);
  font-size: 13px;
}
.md-select:hover { border-color: var(--dk-line-hover); }

.md-chip { border-radius: var(--dk-radius); }
.md-dialog { border-radius: 12px; }
.md-snackbar { border-radius: var(--dk-radius); }

/* ---------- the panel is not a card ---------- */

/* dialkit's panel paints its own surface — `--dial-glass-bg`, a 1px border, a
   14px radius and a backdrop blur — because it is built to float over a page.
   Inline in a column that already has a surface, all of that is a second card
   inside the first: #212121 sitting on #131313 in dark, and the same story a
   shade apart in light. A panel within a panel, and the eye reads the seam
   before it reads the controls.
   
   So the card comes off and the rows sit on the column's own surface. The
   horizontal padding goes with it, or the rows would be indented from
   everything above and below them by twelve pixels for no reason. The vertical
   padding stays: that is the gap between the last heading and the first row.

   Dropdowns and popovers keep their own background, which they need — they are
   genuinely floating, which is the case this styling was written for. */
.dialkit-root .dialkit-panel-inner {
  background: none;
  border: none;
  border-radius: 0;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  padding-inline: 0;
}

/* ---------- one heading, one rule ---------- */

/* dialkit titles the panel and rules a line under it, then the first folder
   rules a line over itself — two hairlines four pixels apart, which is what
   the double divider was.
   
   The title is a duplicate as well. Every tool already heads this column:
   Mirrors says "Settings" above a panel dialkit also calls "Settings", Plinth
   says "Fine tuning" above "Fine tuning", Refract says "Glass" above "The
   glass". The panel's name is for a floating window that has to say what it
   belongs to; docked under a heading that already said it, it is the same word
   twice and a line nobody asked for.

   So the header goes, and the first folder's own rule becomes the only one. */
.dialkit-root .dialkit-panel-header { display: none; }

/* ---------- the last of the strokes ---------- */

/* Tabs and the small add buttons were drawing their edge with a hairline: an
   inset shadow on the selected tab, a real border on the buttons. Same
   substitution as everywhere else — the fill is the edge.

   Galleries are the deliberate exception below. */
.tab[data-on="true"] { box-shadow: none; }
.add-layer,
.layer-add {
  border: none;
  border-radius: var(--dk-radius);
  background: var(--dk-fill);
}
.add-layer:hover,
.layer-add:hover { background: var(--dk-fill-hover); }

/* A gallery keeps its ring, and it is not an oversight.
 *
 * Everywhere else the selected thing is marked by a fill, because everywhere
 * else the thing is a word on a panel. A gallery item is a photograph of your
 * own composition: a fill behind it is invisible, since the picture covers it.
 * The ring is the only mark that survives being laid over an image, which is
 * why every tool that shows pictures uses one. */

/* ---------- dropdowns ---------- */

/* dialkit draws a select as one filled row — label at the left, value and
   chevron at the right, no border, 36px tall, the same wash every other row
   uses. Ours was a label sitting beside a bordered box, which is the shape a
   form field has rather than the shape a panel row has, and it landed directly
   above dialkit's own selects.
   
   The row becomes the control: `.md-field` takes the fill and the height, and
   the select inside it goes transparent and right-aligns. Its chevron is drawn
   with two gradients rather than an icon, so it survives the background coming
   off — only the colour behind it changes. */
.md-field {
  height: var(--dk-row);
  min-height: var(--dk-row);
  padding: 0 12px;
  gap: 8px;
  border-radius: var(--dk-radius);
  background: var(--dk-fill);
  /* Set on the row, not just its parts, so anything added to it later inherits
     the panel's voice rather than the document's. */
  font-size: 13px;
  font-weight: 500;
}
.md-field:hover { background: var(--dk-fill-hover); }
.md-field > label {
  font-size: 13px;
  font-weight: 500;
  color: var(--dk-ink-label);
}

.md-select {
  flex: 1 1 auto;
  height: 100%;
  padding: 0 18px 0 0;
  border: none;
  border-radius: 0;
  background-color: transparent;
  color: var(--dk-ink-label);
  font-size: 13px;
  font-weight: 500;
  /* The value sits against the chevron on the right, the way dialkit's does,
     rather than against the label it is not part of. */
  text-align: right;
  text-align-last: right;
}
.md-select:hover { background-color: transparent; }
.md-select:focus-visible { outline: 2px solid var(--dk-ink); outline-offset: -2px; }

/* The chevron, rather than the triangle the platform select was wearing.
 *
 * Drawn as a mask filled with the row's own label colour, so it follows the
 * theme without a second copy of the file for dark — a background-image would
 * have to bake the stroke colour in, and there are two of those. Sitting after
 * the select as a flex item gives it dialkit's eight-pixel gap for free instead
 * of a background-position that has to be guessed against the padding. */
.md-select {
  appearance: none;
  -webkit-appearance: none;
  background-image: none;
  padding-right: 0;
}
.md-field::after {
  content: "";
  flex: none;
  width: 16px;
  height: 16px;
  background-color: var(--dk-ink-label);
  -webkit-mask: var(--dk-chevron) center / 16px 16px no-repeat;
  mask: var(--dk-chevron) center / 16px 16px no-repeat;
  pointer-events: none;
}

/* ---------- one rule, one colour, one width ---------- */

/* Two dividers a few rows apart were drawn by two different systems and agreed
   about nothing: ours in `outline-variant` at about a fifth opacity, dialkit's
   in its own `--dial-surface-subtle` at six per cent, and ours four pixels
   narrower because the host it sits in carries a negative side margin. Side by
   side that reads as one of them being a mistake.
   
   dialkit's is the quieter and the right one: a rule between groups is a hint
   that the list has parts, not a border. Ours takes its colour, and the host
   loses the negative margin so both run to the same edges. */
:root { --dk-line-subtle: rgba(0, 0, 0, 0.06); }
:root[data-theme="dark"] { --dk-line-subtle: rgba(255, 255, 255, 0.06); }

/* No rule above the section heading at all.
 *
 * It was marking the boundary between the things you point at and the numbers
 * you adjust, which the heading already says in words. With dialkit ruling
 * every group below it, one more line directly above the first of them was the
 * panel clearing its throat twice. Space does the same job and is quieter. */
.group-title--major {
  border-top: none;
  margin-top: 22px;
  padding-top: 0;
}

/* The host adds nothing of its own.
   
   It had 6px above and 2px below, and dialkit's panel a further 10px of block
   padding inside that — all of it left from when the panel was a floating card
   that needed breathing room inside its own border. Stacked on the column's own
   flex gap it put 36 pixels between the Corners control and the rule under it,
   where dialkit leaves 11 between one group of sliders and the next. The gap
   between groups is now the column's gap and nothing else, so a rule falls the
   same distance below whatever precedes it wherever it appears. */
.dial-host { margin: 0; }
.dialkit-root .dialkit-panel-inner { padding-block: 0; }

/* The last two millimetres of it.
 *
 * With the host's own margins gone the gap was 20px against dialkit's 11: the
 * segmented control's bottom margin and the first folder's top margin, both
 * added to the column's gap. Neither is doing anything the column gap is not
 * already doing, so both go and the gap between one group and the next is the
 * column's alone. */
/* No margins of its own, above or below.
 *
 * Above, it was holding the control eighteen pixels off its heading where
 * dialkit leaves about ten: a dialkit folder title is a 36px box with the text
 * centred in it and the first row starts at its exact bottom, so the gap you
 * see is half the leftover height and nothing else. Ours was that plus eight.
 * Below, it was adding to the column gap for no reason. Both go, and the
 * spacing is the column's. */
.md-segmented,
.segmented { margin-block: 0; }
.dialkit-root .dialkit-folder:first-child { margin-top: 0; }

/* ---------- the colour picker says one thing ---------- */

/* Hex, OKLCH and Display P3 are three ways of writing the colour you already
   picked, and the picker's plane and sliders are how anybody actually picks it.
   Two of the three are for somebody transcribing a value into code; the box at
   the bottom already shows the hex, which is the one people paste.
   
   The row goes rather than being narrowed, because a segmented control with one
   segment left is a button that does nothing. */
.dialkit-root .dialkit-color-format-row { display: none; }

/* ---------- the gradient: a colour at each end, and the ramp between ---------- */

/* dialkit has no gradient control, so this one is ours, and its anatomy is the
   colour slider's — label and output above, a track with a thumb at each end
   below. The track is the ramp; the thumbs are its two colours, round and
   FILLED with their own colour under a white ring, so you can see which
   colour you are about to edit before you click it. Click one and dialkit's
   picker opens — the thumb IS its swatch. They do not move and there is
   nothing to add between them. */
.gradient { display: flex; flex-direction: column; gap: 8px; }

.gradient-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 20px;
  padding: 0 2px;
}
.gradient-label {
  font-size: 13px;
  font-weight: 500;
  color: var(--dk-ink-label);
}
.gradient-out {
  font-family: var(--dk-mono);
  font-size: 13px;
  font-weight: 500;
  color: var(--dk-ink-label);
}

.gradient-bar {
  position: relative;
  width: 100%;
  height: 24px;
  border: none;
  border-radius: 999px;
  /* An inset hairline so a ramp that ends in the panel's own grey still has
     an edge. */
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
  /* Nothing to add: the classic bar offered a copy cursor, this one does not. */
  cursor: default;
}
:root[data-theme="dark"] .gradient-bar { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.12); }

.gradient-bar .gradient-stop {
  position: absolute;
  top: 50%;
  left: 0;
  width: 20px;
  height: 20px;
  transform: translate(-50%, -50%);
  /* The classic bar's stop was a tall lozenge with a dark border and a ring of
     surface around it. This one is a circle, and everything drawn is the
     swatch's, so the handle itself paints nothing — otherwise the lozenge's
     corners show behind the circle, most of all on the scaled selected stop. */
  margin: 0;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: none;
  box-shadow: none;
  cursor: pointer;
}

/* The mounted control is the thumb. Everything dialkit's colour row carries
   besides the swatch — its label, its hex field — is hidden; the head above
   is the label and the output. The swatch fills the thumb and shows its
   colour, which is what makes a stop legible over a ramp of the same colour. */
/* The swap, in the middle of the ramp: a small white disc like the stops'
   rings, with the glyph in ink, so it reads as part of the bar rather than
   as a button laid on it. */
.gradient-bar .gradient-swap {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 20px;
  height: 20px;
  margin: 0;
  padding: 0;
  transform: translate(-50%, -50%);
  display: grid;
  place-items: center;
  border: none;
  border-radius: 50%;
  background: #fff;
  color: rgba(0, 0, 0, 0.7);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2), 0 1px 3px rgba(0, 0, 0, 0.3);
  cursor: pointer;
}
.gradient-bar .gradient-swap:hover { color: #000; }
.gradient-bar .gradient-swap .md-icon { fill: currentColor; }

.gradient-stop .dialkit-color-label,
.gradient-stop .dialkit-color-value { display: none; }
.gradient-stop .dialkit-color-control,
.gradient-stop .dialkit-color-inputs {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  /* dialkit paints its colour row with the panel wash. Under a round swatch
     that box is a square, and its corners show past the circle. */
  background: none;
  border: none;
  border-radius: 50%;
  box-shadow: none;
}

.gradient-stop .dialkit-color-swatch {
  width: 100%;
  height: 100%;
  padding: 0;
  background: var(--dial-color);
  border: 2px solid #fff;
  border-radius: 50%;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2), 0 1px 3px rgba(0, 0, 0, 0.3);
  cursor: inherit;
  transition: none;
}
.gradient-stop .dialkit-color-swatch:hover { transform: none; }
.gradient-stop[data-on="true"] .dialkit-color-swatch {
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3), 0 2px 6px rgba(0, 0, 0, 0.35);
}

/* No opacity on a backdrop colour, whether it is one of a gradient's two ends
 * or the single colour of a solid one.
 *
 * The ramp is a list of opaque colours mixed in OKLab and normalise() throws
 * out anything that is not six digits, so the alpha is dropped on the way in —
 * which made the track a control you could drag from full to a quarter and
 * watch nothing happen. A backdrop that is meant to be transparent is Clear,
 * which is a choice in the gallery rather than a slider hidden in a popover.
 * The border's picker keeps its opacity, because there it does something.
 *
 * The second track, by position, because the tracks carry no name in the class:
 * hue first, opacity second. */
.gradient-stop .dialkit-color-tracks .dialkit-color-track-row:nth-child(2),
.solid-colour .dialkit-color-tracks .dialkit-color-track-row:nth-child(2) { display: none; }

/* ---------- a gallery's Show more ---------- */

/* A text button under the grid, in the label ink: an offer, not an action. */
.gallery-more {
  display: block;
  width: 100%;
  height: var(--dk-row);
  margin: 4px 0 0;
  padding: 0 12px;
  border: none;
  border-radius: var(--dk-radius);
  background: none;
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--dk-ink-label);
  text-align: center;
  cursor: pointer;
}
.gallery-more:hover { background: var(--dk-fill-hover); }

/* ---------- the pad ---------- */

/* The pad without its row of fields. dialkit puts a label and an x and a y
   box above the surface; here the surface is a picture of the frame and the
   dot says where the point is, so the row was three boxes restating the one
   thing you could already see. Two classes deep, because dialkit's own sheet
   loads after this one. */
.dialkit-root .dialkit-pad-fields { display: none; }


/* ---------- the layer card ---------- */

/* dialkit has no layer control — its whole list is sliders, toggles, colour,
   select, image, spring, easing, action, pad and text, plus folders and a
   timeline — so the stack is ours. What it can borrow is the language: the
   same wash, the same hairline, the same 8px radius and 13px label as every
   row in the panel beside it, rather than the Material surfaces and 16px
   corners this was built with while the rest of the tool moved on. */
.layers { gap: var(--dk-gap); }

.layer {
  padding: 8px;
  border: none;
  border-radius: var(--dk-radius);
  background: var(--dk-fill);
  column-gap: 10px;
  transition: background 0.15s, box-shadow 0.15s;
}
.layer:hover { background: var(--dk-fill-hover); }
/* The one being edited says so the way dialkit's open controls do: a little
   more fill and an inset hairline. A hard dark border was the only 2px line
   in the panel and read as an error state. */
.layer[data-on="true"] {
  background: var(--dk-fill-active);
  box-shadow: inset 0 0 0 1px var(--dk-line-hover);
}

/* Square, so a stack of cards reads as an even column whatever shape the
   pictures in them are; object-fit crops each to its middle. */
.layer-thumb,
.layer-add {
  width: 56px;
  height: 56px;
  border-radius: 6px;
}
/* The chequer under a picture that has transparency in it, which is what
   dialkit puts behind an image control's frame. */
.layer-thumb {
  background:
    repeating-conic-gradient(rgba(128, 128, 128, 0.18) 0% 25%, transparent 0% 50%) 0 / 12px 12px,
    var(--dk-fill);
  box-shadow: inset 0 0 0 1px var(--dk-line);
}
.layer-add {
  border-color: var(--dk-line-hover);
  color: var(--dk-ink-label);
}
.layer-add:hover {
  background: var(--dk-fill-hover);
  color: var(--dk-ink);
}

/* A row's label, at the panel's own size and weight. */
.layer-name {
  font-size: 13px;
  font-weight: 500;
  color: var(--dk-ink-label);
}
.layer[data-on="true"] .layer-name { color: var(--dk-ink); }
.layer-hint { color: var(--dk-ink-quiet); }

.layer-tool,
.layer-step {
  border-radius: 6px;
  color: var(--dk-ink-label);
}
.layer-tool:hover,
.layer-step:hover { background: var(--dk-fill-hover); color: var(--dk-ink); }
.layer-step { color: var(--dk-ink-quiet); }

/* The panel's own header buttons, which sit above the stack and were the last
   Material chips in the column. */
.add-layer {
  border-radius: 6px;
  color: var(--dk-ink-label);
}
.add-layer:hover { background: var(--dk-fill-hover); color: var(--dk-ink); }

/* ---------- one gap under every heading ---------- */

/* A heading sat further from a gallery than from a row of sliders — fifteen
   pixels against seven — because the column's own gap was being topped up by
   whatever came next: the gallery brought eight pixels of its own, the panel
   of sliders brought none. So a title looked attached to some of the things it
   titles and adrift above others.

   The column gap is now the whole of it. Everything a title can precede has no
   margin of its own, and the title's two margins bend the gap either side of
   it: a group is well separated from the one above, and its heading hugs what
   it names. */
.controls .group-title,
.controls .group-head {              /* a heading with an action against it */
  margin: 11px 0 -7px;               /* with the column's 11: 22 above, 4 below */
}
.controls .group-title:first-child,
.controls .group-head:first-child { margin-top: 0; }
.controls .group-head .group-title { margin: 0; }
.controls .gallery { margin: 0; }

/* The two that were not galleries: the row of frames and the light's grid.
   Both carried eight pixels of their own above, which put them fifteen from
   their heading where a gallery and a panel of sliders sit at four. */
.controls .frames,
.controls .light-grid { margin-top: 0; }


/* ---------- the backdrop swatches ---------- */

/* No name under them, so the tile is the swatch and its padding. */
.gallery-item--ground,
.gallery-item--gobo { gap: 0; }

/* Square from the first frame.
 *
 * A swatch canvas is created at the size of a composition preview and only
 * becomes square when the thumbnail pass reaches it, so every rebuild had the
 * gallery twenty pixels a row shorter for a moment and then taller again —
 * everything below it jumping up and back. The shape is the stylesheet's, so
 * it is right before anything is drawn into it. */
.gallery-item--gobo .gallery-thumb {
  max-height: none;
  width: 100%;
  aspect-ratio: 1;
}

/* The mark on a thumbnail a picture of it cannot explain. Bottom right, over
   the picture rather than beside it, in the panel's own ink with a little of
   the surface behind it so it reads on a photograph as well as on flat grey.

   The wrapper hugs the canvas — which is centred in its tile and can be
   narrower than it — so the corner the mark sits in is the picture's corner
   and not the tile's. */
.gallery-shot {
  position: relative;
  display: block;
  width: fit-content;
  max-width: 100%;
  margin-inline: auto;
}
.gallery-item--ground .gallery-shot { width: 100%; }
.gallery-badge {
  position: absolute;
  right: 7px;
  bottom: 7px;
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 6px;
  background: color-mix(in srgb, var(--md-sys-color-surface) 82%, transparent);
  color: var(--dk-ink);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  pointer-events: none;
}
.gallery-badge .md-icon { display: block; }
