@use '../tokens' as t;

.wrap {
  @include t.control;
  display: flex;
  flex-direction: column;
  gap: t.space(2);

  &:focus-within {
    border-color: t.role('accent');
    outline: t.stroke(thick) solid t.role('accent');
    outline-offset: 1px;
  }

  &[data-disabled='true'] {
    background: t.role('bg-soft');
    color: t.role('fg-muted');
  }

  &:has([aria-invalid='true']) {
    border-color: t.role('danger');
  }
}

// The wrapper owns the box; the native control is transparent inside it. Its own button is
// styled rather than replaced — it is already focusable, keyboard-driven and localised.
.input {
  min-inline-size: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  outline: none;

  &::file-selector-button {
    @include t.transition(background-color, border-color);
    margin-inline-end: t.space(3);
    border: 1px solid t.role('line');
    border-radius: t.radius(md);
    background: t.role('surface');
    color: t.role('fg-strong');
    font: inherit;
    font-weight: t.weight(medium);
    padding-block: t.space(1);
    padding-inline: t.space(3);
    cursor: pointer;
  }

  &::file-selector-button:hover {
    background: t.role('bg-soft');
    border-color: t.role('accent');
  }

  // Dimmed directly: a pseudo-element is never itself `:disabled`, so `@include t.disabled` here
  // compiled to a selector nothing matches (`disabled-dim.test.ts`).
  &:disabled::file-selector-button {
    opacity: 0.55;
    cursor: not-allowed;
  }
}

.progress {
  display: block;
  block-size: 0.375rem;
  border-radius: t.radius(pill);
  background: t.role('bg-soft');
  overflow: hidden;
  // Bounds the layout pass the `.bar` transition below costs to this subtree. See the note there.
  contain: layout;
}

// The upload bar. `inline-size` is a LAYOUT-triggering property and a transition on one is not
// compositor-only, which is a real cost and a deliberate trade — the compositor-safe form is
// `transform: scaleX()`, and `transform-origin` has no logical keyword, so the bar would grow from
// the physical left edge and fill away from the reading edge under `dir="rtl"`. A progress bar that
// runs backwards in Arabic is a worse defect than a layout pass. `contain: layout` on the track is
// what bounds the cost instead: the invalidation stops at the track, so nothing outside it is
// re-laid-out per frame. `layout` alone and NOT `layout size` — `size` makes a box ignore its
// contents in both axes, and FileInput's track takes its inline size from its containing block.
//
// Inline-start, not `left`: the bar has to fill from the reading edge under `dir="rtl"` too.
.bar {
  display: block;
  block-size: 100%;
  inline-size: var(--file-progress, 0%);
  border-start-start-radius: t.radius(pill);
  border-end-start-radius: t.radius(pill);
  background: t.role('accent');
  @include t.transition(inline-size);
}

.size-sm {
  padding-block: t.space(1);
  font-size: t.text(sm);
}

.size-md {
  padding-block: t.space(2);
}

.size-lg {
  padding-block: t.space(3);
  font-size: t.text(lg);
}
