/* 04-inspector.css - right-hand inspector.
   Rhythm: uppercase eyebrow, label column, hairline between sections. Never a
   card inside a card; the frame comes from the pane, the separation from rules.
   Every colour is a --hui-* token, so light and dark both follow the theme. */

/* The shell owns the scrolling `.hui-inspector` grid cell (02-shell.css);
   this is only the content root inside it. */
.hui-inspector {
  scrollbar-gutter: stable;
  /* Hidden CSS tooltips are absolutely positioned past the right edge of their
     trigger, which alone added ~60px of scrollWidth to the pane. Clipping the
     inline axis removes the phantom horizontal scroll without touching the
     vertical one. Everything that is actually a control fits the column. */
  overflow-x: clip;
}

.hui-inspector-pane {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.hui-inspector-body {
  display: flex;
  flex-direction: column;
  min-width: 0;
  /* No top padding: the sticky header owns it, so the header background reaches
     the top edge of the scrollport. */
  padding: 0 var(--hui-space-3) var(--hui-space-5);
}

/* ---------- fit rules ----------
   Nothing in the pane may size itself from its content. `arcane` inputs are
   flex children with the default `min-width: auto`, which pins them at the
   ~161px intrinsic width of a bare <input>; inside the 96px column of the
   x/y/z row that overflowed the pane by 75px and painted over the next field.
   These rules are the single place that guarantees a 300px pane fits. */

.hui-inspector-body *,
.hui-inspector-body *::before,
.hui-inspector-body *::after {
  box-sizing: border-box;
}

.hui-inspector-body :where(
    .hui-field,
    .hui-field-control,
    .hui-number,
    .hui-vec3 > *,
    .arcane-floating-trigger,
    .arcane-text-input-wrapper,
    .arcane-text-input-container,
    .arcane-textarea-wrapper,
    .arcane-select-wrapper
  ) {
  min-width: 0;
}

.hui-inspector-body :where(input, textarea, select) {
  min-width: 0;
  max-width: 100%;
}

/* The three axis fields are emitted with an inline `repeat(3, minmax(0, 1fr))`,
   which cannot wrap; `auto-fit` keeps three columns while they are usable and
   drops to two, then one, on a narrow pane instead of clipping z. */
.hui-inspector-body .hui-vec3 {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 78px), 1fr)) !important;
}

/* ---------- headers ---------- */

/* The header, the lede and the id disclosure are one widget but must be
   siblings in the scrolling body: `position: sticky` only holds for the height
   of its containing block, so a real wrapper box would let the header scroll
   away after ~120px. */
.hui-inspector-headgroup {
  display: contents;
}

/* Sticky so the type, the id and the destructive actions stay on screen while
   the body scrolls. The negative inline margin lets the background span the
   body padding, and the fill is the opaque twin of the pane's translucent one
   so nothing shows through. */
.hui-inspector-header {
  position: sticky;
  top: 0;
  z-index: 4;
  display: flex;
  flex-direction: column;
  gap: var(--hui-space-1);
  min-width: 0;
  margin: 0 calc(-1 * var(--hui-space-3));
  padding: var(--hui-space-2) var(--hui-space-3);
  border-bottom: 1px solid var(--hui-border-soft);
  background: color-mix(in srgb, var(--hui-panel-soft) 42%, var(--hui-bg));
}

.hui-inspector-header-top {
  display: flex;
  align-items: center;
  gap: var(--hui-space-2);
  min-width: 0;
}

/* The id input takes the slack between the type badge and the row tools. */
.hui-inspector-header-id {
  flex: 1 1 auto;
  min-width: 0;
}

.hui-inspector-header-actions {
  display: flex;
  align-items: center;
  gap: 2px;
  flex: 0 0 auto;
}

.hui-inspector-header-error {
  margin: 0;
  color: var(--hui-danger);
  font-size: 0.72rem;
  line-height: 1.45;
}

.hui-inspector-title {
  margin: 0;
  font-size: 0.98rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.15;
  min-width: 0;
  overflow-wrap: anywhere;
}

.hui-inspector-subtitle {
  margin: 0;
  color: var(--hui-muted);
  font-size: 0.72rem;
  line-height: 1.45;
  text-wrap: pretty;
}

/* One muted line under the sticky header, never inside it. */
.hui-inspector-lede {
  margin: 0;
  padding: var(--hui-space-2) 0 0;
  color: var(--hui-muted);
  font-size: 0.72rem;
  line-height: 1.45;
  text-wrap: pretty;
}

/* A disclosure that belongs to no section: same rhythm and hairline, no
   eyebrow. */
.hui-inspector-aside {
  min-width: 0;
  padding: 7px 0;
  border-bottom: 1px solid var(--hui-border-soft);
}

.hui-inspector-aside:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}

.hui-inspector-header-id.is-invalid .arcane-text-input,
.hui-inspector-header-id.is-invalid input {
  border-color: var(--hui-danger);
}

