/**
 * states.css
 * Universal data-view states — UI/UX §0.3. Built once here, reused
 * verbatim (structure driven by states.js) by every later phase's
 * listing/detail screens rather than each module reinventing them.
 */

/* ---- Empty state --------------------------------------------------- */
.hulk-state-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--hulk-space-4);
  padding: var(--hulk-space-10) var(--hulk-space-6);
  text-align: center;
}

.hulk-state-empty-icon {
  width: 84px;
  height: 84px;
  border-radius: var(--hulk-radius-xl);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--hulk-tint-flow);
  color: var(--hulk-color-flow);
  font-size: 32px;
  box-shadow: 0 12px 32px color-mix(in srgb, var(--hulk-color-flow) 35%, transparent);
}

.hulk-state-empty-message {
  color: var(--hulk-text-muted);
  font-size: var(--hulk-font-size-md);
  max-width: 380px;
}

.hulk-state-empty-cta {
  border: none;
  border-radius: var(--hulk-radius-md);
  padding: 11px 22px;
  color: #fff;
  font-weight: 600;
  background: var(--hulk-gradient-flow);
  cursor: pointer;
  box-shadow: 0 6px 16px var(--hulk-tint-flow);
  transition: filter var(--hulk-motion-fast);
}

.hulk-state-empty-cta:hover {
  filter: brightness(1.05);
}

/* No-results is the same empty pattern, magnifying-glass icon variant,
   applied via a modifier class rather than duplicated markup. */
.hulk-state-empty.hulk-state-no-results .hulk-state-empty-icon {
  background: var(--hulk-tint-pending);
  color: #b45309;
}

/* ---- Loading: skeleton shimmer -------------------------------------- */
.hulk-skeleton {
  position: relative;
  overflow: hidden;
  background: var(--hulk-bg-alt);
  border-radius: var(--hulk-radius-md);
}

.hulk-skeleton::after {
  content: '';
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.55), transparent);
  animation: hulk-shimmer 1.3s infinite;
}

@keyframes hulk-shimmer {
  100% {
    transform: translateX(100%);
  }
}

.hulk-skeleton-row {
  height: 44px;
  margin-bottom: 8px;
}

.hulk-skeleton-card {
  height: 120px;
}

.hulk-topbar-progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 3px;
  width: 0%;
  background: var(--hulk-gradient-flow);
  z-index: 100;
  transition: width var(--hulk-motion-base);
}

/* Slow-network inline note (§0.3) */
.hulk-state-slow-network {
  display: none;
  margin-top: 8px;
  font-size: 13px;
  color: var(--hulk-text-muted);
  text-align: center;
}

.hulk-state-slow-network.is-visible {
  display: block;
}

/* ---- Error state ----------------------------------------------------- */
.hulk-state-error {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 16px 18px;
  border-radius: var(--hulk-radius-md);
  background: #fff3f2;
  border: 1px solid #ffd9d6;
}

.hulk-state-error-icon {
  color: var(--hulk-color-blocked);
  font-size: 18px;
  margin-top: 2px;
}

.hulk-state-error-message {
  flex: 1;
  color: var(--hulk-text);
}

.hulk-state-error-retry {
  border: none;
  border-radius: var(--hulk-radius-sm);
  padding: 6px 14px;
  background: var(--hulk-color-blocked);
  color: #fff;
  font-weight: 600;
  cursor: pointer;
  flex-shrink: 0;
}

/* ---- No internet banner ------------------------------------------------ */
.hulk-state-offline-banner {
  display: none;
  align-items: center;
  justify-content: center;
  gap: var(--hulk-space-2);
  padding: var(--hulk-space-2) var(--hulk-space-4);
  background: var(--hulk-tint-pending);
  color: #8a6100;
  font-size: var(--hulk-font-size-sm);
  font-weight: var(--hulk-font-weight-semibold);
  position: sticky;
  top: 0;
  z-index: 50;
}

.hulk-state-offline-banner.is-visible {
  display: flex;
}

.hulk-is-offline-dimmed {
  opacity: 0.95;
  filter: grayscale(5%);
}

.hulk-is-offline-disabled {
  pointer-events: none;
  opacity: 0.5;
}

/* ---- Permission denied -------------------------------------------------- */
.hulk-state-permission-denied {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 56px 24px;
  text-align: center;
}

.hulk-state-permission-denied-icon {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--hulk-bg-alt);
  color: var(--hulk-text-muted);
  font-size: 22px;
}

