/**
 * Vault (drawer / sheet) presentation — Base UI Drawer skinned with quanta
 * tokens. Registers the colocated source (quanta is symlinked) and authors the
 * surface as `@utility q-vault-*`. The drawer width is the one non-token value,
 * exposed as the overridable `--q-vault-width` component dimension whose default
 * lives in the generated component tier (src/css/components/component.css :root).
 * Base UI drives the drag via `--drawer-swipe-movement-*`.
 */
@source "./vault.tsx";

/* Required wrapper around the Popup — Base UI binds swipe/drag + snap handling
 * and touch scroll-locking here. A non-blocking full-screen layer; the Popup
 * keeps its own fixed edge-docking (the viewport sets no transform, so the
 * Popup's `position: fixed` resolves against the browser viewport). */
@utility q-vault-viewport {
  position: fixed;
  inset: var(--hf-space-0);
  z-index: var(--hf-z-index-modal);
  pointer-events: none;

  & > * { pointer-events: auto; }
}

@utility q-vault-backdrop {
  position: fixed;
  inset: var(--hf-space-0);
  z-index: var(--hf-z-index-overlay);
  background-color: var(--hf-color-overlay-scrim);
  /* Fade with the dismiss drag — Base UI feeds `--drawer-swipe-progress`
   * (0 at rest → 1 when dismissed) and leaves the opacity to us. */
  opacity: calc(1 - var(--drawer-swipe-progress, 0));
  transition: opacity var(--hf-duration-400) var(--hf-ease-emphasized);

  &[data-starting-style],
  &[data-ending-style] { opacity: 0; }
}

/* The docked sheet — glassy frosted surface (matches the Modal glass).
 *
 * Transform model (the per-side rules below set it): Base UI leaves `transform`
 * to us and feeds two CSS vars — `--drawer-snap-point-offset` (the resting
 * offset for the active snap point, already sign-corrected per direction) and
 * `--drawer-swipe-movement-{x,y}` (the live drag delta). The open/dragging
 * position is their SUM; the closed state overrides with a full off-edge shift.
 * `touch-action` is intentionally NOT set here — Base UI's Popup applies a
 * direction-aware value inline so touch drag + inner scroll both work. */
@utility q-vault {
  position: fixed;
  z-index: var(--hf-z-index-modal);
  display: flex;
  flex-direction: column;
  background-color: var(--hf-color-background-glass);
  backdrop-filter: blur(var(--hf-space-1000)); /* 40px — glass */
  border: var(--hf-border-width-thin) solid var(--hf-color-border-subtle);
  color: var(--hf-color-text-primary);
  box-shadow:
    inset 0 var(--hf-space-050) 3px var(--hf-color-transparent-light-05), /* no token: 3px blur radius has no spacing token (4px=--hf-space-100 differs) */
    0 var(--hf-space-100) var(--hf-space-600) calc(-1 * var(--hf-space-200)) var(--hf-color-transparent-dark-15);

  /* swipe-strength (0.1–1, set by Base UI on release) scales the snap duration. */
  transition: transform calc(var(--hf-duration-400) * var(--drawer-swipe-strength, 1)) var(--hf-ease-emphasized);

  &[data-swiping] { transition: none; } /* follow the finger, no easing */

  /* Edge-fill — a glass slab that continues past the docked (square) edge so a
   * rubber-band overshoot never reveals the page. It meets the sheet's flat
   * edge (the rounded corners are on the opposite side), so corners stay clean.
   * No `overflow: hidden` on the sheet, or this would be clipped. Off-screen at
   * rest; the per-side rules give it direction. */
  &::after {
    content: "";
    position: absolute;
    background-color: var(--hf-color-background-glass);
    backdrop-filter: blur(var(--hf-space-1000));
    pointer-events: none;
  }
}

