@layer components {
  .invoices-page {
    padding-block-end: 3rem;
  }

  .invoices-header__btn-icon {
    font-size: 1.125rem;
    font-weight: 300;
    line-height: 1;
  }

  .invoices-body {
    padding-block-start: 2.5rem;
  }

  .invoices-toolbar {
    align-items: center;
    display: flex;
    justify-content: space-between;
    margin-block-end: 2rem;
  }

  .invoices-toolbar__manage {
    background: none;
    border: none;
    color: var(--color-brand);
    cursor: pointer;
    flex-shrink: 0;
    font-size: 0.9375rem;
    font-weight: 600;
    margin-inline-start: auto;
    padding: 0;
    white-space: nowrap;
  }

  .invoices-manage {
    align-items: center;
    display: none;
    flex-shrink: 0;
    gap: 0.75rem;
    margin-inline-start: 1rem;
  }

  /* The group of actions (Copy / Export / Delete). Same `gap` as
     `.invoices-manage`, so the row is spaced evenly whether a button sits
     inside the group or beside it. */
  .invoices-manage__actions {
    align-items: center;
    display: flex;
    gap: 0.75rem;
  }

  .invoices-body.is-managing .invoices-toolbar__manage {
    display: none;
  }

  .invoices-body.is-managing .invoices-manage {
    display: flex;
  }

  /* Only the group of actions slides in — "Done" merely takes the place of
     "Manage" in the same spot, so it deliberately doesn't animate and doesn't
     jump on the switch. The fade is on the wrapper (not the buttons), so it
     doesn't override the greying of disabled buttons (`:disabled` → 0.45). */
  .invoices-body.is-managing .invoices-manage__actions {
    animation: invoices-manage-in 0.3s cubic-bezier(0.16, 1, 0.3, 1) both;
  }

  @keyframes invoices-manage-in {
    from {
      opacity: 0;
      transform: translateX(8px);
    }
    to {
      opacity: 1;
      transform: translateX(0);
    }
  }

  /* On a phone the actions appear on a new row under "Done" — a plain fade
     with no slide, so nothing jumps. */
  @keyframes invoices-manage-in-stack {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }

  .invoices-manage__btn {
    background: transparent;
    color: var(--color-ink-secondary);
    padding: 0.5rem 1.5rem;
    transition: background 0.15s, border-color 0.15s, color 0.15s, opacity 0.15s;
  }

  .invoices-manage__btn--danger {
    border-color: var(--color-negative-border);
    color: var(--color-negative-strong);
  }

  .invoices-manage__btn--danger:hover:not(:disabled) {
    background: var(--color-negative-tint);
    border-color: var(--color-negative-border);
  }

  /* Split control: language select + export confirm rendered as one button */
  .invoices-manage__export {
    display: flex;
  }

  .invoices-manage__export-select {
    -webkit-appearance: none;
    appearance: none;
    background-color: transparent;
    background-image: var(--icon-chevron);
    background-position: right 0.8rem center;
    background-repeat: no-repeat;
    border: 1.5px solid var(--color-border);
    border-inline-end: none;
    border-radius: var(--radius-pill) 0 0 var(--radius-pill);
    color: var(--color-ink-secondary);
    cursor: pointer;
    font-size: 0.9375rem;
    font-weight: 600;
    padding: 0.5rem 1.9rem 0.5rem 1.25rem;
    transition: background-color 0.15s, border-color 0.15s;
  }

  .invoices-manage__export-select:hover {
    background-color: var(--color-surface-tint);
    border-color: var(--color-border-strong);
  }

  .invoices-manage__export-btn {
    border-radius: 0 var(--radius-pill) var(--radius-pill) 0;
  }

  .doc-check {
    align-items: center;
    display: flex;
    justify-content: center;
    opacity: 0;
    overflow: hidden;
    transition: opacity 0.25s ease;
  }

  .invoices-body.is-managing .doc-check {
    opacity: 1;
  }

  .invoices-body.is-managing .doc-headers,
  .invoices-body.is-managing .doc-row {
    --doc-check-size: 44px;
  }

  .doc-checkbox {
    accent-color: var(--color-brand);
    block-size: 1.125rem;
    cursor: pointer;
    inline-size: 1.125rem;
    margin: 0;
  }

  /* A turbo-frame is inline by default. */
  #documents {
    display: block;
  }

  /* The grid is the checkbox column, closed until the list is being managed,
     then the side's own columns: variants redefine the two variables, never
     the declaration, so a list with a column of its own (`bills.css`) keeps it
     in every mode and at every width. */
  .doc-headers {
    display: grid;
    grid-template-columns: var(--doc-check-size, 0px) var(--doc-columns, repeat(5, 1fr));
    margin-block-end: 0.75rem;
    padding: 0 1.5rem;
    transition: grid-template-columns 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  }

  .doc-header {
    text-align: center;
    white-space: nowrap;
  }

  .doc-header:nth-child(2) {
    text-align: start;
  }

  .doc-table {
    background: var(--color-surface);
    border-radius: var(--radius-md);
    overflow: hidden;
  }

  .doc-row {
    align-items: center;
    border-block-end: 1px solid var(--color-border-subtle);
    display: grid;
    grid-template-columns: var(--doc-check-size, 0px) var(--doc-columns, repeat(5, 1fr));
    padding: 1.125rem 1.5rem;
    transition: grid-template-columns 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  }

  .doc-row:last-child {
    border-block-end: none;
  }

  .doc-cell {
    color: var(--color-ink-secondary);
    font-size: 1.125rem;
    text-align: center;
  }

  .doc-cell--number {
    text-align: start;
  }

  .doc-cell--number a {
    color: var(--color-brand);
    font-family: var(--font-mono);
    font-size: 1.125rem;
    font-weight: 600;
    text-decoration: none;
  }

  .doc-cell--number a:hover {
    text-decoration: underline;
  }

  .doc-cell--client {
    color: var(--color-ink);
    font-size: 1.125rem;
    font-weight: 700;
    text-align: center;
  }

  /* Truncated client name — a click expands it in full, and it may then cover
     the amount */
  .doc-cell--client.is-truncatable {
    cursor: pointer;
  }

  .doc-cell--client.is-expanded {
    overflow: visible;
    position: relative;
    text-align: start;
    z-index: 3;
  }

  .doc-cell--client.is-expanded .doc-cell--client__text {
    background: var(--color-surface);
    white-space: nowrap;
  }

  .doc-col--amount {
    text-align: end;
  }

  /* The sum below the table. Aligned right, not tied to the rows' grid — that
     changes its column count per breakpoint, while the right edge always
     holds. */
  .doc-total {
    align-items: baseline;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 0.75rem;
    justify-content: flex-end;
    padding: 1.125rem 1.5rem 0;
  }

  .doc-total__amount {
    color: var(--color-brand);
    font-family: var(--font-mono);
    font-size: 1.125rem;
    font-weight: 700;
  }

  .doc-cell.doc-col--amount {
    color: var(--color-ink);
    font-family: var(--font-mono);
    font-size: 1.125rem;
    font-weight: 700;
  }

  .doc-header__short {
    display: none;
  }

  .doc-empty {
    color: var(--color-ink-muted);
    font-size: 0.9375rem;
    padding: 3rem 1.5rem;
    text-align: center;
  }

  @media (width < 768px) {
    .doc-col--date {
      display: none;
    }

    /* Search is hidden — keep the toolbar's height as in managing mode so the
       list doesn't shift on the switch and the text stays on one line.
       flex-wrap + row-gap: on narrow displays the filter and the manage group
       wrap onto rows of their own instead of overflowing to the right. */
    .invoices-toolbar {
      /* `center`: "Manage" is plain text, "Done" a pill — centring the row
         puts them in the same spot, so switching modes doesn't move them.
         `align-content: flex-start`, so the single row (outside managing
         mode) doesn't stretch to `min-height` and shift them by 2px. */
      align-content: flex-start;
      align-items: center;
      column-gap: 0.6rem;
      flex-wrap: wrap;
      justify-content: flex-start;
      min-block-size: 2.5rem;
      row-gap: 0.75rem;
    }

    /* On a phone the manage container is "dissolved" (display: contents), so
       its buttons flow straight in the toolbar along with the filter and wrap
       naturally: what fits stays on the row, the rest drops below. */
    .invoices-body.is-managing .invoices-manage {
      display: contents;
    }

    /* The manage layout on a phone:
       row 1 = Filter (left) … Done (right) — Done lands exactly where "Manage"
       was, so switching modes doesn't move the control elsewhere,
       row 2 = the group of actions aligned right under Done. */
    .invoices-manage__btn[data-action="manage#exit"] {
      margin-inline-start: auto;
      order: 1;
    }

    /* The actions on a row of their own, aligned right (under Done), so they
       form one coherent block instead of buttons scattered across rows. */
    .invoices-manage__actions {
      display: flex;
      flex-basis: 100%;
      flex-wrap: wrap;
      gap: 0.75rem 0.6rem;
      justify-content: flex-end;
      order: 2;
    }

    /* Order within the group: the two narrow pills side by side, the wider
       export after them — on a phone it wraps under them, on a wider display
       it stays on the same row. */
    .invoices-manage__btn:is([data-action="manage#copy"], [data-action="manage#print"]) {
      order: 1;
    }

    .invoices-manage__btn--danger {
      order: 2;
    }

    .invoices-manage__export {
      order: 3;
    }

    /* The actions arrive on a row of their own — a plain fade (no slide from
       the side, which only makes sense in the desktop row). */
    .invoices-body.is-managing .invoices-manage__actions {
      animation-name: invoices-manage-in-stack;
    }

    .doc-headers,
    .doc-row {
      --doc-columns: repeat(3, 1fr);
    }

    .invoices-body.is-managing .doc-headers,
    .invoices-body.is-managing .doc-row {
      --doc-check-size: 56px;
    }

    .doc-header:nth-child(2) {
      text-align: start;
    }

    .doc-header.doc-col--amount {
      text-align: end;
    }

    .doc-cell--number {
      text-align: start;
    }

    .doc-cell.doc-col--amount {
      text-align: end;
    }
  }

  @media (width < 480px) {
    /* Toolbar — search lives in the navbar, only the manage buttons remain */
    .invoices-toolbar {
      margin-block-end: 1.25rem;
    }

    .invoices-manage {
      flex-wrap: wrap;
      gap: 0.5rem;
      margin-inline-start: 0;
    }

    .invoices-manage__btn {
      font-size: 0.875rem;
      padding: 0.4375rem 1rem;
    }

    .invoices-manage__export-select {
      font-size: 0.875rem;
      padding: 0.4375rem 1.75rem 0.4375rem 1rem;
    }

    /* Table */
    .doc-headers,
    .doc-row {
      --doc-columns: repeat(3, 1fr);

      padding-inline-end: 0.875rem;
      padding-inline-start: 0.875rem;
    }

    .invoices-body.is-managing .doc-headers,
    .invoices-body.is-managing .doc-row {
      --doc-check-size: 44px;
    }

    /* Same side padding as the rows, so the sum lines up with the amounts
       above it. */
    .doc-total {
      padding-inline-end: 0.875rem;
      padding-inline-start: 0.875rem;
    }

    .doc-cell,
    .doc-cell--number a,
    .doc-cell--client,
    .doc-cell.doc-col--amount,
    .doc-total__amount {
      font-size: 0.9375rem;
    }

    /* Keep long client names from overflowing */
    .doc-cell--client {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    .doc-header {
      text-align: center;
    }

    .doc-header:nth-child(2) {
      text-align: start;
    }

    .doc-header.doc-col--amount {
      text-align: end;
    }

    .doc-cell--number {
      text-align: start;
    }

    .doc-cell.doc-col--amount {
      text-align: end;
    }

    .doc-header__full {
      display: none;
    }

    .doc-header__short {
      display: inline;
    }
  }


  /* ─── A bill received over Peppol ───────── */

  .doc-row__badge {
    background: var(--color-brand-tint);
    border-radius: var(--radius-pill);
    color: var(--color-brand);
    font-size: 0.6875rem;
    font-weight: 600;
    margin-inline-start: 0.375rem;
    padding: 0.0625rem 0.4375rem;
    vertical-align: middle;
  }
}