.hui-type-badge {
  display: inline-flex;
  align-items: center;
  min-height: 22px;
  padding: 0 9px;
  border: 1px solid var(--hui-border);
  border-radius: 999px;
  background: transparent;
  color: var(--hui-muted);
  font-size: 0.68rem;
  font-weight: 680;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  white-space: nowrap;
}

.hui-type-badge.is-button {
  border-color: color-mix(in srgb, var(--hui-accent) 55%, var(--hui-border));
  background: color-mix(in srgb, var(--hui-accent) 12%, transparent);
  color: var(--hui-text);
}

.hui-type-badge.is-toggle {
  border-color: color-mix(in srgb, var(--hui-info) 55%, var(--hui-border));
  background: color-mix(in srgb, var(--hui-info) 12%, transparent);
  color: var(--hui-text);
}

/* ---------- sections ----------
   Rhythm: 7px of air on each side of the hairline, so adjacent sections sit
   14px apart; fields inside a section sit 10px apart (the widget's gap). */

.hui-inspector-section {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
  padding: 7px 0;
  border-bottom: 1px solid var(--hui-border-soft);
}

.hui-inspector-body > .hui-inspector-section:first-of-type {
  padding-top: var(--hui-space-2);
}

/* Only the last block in the pane drops its rule. A section that is merely the
   last child of a wrapper (the icon editor, the toggle icon tabs) still needs
   its hairline, or it runs into whatever follows the wrapper. */
.hui-inspector-body > .hui-inspector-section:last-child,
.hui-inspector-body > :last-child .hui-inspector-section:last-of-type {
  border-bottom: 0;
  padding-bottom: 0;
}

.hui-inspector-section-note {
  margin: -2px 0 0;
  color: var(--hui-muted);
  font-size: 0.72rem;
  line-height: 1.45;
  text-wrap: pretty;
}

/* Nested sections (the icon editor inside the toggle icon tabs) drop the rule
   so two hairlines never stack. */
.hui-inspector-section .hui-inspector-section {
  border-bottom: 0;
  padding: 0;
}

.hui-count-chip,
.hui-unit-chip {
  display: inline-flex;
  align-items: center;
  min-height: 22px;
  padding: 0 8px;
  border: 1px solid var(--hui-border-soft);
  border-radius: 999px;
  color: var(--hui-muted);
  font-size: 0.7rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---------- notes, details, issues ---------- */

.hui-note + .hui-note {
  margin-top: 2px;
}

.hui-detail-row + .hui-detail-row {
  border-top: 1px solid var(--hui-border-soft);
}

.hui-inline-issue::before {
  content: "";
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-right: 6px;
  border-radius: 50%;
  background: currentColor;
  vertical-align: middle;
}

.hui-field.is-invalid .arcane-input,
.hui-field.is-invalid input,
.hui-field.is-invalid textarea {
  border-color: var(--hui-danger);
}

.hui-inline-check {
  display: inline-flex;
  align-items: center;
}

/* ---------- controls ---------- */

.hui-segmented {
  min-width: 0;
}

/* The renderer emits `display: inline-flex` inline, so the segments were forced
   onto one nowrap row: five of them (`Text | Image | Animated | Item | Custom`)
   need ~540px and the labels painted over each other in a 300px pane. A grid
   that auto-fits at the width of the widest label wraps to further rows
   instead, and never clips. `!important` is the only way past the inline
   declaration. */
.hui-segmented .arcane-toggle-group {
  display: grid !important;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 112px), 1fr));
  justify-content: stretch;
  width: 100%;
  min-width: 0;
}

.hui-segmented .arcane-toggle-group-item {
  min-width: 0;
}

.hui-segment-inner {
  min-width: 0;
}

/* Tooltips are absolutely positioned and centred on their trigger, so a
   right-hand control pushes them past the pane edge. Narrowing and wrapping
   them inside the inspector keeps the hint readable in the column it belongs
   to; the first and last cell of a wrapped row anchor to their own edge. */
.hui-inspector .arcane-css-tooltip-content {
  max-width: 210px !important;
  white-space: normal !important;
  text-align: left;
}

.hui-inspector .hui-vec3 > *:first-child .arcane-css-tooltip-content,
.hui-inspector .hui-segmented .arcane-toggle-group > *:first-child
  .arcane-css-tooltip-content {
  left: 0 !important;
  right: auto !important;
  transform: translateY(-4px) !important;
}

.hui-inspector .hui-vec3 > *:last-child .arcane-css-tooltip-content,
.hui-inspector .hui-segmented .arcane-toggle-group > *:last-child
  .arcane-css-tooltip-content,