/* ── Edge docking: open/drag position = snap offset + live drag; closed = off-edge ── */
@utility q-vault-bottom {
  inset-inline: var(--hf-space-0);
  bottom: var(--hf-space-0);
  width: 100%;
  max-height: 90vh;
  border-bottom: none;
  transform: translateY(calc(var(--drawer-snap-point-offset, 0px) + var(--drawer-swipe-movement-y, 0px)));
  &[data-starting-style], &[data-ending-style] { transform: translateY(100%); }
  &::after { top: 100%; inset-inline: var(--hf-space-0); height: 100vh; } /* fill below */
}
@utility q-vault-top {
  inset-inline: var(--hf-space-0);
  top: var(--hf-space-0);
  width: 100%;
  max-height: 90vh;
  border-top: none;
  transform: translateY(calc(var(--drawer-snap-point-offset, 0px) + var(--drawer-swipe-movement-y, 0px)));
  &[data-starting-style], &[data-ending-style] { transform: translateY(-100%); }
  &::after { bottom: 100%; inset-inline: var(--hf-space-0); height: 100vh; } /* fill above */
}
@utility q-vault-left {
  inset-block: var(--hf-space-0);
  left: var(--hf-space-0);
  height: 100%;
  width: min(var(--q-vault-width), 100vw);
  border-left: none;
  transform: translateX(calc(var(--drawer-snap-point-offset, 0px) + var(--drawer-swipe-movement-x, 0px)));
  &[data-starting-style], &[data-ending-style] { transform: translateX(-100%); }
  &::after { right: 100%; inset-block: var(--hf-space-0); width: 100vw; } /* fill left */
}
@utility q-vault-right {
  inset-block: var(--hf-space-0);
  right: var(--hf-space-0);
  height: 100%;
  width: min(var(--q-vault-width), 100vw);
  border-right: none;
  transform: translateX(calc(var(--drawer-snap-point-offset, 0px) + var(--drawer-swipe-movement-x, 0px)));
  &[data-starting-style], &[data-ending-style] { transform: translateX(100%); }
  &::after { left: 100%; inset-block: var(--hf-space-0); width: 100vw; } /* fill right */
}

/* Grab handle (decorative). */
@utility q-vault-handle {
  flex: none;
  width: var(--hf-space-1000);
  height: var(--hf-space-100);
  margin: var(--hf-space-300) auto var(--hf-space-100);
  border-radius: var(--hf-radius-full);
  background-color: var(--hf-color-border-strong);
}

@utility q-vault-header {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--hf-space-300);
  padding: var(--hf-space-400) var(--hf-space-500);
}

/* Leading group — start + title + end, kept together at the leading edge so the
 * close disc stays trailing (space-between). Only rendered when a flank slot set. */
@utility q-vault-header-lead {
  display: flex;
  align-items: center;
  gap: var(--hf-space-300);
  min-width: var(--hf-space-0);
}

@utility q-vault-title {
  @apply text-q-body-md-semi-bold;
  color: var(--hf-color-text-primary);
}

@utility q-vault-description {
  @apply text-q-body-sm-regular;
  color: var(--hf-color-text-secondary);
}

/* The dismiss disc is the shared CloseButton (q-close, node 2052:109). */

/* Scrollable content region. */
@utility q-vault-body {
  flex: 1 1 auto;
  min-height: var(--hf-space-0);
  overflow: auto;
  padding: var(--hf-space-0) var(--hf-space-500) var(--hf-space-500);
}

@utility q-vault-footer {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--hf-space-300);
  padding: var(--hf-space-400) var(--hf-space-500);
  border-top: var(--hf-border-width-thin) solid var(--hf-color-border-subtle);
}

@utility q-vault-caption {
  @apply text-q-caption-sm-regular;
  color: var(--hf-color-text-secondary);
}

@utility q-vault-actions {
  display: flex;
  align-items: center;
  gap: var(--hf-space-200);
}

/* Full-width actions (e.g. a single primary sheet button). */
@utility q-vault-actions-full {
  flex: 1 1 var(--hf-space-0);
}

@media (prefers-reduced-motion: reduce) {
  .q-vault,
  .q-vault-backdrop { transition-duration: var(--hf-duration-120); }
  .q-vault[data-swiping] { transition: none; }
}
