/* 05-panels-dialogs.css — components rail, validation panel, code editor and
   every dialog. Owned by: agent-panels. Later numbered files override earlier
   ones, so this file only styles `hui-*` hooks plus the Arcane dialog and sheet
   surfaces it opens by id. */

/* ==========================================================================
   1. Components rail
   ========================================================================== */

/* The shell owns the rail cell (`.hui-pane.hui-rail` in 02-shell.css): its
   border, background and scrolling. This root only fills it, so the divider is
   drawn once and there is a single scroll container.

   `flex: 0 0 auto` is load-bearing: the rail cell is a flex column, so a
   shrinkable child would be clamped to the viewport and its overflow would fall
   outside the scroll box — the last rows and the bottom padding were being
   swallowed under the status bar. Sizing to content lets the rail scroll. */
.hui-rail-pane {
  display: flex;
  flex: 0 0 auto;
  flex-direction: column;
  min-width: 0;
}

.hui-rail-inner {
  display: flex;
  flex: 0 0 auto;
  flex-direction: column;
  gap: 8px;
  /* The bottom pad is the scroll runway: the last row never sits flush against
     the status bar. */
  padding: var(--hui-space-2) var(--hui-space-2) var(--hui-space-5);
}

/* Heading, count and add split-button on one line. `nowrap` plus a truncating
   eyebrow keeps it one line down to ~200px of rail. */
.hui-rail-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  flex-wrap: nowrap;
  min-height: 28px;
}

.hui-rail-heading {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.hui-rail-heading .hui-eyebrow {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hui-rail-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  flex: 0 0 auto;
  padding: 0 5px;
  border-radius: 0;
  background: var(--hui-panel-soft);
  color: var(--hui-muted);
  font-size: .68rem;
  font-variant-numeric: tabular-nums;
  font-weight: 650;
}

.hui-rail-add {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: stretch;
  gap: 0;
}

.hui-rail-add > * + * {
  margin-left: 0;
  border-left: 1px solid var(--hui-border-soft) !important;
}

/* Arcane sizes its buttons with inline styles, so trimming them to the rail's
   rhythm needs !important. Sizing only — colour and state stay Arcane's. */
.hui-rail-add .arcane-button {
  height: 28px !important;
  padding: 0 9px !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
  color: var(--hui-text) !important;
  font-size: .78rem !important;
  gap: 5px !important;
}

.hui-rail-add .arcane-button:hover:not(:disabled),
.hui-rail-add .arcane-button:focus-visible {
  background: var(--hui-panel-soft) !important;
}

/* The split-button's second half is the dropdown trigger: icon only. */
.hui-rail-add > .arcane-dropdown .arcane-button {
  padding: 0 4px !important;
}

.hui-rail-hint {
  overflow: hidden;
  margin: 0;
  color: var(--hui-muted);
  font-size: .7rem;
  line-height: 1.3;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hui-rail-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* ~36px: two text lines (id + summary) inside 2px of padding and a hairline. */
.hui-rail-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 4px;
  min-height: 36px;
  padding: 2px 4px 2px 6px;
  border: 0;
  border-radius: var(--hui-radius);
  color: var(--hui-muted);
  background: transparent;
  transition:
    background var(--hui-dur-2) var(--hui-ease-out),
    color var(--hui-dur-2) var(--hui-ease-out);
}

.hui-rail-row:hover {
  background: var(--hui-panel-soft);
  color: var(--hui-text);
}

.hui-rail-row.is-selected {
  color: var(--hui-text);
  background: color-mix(in srgb, var(--hui-panel-soft) 92%, var(--hui-text) 8%);
}

.hui-rail-row.is-dragging { opacity: .45; }

.hui-rail-row.is-drop-target {
  background: color-mix(in srgb, var(--hui-accent) 10%, var(--hui-panel));
  box-shadow: inset 0 0 0 1px var(--hui-accent);
}

.hui-rail-row.is-armed {
  background: color-mix(in srgb, var(--hui-danger) 10%, var(--hui-panel));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--hui-danger) 60%, transparent);
}

/* One line is enough while the row is asking to be deleted. */
.hui-rail-row.is-armed .hui-rail-summary { display: none; }

.hui-rail-main {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
  text-align: left;
}

.hui-rail-main:focus-visible {
  border-radius: 0;
  outline: 2px solid var(--hui-ring);
  outline-offset: 2px;
}

/* One fixed 22px column so every id starts at the same x. The type glyph and
   the drag grip share it and cross-fade on hover — two columns do not fit. */
.hui-rail-mark {
  position: relative;
  display: inline-flex;
  width: 22px;
  height: 22px;
  flex: 0 0 22px;
  align-items: center;
  justify-content: center;
  border-radius: 0;
  background: var(--hui-panel-soft);
  color: var(--hui-muted);
  transition:
    background var(--hui-dur-2) var(--hui-ease-out),
    color var(--hui-dur-2) var(--hui-ease-out);
}

.hui-rail-glyph,
.hui-rail-grip {
  position: absolute;
  inset: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: opacity var(--hui-dur-2) var(--hui-ease-out);
}

.hui-rail-grip {
  cursor: grab;
  opacity: 0;
}

.hui-rail-row:hover .hui-rail-glyph { opacity: 0; }
.hui-rail-row:hover .hui-rail-grip { opacity: .8; }

.hui-rail-row.is-selected .hui-rail-mark {
  background: color-mix(in srgb, var(--hui-accent) 18%, transparent);
  color: var(--hui-text);
}

.hui-rail-text {
  display: grid;
  flex: 1 1 auto;
  gap: 0;
  min-width: 0;
}