/* Row tools and header actions always sit against the right edge. */
.hui-inspector .hui-inspector-header-actions .arcane-css-tooltip-content,
.hui-inspector .hui-inspector-section-trailing .arcane-css-tooltip-content,
.hui-inspector .hui-field-trailing .arcane-css-tooltip-content,
.hui-inspector .hui-row-tools .arcane-css-tooltip-content,
/* The range row's reset button is the last thing in its row, so its hidden
   tooltip hangs past the pane and adds ~25px of phantom scrollWidth per row —
   the same effect the header comment describes, and the same fix. */
.hui-inspector .hui-slider-field .arcane-css-tooltip-content {
  left: auto !important;
  right: 0 !important;
  transform: translateY(-4px) !important;
}

/* One column is unreadable for a track: below this the number field and the
   reset keep their own row under it rather than squeezing the track to nothing. */
@media (max-width: 420px) {
  .hui-slider-field {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ---------- demoted help ----------
   Secondary text is one muted line. `HuiField` writes its help style inline, so
   the demotion has to out-rank it. Anything longer than a line belongs in a
   `.hui-more` disclosure, closed by default.

   Element-qualified: `HuiField`'s help line is a <p> and `HuiFieldHelp`'s
   popover root is a <span>, and they share the class name. Without the tag the
   font-size below would shrink the help button's icon. */

.hui-inspector p.hui-field-help {
  margin-top: 4px !important;
  color: var(--hui-muted) !important;
  font-size: 0.72rem !important;
  line-height: 1.45 !important;
}

.hui-inspector .hui-field-error {
  margin-top: 4px !important;
  font-size: 0.72rem !important;
  line-height: 1.45 !important;
}

.hui-inspector .hui-switch-row-help,
.hui-inspector .hui-switch-row-warning {
  font-size: 0.72rem !important;
  line-height: 1.45 !important;
}

/* ---------- collapsed detail ---------- */

.hui-more {
  min-width: 0;
}

/* The `#arcane-root` prefix is load-bearing, not decoration: the framework's
   own base sheet is id-prefixed, so a plain class selector loses the cascade on
   colour and transform. `!important` covers the declarations the renderer
   writes inline (summary padding and gap, chevron font-size). */
#arcane-root .hui-more > summary {
  gap: 8px !important;
  padding: 3px 0 !important;
  font-size: 0.72rem;
  font-weight: 620;
  border-radius: var(--hui-radius);
  transition: color var(--hui-transition);
}

#arcane-root .hui-more > summary::-webkit-details-marker {
  display: none;
}

/* The label and the chevron carry the colour themselves: the framework pins the
   summary element to a fixed grey that does not follow the light theme, and a
   colour set on our own span is not in that fight. */
#arcane-root .hui-more .hui-more-summary,
#arcane-root .hui-more .arcane-disclosure-chevron {
  color: var(--hui-muted) !important;
}

#arcane-root .hui-more > summary:hover .hui-more-summary,
#arcane-root .hui-more[open] > summary .hui-more-summary,
#arcane-root .hui-more > summary:hover .arcane-disclosure-chevron,
#arcane-root .hui-more[open] > summary .arcane-disclosure-chevron {
  color: var(--hui-text) !important;
}

#arcane-root .hui-more > summary:focus-visible {
  outline: 2px solid var(--hui-ring);
  outline-offset: 2px;
}

#arcane-root .hui-more .arcane-disclosure-chevron {
  font-size: 0.5rem !important;
  transition: transform var(--hui-transition);
}

#arcane-root .hui-more[open] .arcane-disclosure-chevron {
  transform: rotate(180deg) !important;
}

#arcane-root .hui-more > .arcane-disclosure-content {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
  padding: 4px 0 2px !important;
}

.hui-row-tools button {
  color: var(--hui-muted);
}

.hui-row-tools button:hover:not(:disabled) {
  color: var(--hui-text);
}

/* ---------- minecraft text editor ---------- */

.hui-text-editor {
  display: flex;
  flex-direction: column;
  gap: var(--hui-space-3);
  min-width: 0;
}

.hui-text-editor-control {
  display: flex;
  flex-direction: column;
  gap: var(--hui-space-1);
  min-width: 0;
}

.hui-text-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  min-width: 0;
}

.hui-text-tag,
.hui-text-color {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 26px;
  padding: 0 8px;
  border: 1px solid var(--hui-border);
  border-radius: var(--hui-radius);
  background: transparent;
  color: var(--hui-muted);
  font: inherit;
  font-size: 0.72rem;
  font-weight: 580;
  cursor: pointer;
  transition: color var(--hui-transition), border-color var(--hui-transition),
    background-color var(--hui-transition);
}

.hui-text-tag:hover,
.hui-text-color:hover,
.hui-text-tag:focus-visible {
  color: var(--hui-text);
  border-color: color-mix(in srgb, var(--hui-accent) 55%, var(--hui-border));
  background: color-mix(in srgb, var(--hui-accent) 10%, transparent);
  outline: none;
}

