.noora-table {
  box-sizing: border-box;
  position: relative;
  box-shadow: var(--noora-border-light-default);
  border-radius: var(--noora-radius-4);
  background: var(--noora-surface-table-header);
  padding: var(--noora-spacing-0);
  width: 100%;

  /* The horizontal scroll lives on an inner wrapper rather than `.noora-table` itself, so the
   * scrollbar (and the space it occupies) only exist when the table actually overflows. The wrapper
   * is auto-height and grows to fit the scrollbar below the content, so the last row is never
   * clipped, and non-scrolling tables get no scrollbar gutter at all. */
  & [data-part="scroll-container"] {
    border-radius: var(--noora-radius-4);
    width: 100%;
    overflow-x: auto;
    overscroll-behavior-x: none;

    /* Browsers make a horizontally scrollable region keyboard-focusable so it can be scrolled
     * with the arrow keys. Replace the default full-bleed focus ring with a restrained inset
     * one that follows the table's rounded corners, so a focused scroll area reads as a focused
     * control rather than a selected table. */
    &:focus-visible {
      outline: 2px solid
        light-dark(
          var(--noora-neutral-light-1000),
          var(--noora-neutral-dark-1200)
        );
      outline-offset: -2px;
    }
  }

  /* Floating horizontal scrollbar, driven by the `NooraTable` hook. While the table is on screen
   * but its native scrollbar is below the viewport, this proxy is fixed to the viewport bottom and
   * synced with the scroll container; once the table's bottom scrolls into view, it hides and the
   * native scrollbar takes over. Hidden whenever JS is unavailable. */
  & [data-part="scrollbar"] {
    display: none;
    position: fixed;
    bottom: 0;
    z-index: 2;
    overflow-x: auto;
    overscroll-behavior-x: none;

    &[data-visible] {
      display: block;
    }

    & > [data-part="scrollbar-content"] {
      height: 1px;
    }
  }

  /* Custom scrollbar, used where the native one cannot match the webkit-styled design: Firefox
   * (no `::-webkit-scrollbar` support, so no thumb insets) and overlay-scrollbar platforms
   * (the bar paints over content and hides at rest). The `NooraTable` hook suppresses the native
   * bar, keeps the thumb in sync, and — mirroring the proxy scrollbar in webkit browsers — pins
   * this bar to the viewport bottom while the table extends below it. */
  & [data-part="overlay-scrollbar"] {
    display: none;
    position: absolute;
    right: var(--noora-spacing-4);
    /* With the 16px lane the hook pads below the body plus the root's 4px, this centers the 8px
     * thumb — 6px to the last row above and 6px to the table edge below, matching webkit. */
    bottom: 6px;
    left: var(--noora-spacing-4);
    z-index: 2;
    height: 8px;

    &[data-visible] {
      display: block;
    }

    & > [data-part="overlay-thumb"] {
      position: absolute;
      top: 0;
      height: 100%;
      border-radius: var(--noora-radius-4);
      background-color: light-dark(
        var(--noora-neutral-light-600),
        var(--noora-neutral-dark-600)
      );
      touch-action: none;
    }
  }

  & [data-part="scroll-container"],
  & [data-part="scrollbar"] {
    /* `scrollbar-color` is inherited, and any non-`auto` value (e.g. an app-level global on
     * `html`) makes Chromium ignore the `::-webkit-scrollbar` styling below, falling back to a
     * full-width scrollbar. Reset both standard properties so the detailed styling applies
     * regardless of the host app's globals. */
    scrollbar-color: auto;
    scrollbar-width: auto;

    /* Firefox cannot style the scrollbar through `::-webkit-scrollbar`, and Chromium ignores those
     * pseudo-elements whenever the standard `scrollbar-*` properties are set. Scoping the standard
     * properties to Firefox lets Chromium/Safari fall through to the detailed styling below. */
    @supports (scrollbar-width: thin) and (not selector(::-webkit-scrollbar)) {
      /* #c1c1c1/#6b6b6b are the browser's default scrollbar thumb grays, so the table scrollbar
       * matches the native ones elsewhere on the page. */
      scrollbar-color: light-dark(
          var(--noora-neutral-light-600),
          var(--noora-neutral-dark-600)
        )
        transparent;
      scrollbar-width: thin;
    }

    &::-webkit-scrollbar {
      width: 12px;
      height: 12px;
      background: transparent;
    }

    &::-webkit-scrollbar-corner {
      background: transparent;
    }

    &::-webkit-scrollbar-track {
      margin: 0 var(--noora-spacing-2);
      background: transparent;
    }

    &::-webkit-scrollbar-thumb {
      border-color: transparent;
      border-style: solid;
      border-width: 2px 4px;
      border-radius: var(--noora-radius-4);
      background-color: light-dark(
        var(--noora-neutral-light-600),
        var(--noora-neutral-dark-600)
      );
      background-clip: padding-box;
    }
  }

  & table {
    position: relative;
    border-collapse: collapse;
    border-spacing: 0;
    width: 100%;
    min-width: max-content;

    /* Table elements do not support `box-shadow`, which we are using for borders. In order to still have a shadow around the body, we are
    *  adding a pseudo element with standard layouting around the table and add a box-shadow around it. */
    &:has(td):after {
      position: absolute;
      top: 44px;
      right: 0;
      bottom: 0;
      left: 0;
      z-index: 1;
      box-shadow: var(--noora-border-light-default);
      border-radius: var(--noora-radius-4);
      pointer-events: none;
      content: "";
    }

    & tbody {
      background: transparent;

      & tr {
        &[data-state="expanded"] td {
          background-color: var(--noora-surface-background-secondary);
        }
        /* No pointer cursor: the row is passive and only the disclosure button toggles it.
         * The hover tint stays as a lightweight affordance that the row is interactive. */
        &[data-expandable] {
          &:hover td {
            background-color: var(--noora-surface-background-secondary);
          }
        }

        &:hover {
          & td[data-selectable] {
            background: var(--noora-surface-background-secondary);
            cursor: pointer;
          }
        }

        & td {
          background-color: var(--noora-surface-background-primary);

          & > [data-part="expand-cell"] {
            display: flex;
            align-items: center;
            gap: var(--noora-spacing-5);
            padding-left: var(--noora-spacing-5);

            /* The disclosure trigger: a bare, icon-only button wrapping the chevron. It carries
             * the interaction (focus, click) so the row can stay passive. */
            & > [data-part="expand-toggle"] {
              display: inline-flex;
              flex-shrink: 0;
              align-items: center;
              justify-content: center;
              margin: 0;
              padding: 0;
              border: 0;
              border-radius: var(--noora-radius-2);
              background: none;
              color: inherit;
              cursor: pointer;
              appearance: none;

              &:focus-visible {
                outline: none;
                box-shadow: var(--noora-button-border-secondary-focus);
              }

              /* The chevron is a 16px icon; the crossfade transition wraps it in a span, so the
               * size is applied to the nested svg rather than a direct child. */
              & svg {
                width: 16px;
                height: 16px;
              }
            }
          }

          & > [data-part="expand-cell"] > [data-part="cell"] {
            padding-left: 0;
          }

          &[data-part="expanded-content"] {
            position: relative;
            background-color: var(--noora-surface-background-secondary);
            /* Vertical padding must stay zero: the expanded row is always in the DOM, collapsed
             * to zero height, and any padding here would leave a visible sliver between rows. */
            padding-top: 0;
            padding-bottom: 0;
            padding-left: var(--noora-spacing-8);

            &::before {
              position: absolute;
              top: 0;
              bottom: 0;
              left: var(--noora-spacing-7);
              background-color: var(--noora-surface-border-primary);
              width: 1px;
              content: "";
            }

            /* Animated reveal: the row's `data-state` drives a grid-row transition 0fr <-> 1fr.
             * A transition (not mount/unmount keyframes) means expanding starts instantly,
             * collapsing can never be cut short by element removal, and an interrupted toggle
             * reverses from wherever it currently is. */
            & [data-part="expand-wrapper"] {
              display: grid;
              grid-template-rows: 0fr;

              @media (prefers-reduced-motion: no-preference) {
                transition: grid-template-rows 200ms var(--ease-out-cubic);
              }

              tr[data-state="expanded"] + tr & {
                grid-template-rows: 1fr;
              }

              & > [data-part="expand-wrapper-content"] {
                min-height: 0;
                overflow: hidden;
                /* Hidden from interaction and find-in-page while collapsed; the delay holds
                 * visibility through the collapse so content doesn't vanish mid-shrink. */
                visibility: hidden;
                transition: visibility 0s 200ms;

                tr[data-state="expanded"] + tr & {
                  visibility: visible;
                  transition-delay: 0s;
                }
              }
            }
          }
        }
      }

      & tr:not(:first-child):not([data-part="expanded-row"]) td {
        box-shadow: 0 1px 0 0
          light-dark(
            var(--noora-neutral-light-400),
            var(--noora-neutral-dark-900)
          )
          inset;
      }

      /* Expanded rows are excluded: they are always in the DOM, collapsed to zero height,
       * and these paddings would otherwise win the cascade over the expanded-content cell's
       * zero padding (same specificity, later in source) and leave a sliver between rows. */
      & tr:not(:last-child):not([data-part="expanded-row"]) td {
        padding-bottom: 2px;
      }

      & tr:not(:first-child):not([data-part="expanded-row"]) td {
        padding-top: 2px;
      }

      /* Border radius on the `tbody` itself is unsupported, so we're selectively adding radius to specific cells. */
      & tr:first-child {
        & td:first-child {
          border-top-left-radius: var(--noora-radius-4);
        }
        & td:last-child {
          border-top-right-radius: var(--noora-radius-4);
        }
      }

      & tr:last-child {
        & td:first-child {
          border-bottom-left-radius: var(--noora-radius-4);
        }
        & td:last-child {
          border-bottom-right-radius: var(--noora-radius-4);
        }
      }

      /* When the last row is expandable, the final tbody child is its always-rendered expanded
       * row. While that row is collapsed to zero height, the visible row above it carries the
       * bottom radius instead. */
      &
        tr[data-state="collapsed"]:nth-last-child(2):has(
          + tr[data-part="expanded-row"]
        ) {
        & td:first-child {
          border-bottom-left-radius: var(--noora-radius-4);
        }
        & td:last-child {
          border-bottom-right-radius: var(--noora-radius-4);
        }
      }
    }
  }

  & th {
    /* Border-box so the hook's measured column widths (which include padding) can be pinned
     * back as `min-width` without compounding. */
    box-sizing: border-box;
    position: sticky;
    top: 0;
    background-color: var(--noora-surface-table-header);
    padding: var(--noora-spacing-5) var(--noora-spacing-7)
      var(--noora-spacing-5) var(--noora-spacing-7);
    color: var(--noora-surface-label-primary);
    font: var(--noora-font-weight-medium) var(--noora-font-body-medium);
    text-align: left;
    white-space: nowrap;

    & > [data-part="sort-link"] {
      color: unset;
      text-decoration: unset;

      &:hover [data-part="icon"] {
        color: var(--noora-surface-label-primary);
      }

      /* The sort-direction arrow (the only header icon carrying `data-state`) is an indicator,
       * not a button, so it stays `label-secondary` even while the header is hovered. */
      &:hover [data-part="icon"][data-state] {
        color: var(--noora-surface-label-secondary);
      }
    }

    & [data-part="icon"] {
      display: inline-block;
      position: relative;
      top: 2.5px;
      left: var(--noora-spacing-2);
      width: var(--noora-icon-size-medium);
      height: var(--noora-icon-size-medium);
      /* We cannot make `th` a flex element for vertical alignment and `gap`, so we are using `top` to vertically align, and `left` for
      * spacing. */
      color: var(--noora-surface-label-secondary);

      & svg {
        width: 100%;
        height: 100%;
      }
    }
  }

  /* Floating header, driven by the `NooraTable` hook: a fixed-position clone of the `thead`,
   * appended to `body`, pinned to the viewport top while the table is scrolled past it. It also
   * carries the `noora-table` class so the cloned header cells pick up the regular styling. */
  &.noora-table-floating-header {
    display: none;
    position: fixed;
    top: 0;
    z-index: 2;
    box-shadow: 0 1px 0 0
      light-dark(var(--noora-neutral-light-400), var(--noora-neutral-dark-900));
    /* Keep the table's top corner radius while detached, for consistency with the resting
     * header. */
    border-radius: 0;
    overflow: hidden;

    &[data-visible] {
      display: block;
    }
  }

  /* Whole-row navigation. A single anchor in the first cell carries the link; its `::after`
   * overlay stretches across the row (which is the positioning context) so the entire row is the
   * click target, while the DOM holds just one link per row. Trade-off: the overlay sits over the
   * row's text, so text in navigable rows isn't selectable. */
  & tr:has([data-part="row-link"]) {
    position: relative;
  }

  & [data-part="row-link"] {
    color: inherit;
    text-decoration: none;

    &::after {
      position: absolute;
      inset: 0;
      z-index: 0;
      content: "";
    }

    &:focus-visible {
      outline: none;

      &::after {
        outline: 2px solid
          light-dark(
            var(--noora-neutral-light-1000),
            var(--noora-neutral-dark-1200)
          );
        outline-offset: -2px;
      }
    }
  }

  /* Controls in the row's other cells must sit above the overlay to stay clickable. */
  &
    tr:has([data-part="row-link"])
    :is(a, button, input, select, [tabindex]):not([data-part="row-link"]) {
    position: relative;
    z-index: 1;
  }

  & [data-part="cell"] {
    display: flex;
    align-items: center;
    box-sizing: border-box;
    max-width: 100%;

    &[data-type="text"] {
      display: flex;
      align-items: center;
      gap: var(--noora-spacing-2);
      padding: var(--noora-spacing-7);
      font: var(--noora-font-body-medium);

      & [data-part="icon"] {
        display: inline-flex;
        width: var(--noora-icon-size-medium);
        height: var(--noora-icon-size-medium);
        color: var(--noora-surface-label-primary);

        & svg {
          width: 100%;
          height: 100%;
        }
      }

      & [data-part="label"] {
        color: var(--noora-surface-label-primary);
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }

      & [data-part="sublabel"] {
        color: var(--noora-surface-label-secondary);
      }
    }

    &[data-type="text_and_description"] {
      display: flex;
      align-items: center;
      gap: var(--noora-spacing-5);
      padding: var(--noora-spacing-5) var(--noora-spacing-7)
        var(--noora-spacing-5) var(--noora-spacing-5);

      & [data-part="icon"] {
        display: flex;
        border-radius: var(--noora-radius-4);
        color: var(--noora-surface-label-primary);

        &:not(:has(img)) {
          box-shadow: var(--noora-border-light-default);
          padding: 10px;
        }

        & img {
          border-radius: var(--noora-radius-4);
          width: 40px;
          height: 40px;
        }

        & svg {
          width: var(--noora-icon-size-large);
          height: var(--noora-icon-size-large);
        }
      }

      & [data-part="column"] {
        display: flex;
        flex-direction: column;
        gap: var(--noora-spacing-2);
      }

      & [data-part="label"] {
        color: var(--noora-surface-label-primary);
        font: var(--noora-font-weight-medium) var(--noora-font-body-medium);
      }

      & [data-part="description"] {
        color: var(--noora-surface-label-secondary);
        font: var(--noora-font-body-small);
      }
    }

    &[data-type="badge"],
    &[data-type="status_badge"],
    &[data-type="button"],
    &[data-type="link_button"],
    &[data-type="tag"] {
      padding: var(--noora-spacing-7);
    }

    &[data-type="button"] {
      display: flex;
      gap: var(--noora-spacing-4);
    }
  }

  & .noora-table-empty-state {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    padding: var(--noora-spacing-10) var(--noora-spacing-0);

    & > [data-part="icon"] {
      margin-bottom: var(--noora-spacing-8);
      box-shadow: var(--noora-border-light-default);
      border-radius: var(--noora-radius-3);
      background: var(--noora-surface-background-primary);
      padding: var(--noora-spacing-3);
      width: var(--noora-icon-size-large);
      height: var(--noora-icon-size-large);
      color: var(--noora-surface-label-primary);

      & svg {
        width: 100%;
        height: 100%;
      }
    }

    & > [data-part="title"] {
      color: var(--noora-surface-label-secondary);
      font: var(--noora-font-weight-medium) var(--noora-font-body-medium);
    }

    & > [data-part="subtitle"] {
      margin-top: var(--noora-spacing-4);
      color: var(--noora-surface-label-tertiary);
      font: var(--noora-font-body-small);
    }
  }
}