.hui-rail-id {
  overflow: hidden;
  color: var(--hui-text);
  font-size: .84rem;
  font-weight: 620;
  line-height: 1.2;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hui-rail-summary {
  overflow: hidden;
  color: var(--hui-muted);
  font-size: .7rem;
  line-height: 1.25;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hui-rail-dot {
  width: 6px;
  height: 6px;
  flex: 0 0 auto;
  border-radius: 999px;
  background: var(--hui-warning);
}

.hui-rail-dot.is-error { background: var(--hui-danger); }

.hui-rail-tools,
.hui-rail-confirm {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 2px;
}

/* The arrows are hover/selection furniture: fourteen permanent chevron pairs
   are most of what made the rail read as clutter. `visibility` (not `display`)
   plus the `:focus-within` reversal keeps them keyboard reachable — tabbing to
   the row's own button reveals them before focus can reach them. */
.hui-rail-tools {
  opacity: 0;
  visibility: hidden;
  /* Slides the last few pixels in from the trailing edge, which reads as the
     tools belonging to the row rather than being stamped onto it. */
  transform: translate3d(4px, 0, 0);
  transition:
    opacity var(--hui-dur-2) var(--hui-ease-out),
    visibility var(--hui-dur-2) var(--hui-ease-out),
    transform var(--hui-dur-2) var(--hui-ease-out);
}

.hui-rail-row:hover .hui-rail-tools,
.hui-rail-row:focus-within .hui-rail-tools,
.hui-rail-row.is-selected .hui-rail-tools,
.hui-rail-row.is-drop-target .hui-rail-tools {
  opacity: 1;
  visibility: visible;
  transform: none;
}

.hui-rail-tools .arcane-button,
.hui-rail-confirm .arcane-button {
  width: 24px !important;
  height: 24px !important;
  padding: 0 !important;
  border-radius: 0 !important;
}

.hui-rail-tools .arcane-button[data-variant="ghost"],
.hui-rail-confirm .arcane-button[data-variant="ghost"],
.hui-rail-rename .arcane-button[data-variant="ghost"] {
  border: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
}

.hui-rail-tools .arcane-button[data-variant="ghost"]:hover:not(:disabled),
.hui-rail-confirm .arcane-button[data-variant="ghost"]:hover:not(:disabled),
.hui-rail-rename .arcane-button[data-variant="ghost"]:hover:not(:disabled) {
  background: var(--hui-panel-soft) !important;
}

/* No hover to reveal them with, and a coarse pointer needs a bigger target. */
@media (hover: none) {
  .hui-rail-tools { opacity: 1; visibility: visible; transform: none; }
  .hui-rail-tools .arcane-button,
  .hui-rail-confirm .arcane-button {
    width: 32px !important;
    height: 32px !important;
  }
  /* No drag-and-drop on touch, so the grip never replaces the type glyph. */
  .hui-rail-grip,
  .hui-rail-row:hover .hui-rail-grip { opacity: 0; }
  .hui-rail-row:hover .hui-rail-glyph { opacity: 1; }
}

.hui-rail-confirm-label {
  color: var(--hui-danger);
  font-size: .7rem;
  font-weight: 650;
  white-space: nowrap;
}

.hui-rail-rename {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 4px;
  margin: 3px 6px 7px 28px;
  align-items: center;
}

.hui-rail-rename .arcane-button {
  width: 32px !important;
  height: 32px !important;
  padding: 0 !important;
}

@media (pointer: coarse) and (max-width: 1024px), (max-width: 700px) {
  .hui-rail-add .arcane-button {
    min-width: 40px;
    height: 40px !important;
    min-height: 40px;
  }

  .hui-rail-tools .arcane-button,
  .hui-rail-confirm .arcane-button,
  .hui-rail-rename .arcane-button {
    width: 40px !important;
    height: 40px !important;
    min-width: 40px;
    min-height: 40px;
  }

}

.hui-rail-empty { padding: var(--hui-space-3) var(--hui-space-1); }

.hui-two-step { display: inline-flex; align-items: center; gap: 4px; }

/* ==========================================================================
   2. Validation panel
   ========================================================================== */

[data-arcane-surface="sheet"][data-arcane-id="hui-validation-sheet"] {
  backdrop-filter: blur(6px);
}

.hui-validation {
  display: flex;
  flex-direction: column;
  gap: var(--hui-space-3);
  max-height: min(62vh, 640px);
  padding: var(--hui-space-2) 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.hui-validation-strip {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border: 1px solid var(--hui-border-soft);
  border-radius: var(--hui-radius);
  overflow: hidden;
}

.hui-validation-cell {
  display: grid;
  gap: 2px;
  padding: 10px 14px;
  border-right: 1px solid var(--hui-border-soft);
}

.hui-validation-cell:last-child { border-right: 0; }

.hui-validation-cell-value {
  color: var(--hui-text);
  font-size: 1.25rem;
  font-variant-numeric: tabular-nums;
  font-weight: 680;
  line-height: 1.1;
}

.hui-validation-cell-label {
  color: var(--hui-muted);
  font-size: .7rem;
  font-weight: 650;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.hui-validation-cell.is-error .hui-validation-cell-value { color: var(--hui-danger); }
.hui-validation-cell.is-warning .hui-validation-cell-value { color: var(--hui-warning); }
.hui-validation-cell.is-info .hui-validation-cell-value { color: var(--hui-info); }

.hui-validation-group { display: grid; gap: 8px; }

.hui-validation-group-head {
  display: flex;
  align-items: center;
  gap: 8px;
}

.hui-validation-group.is-error .hui-validation-group-head,
.hui-validation-group.is-error .hui-validation-group-head .hui-eyebrow { color: var(--hui-danger); }
.hui-validation-group.is-warning .hui-validation-group-head,
.hui-validation-group.is-warning .hui-validation-group-head .hui-eyebrow { color: var(--hui-warning); }
.hui-validation-group.is-info .hui-validation-group-head,
.hui-validation-group.is-info .hui-validation-group-head .hui-eyebrow { color: var(--hui-info); }

.hui-validation-list {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  border: 1px solid var(--hui-border-soft);
  border-radius: var(--hui-radius);
  list-style: none;
  overflow: hidden;
}

/* The sheet is hidden with [hidden] between openings, so this entrance is
   created fresh every time the panel opens. The list is one fade rather than a
   per-row stagger on purpose: it re-renders on every keystroke in the
   inspector, and a stagger would replay while the user typed. */
.hui-validation-list {
  animation: hui-fade-in var(--hui-dur-2) var(--hui-ease-out) backwards;
}

.hui-validation-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--hui-space-2);
  padding: 10px 12px;
  border-bottom: 1px solid var(--hui-border-soft);
}

.hui-validation-row:last-child { border-bottom: 0; }

.hui-validation-body { display: grid; gap: 3px; min-width: 0; }

.hui-validation-message {
  margin: 0;
  color: var(--hui-text);
  font-size: .82rem;
  line-height: 1.4;
}

.hui-validation-fix {
  margin: 0;
  color: var(--hui-muted);
  font-size: .75rem;
  line-height: 1.4;
}

/* A loaded history version is read, not edited: monospace, bounded, scrolls
   on its own so the sheet's own list never grows past the viewport. */
.hui-history-source {
  margin: .5rem 0 0;
  max-height: 14rem;
  overflow: auto;
  padding: .6rem .75rem;
  background: var(--hui-surface-2, rgba(255, 255, 255, .03));
  border: 1px solid var(--hui-border, rgba(255, 255, 255, .08));
  border-radius: .5rem;
  color: var(--hui-fg, inherit);
  font-family: var(--font-mono);
  font-size: .72rem;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
}

.hui-validation-path,
.hui-code-issue-path,
.hui-import-issue code {
  color: var(--hui-muted);
  font-family: var(--font-mono);
  font-size: .72rem;
  word-break: break-all;
}

/* ==========================================================================
   3. Code editor
   ========================================================================== */

.hui-code {
  display: flex;
  flex-direction: column;
  min-height: 0;
  height: 100%;
  overflow: hidden;
  background: var(--hui-bg);
}

.hui-code-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--hui-space-2);
  min-height: 34px;
  padding: 3px 8px;
  border-bottom: 1px solid var(--hui-border-soft);
  background: var(--hui-panel-soft);
}