.hui-text-color-input {
  width: 22px;
  height: 18px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.hui-text-color-input::-webkit-color-swatch-wrapper {
  padding: 0;
}

.hui-text-color-input::-webkit-color-swatch {
  border: 1px solid var(--hui-border);
  border-radius: 3px;
}

.hui-text-preview-block {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

/* Dark plate with a faint checker so transparent-looking text still reads, and
   so the preview never pretends the game has a text background (it has none). */
.hui-mc-preview-surface {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: 10px 12px;
  border: 1px solid var(--hui-border-soft);
  border-radius: var(--hui-radius);
  background:
    linear-gradient(
      color-mix(in srgb, var(--hui-bg) 78%, #000),
      color-mix(in srgb, var(--hui-bg) 78%, #000)
    ),
    conic-gradient(
      from 45deg,
      color-mix(in srgb, var(--hui-border) 40%, transparent) 0 25%,
      transparent 0 50%
    );
  background-size: auto, 12px 12px;
  overflow-x: auto;
}

.hui-mc-line {
  font-family: var(--hui-mc-font);
  font-size: 0.92rem;
  line-height: 1.35;
  white-space: pre;
  text-shadow: 1px 1px 0 rgb(0 0 0 / 0.55);
}

.hui-mc-line.is-empty {
  color: var(--hui-muted);
  font-family: inherit;
  font-size: 0.74rem;
  text-shadow: none;
}

.hui-mc-span.is-obfuscated {
  animation: hui-mc-flicker 260ms steps(2, end) infinite alternate;
}

@keyframes hui-mc-flicker {
  from {
    opacity: 1;
    letter-spacing: 0;
  }
  to {
    opacity: 0.62;
    letter-spacing: 0.5px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hui-mc-span.is-obfuscated {
    animation: none;
    opacity: 0.72;
  }
}

.hui-mc-preview-metrics {
  margin: 0;
  color: var(--hui-muted);
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
}

.hui-mc-preview-warnings {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin: 0;
  padding: 0;
  list-style: none;
  color: var(--hui-warning);
  font-size: 0.72rem;
  line-height: 1.4;
}

/* ---------- image library ---------- */

.hui-image-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: 6px;
  min-width: 0;
  max-height: 220px;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.hui-image-tile {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 4px;
  min-width: 0;
  padding: 6px;
  border: 1px solid var(--hui-border-soft);
  border-radius: var(--hui-radius);
  background: transparent;
  color: var(--hui-muted);
  font: inherit;
  text-align: left;
  cursor: pointer;
  /* Carries the shared --hui-lift affordance: this is the one grid in the pane
     where the target is the artwork rather than a label, so a border change
     alone under-reads. Safe to transform — a tile is a plain button with no
     fixed-position descendant (06-motion.css rule 3). */
  transition:
    transform var(--hui-dur-2) var(--hui-ease-out),
    border-color var(--hui-dur-2) var(--hui-ease-out),
    background-color var(--hui-dur-2) var(--hui-ease-out);
}

.hui-image-tile:hover,
.hui-image-tile:focus-visible {
  border-color: var(--hui-ring);
  outline: none;
  transform: translate3d(0, calc(var(--hui-lift) * -1), 0);
}

/* After the hover rule so a press beats it. */
.hui-image-tile:active {
  transform: translate3d(0, 0, 0) scale(0.99);
}

.hui-image-tile.is-selected {
  border-color: var(--hui-accent);
  background: color-mix(in srgb, var(--hui-accent) 8%, transparent);
  color: var(--hui-text);
}

.hui-image-tile-frame {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 52px;
  border-radius: 4px;
  background: conic-gradient(
    from 45deg,
    color-mix(in srgb, var(--hui-border) 55%, transparent) 0 25%,
    transparent 0 50%
  );
  background-size: 10px 10px;
  overflow: hidden;
}

.hui-image-tile-img {
  max-width: 100%;
  max-height: 48px;
}

.hui-image-tile-path {
  font-size: 0.68rem;
  font-weight: 600;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

.hui-image-tile-size {
  font-size: 0.66rem;
  font-variant-numeric: tabular-nums;
  opacity: 0.75;
}

.hui-image-upload {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
  margin-top: 6px;
}

.hui-image-upload-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: var(--hui-control-height);
  padding: 0 12px;
  border: 1px dashed var(--hui-border);
  border-radius: var(--hui-radius);
  color: var(--hui-muted);
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
  transition: color var(--hui-transition), border-color var(--hui-transition),
    background-color var(--hui-transition);
}

.hui-image-upload-button:hover,
.hui-image-upload-button:focus-within {
  color: var(--hui-text);
  border-color: color-mix(in srgb, var(--hui-accent) 55%, var(--hui-border));
  background: color-mix(in srgb, var(--hui-accent) 8%, transparent);
}

.hui-image-upload-button.is-busy {
  opacity: 0.6;
  cursor: progress;
}

.hui-image-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 96px;
  padding: 8px;
  border: 1px solid var(--hui-border-soft);
  border-radius: var(--hui-radius);
  background: conic-gradient(
    from 45deg,
    color-mix(in srgb, var(--hui-border) 55%, transparent) 0 25%,
    transparent 0 50%
  );
  background-size: 12px 12px;
}

.hui-image-preview img {
  max-width: 100%;
  max-height: 160px;
}

/* ---------- animated frames ---------- */

.hui-animated-preview {
  display: flex;
  align-items: center;
  gap: var(--hui-space-2);
  min-width: 0;
}

.hui-animated-preview-frame {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 72px;
  height: 72px;
  border: 1px solid var(--hui-border-soft);
  border-radius: var(--hui-radius);
  background: conic-gradient(
    from 45deg,
    color-mix(in srgb, var(--hui-border) 55%, transparent) 0 25%,
    transparent 0 50%
  );
  background-size: 12px 12px;
  overflow: hidden;
}

.hui-animated-preview-frame img {
  max-width: 100%;
  max-height: 100%;
  image-rendering: pixelated;
}

.hui-animated-preview-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.hui-animated-preview-count {
  color: var(--hui-muted);
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
}

.hui-frame-row {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  padding: 5px 0;
  border-bottom: 1px solid var(--hui-border-soft);
}

.hui-frame-row:last-of-type {
  border-bottom: 0;
}

.hui-frame-index {
  flex: 0 0 auto;
  width: 18px;
  color: var(--hui-muted);
  font-size: 0.7rem;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.hui-frame-thumb {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border: 1px solid var(--hui-border-soft);
  border-radius: 4px;
  overflow: hidden;
}

.hui-frame-thumb img {
  max-width: 100%;
  max-height: 100%;
  image-rendering: pixelated;
}

/* Mirrors the plugin's built-in missing-icon checker. */
.hui-frame-thumb-missing {
  width: 100%;
  height: 100%;
  background: conic-gradient(from 45deg, #ff00ff 0 25%, #000 0 50%);
  background-size: 12px 12px;
}

.hui-frame-path {
  flex: 1 1 auto;
  min-width: 0;
}

/* ---------- registry picker ---------- */

.hui-registry-picker {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

.hui-registry-browser {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
  padding: 8px;
  border: 1px solid var(--hui-border-soft);
  border-radius: var(--hui-radius);
  background: var(--hui-panel-soft);
}

.hui-registry-results {
  display: flex;
  flex-direction: column;
  min-width: 0;
  max-height: 210px;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.hui-registry-result {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 30px;
  padding: 3px 6px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--hui-text);
  font: inherit;
  font-size: 0.76rem;
  text-align: left;
  cursor: pointer;
}

.hui-registry-result:hover,
.hui-registry-result:focus-visible {
  background: color-mix(in srgb, var(--hui-accent) 12%, transparent);
  outline: none;
}

.hui-registry-result.is-selected {
  /* Square leading corners: an inset shadow is clipped by the border radius,
     so with the row's 5px radius intact this 3px accent bent into a crescent
     of light on the leading edge — the banned accent. Straight bar, rounded
     trailing corners, same as the palette row. */
  border-start-start-radius: 0;
  border-end-start-radius: 0;
  box-shadow: inset 3px 0 0 var(--hui-accent);
  font-weight: 620;
}

.hui-registry-result-icon.is-blank {
  display: inline-block;
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
}

.hui-registry-result-text {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.hui-registry-result-key {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--font-mono, ui-monospace, monospace);
}

/* Second line of a custom item row: display name and owning plugin. */
.hui-registry-result-detail {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--hui-muted);
  font-size: 0.68rem;
}

.hui-registry-empty,
.hui-registry-more {
  margin: 0;
  color: var(--hui-muted);
  font-size: 0.72rem;
  line-height: 1.4;
}

/* ---------- actions ---------- */

.hui-action-row {
  display: flex;
  flex-direction: column;
  gap: var(--hui-space-2);
  min-width: 0;
  padding: var(--hui-space-2) 0;
  border-bottom: 1px solid var(--hui-border-soft);
}

.hui-action-row:last-of-type {
  border-bottom: 0;
}

.hui-action-row-head {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.hui-action-row-head .hui-segmented {
  flex: 1 1 auto;
}

.hui-action-index {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border: 1px solid var(--hui-border-soft);
  border-radius: 999px;
  color: var(--hui-muted);
  font-size: 0.68rem;
  font-variant-numeric: tabular-nums;
}

.hui-action-row-body,
.hui-action-fields {
  display: flex;
  flex-direction: column;
  gap: var(--hui-space-2);
  min-width: 0;
}

.hui-action-add {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  min-width: 0;
}

/* ---------- icon editor ---------- */

.hui-icon-editor,
.hui-icon-image,
.hui-icon-animated,
.hui-icon-item,
.hui-icon-custom,
.hui-icon-empty,
.hui-icon-image-library,
.hui-icon-animated-library,
.hui-toggle-icons {
  display: flex;
  flex-direction: column;
  gap: var(--hui-space-2);
  min-width: 0;
}

.hui-icon-empty-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* ---------- placeholder popover ---------- */

.hui-placeholder-list {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 240px;
  max-width: min(320px, 80vw);
  max-height: 320px;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.hui-placeholder-row {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 5px 6px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--hui-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.hui-placeholder-row:hover,
.hui-placeholder-row:focus-visible {
  background: color-mix(in srgb, var(--hui-accent) 12%, transparent);
  outline: none;
}

.hui-placeholder-key {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.74rem;
  font-weight: 620;
  overflow-wrap: anywhere;
}

.hui-placeholder-desc,
.hui-placeholder-empty,
.hui-placeholder-foot {
  margin: 0;
  color: var(--hui-muted);
  font-size: 0.7rem;
  line-height: 1.4;
}

.hui-placeholder-foot {
  padding-top: 6px;
  border-top: 1px solid var(--hui-border-soft);
}

/* A trailing control sits against the pane's right edge, so its tooltip must
   anchor right even when the trigger is the first item of its group — the
   generic first-child rule above assumes a left-aligned group and would push
   the hint past the edge, where `overflow-x: clip` cuts it. Specificity is
   matched deliberately so source order decides. */
.hui-inspector
  .hui-inspector-section-trailing
  .hui-segmented
  .arcane-toggle-group
  > *
  .arcane-css-tooltip-content,
.hui-inspector
  .hui-field-trailing
  .hui-segmented
  .arcane-toggle-group
  > *
  .arcane-css-tooltip-content {
  left: auto !important;
  right: 0 !important;
  transform: translateY(-4px) !important;
}

/* ---------- field help popover (T1.5 HuiFieldHelp) ----------
   The card is absolutely positioned inside `.hui-inspector`, which clips its
   inline axis to kill phantom horizontal scroll. A 300px card hanging off the
   right edge of a 320px pane would lose its left edge to that clip, so the
   width is capped against the pane variable. `!important` because the widget
   writes its box inline, which is what keeps it readable with no stylesheet. */

/* The widget positions its card against its own trigger, which is right for a
   free-standing popover and wrong inside a pane that clips its inline axis: a
   trigger with anything after it (the duplicate and delete buttons, a count
   chip) puts the card's far edge past the clip and loses a strip of the text.
   Measured at 57px of the card cut off in the component header.

   Dropping the trigger out of the positioning chain and positioning the row
   instead makes `right: 0` mean the pane's right edge everywhere, whatever sits
   beside the button. Every row listed here spans the pane, and the card's
   `top: calc(100% + 6px)` lands in the same place it did before, because the
   trigger is the full height of its row. */

.hui-inspector .hui-field-help {
  position: static !important;
}

.hui-inspector :where(
    .hui-field-head,
    .hui-inspector-section-head,
    .hui-inspector-header-top,
    .hui-inspector-title-row,
    .hui-switch-row-head,
    .hui-help-cluster
  ) {
  position: relative;
}

/* ---------- defending the two hand-built disclosures ----------
   `AccordionScripts.bindExpandersAccordions` binds EVERY `button[aria-expanded]`
   on the page during the legacy bundle's one-shot `setTimeout(…, 100)` scan and
   then writes `display: none | block` straight onto the button's next sibling,
   plus `transform: rotate(180deg)` onto its icon. Both of ours — the extras
   summary and the help trigger — carry `aria-expanded` because they should, and
   both keep their open state in Dart.

   The primary fix is now in Dart: both triggers render
   `data-arcane-interactive="true"`, which is the binder's own opt-out
   (`accordion_scripts.dart:8`), so it never binds them at all. That also covers
   the half CSS cannot reach — the binder flipping `aria-expanded` itself.

   These rules stay as belt-and-braces. They cost nothing and they still hold if
   a future trigger is added without the attribute. The bodies only exist in the
   DOM while their Dart flag is true, so forcing them visible can never show
   something that should be hidden. */

.hui-extras-body {
  display: flex !important;
}

.hui-field-help-scrim {
  display: block !important;
}

.hui-extras > button svg,
.hui-field-help > button svg {
  transform: none !important;
}

.hui-inspector .hui-field-help-card {
  width: min(
    300px,
    calc(var(--hui-inspector-width, 320px) - 44px),
    calc(100vw - 40px)
  ) !important;
  border-color: var(--hui-border-soft) !important;
  animation: hui-help-in var(--hui-dur-2, 140ms) var(--hui-ease-out, ease) backwards;
}

.hui-field-help-title {
  color: var(--hui-text);
}

.hui-field-help-body {
  color: var(--hui-muted) !important;
  text-wrap: pretty;
}

.hui-field-help-citation {
  padding-top: 6px;
  border-top: 1px solid var(--hui-border-soft);
}

@keyframes hui-help-in {
  from {
    opacity: 0;
    transform: translateY(-3px);
  }
}

/* Cluster of help affordances for the fields whose editors this pane only
   mounts (text, item, custom item). Reads as a legend, not as controls. */

.hui-help-cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 10px;
  min-width: 0;
  color: var(--hui-muted);
  font-size: 0.7rem;
}

.hui-help-cluster-label {
  font-weight: 640;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.hui-help-cluster-item {
  display: inline-flex;
  align-items: center;
  gap: 1px;
  min-width: 0;
}

/* Two or more controls in a `HuiField` / section trailing slot. */

.hui-field-tools,
.hui-frame-tools {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  flex: 0 0 auto;
}

.hui-inspector-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-width: 0;
}

/* ---------- extras (T1.5 ExtrasEditor) ---------- */

.hui-extras {
  padding: 2px 0;
}

.hui-extras.is-empty .hui-count-chip {
  opacity: 0.6;
}

.hui-extras-summary {
  font-size: 0.72rem;
  font-weight: 620;
}

.hui-extras-body {
  padding: 4px 0 2px;
}

.hui-extras-note,
.hui-extras-empty {
  text-wrap: pretty;
}

.hui-extras-row + .hui-extras-row {
  padding-top: 2px;
}

/* ---------- action presets (T1.5 ActionPresetsRow) ---------- */

.hui-action-presets {
  padding-bottom: 2px;
}

.hui-action-presets-note {
  text-wrap: pretty;
}

/* ---------- drag reorder (T1.5 HuiReorderList) ---------- */

.hui-reorder-row {
  border-bottom: 1px solid var(--hui-border-soft);
}

.hui-reorder-row:last-of-type {
  border-bottom: 0;
}

/* The dragged row stays in place; only the line moves, so nothing under the
   pointer reflows mid-gesture. */
.hui-reorder-row.is-dragging {
  background: color-mix(in srgb, var(--hui-accent) 8%, transparent);
}

.hui-reorder-line {
  transition: background var(--hui-dur-1, 80ms) linear;
}

.hui-reorder-handle:hover {
  color: var(--hui-text) !important;
}

.hui-reorder .hui-frame-row {
  border-bottom: 0;
}

/* ---------- toggle icons, side by side ---------- */

.hui-toggle-copy {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  min-width: 0;
}

/* Two columns while both stay usable, one below that: a 300px pane cannot show
   two icon editors, and stacking is still both-editable, which is the point. */
.hui-toggle-icon-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr));
  gap: var(--hui-space-2);
  min-width: 0;
}

.hui-toggle-icon-cell {
  min-width: 0;
  padding: 2px 0 0;
  border-top: 1px solid var(--hui-border-soft);
}

/* Which one the canvas is drawing, so the segmented control above still means
   something now that both are on screen. */
.hui-toggle-icon-cell.is-previewed {
  border-top-color: var(--hui-accent);
}

/* ---------- animated frame staging ---------- */

.hui-frame-staged {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
  padding: 8px;
  border: 1px solid var(--hui-border-soft);
  border-radius: var(--hui-radius);
  background: var(--hui-panel-soft);
}

.hui-frame-staged-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  min-width: 0;
}

.hui-frame-staged-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  max-width: 100%;
  padding: 2px 6px;
  border: 1px solid var(--hui-border-soft);
  border-radius: 999px;
  background: var(--background);
  color: var(--hui-text);
  font: inherit;
  font-size: 0.68rem;
  font-variant-numeric: tabular-nums;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
}

.hui-frame-staged-chip:hover,
.hui-frame-staged-chip:focus-visible {
  border-color: var(--hui-accent);
  outline: none;
}

.hui-frame-staged-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* ---------- empty states ---------- */

.hui-empty {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: 4px 10px;
  min-width: 0;
  padding: 10px;
  border: 1px dashed var(--hui-border-soft);
  border-radius: var(--hui-radius);
}

.hui-empty-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--hui-muted);
}

.hui-empty.is-warning .hui-empty-icon {
  color: var(--hui-warning);
}

.hui-empty.is-danger .hui-empty-icon {
  color: var(--hui-danger);
}

.hui-empty.is-danger {
  border-color: color-mix(in srgb, var(--hui-danger) 45%, transparent);
}

.hui-empty-text {
  min-width: 0;
}

.hui-empty-title {
  display: block;
  font-size: 0.76rem;
  font-weight: 640;
  letter-spacing: -0.01em;
}

.hui-empty-body {
  margin: 3px 0 0;
  color: var(--hui-muted);
  font-size: 0.72rem;
  line-height: 1.45;
  text-wrap: pretty;
}

.hui-empty-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  grid-column: 2;
  padding-top: 2px;
}