/* ---- Session expired modal ----------------------------------------------- */
/* Shared modal overlay: many portal JS files (dashboard, accounts, attendance,
   grn, payroll, stock, discount-guard, quotations, …) create
   `.hulk-modal-overlay` + `.hulk-modal` for quick-create/confirm dialogs.
   Previously only billing.css defined `.hulk-modal-overlay`, so any page that
   did not load billing.css rendered those modals as unstyled blocks at the
   bottom of the page flow instead of a fixed centered overlay. Declared here
   in states.css so every page gets a correct overlay by default. */
.hulk-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, .45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1200;
  opacity: 0;
  overflow-y: auto;
  padding: var(--hulk-space-6) 0;
  transition: opacity .2s ease;
}

.hulk-modal-overlay.is-open { opacity: 1; }
.hulk-modal-overlay.is-closing { opacity: 0; }

.hulk-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(20, 20, 40, 0.4);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 90;
  overflow-y: auto;
  padding: var(--hulk-space-6) 0;
}

.hulk-modal-backdrop.is-open {
  display: flex;
}

.hulk-modal {
  width: 100%;
  max-width: 380px;
  max-height: calc(100vh - var(--hulk-space-6) * 2);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--hulk-surface);
  border: 1px solid var(--hulk-border-faint);
  border-radius: var(--hulk-radius-xl);
  box-shadow: var(--hulk-shadow-pop);
  padding: var(--hulk-space-6);
}

.hulk-modal-title {
  font-size: var(--hulk-font-size-xl);
  margin-bottom: var(--hulk-space-2);
  letter-spacing: var(--hulk-letter-spacing-tight);
}

.hulk-modal-body {
  color: var(--hulk-text-muted);
  margin-bottom: var(--hulk-space-5);
  font-size: var(--hulk-font-size-body);
}

.hulk-modal-pin-input {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--hulk-border-strong);
  border-radius: var(--hulk-radius-md);
  font-size: 18px;
  letter-spacing: 6px;
  text-align: center;
  margin-bottom: var(--hulk-space-4);
  transition: border-color var(--hulk-motion-fast), box-shadow var(--hulk-motion-fast);
}

.hulk-modal-pin-input:focus {
  outline: none;
  border-color: var(--hulk-portal-accent, var(--hulk-accent-admin));
  box-shadow: var(--hulk-ring);
}

.hulk-modal-submit {
  width: 100%;
  border: none;
  border-radius: var(--hulk-radius-md);
  padding: 12px;
  color: #fff;
  font-weight: 600;
  background: var(--hulk-gradient-flow);
  cursor: pointer;
}

/* Session-expired modal: even, comfortable spacing (override the
   generic .hulk-modal margins so content doesn't bunch up). */
.hulk-session-expired-modal .hulk-modal {
  max-width: 420px;
  padding: 30px 28px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 16px;
  text-align: center;
}

.hulk-session-expired-modal .hulk-modal-title {
  margin: 0;
  font-size: 20px;
  font-weight: 700;
  color: var(--hulk-text);
}

.hulk-session-expired-modal .hulk-modal-body {
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
}

.hulk-session-expired-modal .hulk-modal-pin-input {
  margin: 0;
  max-width: 220px;
  margin-left: auto;
  margin-right: auto;
}

.hulk-session-expired-modal .hulk-modal-submit {
  margin: 0;
  padding: 13px;
  font-size: 15px;
}

/* Close (×) button used by billing/confirm modals + history popup.
   Previously undefined, so it rendered as a native button. */
.hulk-bi-row-del {
  border: none;
  background: transparent;
  color: var(--hulk-text-muted);
  font-size: 22px;
  line-height: 1;
  width: 34px;
  height: 34px;
  border-radius: var(--hulk-radius-md);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background var(--hulk-motion-fast), color var(--hulk-motion-fast);
}

.hulk-bi-row-del:hover {
  background: var(--hulk-surface-3);
  color: var(--hulk-text);
}

/* ---- Account modals (Profile / Settings) ------------------------------ */
.hulk-modal-head {
  display: flex;
  align-items: center;
  gap: var(--hulk-space-3);
  margin-bottom: var(--hulk-space-5);
}

.hulk-modal-head-icon {
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  border-radius: var(--hulk-radius-md);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--hulk-tint-flow);
  color: var(--hulk-color-flow);
  font-size: 16px;
}

.hulk-modal-section {
  margin-bottom: var(--hulk-space-5);
}

.hulk-modal-section-title {
  font-size: var(--hulk-font-size-sm);
  font-weight: var(--hulk-font-weight-semibold);
  color: var(--hulk-text);
  margin-bottom: var(--hulk-space-3);
}

.hulk-modal-actions {
  display: flex;
  gap: var(--hulk-space-3);
  justify-content: flex-end;
  margin-top: var(--hulk-space-5);
}

