@layer cinder.tokens, cinder.foundation, cinder.components, cinder.utilities;
@layer cinder.components {
  /* ========================================
 * DRAWER
 * Edge-anchored (left/right/bottom) slide-in panel.
 * The <dialog> fills the viewport so backdrop-click on dialog is reliable;
 * the visible panel is a child absolutely positioned at the chosen edge.
 * ======================================== */

  .cinder-drawer {
    border: none;
    background: transparent;
    padding: 0;
    margin: 0;
    position: fixed;
    inset: 0;
    width: 100vw;
    height: 100dvh;
    max-width: none;
    max-height: none;
    z-index: var(--cinder-z-modal);
  }

  .cinder-drawer::backdrop {
    background-color: var(--cinder-overlay-backdrop);
    backdrop-filter: blur(var(--cinder-overlay-blur));
    transition:
      background-color var(--cinder-duration-normal) var(--cinder-ease-standard),
      backdrop-filter var(--cinder-duration-normal) var(--cinder-ease-standard);
    /* `::backdrop` is added to/removed from the top layer as a discrete step
     (like `display`), so `@starting-style` below needs `allow-discrete` to
     actually engage on insertion instead of silently no-op'ing. */
    transition-behavior: allow-discrete;
  }

  .cinder-drawer[data-cinder-closing]::backdrop {
    background-color: transparent;
    backdrop-filter: blur(0);
  }

  .cinder-drawer[data-cinder-modal='false'] {
    pointer-events: none;
  }

  .cinder-drawer[data-cinder-modal='false'] .cinder-drawer__panel {
    pointer-events: auto;
  }

  /* Without this, the backdrop had no FROM state to transition from on open —
   it fades out on close (via the rule above) but snapped to full opacity
   instantly on open, which read as an asymmetric "eases out, pops in". */
  @starting-style {
    .cinder-drawer::backdrop {
      background-color: transparent;
      backdrop-filter: blur(0);
    }
  }

  .cinder-drawer__panel {
    position: absolute;
    max-width: 100vw;
    background: var(--cinder-surface-raised);
    box-shadow: var(--cinder-shadow-lg);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    opacity: 1;
    transition:
      translate var(--cinder-duration-normal) var(--cinder-ease-spring),
      opacity var(--cinder-duration-normal) var(--cinder-ease-standard);
  }

  .cinder-drawer__portal-scope {
    display: contents;
    pointer-events: auto;
  }

  /* Each placement block owns its slide vector via --_cinder-drawer-slide;
   the single closing rule and single @starting-style rule below consume it,
   so adding a placement means ONE block here — no per-placement motion
   twins to keep in sync. */
  .cinder-drawer__panel[data-cinder-placement='right'] {
    --_cinder-drawer-slide: 100% 0;

    top: 0;
    bottom: 0;
    right: 0;
    left: auto;
    height: 100%;
    border-inline-start: 1px solid var(--cinder-border);
  }

  .cinder-drawer__panel[data-cinder-placement='left'] {
    --_cinder-drawer-slide: -100% 0;

    top: 0;
    bottom: 0;
    left: 0;
    right: auto;
    height: 100%;
    border-inline-end: 1px solid var(--cinder-border);
  }

  /* Width tokens size the side placements. The bottom-placement block below
   is declared LATER at equal specificity, so its full-viewport width wins
   over any size token without per-rule exclusions. */
  .cinder-drawer__panel[data-cinder-size='sm'] {
    width: min(20rem, 100vw);
  }
  .cinder-drawer__panel[data-cinder-size='md'] {
    width: min(28rem, 100vw);
  }
  .cinder-drawer__panel[data-cinder-size='lg'] {
    width: min(36rem, 100vw);
  }
  .cinder-drawer__panel[data-cinder-size='xl'] {
    width: min(48rem, 100vw);
  }

  .cinder-drawer__panel[data-cinder-placement='bottom'] {
    --_cinder-drawer-slide: 0 100%;

    left: 0;
    right: 0;
    bottom: 0;
    /* Declared after the size tokens so this always wins: the bottom
     placement spans the full viewport width regardless of `size`. */
    width: 100%;
    /* Physically bottom-anchored, so the viewport cap, the exposed edge's
     border, and the rounded corners all stay physical too — logical
     properties would rotate away from the top edge in vertical writing
     modes while the panel itself stays pinned to the bottom. */
    max-height: 90dvh;
    border-top: 1px solid var(--cinder-border);
    border-top-left-radius: var(--cinder-radius-lg);
    border-top-right-radius: var(--cinder-radius-lg);
  }

  .cinder-drawer__drag-handle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    /* 44px minimum touch target. */
    min-height: var(--cinder-touch-target-min);
    flex-shrink: 0;
    /* The handle is decorative until swipe-to-close ships — no grab cursor. */
    cursor: default;
    user-select: none;
  }

  .cinder-drawer__drag-handle-pill {
    display: block;
    width: 2.5rem;
    height: 0.25rem;
    border-radius: var(--cinder-radius-full);
    background: var(--cinder-border);
  }

  .cinder-drawer__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--cinder-space-4);
    padding: var(--cinder-space-4) var(--cinder-space-5);
    border-block-end: 1px solid var(--cinder-border-muted);
    flex-shrink: 0;
    background: var(--cinder-surface);
  }

  .cinder-drawer__title {
    margin: 0;
    font-size: var(--cinder-text-lg);
    font-weight: var(--cinder-font-semibold);
    line-height: var(--cinder-leading-snug);
    color: var(--cinder-text-default);
    flex: 1;
    min-width: 0;
  }

  .cinder-drawer__close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    /* 44px minimum touch target. */
    width: 2.75rem;
    height: 2.75rem;
    padding: var(--cinder-space-1);
    border-radius: var(--cinder-radius-md);
    border: none;
    background: transparent;
    color: var(--cinder-text-muted);
    cursor: pointer;
    transition:
      background-color var(--cinder-duration-fast) var(--cinder-ease-standard),
      color var(--cinder-duration-fast) var(--cinder-ease-standard);
  }

  /* Sticky-hover suppression on touch. */
  @media (hover: hover) {
    .cinder-drawer__close:hover {
      background: color-mix(in oklch, currentColor, transparent 85%);
      color: var(--cinder-text-default);
    }
  }

  /* The close button sits in the panel corner, and the panel has
   `overflow: hidden`. An outset box-shadow ring would be clipped there, so
   paint an INSET ring (Strategy B-inset) within the button's own border box. */
  .cinder-drawer__close:focus-visible {
    outline: var(--cinder-ring-width) solid transparent;
    box-shadow: inset 0 0 0 var(--cinder-ring-width)
      var(--_cinder-drawer-close-ring, var(--cinder-ring-color));
  }

  @media (forced-colors: active) {
    .cinder-drawer__close:focus-visible {
      outline: var(--cinder-ring-width) solid ButtonText;
      outline-offset: calc(var(--cinder-ring-width) * -1);
    }
  }

  .cinder-drawer__close-icon {
    width: 1.25rem;
    height: 1.25rem;
  }

  .cinder-drawer__body {
    --_cinder-scroll-fade-color: var(--cinder-surface);

    flex: 1;
    min-block-size: 0;
    overflow-y: auto;
    padding: var(--cinder-space-6);
    overscroll-behavior: contain;
    scrollbar-gutter: stable;
    background: var(--cinder-surface);
  }

  /* Suppress the focus ring only for programmatic (open-effect) focus — the
 * body container is the drawer's initial focus target, and keyboard-driven
 * `:focus-visible` focus keeps its indication (the former Sheet's policy;
 * the pre-merge unconditional reset silenced keyboard indication too). */
  .cinder-drawer__body:focus:not(:focus-visible) {
    /* cinder-focus-ring-owner: parent */
    outline: none;
  }

  .cinder-drawer__footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--cinder-space-3);
    padding: var(--cinder-space-3) var(--cinder-space-5);
    border-block-start: 1px solid var(--cinder-border-muted);
    flex-shrink: 0;
    background: var(--cinder-surface);
  }

  /* ----------------------------------------
 * Motion — slide from the anchored edge.
 * Animation targets the panel, not the dialog (which is transparent).
 * The slide vector comes from --_cinder-drawer-slide, declared once per
 * placement block above; a placement whose block forgets the property
 * gets `translate: none` here — visible immediately — instead of a
 * silently missing @starting-style twin.
 * ---------------------------------------- */

  .cinder-drawer__panel[data-cinder-closing] {
    translate: var(--_cinder-drawer-slide);
    opacity: 0.85;
    pointer-events: none;
  }

  @starting-style {
    .cinder-drawer__panel {
      translate: var(--_cinder-drawer-slide);
      opacity: 0.85;
    }
  }

  @media (prefers-reduced-motion: reduce) {
    :root:not([data-cinder-reduced-motion='false']):not([data-reduced-motion='off'])
      .cinder-drawer__panel {
      transition: none;
    }

    :root:not([data-cinder-reduced-motion='false']):not([data-reduced-motion='off'])
      .cinder-drawer::backdrop {
      transition: none;
    }
  }
}