/* ---------- range fields ----------
   The track, thumb and focus ring come from `.hui-range` in
   05-panels-dialogs.css, shared with the settings dialog on purpose: both edit
   a number by dragging and must not read as two different widgets. Only the
   row is the inspector's, and it is a grid rather than that file's flex row
   because the readout here is an editable number field, not a label.

   `HuiSliderField` writes the grid inline; these two rules are the parts the
   inspector's own fit rules would otherwise fight. */

.hui-inspector .hui-slider-field .hui-range {
  width: 100%;
  min-width: 0;
}

.hui-inspector .hui-slider-field .hui-number {
  min-width: 0;
}

/* ---------- skeletons ----------
   The box and its shimmer are the motion layer's (`.hui-skeleton` in
   06-motion.css); the inspector only decides where one belongs. That is never
   in place of a control the user can already type into — only where a
   catalogue-backed affordance will appear once the asset lands.

   `HuiSkeletonRows` is stacked above the picker it stands in for, so the
   loading strip and the free-text field are both on screen. */

.hui-skeleton-rows {
  padding-bottom: 2px;
}

/* ---------- hover reveals ----------
   One rule decides what may recede and what may not: an affordance that is the
   only way to reach a behaviour stays visible and reveals EMPHASIS; an
   affordance that duplicates a keyboard path may recede entirely.

   So the row tools never fade — the delete button is a row's only delete — and
   the drag handle does, because it is `aria-hidden` and the up/down buttons
   are its accessible twin (reorder_list.dart). Every duration resolves from
   --hui-dur-*, so 06-motion.css's single switch flattens all of it. */

