
/* ---- buttons, prev/next ---- */

.aucra-btn {
  height: 32px;
  padding: 0 12px;
  border-radius: 6px;
  font-size: 0.81rem;
  font-weight: 500;
}
.aucra-btn-primary {
  background: var(--ink);
  color: #ffffff;
  border: 1px solid var(--ink);
}
.aucra-btn-gold {
  background: var(--gold);
  color: var(--ink);
  border: 1px solid var(--gold);
}
.aucra-btn-ghost {
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--line);
}
/* A button that reads as a link: the row it sits under is the frame, so it
   carries none of its own. */
.q-btn.aucra-btn-text {
  background: none;
  border: none;
  color: var(--gold-deep);
  font-size: 12.5px;
  /* The mockup's text ghosts are body weight, not the 500 a bordered button
     carries: the words are a link, not a button face. */
  font-weight: 400;
  /* The words are the button, so it is as tall as its line and no taller: a
     32px box on every line of a band reads as a second register. */
  height: 18px;
  min-height: 18px;
  padding: 0 6px;
  align-self: flex-start;
}
.q-btn.aucra-btn-text .q-icon {
  font-size: 14px;
}
.q-btn.aucra-btn-text:hover {
  background: var(--gold-wash);
}
.q-btn.aucra-btn-text:active {
  background: var(--gold);
  color: var(--ink);
}
/* A control that is its icon: no label, no border, no background. */
.q-btn.aucra-icon-btn {
  width: 32px;
  height: 32px;
  min-height: 32px;
  padding: 0;
  border: none;
  background: none;
  color: var(--muted);
}
.q-btn.aucra-icon-btn .q-icon {
  font-size: 16px;
}
.q-btn.aucra-icon-btn:hover {
  color: var(--text);
  background: var(--mist);
}
.q-btn.aucra-icon-btn:active {
  background: var(--line);
}

