/* Column tracks for every list, one block per table. */

/* ------------------------------------------------------- one grid per table */
/* A list table is ONE grid. The tracks are declared on the box that holds the
   whole table — marked data-table — and the heading, the row group and every
   row pass them down with subgrid.

   Two things follow from that. A column can be sized by what it holds:
   content-based tracks are measured per grid, so a heading and rows in
   separate grids would each pick their own widths and stop lining up. And a
   nested row (an invoice under its client, a project under its client) simply
   starts at the track it belongs to, instead of being matched to its parent
   by hand with paddings.

   Each width is either a share of the table or its own content: fit-content(N)
   takes the content's width and only caps how far it may grow, max-content
   takes exactly what the cell holds, and minmax(px,1fr) is the one flexible
   track that soaks up the slack. */
[data-table] {
  display: grid;
  align-content: start;
  column-gap: var(--table-gap);
  row-gap: 0;
  /* The grid is the box that must not shrink below the sum of its tracks;
     the section around it takes over the scrolling (see below). */
  min-width: min-content;
}

/* Every box between the table and its cells passes the tracks down… */
[data-table] > .thead,
[data-table] > .rows,
[data-table] .bucket,
[data-table] .bucket > .rows,
[data-table] .group,
[data-table] details.client,
[data-table] .kids,
[data-table] .row,
[data-table] .child {
  display: grid;
  grid-template-columns: subgrid;
}

/* …and everything that is not a cell spans the whole width. */
[data-table] > *,
[data-table] .rows > *,
[data-table] .bucket > *,
[data-table] .group > *,
[data-table] details.client > *,
[data-table] .kids > * {
  grid-column: 1 / -1;
}

/* One mechanism owns the vertical spacing of a list: the gap between the rows
   of the table, and the gap between the rows nested inside a group. There is
   none between a group's own row and the first row under it, because that row
   already carries its padding under its avatar, which is the same distance. */
[data-table] > .rows,
[data-table] .bucket > .rows,
[data-table] .kids {
  row-gap: 10px;
}

/* --------------------------------------------------------------- dashboard */
/* Debtor row and its invoices share one track list. The invoice starts at the
   second track — the one after the client's avatar — so "N фактури", the days
   and the amounts sit under each other by construction. */
[data-table]:has(.row.t-debt) {
  grid-template-columns:
    minmax(240px,1fr)
    max-content
    fit-content(180px)
    max-content;
  column-gap: 8px;
}

/* The invoice row spans the whole width, like every other nested row: its
   first cell is the elbow, in the same track as the client's avatar, so the
   branch is drawn inside the row's own box rather than beside it. The four
   cells after it fall on the client's four columns by construction. */

.t-debt > .sub {
  font-weight: 600;
  color: var(--text);
}

/* Tick, title, project, checklist, deadline. The amount is not a column of its
   own: it belongs to the task, so it rides with the name. The title is the one
   flexible track, so all the slack lands there and the right-hand columns sit
   next to each other rather than drifting apart. */
[data-table]:has(.row.t-work) {
  grid-template-columns:
    max-content
    minmax(180px,1fr)
    fit-content(220px)
    max-content
    fit-content(200px);
  column-gap: 8px;
}

/* The chips start at the cell's left edge, so the first one sits at the same
   place down the page whether the row carries one chip or both. */