/* The row band. Background only: a transform here would make the row a
   containing block for the field-help popover it hosts, which is exactly the
   trap 06-motion.css rule 3 describes. `:focus-within` is not decoration —
   typing in a command field should light the row its tools belong to. */
.hui-inspector .hui-action-row,
.hui-inspector .hui-frame-row {
  transition: background-color var(--hui-dur-2) var(--hui-ease-out);
}

.hui-inspector .hui-action-row:hover,
.hui-inspector .hui-action-row:focus-within,
.hui-inspector .hui-frame-row:hover,
.hui-inspector .hui-frame-row:focus-within {
  background: color-mix(in srgb, var(--hui-accent) 5%, transparent);
}

/* The whole cluster recedes with the row, not just the button under the
   pointer.

   Opacity on the WRAPPER, not colour on the buttons: measured, the icon
   buttons compute to full --hui-text, not the --hui-muted the rule above them
   asks for, because Arcane's own ghost-button colour outranks a plain class
   selector. A colour promotion would therefore have been a no-op. Opacity on a
   node the framework does not style cannot lose that fight, and at 0.6 of
   foreground the contrast is still an order of magnitude past the 3:1 a
   non-text control owes. */
.hui-inspector .hui-row-tools {
  opacity: 0.6;
  transition: opacity var(--hui-dur-2) var(--hui-ease-out);
}

