/* The actions bar that sits in a list header, and the sort menu it opens.
 * Shared by the holdings list and the transactions list — same component,
 * same markup shape, so it lives in one place. */
@layer components {
  .actions-bar {
    align-items: center;
    color: var(--color-ink-medium);
    display: flex;
    gap: var(--inline-space);

    /* base.css paints a classless <a> link-blue. Two of this bar's controls
       come from link_to and carry no class, so they took the blue while the
       <label> and .sort-menu kept the ink above - the colour tracked whether
       an anchor happened to have a class attribute, not whether it did
       something. Every control here is equally interactive, so they all take
       the bar's own colour. This wins on layer, not specificity: components
       beats base. */
    a {
      color: inherit;
    }

    /* An inline-block .icon rests on the text baseline, so an inline wrapper
       grows by the font's descender and the icon rides high inside it. This
       bar centres its children, so wrappers of different heights land their
       icons at different heights - the calendar sat 3.6px below the download
       arrow. Making each wrapper hug its icon lines them all up. .sort-menu
       already flexes, so this only restates what it does. */
    :is(a, label):has(> .icon) {
      display: flex;
    }
  }

  .actions-bar__icon {
    --icon-size: var(--icon-lg);

    cursor: pointer;
  }

  /* Sort direction is a checkbox: one arrow per state */
  .sort-direction {
    .icon-sort-desc { display: none; }

    &:has(:checked) {
      .icon-sort-asc { display: none; }
      .icon-sort-desc { display: inline-block; }
    }
  }

  .sort-menu {
    align-items: flex-end;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    gap: var(--block-space);
    position: relative;
  }

  /* The trigger shows whichever attribute is active. This used to be an inline
     <style> in transactions/_actions.html.erb setting `content: url("...")` -
     that paints a fixed-colour image, so it could not follow currentColor and
     never inverted in dark mode. Driving --svg instead makes it a mask, which
     does, and the rule lives in CSS rather than in the view. */
  .sort-menu__glyph {
    --icon-size: var(--icon-lg);

    &[data-sort-by="date"] { --svg: url("/assets/calendar-44568894.svg"); }
    &[data-sort-by="amount"] { --svg: url("/assets/banknotes-994eff05.svg"); }
  }

  /* Opening should read as instant. Three things decide that, and the duration
     is the least of them:

     - ease-out, not ease-in-out. An ease-in start is read as lag on something
       that should be there the moment you click. --ease-out-expo puts most of
       the motion in the first third.
     - 0.95, not 0. Growing from nothing means the whole distance has to be
       travelled inside the duration; a 5% delta is most of the perceptual
       work for none of the time.
     - opacity carries the rest. It and scale are the only two properties that
       stay on the compositor.

     Closed, the panel is now full-size rather than zero-scaled, so it would
     still swallow clicks - hence pointer-events. That flips instantly, which
     is what you want. prefers-reduced-motion is handled globally in
     _reset.css. */
  .sort-menu__panel {
    inset-block-start: 3rem;
    opacity: 0;
    pointer-events: none;
    position: absolute;
    scale: 0.95;
    transform-origin: top right;
    transition:
      opacity 120ms var(--ease-out-expo),
      scale 120ms var(--ease-out-expo);
    z-index: var(--z-nav);

    &.is-open {
      opacity: 1;
      pointer-events: auto;
      scale: 1;
    }
  }

  .sort-menu__options {
    background-color: var(--color-canvas);
    border-radius: 0.5em;
    border: var(--border);
    box-shadow: var(--shadow);
    font-size: var(--text-small);
    inline-size: 12rem;
  }

  .sort-menu__option {
    align-items: center;
    cursor: pointer;
    display: flex;
    gap: var(--inline-space);
    padding-block: var(--block-space);
    padding-inline-start: var(--inline-space);

    & + & {
      border-block-start: var(--border);
    }

    /* The checkmark only shows against the selected attribute */
    .sort-menu__check {
      visibility: hidden;
    }

    &:has(input:checked) .sort-menu__check {
      visibility: visible;
    }
  }

  .sort-menu__option-icon {
    --icon-size: var(--icon-sm);
  }
}