.hulk-modal-btn {
  border: none;
  border-radius: var(--hulk-radius-md);
  padding: 10px 18px;
  font-weight: 600;
  cursor: pointer;
  font-size: var(--hulk-font-size-body);
  transition: filter var(--hulk-motion-fast), background var(--hulk-motion-fast);
}

.hulk-modal-btn-primary {
  background: var(--hulk-gradient-flow);
  color: #fff;
}

.hulk-modal-btn-primary:hover {
  filter: brightness(1.05);
}

.hulk-modal-btn-ghost {
  background: var(--hulk-surface-3);
  color: var(--hulk-text);
  border: 1px solid var(--hulk-border);
}

.hulk-modal-btn-ghost:hover {
  background: var(--hulk-bg-alt);
}

/* ---- Account modals (core/user-chip.js): Profile / Settings -------------
   openModal() wrapped bodyHTML in a bare <div> with no class, so nothing could
   space the body against the action row — every gap came from a bottom margin
   on a child, which then collapsed against its parent's own margin. The
   wrapper now has a name and the rhythm below is explicit. */
.hulk-modal-content {
  display: flex;
  flex-direction: column;
}

/* .hulk-modal-title carries margin-bottom:8px so that the session-expired
   modal (where it is a direct child of a centred flex column) gets breathing
   room. Inside .hulk-modal-head the head is align-items:center, so that same
   8px pushed the title text 4px ABOVE the 40px icon instead of centring it —
   the icon and the text looked misaligned. Scoped to the head only: every
   other module puts an <h3> there and already zeroes its own margin. */
.hulk-modal-head .hulk-modal-title {
  margin-bottom: 0;
}

/* The action row now owns the gap below the body, so the section must not also
   contribute one — two sibling margins collapse to the larger, which made the
   real spacing depend on which value happened to be bigger. */
.hulk-modal-content > .hulk-modal-section {
  margin-bottom: 0;
}

.hulk-modal-content + .hulk-modal-actions {
  margin-top: var(--hulk-space-6);
}

/* Field rhythm as one gap rather than a bottom margin per field. With a
   margin on each, the LAST field's margin was dead space that fought
   .hulk-modal-section's — and fieldRow() was hardcoding 14px inline, which
   silently overrode .hulk-field's 16px from the scale. */
.hulk-modal-fields {
  display: flex;
  flex-direction: column;
  gap: var(--hulk-space-4);
}

.hulk-modal-fields > .hulk-field {
  margin-bottom: 0;
}

/* A lone row IS the whole section (the Settings modal has exactly one). The
   section title already separates it from what's above, and :last-child has
   already dropped its bottom border, so its own 12px top padding just opened a
   24px hole under the title — 12px from the title's margin plus 12px from the
   row. */
.hulk-modal-content .hulk-modal-row:only-child {
  padding-top: 0;
}

/* ---- My Profile modal ---------------------------------------------------
   The base .hulk-modal is 380px wide with 24px of padding, which leaves the
   name and email inputs at 332px — cramped for the one form in the app a user
   opens most often. Widened, with padding to match so the fields do not turn
   into stretched text lines.

   The height is handled with a flex column and a bottom-anchored action row
   rather than a stack of bottom margins: min-height alone would have left a
   dead gap above Save that read as a layout bug. This way the extra space is
   absorbed by the body, and the buttons sit on the panel's bottom edge — which
   is deliberate, and stays correct if a field is ever added here. */
.hulk-modal-profile {
  max-width: 480px;
  min-height: 440px;
  padding: var(--hulk-space-7);
  display: flex;
  flex-direction: column;
}

.hulk-modal-profile .hulk-modal-head {
  margin-bottom: var(--hulk-space-6);
}

.hulk-modal-profile .hulk-modal-content {
  flex: 1;
}

.hulk-modal-profile .hulk-modal-fields {
  gap: var(--hulk-space-5);
}

/* Taller inputs to match the roomier panel — the extra height is content, not
   empty space, so the form still fills the modal honestly. */
.hulk-modal-profile .hulk-field-input {
  padding: 14px 16px;
}

.hulk-modal-profile .hulk-modal-btn {
  padding: 12px 22px;
}

/* Below 480px the panel is already edge-to-edge — .hulk-modal-backdrop only
   pads vertically, never horizontally — so re-adding 32px of panel padding
   would leave the fields unusably narrow. The margin supplies the horizontal
   inset the backdrop does not. */
@media (max-width: 520px) {
  .hulk-modal-profile {
    min-height: 0;
    padding: var(--hulk-space-5);
    margin: 0 var(--hulk-space-3);
  }
}