.hui-code-toolbar-info { display: flex; align-items: baseline; gap: 10px; }

.hui-code-stat {
  color: var(--hui-muted);
  font-size: .72rem;
  font-variant-numeric: tabular-nums;
}

.hui-code-toolbar-tools { display: flex; align-items: center; gap: 2px; }

.hui-code-toolbar .arcane-button {
  height: 28px !important;
  min-height: 28px;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
}

.hui-code-toolbar .arcane-button:hover:not(:disabled),
.hui-code-toolbar .arcane-button:focus-visible {
  background: var(--hui-panel-soft) !important;
}

@media (pointer: coarse) and (max-width: 1024px), (max-width: 700px) {
  .hui-code-toolbar .arcane-button {
    min-width: 40px;
    height: 40px !important;
    min-height: 40px;
  }
}

.hui-code-error {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-bottom: 1px solid color-mix(in srgb, var(--hui-danger) 45%, transparent);
  background: color-mix(in srgb, var(--hui-danger) 12%, var(--hui-panel));
  color: var(--hui-danger);
  font-size: .78rem;
}

.hui-code-error-text { color: var(--hui-text); }

/* This element owns both scroll axes. Everything inside it is sized to the
   document rather than to the pane, so no layer ever scrolls on its own and
   the gutter, the highlight and the textarea cannot drift apart. */
.hui-code-body {
  display: flex;
  flex: 1 1 auto;
  align-items: flex-start;
  min-height: 0;
  overflow: auto;
  overscroll-behavior: contain;
  font-family: var(--font-mono);
  font-size: .8rem;
  line-height: 1.55;
}

/* Pinned to the left edge while the body scrolls sideways, and at least as
   tall as the pane so its background never stops partway down a short file. */
.hui-code-gutter {
  position: sticky;
  left: 0;
  z-index: 2;
  display: flex;
  flex: 0 0 auto;
  flex-direction: column;
  min-height: 100%;
  padding: 12px 10px 12px 12px;
  border-right: 1px solid var(--hui-border-soft);
  background: var(--hui-panel);
  color: color-mix(in srgb, var(--hui-muted) 75%, transparent);
  text-align: right;
  user-select: none;
}

.hui-code-line {
  font-variant-numeric: tabular-nums;
  white-space: pre;
}

/* Wide as the longest line and tall as the document — the pre inside sets
   both — so the textarea laid over it at 100% x 100% covers every line and
   has nothing to scroll. Grows to fill the pane when the file is small. */
.hui-code-input {
  position: relative;
  flex: 1 0 auto;
  width: max-content;
  min-height: 100%;
}

.hui-code-area {
  padding: 12px 16px;
  border: 0;
  background: transparent;
  color: var(--hui-text);
  font: inherit;
  overflow: hidden;
  resize: none;
  white-space: pre;
  tab-size: 2;
}

