/*
Attachment

A file or source as a thumbnail (grid), a chip (inline) or a row (list).
The container's data-variant sets every item's layout in CSS; an item's
own data-variant overrides it. Progress, errors and the remove button sit
over the item or in space it always has, so uploading, failing, hovering
and removing never change its size.

  .attachments[data-variant]                 grid | inline | list
  .attachment[data-category][data-state]     idle | uploading | error
    .attachment-body > .attachment-preview, .attachment-info
      .attachment-link                       stretched link (href), inside the body so it is the hover card trigger too
    .attachment-progress > .attachment-progress-bar
    .attachment-remove
  .attachment-card                           hover card preview
  .attachment-empty
*/

@layer components {

.attachments {
  display:     flex;
  flex-wrap:   wrap;
  align-items: flex-start;
  gap:         var(--space-2);
  min-width:   0;
}

/* The grid sits at the inline end, as the reference's ml-auto w-fit does,
   packed by the content rather than an outer margin. */
.attachments[data-variant="grid"] {
  justify-content: flex-end;
}

/* Focus lands on the list only when its last item is removed from the keyboard. */
.attachments:focus-visible {
  outline:       none;
  box-shadow:    var(--focus-ring);
  border-radius: var(--radius-control);
}

.attachments[data-variant="list"] {
  flex-direction: column;
  align-items:    stretch;
  flex-wrap:      nowrap;
}

/* Grid (the default) */

.attachment {
  --attachment-tile: calc(var(--control-height-lg) * 2);

  position:      relative;
  flex:          none;
  width:         var(--attachment-tile);
  height:        var(--attachment-tile);
  overflow:      hidden;
  border:        var(--surface-border-width) solid var(--surface-border);
  border-radius: var(--radius-surface);
  background:    var(--bg-muted);
  color:         var(--ink);
  font-family:   var(--font-ui);
  font-size:     var(--text-ui);
}

.attachment-body {
  display:     flex;
  align-items: center;
  width:       100%;
  height:      100%;
  min-width:   0;
}

.attachment-body:focus-visible {
  outline:    none;
  box-shadow: inset 0 0 0 var(--focus-ring-width) var(--focus);
}

.attachment-preview {
  display:         flex;
  flex:            none;
  align-items:     center;
  justify-content: center;
  width:           100%;
  height:          100%;
  overflow:        hidden;
  color:           var(--ink-dim);
}

.attachment :is(.attachment-preview, .attachment-card-preview) > svg.attachment-fallback,
.attachment :is(.attachment-preview, .attachment-card-preview)[data-broken] > img {
  display: none;
}

.attachment :is(.attachment-preview, .attachment-card-preview)[data-broken] > svg.attachment-fallback {
  display: block;
}

.attachment-preview > img,
.attachment-preview > video {
  display:    block;
  width:      100%;
  height:     100%;
  object-fit: cover;
}

.attachment-preview > svg {
  width:  var(--icon-size);
  height: var(--icon-size);
}

/* Grid hides the name visually; screen readers still read it. */
.attachment-info {
  position:    absolute;
  width:       1px;
  height:      1px;
  overflow:    hidden;
  clip-path:   inset(50%);
  white-space: nowrap;
}

.attachment-name,
.attachment-meta {
  display:       block;
  overflow:      hidden;
  white-space:   nowrap;
  text-overflow: ellipsis;
}

.attachment-meta {
  color:     var(--ink-dim);
  font-size: var(--text-caption);
}

.attachment-remove.button {
  position:   absolute;
  top:        var(--space-1-5);
  inset-inline-end: var(--space-1-5);
  z-index:    var(--z-raised);
  width:      calc(var(--control-height-sm) * 0.75);
  height:     calc(var(--control-height-sm) * 0.75);
  padding:    0;
  border-radius: var(--radius-full);
  background: color-mix(in oklab, var(--bg) 85%, transparent);
  color:      var(--ink);
  opacity:    0;
  transition: opacity var(--duration-fast) var(--ease-out);
}

.attachment-remove.button:hover {
  background: var(--bg);
}

.attachment-remove.button svg {
  width:  var(--icon-size-sm);
  height: var(--icon-size-sm);
}

.attachment:hover > .attachment-remove,
.attachment:focus-within > .attachment-remove,
.attachment-remove:focus-visible {
  opacity: 1;
}

@media (hover: none) {
  .attachment-remove.button {
    opacity: 1;
  }
}

/* A stretched link: the whole item opens the file. */
.attachment-link {
  position: absolute;
  inset:    0;
  border-radius: inherit;
}

.attachment-link:focus-visible {
  outline:    none;
  box-shadow: inset 0 0 0 var(--focus-ring-width) var(--focus);
}

/* Progress: a bar along the bottom edge, over the item. */
.attachment-progress {
  position:   absolute;
  inset:      auto 0 0 0;
  height:     var(--space-1);
  background: color-mix(in oklab, var(--ink) 15%, transparent);
}

.attachment-progress-bar {
  display:          block;
  width:            100%;
  height:           100%;
  background:       var(--accent);
  transform:        scaleX(var(--attachment-progress));
  transform-origin: left;
  transition:       transform var(--duration-fast) var(--ease-out);
}

.attachment-progress-bar:dir(rtl) {
  transform-origin: right;
}

.attachment-progress {
  --attachment-progress: 0;
}

.attachment[data-state="uploading"] .attachment-preview > :is(img, video) {
  opacity: var(--opacity-muted);
}

.attachment[data-state="error"] {
  border-color: var(--danger);
}

.attachment[data-state="error"] .attachment-preview {
  color: var(--danger);
}

.attachment[data-state="error"] .attachment-meta {
  color: var(--danger);
}

/* Inline */

:is(.attachments[data-variant="inline"] .attachment:not([data-variant]), .attachment[data-variant="inline"]) {
  width:         auto;
  max-width:     calc(var(--container-xs) * 0.7);
  height:        var(--control-height-sm);
  padding:       0 var(--space-1-5);
  border:        var(--control-border-width) solid var(--control-border);
  border-radius: var(--radius-control);
  background:    var(--control-bg);
  font-size:     var(--text-ui-sm);
  font-weight:   var(--weight-ui);
  transition:    background-color var(--duration-fast) var(--ease-out);
}

:is(.attachments[data-variant="inline"] .attachment:not([data-variant]), .attachment[data-variant="inline"]):hover {
  background: var(--item-highlight);
}

:is(.attachments[data-variant="inline"] .attachment:not([data-variant]), .attachment[data-variant="inline"]) .attachment-body {
  gap: var(--space-1-5);
}

:is(.attachments[data-variant="inline"] .attachment:not([data-variant]), .attachment[data-variant="inline"]) .attachment-preview {
  width:         calc(var(--control-height-sm) - var(--space-3));
  height:        calc(var(--control-height-sm) - var(--space-3));
  border-radius: var(--radius-xs);
  background:    var(--bg-muted);
}

:is(.attachments[data-variant="inline"] .attachment:not([data-variant]), .attachment[data-variant="inline"]) .attachment-preview > svg {
  width:  var(--icon-size-sm);
  height: var(--icon-size-sm);
}

/* Inline and list show the name. */
:is(.attachments:is([data-variant="inline"], [data-variant="list"]) .attachment:not([data-variant]), .attachment:is([data-variant="inline"], [data-variant="list"])) .attachment-info {
  position:  static;
  flex:      1 1 auto;
  width:     auto;
  height:    auto;
  min-width: 0;
  overflow:  hidden;
  clip-path: none;
}

/* The inline chip keeps its meta (type, size, progress, error) for screen
   readers only, so a chip is one line and an error never widens it. */
:is(.attachments[data-variant="inline"] .attachment:not([data-variant]), .attachment[data-variant="inline"]) .attachment-meta {
  position:  absolute;
  width:     1px;
  height:    1px;
  overflow:  hidden;
  clip-path: inset(50%);
}

/* The remove button takes its own slot in the chip, revealed on hover. */
:is(.attachments[data-variant="inline"] .attachment:not([data-variant]), .attachment[data-variant="inline"]) {
  display:     flex;
  align-items: center;
  gap:         var(--space-1);
}

:is(.attachments[data-variant="inline"] .attachment:not([data-variant]), .attachment[data-variant="inline"]) .attachment-body {
  flex:  1 1 auto;
  width: auto;
}

:is(.attachments[data-variant="inline"] .attachment:not([data-variant]), .attachment[data-variant="inline"]) .attachment-remove.button {
  position:      relative;
  inset:         auto;
  flex:          none;
  width:         calc(var(--control-height-sm) - var(--space-3));
  height:        calc(var(--control-height-sm) - var(--space-3));
  border-radius: var(--radius-xs);
  background:    transparent;
}

:is(.attachments[data-variant="inline"] .attachment:not([data-variant]), .attachment[data-variant="inline"]) .attachment-remove.button:hover {
  background: var(--bg-muted);
}

:is(.attachments[data-variant="inline"] .attachment:not([data-variant]), .attachment[data-variant="inline"]) .attachment-progress {
  height: var(--space-0-5);
}

/* List */

:is(.attachments[data-variant="list"] .attachment:not([data-variant]), .attachment[data-variant="list"]) {
  display:       flex;
  align-items:   center;
  gap:           var(--space-3);
  width:         100%;
  height:        auto;
  padding:       var(--space-3);
  border:        var(--surface-border-width) solid var(--surface-border);
  border-radius: var(--radius-surface);
  background:    var(--surface-bg);
  transition:    background-color var(--duration-fast) var(--ease-out);
}

:is(.attachments[data-variant="list"] .attachment:not([data-variant]), .attachment[data-variant="list"]):hover {
  background: var(--item-highlight);
}

:is(.attachments[data-variant="list"] .attachment:not([data-variant]), .attachment[data-variant="list"]) .attachment-body {
  flex: 1 1 auto;
  gap:  var(--space-3);
}

:is(.attachments[data-variant="list"] .attachment:not([data-variant]), .attachment[data-variant="list"]) .attachment-preview {
  width:         var(--control-height-lg);
  height:        var(--control-height-lg);
  border-radius: var(--radius-control);
  background:    var(--bg-muted);
}

/* The list's meta line is always there, so an error or progress fills it, never adds it. */
:is(.attachments[data-variant="list"] .attachment:not([data-variant]), .attachment[data-variant="list"]) .attachment-info {
  display:        flex;
  flex-direction: column;
  gap:            var(--space-0-5);
}

:is(.attachments[data-variant="list"] .attachment:not([data-variant]), .attachment[data-variant="list"]) .attachment-meta:empty::before {
  content: "\00a0";
}

:is(.attachments[data-variant="list"] .attachment:not([data-variant]), .attachment[data-variant="list"]) .attachment-remove.button {
  position:      relative;
  inset:         auto;
  flex:          none;
  width:         var(--control-height-sm);
  height:        var(--control-height-sm);
  border-radius: var(--radius-control);
  background:    transparent;
  opacity:       1;
}

:is(.attachments[data-variant="list"] .attachment:not([data-variant]), .attachment[data-variant="list"]) .attachment-remove.button svg {
  width:  var(--icon-size);
  height: var(--icon-size);
}

:is(.attachments[data-variant="list"] .attachment:not([data-variant]), .attachment[data-variant="list"]) .attachment-remove.button:hover {
  background: var(--bg-muted);
}

/* Hover Card */

.attachment-hover-card.popover {
  width:   auto;
  padding: var(--space-2);
}

.attachment-card {
  display:        flex;
  flex-direction: column;
  gap:            var(--space-1);
  max-width:      calc(var(--container-xs) * 0.7);
  font-size:      var(--text-ui-sm);
}

.attachment-card-preview {
  display:         flex;
  align-items:     center;
  justify-content: center;
  width:           calc(var(--control-height-lg) * 4);
  max-width:       100%;
  aspect-ratio:    4 / 3;
  overflow:        hidden;
  border-radius:   var(--radius-control);
  background:      var(--bg-muted);
  color:           var(--ink-dim);
}

.attachment-card-preview > img,
.attachment-card-preview > video {
  width:      100%;
  height:     100%;
  object-fit: cover;
}

.attachment-card-preview > svg {
  width:  var(--icon-size-lg);
  height: var(--icon-size-lg);
}

.attachment-card-name {
  overflow:      hidden;
  font-weight:   var(--weight-ui);
  white-space:   nowrap;
  text-overflow: ellipsis;
}

.attachment-card-meta {
  color:     var(--ink-dim);
  font-size: var(--text-caption);
}

/* Empty */

.attachment-empty {
  display:         flex;
  align-items:     center;
  justify-content: center;
  padding:         var(--space-4);
  color:           var(--ink-dim);
  font-family:     var(--font-ui);
  font-size:       var(--text-ui);
}

}