.hui-inspector .hui-action-row:hover .hui-row-tools,
.hui-inspector .hui-action-row:focus-within .hui-row-tools,
.hui-inspector .hui-frame-row:hover .hui-row-tools,
.hui-inspector .hui-frame-row:focus-within .hui-row-tools,
.hui-inspector .hui-row-tools:hover,
.hui-inspector .hui-row-tools:focus-within {
  opacity: 1;
}

/* The one thing here that may genuinely recede. */
.hui-inspector .hui-reorder-handle {
  opacity: 0.45;
  transition: opacity var(--hui-dur-2) var(--hui-ease-out);
}

.hui-inspector .hui-reorder-row:hover .hui-reorder-handle,
.hui-inspector .hui-reorder-row:focus-within .hui-reorder-handle {
  opacity: 1;
}

/* A coarse pointer has no hover to reveal with. */
@media (hover: none) {
  .hui-inspector .hui-reorder-handle,
  .hui-inspector .hui-row-tools {
    opacity: 1;
  }
}

/* Pick lists already highlight; they just did it as a hard cut. --hui-dur-1,
   because a row highlight that lags the pointer down a list feels broken. */
.hui-registry-result,
.hui-placeholder-row,
.hui-frame-staged-chip {
  transition:
    color var(--hui-dur-1) var(--hui-ease-out),
    border-color var(--hui-dur-1) var(--hui-ease-out),
    background-color var(--hui-dur-1) var(--hui-ease-out);
}

/* The duration tokens zero out under reduced motion, which a one-shot entrance
   handles but the card's own animation should not have to reason about. The
   press scale is the other case a token cannot reach: it is a distance, not a
   duration, so --hui-lift going to 0 does not touch it. */
@media (prefers-reduced-motion: reduce) {
  .hui-inspector .hui-field-help-card {
    animation: none;
  }

  .hui-image-tile:active {
    transform: none;
  }
}