.hui-code-area:focus,
.hui-code-area:focus-visible { outline: none; }

.hui-code-issues {
  flex: 0 0 auto;
  max-height: 28vh;
  padding: var(--hui-space-2) var(--hui-space-3);
  border-top: 1px solid var(--hui-border-soft);
  background: var(--hui-panel);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.hui-code-issues-head { margin-bottom: 6px; }

.hui-code-issues-empty {
  margin: 0;
  color: var(--hui-muted);
  font-size: .78rem;
}

.hui-code-issues-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.hui-code-issue {
  display: grid;
  grid-template-columns: minmax(120px, .34fr) minmax(0, 1fr);
  gap: 10px;
  padding: 7px 9px;
  border: 1px solid var(--hui-border);
  border-radius: 0;
  background: color-mix(in srgb, var(--hui-panel) 92%, var(--hui-bg));
  font-size: .76rem;
}

.hui-code-issue.is-error { border-color: var(--hui-danger); }
.hui-code-issue.is-warning { border-color: var(--hui-warning); }
.hui-code-issue.is-info { border-color: var(--hui-info); }

.hui-code-issue-message { color: var(--hui-text); line-height: 1.4; }

@media (max-width: 860px) {
  .hui-code-issue { grid-template-columns: 1fr; gap: 2px; }
}

/* --- buffer state -------------------------------------------------------- */

/* Says whether the document has the text. Dirty is the loud one: it is the
   state the user has to act on, and the only one they can lose work from. */
.hui-code-state {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: -.01em;
}

.hui-code-state.is-dirty { color: var(--hui-warning); }
.hui-code-state.is-clean { color: var(--hui-muted); }

/* Passive: the buffer is mid-keystroke and does not parse yet. Never an alert
   — the loud strip is reserved for a save the user asked for and did not get. */
.hui-code-syntax-hint {
  margin-right: 6px;
  color: var(--hui-muted);
  font-size: .72rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 34ch;
}

/* The toolbar flattens every button to a ghost, which is right for Format and
   Revert and wrong for the one control that commits. Save gets its weight back
   only while there is something to save. */
.hui-code-save.is-dirty .arcane-button {
  background: var(--hui-accent) !important;
  color: var(--hui-bg) !important;
}

.hui-code-save.is-dirty .arcane-button:hover:not(:disabled),
.hui-code-save.is-dirty .arcane-button:focus-visible {
  background: color-mix(in srgb, var(--hui-accent) 84%, var(--hui-text)) !important;
}

/* The toolbar carries four things on one row now — the eyebrow, the counts,
   the buffer state and three controls — so below a phone width it wraps the
   controls onto their own line instead of pushing Save off the edge. The
   counts and the passive hint are the first to go: both restate something the
   editor is already showing. */
@media (max-width: 640px) {
  .hui-code-toolbar { flex-wrap: wrap; row-gap: 2px; }
  .hui-code-toolbar-info { flex: 1 1 100%; flex-wrap: wrap; row-gap: 2px; }
  .hui-code-toolbar-tools { flex: 1 1 100%; justify-content: flex-end; }
  .hui-code-syntax-hint { max-width: 22ch; }
}

@media (max-width: 460px) {
  .hui-code-stat,
  .hui-code-syntax-hint { display: none; }
}

.hui-code-notice {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--hui-border-soft);
  background: var(--hui-panel-soft);
  color: var(--hui-muted);
  font-size: .76rem;
}

.hui-code-notice.is-warning {
  border-bottom-color: color-mix(in srgb, var(--hui-warning) 45%, transparent);
  background: color-mix(in srgb, var(--hui-warning) 12%, var(--hui-panel));
  color: var(--hui-warning);
}

.hui-code-notice-text {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--hui-text);
  line-height: 1.4;
}

.hui-code-notice-tools {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 2px;
}

.hui-code-notice .arcane-button {
  height: 26px !important;
  min-height: 26px;
  border: 1px solid var(--hui-border) !important;
  border-radius: 0 !important;
  background: var(--hui-panel) !important;
  box-shadow: none !important;
}

@media (max-width: 860px) {
  .hui-code-notice { flex-wrap: wrap; }
}

/* Ten zeroes in the editor's own font, out of flow and unpainted. Its box is
   one line tall and ten cells wide, which is what the caret arithmetic needs
   and the only honest way to get it: the font stack resolves in the browser. */
.hui-code-measure {
  position: absolute;
  top: 0;
  left: 0;
  display: inline-block;
  font: inherit;
  line-height: inherit;
  white-space: pre;
  visibility: hidden;
  pointer-events: none;
}

/* --- completion ---------------------------------------------------------- */

/* Fixed, so the scroll container the caret lives in cannot clip it. Positioned
   from Dart against the measured caret cell; the clamp keeps it on screen. */
.hui-code-complete {
  position: fixed;
  z-index: 2147482000;
  display: flex;
  flex-direction: column;
  width: 340px;
  max-width: calc(100vw - 16px);
  max-height: 260px;
  overflow-y: auto;
  overscroll-behavior: contain;
  border: 1px solid var(--hui-border);
  border-radius: 0;
  background: var(--hui-panel);
  box-shadow: 0 10px 30px rgb(0 0 0 / .32);
}

.hui-code-complete-row {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 5px 9px;
  border-bottom: 1px solid var(--hui-border-soft);
  cursor: pointer;
}

.hui-code-complete-row:last-child { border-bottom: 0; }

.hui-code-complete-row.is-active {
  background: color-mix(in srgb, var(--hui-accent) 18%, var(--hui-panel));
}