/* ---- Dispatch-shortage popup (insufficient stock at source location) ----
   The server returns the whole reason as one long sentence, so the client
   parses it into this table. Numbers are tabular-aligned so a multi-line
   shortage list scans as a column, and zero/short values are tinted with
   the existing --hulk-color-blocked token. */
.hulk-shortage-backdrop .hulk-modal {
  max-width: 560px;
}

.hulk-modal-head-icon.is-danger {
  background: #fff3f2;
  color: var(--hulk-color-blocked);
}

.hulk-shortage-lead {
  margin: 0 0 var(--hulk-space-4);
  line-height: 1.5;
}

.hulk-shortage-table-wrap {
  overflow-x: auto;
  border: 1px solid var(--hulk-border-faint);
  border-radius: var(--hulk-radius-md);
}

.hulk-shortage-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--hulk-font-size-sm);
}

.hulk-shortage-table th,
.hulk-shortage-table td {
  padding: 8px 10px;
  text-align: left;
  border-bottom: 1px solid var(--hulk-border-faint);
  white-space: nowrap;
}

.hulk-shortage-table th {
  background: var(--hulk-surface-3);
  color: var(--hulk-text-muted);
  font-weight: var(--hulk-font-weight-semibold);
}

.hulk-shortage-table tbody tr:last-child td {
  border-bottom: none;
}

.hulk-shortage-table .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.hulk-shortage-pid {
  color: var(--hulk-text-muted);
}

.hulk-shortage-table .is-zero,
.hulk-shortage-table .is-short {
  color: var(--hulk-color-blocked);
  font-weight: 700;
}

.hulk-shortage-notes {
  margin: var(--hulk-space-4) 0 0;
  padding-left: 18px;
  color: var(--hulk-text-muted);
  font-size: var(--hulk-font-size-sm);
}

.hulk-shortage-notes li {
  margin-bottom: 4px;
}

/* "Dispatch anyway" override — a destructive action (it writes the sale and
   drives stock negative), so it uses the blocked/danger token rather than
   the brand gradient. */
.hulk-modal-btn-danger {
  background: var(--hulk-color-blocked);
  color: #fff;
}

.hulk-modal-btn-danger:hover {
  filter: brightness(1.05);
}

.hulk-shortage-override-note {
  margin: var(--hulk-space-4) 0 0;
  padding: 10px 12px;
  border: 1px solid #ffd9d6;
  border-radius: var(--hulk-radius-md);
  background: #fff3f2;
  color: #b42318;
  font-size: var(--hulk-font-size-sm);
  line-height: 1.5;
}

.hulk-shortage-override-note i {
  margin-right: 4px;
}

.hulk-modal-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--hulk-space-4);
  padding: var(--hulk-space-3) 0;
  border-bottom: 1px solid var(--hulk-border-faint);
}

.hulk-modal-row:last-child {
  border-bottom: none;
}

.hulk-modal-row-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.hulk-modal-row-label {
  font-size: var(--hulk-font-size-body);
  color: var(--hulk-text);
}

.hulk-modal-row-sub {
  font-size: 12px;
  color: var(--hulk-text-faint);
}

.hulk-switch {
  position: relative;
  width: 42px;
  height: 24px;
  flex-shrink: 0;
  border-radius: var(--hulk-radius-pill);
  border: none;
  background: var(--hulk-border-strong);
  cursor: pointer;
  transition: background var(--hulk-motion-fast);
}

.hulk-switch::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  transition: transform var(--hulk-motion-fast);
  box-shadow: var(--hulk-shadow-sm);
}

.hulk-switch[aria-checked="true"] {
  background: var(--hulk-gradient-flow);
}

.hulk-switch[aria-checked="true"]::after {
  transform: translateX(18px);
}

/* ---- Form validation --------------------------------------------------- */
.hulk-field.has-error .hulk-field-input {
  border-color: var(--hulk-color-blocked);
}

.hulk-field.is-valid .hulk-field-input {
  border-color: var(--hulk-color-close);
}

.hulk-field-message {
  font-size: 12px;
  margin-top: 4px;
  display: none;
}

.hulk-field.has-error .hulk-field-message {
  display: block;
  color: var(--hulk-color-blocked);
}

.hulk-field-input {
  border: 1px solid var(--hulk-border-strong);
  border-radius: var(--hulk-radius-md);
  padding: 11px 14px;
  width: 100%;
  background: var(--hulk-surface);
  font-size: var(--hulk-font-size-body);
  color: var(--hulk-text);
  transition: border-color var(--hulk-motion-fast), box-shadow var(--hulk-motion-fast), background var(--hulk-motion-fast);
}