.aucra-prevnext {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  flex: 0 1 auto;
  min-width: 0;
  max-width: 100%;
  gap: 8px;
  font-size: 0.78rem;
}
a.aucra-step {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  /* Two steps side by side are wider than a phone's content column, so the
     pair wraps and each one gives up its fixed cap. */
  max-width: min(260px, 100%);
  padding: 4px 10px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel);
  color: var(--text);
  text-decoration-line: none;
  transition: background 0.15s;
}
a.aucra-step:hover {
  background: #fdf8ec;
  opacity: 1;
}
.aucra-step-id {
  color: var(--muted);
}
.aucra-step-title {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.aucra-clause-number {
  font-size: 1.35rem;
  color: var(--gold-deep);
}
/* One row, never two: the number, the gap count and the chip keep their size
   and the title takes what is left, wrapping inside it. */
.aucra-clause-headline {
  flex-wrap: nowrap;
  gap: 16px;
}
.aucra-clause-headline > * {
  flex: 0 0 auto;
}
.aucra-clause-headline > .aucra-title {
  flex: 1 1 auto;
  min-width: 0;
}
/* Below 640px one line is too narrow for the number, the title and the chip:
   the chip sat on the title. The title claims most of the first line, so the
   gap count and the chip wrap to a line of their own under it. */
@media (max-width: 639px) {
  .aucra-clause-headline {
    flex-wrap: wrap;
    gap: 8px 12px;
  }
  .aucra-clause-headline > * {
    max-width: 100%;
  }
  .aucra-clause-headline > .aucra-title {
    flex: 1 1 70%;
  }
}

/* ---- toasts (the "Saved" toast and every /debug call result) ---- */

.q-notification {
  background: var(--panel) !important;
  border: 1px solid var(--line);
  border-radius: 6px;
  box-shadow: 0 2px 10px rgba(28, 33, 38, 0.12);
  font-family: "IBM Plex Sans", "Segoe UI", sans-serif;
  font-size: 13px;
  min-height: 0;
  padding: 6px 12px;
}
.q-notification .q-notification__message {
  padding: 0;
}
.q-notification.bg-negative {
  border-color: var(--warn);
}
.q-notification.bg-positive {
  border-color: var(--pass);
}

/* Quasar puts `text-white` on every notification and paints a negative one
   `bg-negative`; both utilities are `!important` inside Quasar's own cascade
   layer, where an unlayered `!important` cannot reach them however specific it
   is (measured: white ink on the white panel, so every toast read as blank).
   An important declaration in an EARLIER layer does win, and NiceGUI declares
   `base` before `quasar`, hence this block. */
@layer base {
  .q-notification.text-white {
    color: var(--text) !important;
  }
  /* A negative toast is the warn colour on the warn wash, like every other
     negative surface in the app. */
  .q-notification.bg-negative {
    background: var(--warn-wash) !important;
  }
  .q-notification.bg-negative.text-white {
    color: var(--warn) !important;
  }
  .q-notification.bg-positive {
    background: var(--panel) !important;
  }
  .q-notification.bg-positive.text-white {
    color: var(--pass) !important;
  }
}

/* ---- one focus vocabulary ---- */

.aucra-nav:focus-visible,
.aucra-clause:focus-visible,
.aucra-step:focus-visible,
.aucra-row-link:focus-visible,
.aucra-input-link:focus-visible,
.aucra-open-link:focus-visible,
.aucra-row-delete:focus-visible,
.aucra-toggle-option:focus-visible,
.aucra-tabs .q-tab:focus-visible,
.aucra-btn:focus-visible,
.aucra-ai-tab:focus-visible,
.aucra-user:focus-visible,
.aucra-editor .q-editor__toolbar .q-btn:focus-visible,
.aucra-outline-row:focus-visible,
.aucra-threshold-chip:focus-visible,
.aucra-guidance .q-item:focus-visible,
.aucra-matrix-cell .q-field__native:focus-visible,
.q-btn.aucra-icon-btn:focus-visible,
.q-btn.aucra-btn-text:focus-visible {
  /* !important beats Quasar's .no-outline, which otherwise removes the ring
     from every button it draws, the applicability toggle included. */
  outline: 2px solid var(--focus-ring) !important;
  outline-offset: 2px;
}
/* Quasar draws its buttons with the class `no-outline`, and its own sheet wins
   the outline back even from an !important rule, so a button's focus ring is a
   shadow instead: the applicability toggle and the editor toolbar. */
.aucra-toggle-option:focus-visible,
.aucra-editor .q-editor__toolbar .q-btn:focus-visible {
  box-shadow: inset 0 0 0 2px var(--focus-ring);
}
/* On the picked option's ink the gold text colour reads 2.82:1, so the ring
   inside it is the bright gold the chrome uses (9.69:1). */
.aucra-toggle-option.on:focus-visible {
  box-shadow: inset 0 0 0 2px var(--gold);
}
/* The same for every kit button: Quasar's importants sheet sits in a cascade
   layer, and an important rule in a layer beats an unlayered one, so the
   outline above never lands on a q-btn. The ring is drawn outside the box, the
   way outline-offset draws it on the other controls. */
.q-btn.aucra-btn:focus-visible,
.q-btn.aucra-icon-btn:focus-visible {
  box-shadow: 0 0 0 2px var(--focus-ring);
}

/* The header's two menu buttons are q-btns too, so they take the same shadow
   ring; without it Quasar's own white focus helper is all a keyboard reader
   gets, on a wash that is already white. */
.q-btn.aucra-menu-btn:focus-visible {
  box-shadow: 0 0 0 2px var(--focus-ring);
}
.aucra-menu-btn .q-focus-helper {
  display: none;
}

/* A text box and a text area take the focus on their native input, and the
   class that says so lands on the field root, so the ring is drawn on the
   control the reader sees rather than on the input inside it. */
.aucra-control.q-field--focused .q-field__control {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}
/* The rich text editor clips an outward ring on its own box, so the ring is
   drawn on the wrapper when the editable area holds the caret. The toolbar
   buttons inside it keep their own inset ring and never double this one. */
.aucra-editor:has(.q-editor__content:focus-visible) {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: 6px;
}
/* The checkbox draws no outline of its own, whichever of the two elements
   takes the caret, so the ring goes on the box the reader is looking at. */
.aucra-check:focus-visible .q-checkbox__inner,
.aucra-check:has(.q-checkbox__native:focus-visible) .q-checkbox__inner {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  aside.q-drawer--left,
  .q-page-container,
  .nav-label,
  .aucra-collapsible,
  .aucra-nav,
  .aucra-clause,
  .aucra-row,
  .aucra-step,
  .aucra-status,
  .aucra-search .q-field__control,
  .aucra-tabs .q-tab,
  .aucra-editor .q-editor__toolbar .q-btn,
  .aucra-outline-row,
  .aucra-threshold-chip,
  .aucra-ai-tab .tab-chevron,
  .aucra-ai-tab .tab-spark {
    transition: none !important;
  }
  /* Quasar's slide transition writes the height and its transition onto the
     element itself, so only an important rule reaches it: the fold's height
     jumps in one frame instead of sliding. */
  .q-expansion-item__content {
    transition: none !important;
    animation: none !important;
  }
  .aucra-ai-tab:hover .tab-spark {
    animation: none;
  }
  /* Quasar's own component transitions ignore the setting: the field's
     border line, and the tooltip and menu, which enter and leave through the
     q-transition--* classes Vue adds for the named transition. The duration
     is a custom property Quasar also writes inline, so the rule is important
     and removes the transition itself. */
  .q-field__control:before,
  .q-field__control:after,
  .q-tooltip,
  .q-menu,
  [class*="q-transition--"] {
    transition: none !important;
    animation: none !important;
  }
}

/* ---- content region ---- */

/* The one container ui.sub_pages swaps; positioned so the loading veil and the
   error panel can cover the content without touching the shell. */
.aucra-region {
  position: relative;
  min-width: 0;
  container: aucra-workspace / inline-size;
}

/* ---- loading veil ---- */

/* Covers the content region only (see .aucra-region above). Two modes: the
   loading veil with the ring and its label, and the frozen veil a dropped
   socket leaves behind, which says nothing because nothing is in progress. */
.aucra-veil {
  display: none;
  position: absolute;
  inset: 0;
  z-index: 5;
  background: rgba(255, 255, 255, 0.55);
  backdrop-filter: blur(6px);
  font-size: 0.81rem;
  color: var(--muted);
}
.aucra-veil-loading,
.aucra-veil-navigating,
.aucra-veil-frozen {
  display: block;
}
/* The content region can be many viewports tall, so the ring and the label
   ride in a sticky body instead of being centred on the whole region. Both
   offsets are set and the body is exactly the height between them, so it is
   centred on the visible part of the region at any scroll position. The header
   is fixed and 56px tall; `backdrop-filter` above makes .aucra-veil a
   containing block, so `position: fixed` would not escape it either. */
.aucra-veil-body {
  position: sticky;
  top: 56px;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  height: calc(100vh - 56px);
  max-height: 100%;
}
/* ui.sub_pages empties the region the moment a navigation starts, so a veil
   over a slow page would otherwise be a strip at the top of nothing. */
.aucra-region:has(> .aucra-veil-loading),
.aucra-region:has(> .aucra-veil-navigating),
.aucra-region:has(> .aucra-veil-frozen) {
  min-height: 320px;
}
.aucra-veil-ring {
  flex: 0 0 28px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 3px solid var(--line);
  border-top-color: var(--gold);
  animation: aucra-spin 0.9s linear infinite;
}
.aucra-veil-frozen .aucra-veil-ring,
.aucra-veil-frozen .aucra-veil-label {
  display: none;
}
@keyframes aucra-spin {
  to {
    transform: rotate(360deg);
  }
}

/* ---- connection banner and the header's cloud states ---- */

.aucra-banner {
  display: none;
  align-items: center;
  gap: 10px;
  height: 36px;
  padding: 0 18px;
  background: var(--warn-wash);
  color: var(--warn);
  font-size: 0.81rem;
}
.aucra-banner-on {
  display: flex;
}
.aucra-banner-icon {
  font-size: 18px;
}

.aucra-status-slot {
  display: inline-flex;
  align-items: center;
}
.aucra-status-icon {
  display: none;
  font-size: inherit;
  color: inherit;
}
.aucra-status-online {
  display: inline-flex;
}
.aucra-status-slot.aucra-status-reconnecting .aucra-status-online,
.aucra-status-slot.aucra-status-offline .aucra-status-online {
  display: none;
}
.aucra-status-slot.aucra-status-reconnecting .aucra-status-syncing {
  display: inline-flex;
  color: var(--gold);
}
.aucra-status-slot.aucra-status-offline .aucra-status-gone {
  display: inline-flex;
  color: var(--warn);
}

/* NiceGUI's own "Connection lost" overlay: the banner and the frozen veil say
   the same thing inside the shell, so its popup stays out of the way. */
#popup.nicegui-error-popup {
  display: none !important;
}

/* ---- the error panel of a page that could not be built ---- */

.aucra-error-head {
  box-shadow: inset 3px 0 0 var(--warn);
}
.aucra-error-icon {
  color: var(--warn);
  font-size: 18px;
}
.aucra-error-route {
  font-size: 0.75rem;
  color: var(--muted);
}
.aucra-error-copy {
  font-size: 0.81rem;
}

@media (prefers-reduced-motion: reduce) {
  .aucra-veil-ring {
    animation: none;
  }
}