.hui-code-complete-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.hui-code-complete-label {
  color: var(--hui-text);
  font-family: var(--font-mono);
  font-size: .76rem;
}

.hui-code-complete-row.is-default .hui-code-complete-label {
  color: var(--hui-accent);
}

.hui-code-complete-detail {
  flex: 0 0 auto;
  color: var(--hui-muted);
  font-size: .68rem;
  text-transform: lowercase;
}

.hui-code-complete-desc {
  color: var(--hui-muted);
  font-size: .7rem;
  line-height: 1.35;
}

/* --- hover card ---------------------------------------------------------- */

/* Reuses the shared tooltip surface from 11-tooltip-overlay.css; this rule adds
   only what a free-floating copy of it needs — its own stacking context, and
   the guarantee it never eats a pointer event meant for the textarea. */
.hui-code-hovercard {
  z-index: 2147482100;
  pointer-events: none;
}

.hui-code-hovercard-title {
  font-size: .76rem;
  font-weight: 650;
  letter-spacing: -.01em;
}

.hui-code-hovercard-path,
.hui-code-hovercard-citation {
  color: var(--muted-foreground, var(--hui-muted));
  font-family: var(--font-mono);
  font-size: .66rem;
  overflow-wrap: anywhere;
}

.hui-code-hovercard-body { font-size: .72rem; line-height: 1.45; }

.hui-code-hovercard-detail {
  color: var(--muted-foreground, var(--hui-muted));
  font-size: .68rem;
  line-height: 1.4;
}

/* ==========================================================================
   4. Dialog surfaces
   ========================================================================== */

/* The renderer writes these boxes with inline styles, so overriding them needs
   !important. This is the documented way to restyle an Arcane surface by id;
   nothing else in this file uses it. */

[data-arcane-surface="dialog"][data-arcane-id^="hui-"] {
  padding: clamp(10px, 3vw, 28px) !important;
  background-color: color-mix(in srgb, #000 66%, transparent) !important;
  backdrop-filter: blur(7px);
}

[data-arcane-id^="hui-"] .arcane-dialog {
  max-height: min(92vh, 980px) !important;
  border: 1px solid var(--hui-border) !important;
  border-radius: 0 !important;
  background-color: var(--hui-panel) !important;
  box-shadow: var(--hui-shadow-md) !important;
}

[data-arcane-id^="hui-"] .arcane-dialog-header {
  padding: 18px 22px 14px !important;
  border-bottom: 1px solid var(--hui-border-soft);
}

[data-arcane-id^="hui-"] .arcane-dialog-body {
  padding: 0 22px !important;
  scrollbar-gutter: stable;
}

[data-arcane-id^="hui-"] .arcane-dialog-footer {
  padding: 14px 22px !important;
  border-top: 1px solid var(--hui-border-soft);
  background: color-mix(in srgb, var(--hui-panel) 94%, var(--hui-bg));
}

[data-arcane-id^="hui-"] .arcane-button {
  border-radius: 0 !important;
}

[data-arcane-id^="hui-"] .arcane-button[data-variant="ghost"] {
  border: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
}

/* ---- Dialog entrance ----
   The framework already animates the two boxes it writes inline styles on: the
   overlay fades and the panel scales in, both on `var(--transition-slow)`. What
   it does not do is give the dialog's own content any sense of arrival, and
   those two inline animations are the only ones a stylesheet cannot reach.

   So the content is where this task's motion lives. `.hui-dialog-body` carries
   `hui-stagger`, so its sections rise in sequence behind the panel's scale;
   the header and footer bracket them. Every one of these runs fresh on each
   open, because the surface is display:none in between.

   There is no matching exit anywhere in this file, and that is a framework
   limit rather than an omission — see the note at the foot of 06-motion.css. */

[data-arcane-id^="hui-"] .arcane-dialog-header {
  animation: hui-fade-in var(--hui-dur-2) var(--hui-ease-out) backwards;
}

/* Fade, not rise: the panel clips its overflow, so a footer translated down
   would have its buttons cut off for the length of the animation. */
[data-arcane-id^="hui-"] .arcane-dialog-footer {
  animation: hui-fade-in var(--hui-dur-3) var(--hui-ease-out) backwards;
  animation-delay: var(--hui-dur-1);
}

.hui-dialog-body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.hui-dialog-section {
  display: grid;
  grid-template-columns: minmax(150px, .32fr) minmax(0, 1fr);
  gap: clamp(16px, 3vw, 30px);
  padding: 18px 0;
  border-bottom: 1px solid var(--hui-border-soft);
}

.hui-dialog-section:last-child { border-bottom: 0; }

.hui-dialog-section-heading { display: grid; align-content: start; gap: 4px; }

.hui-dialog-section-heading strong {
  color: var(--hui-text);
  font-size: .9rem;
  font-weight: 650;
  line-height: 1.25;
}

.hui-dialog-section-heading span {
  color: var(--hui-muted);
  font-size: .78rem;
  line-height: 1.45;
}

.hui-dialog-section-body {
  display: grid;
  align-content: start;
  gap: 13px;
  min-width: 0;
}

.hui-dialog-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
}

.hui-dialog-note {
  margin: 0;
  color: var(--hui-muted);
  font-size: .78rem;
  line-height: 1.5;
}

/* Import sits next to a two-step destructive button, so they share a row and
   wrap together on a narrow dialog. */
.hui-catalog-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
}

.hui-dialog-filename {
  color: var(--hui-text);
  font-family: var(--font-mono);
  font-size: .76rem;
}