.hulk-field-input::placeholder {
  color: var(--hulk-text-faint);
}

/* Helper text under a .hulk-field. Sits in the same 4px gap the hidden
   .hulk-field-message uses, so showing one never shifts the control. */
.hulk-field-hint {
  display: block;
  margin-top: 4px;
  font-size: var(--hulk-font-size-xs);
  color: var(--hulk-text-muted);
  line-height: 1.45;
}

.hulk-field-input:hover {
  border-color: var(--hulk-text-faint);
}

.hulk-field-input:focus {
  outline: none;
  border-color: var(--hulk-portal-accent, var(--hulk-accent-admin));
  box-shadow: var(--hulk-ring);
  background: var(--hulk-surface);
}

/* ---- Global form-control baseline -------------------------------------
   Applies the same polished look to ANY raw <input>/<select>/<textarea>
   (not only those carrying .hulk-field-input), so module screens that
   render plain controls still match the design system. Checkboxes,
   radios, buttons and file inputs are intentionally excluded. */
:where(input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="file"]):not([type="range"]):not([type="color"]),
select,
textarea) {
  width: 100%;
  border: 1px solid var(--hulk-border-strong);
  border-radius: var(--hulk-radius-md);
  padding: 11px 14px;
  background: var(--hulk-surface);
  font-size: var(--hulk-font-size-body);
  color: var(--hulk-text);
  font-family: inherit;
  transition: border-color var(--hulk-motion-fast), box-shadow var(--hulk-motion-fast), background var(--hulk-motion-fast);
}

:where(input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="file"]):not([type="range"]):not([type="color"]),
select,
textarea):hover {
  border-color: var(--hulk-text-faint);
}

:where(input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="file"]):not([type="range"]):not([type="color"]),
select,
textarea):focus {
  outline: none;
  border-color: var(--hulk-portal-accent, var(--hulk-accent-admin));
  box-shadow: var(--hulk-ring);
  background: var(--hulk-surface);
}

textarea {
  resize: vertical;
  min-height: 88px;
  line-height: var(--hulk-line-height-base);
}

.hulk-field-label {
  display: block;
  font-size: var(--hulk-font-size-sm);
  font-weight: var(--hulk-font-weight-semibold);
  color: var(--hulk-text-muted);
  margin-bottom: 7px;
}

.hulk-field {
  margin-bottom: var(--hulk-space-4);
}

select.hulk-field-input {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239aa1b6' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  padding-right: 38px;
}

.hulk-form-error-summary {
  display: none;
  background: #fff3f2;
  border: 1px solid #ffd9d6;
  border-radius: var(--hulk-radius-md);
  padding: 12px 16px;
  margin-bottom: 16px;
  font-size: 13px;
}

.hulk-form-error-summary.is-visible {
  display: block;
}

.hulk-form-error-summary a {
  color: var(--hulk-color-blocked);
  font-weight: 600;
}

/* ---- Toast (success / minor) -------------------------------------------- */
.hulk-toast-stack {
  position: fixed;
  top: 16px;
  right: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 95;
}

.hulk-toast {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 240px;
  max-width: 360px;
  padding: 12px 16px;
  border-radius: var(--hulk-radius-md);
  background: var(--hulk-surface);
  box-shadow: var(--hulk-shadow-pop);
  font-size: 13px;
  animation: hulk-toast-in var(--hulk-motion-base);
}

.hulk-toast-icon {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 12px;
  flex-shrink: 0;
}

.hulk-toast.hulk-toast-success .hulk-toast-icon {
  background: var(--hulk-gradient-close);
}

.hulk-toast.hulk-toast-error .hulk-toast-icon {
  background: var(--hulk-gradient-blocked);
}

.hulk-toast.hulk-toast-info .hulk-toast-icon {
  background: var(--hulk-gradient-flow);
}

@keyframes hulk-toast-in {
  from {
    opacity: 0;
    transform: translateY(-8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Full-card success checkmark for major actions (§0.3) */
.hulk-success-overlay {
  position: fixed;
  inset: 0;
  background: rgba(255, 255, 255, 0.9);
  display: none;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 12px;
  z-index: 96;
}

.hulk-success-overlay.is-open {
  display: flex;
}

.hulk-success-overlay-icon {
  width: 84px;
  height: 84px;
  border-radius: 50%;
  background: var(--hulk-gradient-close);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 36px;
  animation: hulk-pop-in var(--hulk-motion-base);
}

@keyframes hulk-pop-in {
  from {
    transform: scale(0.6);
    opacity: 0;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}