.work-cell {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

/* The title cell holds the state mark, the title and the chips: the text
   truncates, everything else keeps its size. The mark sits a hair closer to
   the words than the chips do, so it reads as part of the title. */
.t-work .name {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.t-work .name > .statemark {
  margin-right: -1px;
}

.t-work .name > .tchip {
  flex: none;
}

/* ------------------------------------------------------------------- money */
/* The client and the project/plan are the two columns worth reading at a
   glance, so they take the slack; the project one never falls under its own
   text, which is what stops a plan name from wrapping while there is room.
   Основание and everything to its right take exactly what they hold. That is
   also what makes the paid list, with its two buttons, and the unpaid one,
   with a single button, size their action column right without a variant. */
[data-table]:has(> .thead.t-money) {
  grid-template-columns:
    minmax(150px,1fr)
    minmax(max-content,1fr)
    fit-content(260px)
    max-content
    max-content
    max-content
    fit-content(200px)
    max-content;
}

/* Date, amount, status, method and action sit centred under their headings
   (the first three columns stay left-aligned). Applies to .thead and .row alike. */
.t-money > :nth-child(n+4) {
  text-align: center;
}

.t-money .actions {
  justify-content: center;
}

/* ---------------------------------------------------------------- projects */
[data-table]:has(> .thead.t-proj) {
  grid-template-columns:
    minmax(220px,1fr)
    fit-content(240px)
    max-content
    max-content
    max-content
    fit-content(190px)
    max-content;
}

/* ----------------------------------------------------------------- clients */
/* The client row, its projects and its plans all live on these tracks, so the
   fixed columns sit under each other; only the first differs, by the indent
   the nested rows carry in their own padding. */
/* The fold arrow has a column to itself, ahead of the client. That is what
   places the nested rows: they start at the second track, so a project or a
   plan begins under the client's own circle and its elbow is drawn there,
   without a margin or a padding set by hand anywhere. */
[data-table]:has(> .thead.t-cli) {
  grid-template-columns:
    max-content
    minmax(200px,1fr)
    fit-content(190px)
    max-content
    max-content
    max-content
    max-content;
}

[data-table] .kids > .child.t-cli-kid {
  grid-column: 2 / -1;
}

/* A <details> wraps everything after its <summary> in an anonymous box, which
   cuts the subgrid chain before it can reach the nested rows. Letting that box
   through with display:contents puts .kids back on the table's own tracks, so
   a project or a plan lines up with its client without any hand-set padding.
   Only while the client is open: that box is also what the browser hides to
   fold the accordion, and a display:contents box cannot be hidden. */
details.client[open]::details-content {
  display: contents;
}

/* Where that pseudo-element is missing the chain cannot be repaired, so the
   clients table keeps the older arrangement instead: separate grids that carry
   one identical set of fixed tracks. */
@supports not selector(::details-content) {
  [data-table]:has(> .thead.t-cli),
  [data-table]:has(> .thead.t-cli) details.client,
  [data-table]:has(> .thead.t-cli) .kids {
    display: block;
  }

  [data-table]:has(> .thead.t-cli) > .rows {
    display: flex;
    flex-direction: column;
    gap: 10px;
  }

  [data-table]:has(> .thead.t-cli) :is(.thead, .row, .child) {
    grid-template-columns: 26px minmax(200px,1fr) 158px 72px 96px 96px 112px;
  }
}

/* ----------------------------------------------------------- subscriptions */
[data-table]:has(> .thead.t-sub) {
  grid-template-columns:
    minmax(280px,1fr)
    fit-content(160px)
    max-content
    max-content
    max-content
    max-content;
}

/* --------------------------------------------- tables that are not lists */
/* Key and value in the receipt, and the API tokens in Настройки: two or four
   plain columns, no heading, nothing to align across rows. */
.t-kv {
  grid-template-columns: 170px 1fr;
}

.t-tok {
  grid-template-columns: minmax(140px,1fr) 150px 200px 90px;
}

/* ------------------------------------------------------ narrow windows */
/* The content floors are what decides the width now, so a laptop needs only a
   tighter gap and lower floors on the flexible columns; the columns that size
   themselves already take no more than they need. */
@media (max-width:1500px) {
  [data-table],
  .thead,
  .row,
  .child {
    --table-gap: 10px;
  }

  [data-table]:has(.row.t-work) {
    grid-template-columns:
      max-content
      minmax(150px,1fr)
      fit-content(200px)
      max-content
      fit-content(200px);
  }

  [data-table]:has(.row.t-debt) {
    grid-template-columns:
      minmax(200px,1fr)
      max-content
      fit-content(150px)
      max-content;
  }

  [data-table]:has(> .thead.t-money) {
    grid-template-columns:
      minmax(120px,1fr)
      minmax(max-content,1fr)
      fit-content(220px)
      max-content
      max-content
      max-content
      fit-content(160px)
      max-content;
  }

  [data-table]:has(> .thead.t-proj) {
    grid-template-columns:
      minmax(180px,1fr)
      fit-content(190px)
      max-content
      max-content
      max-content
      fit-content(150px)
      max-content;
  }

  [data-table]:has(> .thead.t-cli) {
    grid-template-columns:
      max-content
      minmax(170px,1fr)
      fit-content(150px)
      max-content
      max-content
      max-content
      max-content;
  }

  [data-table]:has(> .thead.t-sub) {
    grid-template-columns:
      minmax(240px,1fr)
      fit-content(140px)
      max-content
      max-content
      max-content
      max-content;
  }
}

/* Narrower than that - a tablet in portrait, or a phone - the columns cannot
   shrink any further without becoming unreadable, so the list keeps its
   shape and its headings and the SECTION scrolls sideways instead of the
   page. This replaces the old collapse to one column: a money row stacked
   into eight unlabelled lines ("12.09.2026", "€ 525", "Банков превод" one
   under another) cannot be read without remembering the desktop order, and
   .thead, which holds the only labels, was hidden.
   The tables that live inside a popup are the exception: a modal is 343px
   wide on a phone and has no room to scroll, so those do collapse. */
.section:has([data-table]),
.section[data-table] {
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

/* The section's own heading keeps its place while the list slides under it. */
.section:has([data-table]) > header,
.section[data-table] > header {
  position: sticky;
  left: 0;
}

@media (max-width:900px) {
  /* rows.css stacks .row/.child on a phone; the list tables opt out of that
     (they are subgrids of their table, declared above, which comes later in
     the cascade than rows.css) and show their heading again. */
  [data-table] > .thead {
    display: grid;
  }

  /* Inside a popup there is nowhere to scroll: these stack instead. */
  .t-kv,
  .t-tok {
    grid-template-columns: 1fr;
  }
}