.hui-codeblock {
  margin: 0;
  padding: 10px 12px;
  border: 1px solid var(--hui-border-soft);
  border-radius: var(--hui-radius);
  background: color-mix(in srgb, var(--hui-bg) 70%, var(--hui-panel));
  color: var(--hui-text);
  font-family: var(--font-mono);
  font-size: .76rem;
  line-height: 1.5;
  overflow-x: auto;
  white-space: pre;
}

.hui-codeblock.is-scroll {
  max-height: 320px;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.hui-steps {
  display: grid;
  gap: 8px;
  margin: 0;
  padding: 0;
  counter-reset: hui-step;
  list-style: none;
}

.hui-steps li {
  position: relative;
  padding-left: 30px;
  color: var(--hui-text);
  font-size: .82rem;
  line-height: 1.5;
  counter-increment: hui-step;
}

.hui-steps li::before {
  position: absolute;
  top: 1px;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--hui-accent) 16%, transparent);
  color: var(--hui-text);
  font-size: .7rem;
  font-variant-numeric: tabular-nums;
  font-weight: 680;
  content: counter(hui-step);
}

/* Native range row. Deliberately not sharing `.hui-scale-range` with the canvas
   toolbar: that class lives in 03-canvas.css, which this task does not own, and
   a dialog row needs a value readout beside the track rather than under it. The
   look is matched by hand — if one moves, move the other. */
.hui-range-row {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}

.hui-range {
  flex: 1 1 auto;
  min-width: 0;
  height: 20px;
  margin: 0;
  background: transparent;
  accent-color: var(--hui-accent);
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}

.hui-range::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--hui-border) 90%, transparent);
}

.hui-range::-moz-range-track {
  height: 4px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--hui-border) 90%, transparent);
}

.hui-range::-webkit-slider-thumb {
  width: 14px;
  height: 14px;
  margin-top: -5px;
  border: 0;
  border-radius: 999px;
  background: var(--hui-accent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--hui-accent) 40%, transparent);
  -webkit-appearance: none;
  appearance: none;
}

.hui-range::-moz-range-thumb {
  width: 14px;
  height: 14px;
  border: 0;
  border-radius: 999px;
  background: var(--hui-accent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--hui-accent) 40%, transparent);
}

.hui-range:focus-visible {
  outline: 2px solid var(--hui-ring);
  outline-offset: 3px;
}

/* Tabular so the number does not jitter the row width as it is dragged. */
.hui-range-value {
  flex: 0 0 auto;
  min-width: 48px;
  color: var(--hui-text);
  font-size: .78rem;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.hui-chips { display: flex; flex-wrap: wrap; gap: 6px; }

.hui-chip {
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding: 0 9px;
  border: 1px solid var(--hui-border-soft);
  border-radius: 0;
  color: var(--hui-muted);
  font-size: .72rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.hui-chip.is-accent {
  border-color: color-mix(in srgb, var(--hui-accent) 45%, transparent);
  background: color-mix(in srgb, var(--hui-accent) 12%, transparent);
  color: var(--hui-text);
}

/* ==========================================================================
   5. Import preview
   ========================================================================== */

.hui-import-preview { display: grid; gap: 10px; }

.hui-import-issues {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 220px;
  margin: 0;
  padding: 0;
  list-style: none;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.hui-import-issue {
  display: grid;
  grid-template-columns: minmax(110px, .3fr) minmax(0, 1fr);
  gap: 10px;
  padding: 7px 9px;
  border: 1px solid var(--hui-border);
  border-radius: 0;
  background: color-mix(in srgb, var(--hui-panel) 92%, var(--hui-bg));
  color: var(--hui-text);
  font-size: .76rem;
  line-height: 1.4;
}

.hui-import-issue.is-error { border-color: var(--hui-danger); }
.hui-import-issue.is-warning { border-color: var(--hui-warning); }
.hui-import-issue.is-info { border-color: var(--hui-info); }

@media (max-width: 720px) {
  .hui-import-issue { grid-template-columns: 1fr; gap: 2px; }
}

/* ==========================================================================
   6. Image manager
   ========================================================================== */

.hui-image-toolbar { display: grid; gap: 8px; padding: 16px 0; }

.hui-quota {
  display: grid;
  gap: 8px;
  padding: 12px 14px;
  border: 1px solid var(--hui-border-soft);
  border-radius: var(--hui-radius);
  background: var(--hui-panel-soft);
}

.hui-quota.is-warning { border-color: color-mix(in srgb, var(--hui-warning) 55%, transparent); }
.hui-quota.is-critical { border-color: color-mix(in srgb, var(--hui-danger) 55%, transparent); }

.hui-quota-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.hui-quota-value {
  color: var(--hui-text);
  font-size: .76rem;
  font-variant-numeric: tabular-nums;
}

.hui-image-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 12px;
  padding: 16px 0;
}

/* The lift, the press and the transitions that carry them come from
   `hui-lift` in 06-motion.css; only the colour states are local. */
.hui-image-card {
  display: grid;
  gap: 8px;
  padding: 10px;
  border: 1px solid var(--hui-border-soft);
  border-radius: var(--hui-radius);
  background: var(--hui-panel);
}

.hui-image-card:hover {
  border-color: var(--hui-border);
  box-shadow: var(--hui-shadow-sm);
}

.hui-image-card.is-used {
  border-color: color-mix(in srgb, var(--hui-accent) 45%, transparent);
}

.hui-image-card.is-oversized {
  border-color: color-mix(in srgb, var(--hui-warning) 55%, transparent);
}

.hui-image-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 128px;
  border-radius: 0;
  overflow: hidden;
}

.hui-image-thumb {
  max-width: 100%;
  max-height: 100%;
  image-rendering: pixelated;
  object-fit: contain;
}

.hui-image-meta { display: grid; gap: 8px; min-width: 0; }

.hui-image-card-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
}

.hui-image-card-tools .hui-chip { margin-right: auto; }

.hui-image-empty { padding: var(--hui-space-4) 0; }

/* A placeholder card is the image card's box with none of its affordances: no
   hover lift, no pointer, nothing that suggests it can be acted on yet. Same
   padding and border as the real thing, so the swap is not a layout shift. */
.hui-skeleton-card {
  padding: 10px;
  border: 1px solid var(--hui-border-soft);
  border-radius: var(--hui-radius);
  background: var(--hui-panel);
}

/* ==========================================================================
   7. Templates
   ========================================================================== */

.hui-option-groups {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.hui-template-dialog-body {
  gap: 16px;
  padding: 18px 0 20px;
}

.hui-template-dialog-body > .hui-dialog-note {
  margin: 0;
  line-height: 1.5;
}

.hui-option-group-head {
  display: grid;
  gap: 2px;
  padding: 10px 0 0;
}

.hui-option-group-head .hui-dialog-note {
  margin: 0;
}

.hui-option-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 10px;
  padding: 0 0 14px;
}

.hui-template-tabs {
  width: 100%;
  margin: 0;
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  scrollbar-width: thin;
}

.hui-template-tabs [role="group"] {
  display: flex !important;
  flex-wrap: wrap;
  width: 100%;
  gap: 0 !important;
  border-bottom: 1px solid var(--hui-border-soft);
  border-radius: 0 !important;
}

.hui-template-tabs .arcane-toggle-group-item {
  height: 30px !important;
  min-height: 30px;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
}

.hui-template-tabs .arcane-toggle-group-item:hover,
.hui-template-tabs .arcane-toggle-group-item:focus-visible,
.hui-template-tabs .arcane-toggle-group-item[aria-pressed="true"] {
  background: var(--hui-panel-soft) !important;
}

.hui-template-tabs .arcane-toggle-group-item[aria-pressed="true"] {
  box-shadow: inset 0 -2px 0 var(--hui-accent) !important;
}

.hui-option-card {
  display: grid;
  align-content: start;
  gap: 6px;
  min-height: 118px;
  padding: 12px;
  border: 1px solid var(--hui-border);
  border-radius: 0;
  background: var(--hui-panel);
  color: inherit;
  cursor: pointer;
  text-align: left;
}

/* Lift, press and transitions: `hui-lift` in 06-motion.css. */
.hui-option-card:hover,
.hui-option-card:focus-visible {
  border-color: var(--hui-ring);
  background: var(--hui-panel-soft);
  box-shadow: var(--hui-shadow-sm);
  outline: none;
}

.hui-option-card.is-selected {
  border-color: var(--hui-accent);
  background: color-mix(in srgb, var(--hui-accent) 7%, var(--hui-panel));
  box-shadow: 0 0 0 1px var(--hui-accent);
}

.hui-option-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}

.hui-option-card-head strong {
  color: var(--hui-text);
  font-size: .88rem;
  font-weight: 650;
}

.hui-option-card-id {
  color: var(--hui-muted);
  font-family: var(--font-mono);
  font-size: .7rem;
}

.hui-option-card-text {
  margin: 0;
  color: var(--hui-muted);
  font-size: .78rem;
  line-height: 1.45;
}

/* ==========================================================================
   8. Help
   ========================================================================== */

.hui-axis { display: grid; gap: 10px; }

.hui-axis-stage {
  position: relative;
  display: grid;
  align-content: space-between;
  gap: 6px;
  min-height: 170px;
  padding: 12px 14px 26px;
  border: 1px solid var(--hui-border-soft);
  border-radius: var(--hui-radius);
  background:
    linear-gradient(to right, color-mix(in srgb, var(--hui-border) 40%, transparent) 1px, transparent 1px) 14px 0 / 100% 100%,
    var(--hui-panel-soft);
  background-repeat: no-repeat;
  font-family: var(--font-mono);
  font-size: .72rem;
}

.hui-axis-tick {
  position: relative;
  padding-left: 16px;
  color: var(--hui-muted);
}

.hui-axis-tick::before {
  position: absolute;
  top: 50%;
  left: 0;
  width: 9px;
  height: 9px;
  margin-top: -4px;
  border-radius: 999px;
  content: "";
}

.hui-axis-tick.is-menu { color: var(--hui-text); }
.hui-axis-tick.is-menu::before { background: var(--hui-accent); }
.hui-axis-tick.is-eye::before {
  border: 1px dashed var(--hui-muted);
  background: transparent;
}
.hui-axis-tick.is-feet::before { background: var(--hui-muted); }

.hui-axis-ground {
  position: absolute;
  right: 14px;
  bottom: 6px;
  left: 14px;
  padding-top: 4px;
  border-top: 2px solid var(--hui-border);
  color: var(--hui-muted);
}

.hui-cheat { display: grid; gap: 6px; }

.hui-cheat-list {
  display: grid;
  grid-template-columns: minmax(160px, .38fr) minmax(0, 1fr);
  gap: 4px 14px;
  margin: 0;
}

.hui-cheat-list dt { margin: 0; }

.hui-cheat-list dt code {
  color: var(--hui-text);
  font-family: var(--font-mono);
  font-size: .74rem;
  word-break: break-word;
}

.hui-cheat-list dd {
  margin: 0;
  color: var(--hui-muted);
  font-size: .78rem;
  line-height: 1.45;
}

@media (max-width: 720px) {
  .hui-cheat-list { grid-template-columns: 1fr; gap: 1px 0; }
  .hui-cheat-list dd { margin-bottom: 6px; }
}

.hui-nonfeatures {
  display: grid;
  gap: 7px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.hui-nonfeatures li {
  position: relative;
  padding-left: 20px;
  color: var(--hui-muted);
  font-size: .8rem;
  line-height: 1.5;
}

.hui-nonfeatures li::before {
  position: absolute;
  top: .62em;
  left: 2px;
  width: 9px;
  height: 2px;
  border-radius: 2px;
  background: var(--hui-danger);
  content: "";
}

.hui-link-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 8px;
}

.hui-link-card {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 12px;
  border: 1px solid var(--hui-border-soft);
  border-radius: var(--hui-radius);
  background: var(--hui-panel);
  color: var(--hui-text);
  text-decoration: none;
}

/* Lift, press and transitions: `hui-lift` in 06-motion.css. */
.hui-link-card:hover,
.hui-link-card:focus-visible {
  border-color: var(--hui-accent);
  background: var(--hui-panel-soft);
  outline: none;
}

.hui-link-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex: 0 0 auto;
  border-radius: 0;
  background: color-mix(in srgb, var(--hui-accent) 12%, transparent);
  transition: transform var(--hui-dur-2) var(--hui-ease-spring);
}

/* These all open a new tab. The glyph leaning towards the label is the only
   thing on the card that says "this goes somewhere". */
.hui-link-card:hover .hui-link-icon,
.hui-link-card:focus-visible .hui-link-icon { transform: translate3d(2px, 0, 0); }

.hui-link-text { display: grid; gap: 1px; min-width: 0; }

.hui-link-text strong { font-size: .82rem; font-weight: 650; }

.hui-link-text span {
  color: var(--hui-muted);
  font-size: .72rem;
  line-height: 1.35;
}

/* ==========================================================================
   9. Narrow screens
   ========================================================================== */

@media (max-width: 700px) {
  [data-arcane-surface="dialog"][data-arcane-id^="hui-"] {
    align-items: flex-end !important;
    padding: 0 !important;
  }

  [data-arcane-id^="hui-"] .arcane-dialog {
    max-height: 96vh !important;
    border-right: 0 !important;
    border-bottom: 0 !important;
    border-left: 0 !important;
    border-radius: 0 !important;
  }

  [data-arcane-id^="hui-"] .arcane-dialog-footer {
    padding: 12px 18px calc(12px + env(safe-area-inset-bottom)) !important;
  }

  .hui-dialog-section { grid-template-columns: 1fr; gap: 12px; padding: 16px 0; }
  .hui-template-tabs [role="group"] { flex-wrap: nowrap; width: max-content; }
  .hui-option-grid { grid-template-columns: 1fr; }
  .hui-validation-strip { grid-template-columns: 1fr; }
  .hui-validation-cell { border-right: 0; border-bottom: 1px solid var(--hui-border-soft); }
  .hui-validation-cell:last-child { border-bottom: 0; }
  .hui-validation-row { flex-direction: column; align-items: stretch; }
  .hui-template-tabs .arcane-toggle-group-item { min-height: 40px; }
}

/* No prefers-reduced-motion block here any more: every transition and animation
   in this file resolves its duration from --hui-dur-*, and 06-motion.css zeroes
   those in one place. Anything added here must do the same. */

/* Validation sheet: Dart-owned close control (Arcane's chrome X is JS-only). */
.hui-validation-footer {
  display: flex;
  justify-content: flex-end;
  padding: var(--hui-space-2) 0 0;
}

[data-arcane-surface="dialog"][data-arcane-id="hui-new-document-dialog"] {
  padding: 0 !important;
  height: 100dvh;
  box-sizing: border-box;
}

[data-arcane-id="hui-new-document-dialog"] .arcane-dialog {
  width: 100% !important;
  max-width: none !important;
  height: 100% !important;
  max-height: 100% !important;
  border: 0 !important;
  box-sizing: border-box;
}

[data-arcane-id="hui-new-document-dialog"] .arcane-dialog-header {
  min-height: 72px;
  box-sizing: border-box;
  padding-top: max(24px, env(safe-area-inset-top)) !important;
  padding-right: max(72px, env(safe-area-inset-right)) !important;
  padding-left: max(22px, env(safe-area-inset-left)) !important;
}

[data-arcane-id="hui-new-document-dialog"] .arcane-dialog-close {
  min-width: 44px;
  min-height: 44px;
  top: max(12px, env(safe-area-inset-top)) !important;
  right: max(12px, env(safe-area-inset-right)) !important;
}

[data-arcane-id="hui-new-document-dialog"] .arcane-dialog-body {
  min-height: 0;
  overflow-x: hidden;
  overscroll-behavior: contain;
}

[data-arcane-id="hui-new-document-dialog"] .arcane-dialog-footer {
  padding-bottom: max(14px, env(safe-area-inset-bottom)) !important;
}

.hui-new-document-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: 12px;
  max-width: 1200px;
  margin: 0 auto;
  padding: 24px 0;
}

.hui-new-document-grid button {
  min-width: 0;
  min-height: 72px;
  height: auto !important;
  justify-content: flex-start !important;
  white-space: normal !important;
  overflow-wrap: anywhere;
  text-align: left;
  padding: 16px !important;
}

[data-arcane-id="hui-new-document-dialog"] .arcane-dialog-footer button {
  min-height: 44px;
}
