/* Styling for the one table (see table.js).
 *
 * Two rules this file obeys, both earned the hard way in the reference:
 *
 *  - Every colour, font face and corner radius comes from a token (D25). The
 *    reference used 16 colour names that were never defined anywhere, which
 *    silently dropped 91 declarations.
 *
 *    Stated honestly rather than overclaimed: text sizes and spacing are
 *    written here directly, because there are no tokens for them yet. When
 *    a size scale is added to tokens.css these move onto it. Colour, font and
 *    radius are the ones that are absolute today.
 *
 *  - Every rule is a single class, sitting on the element it styles. No rule
 *    reaches through a container into an element type. A generic ".wrapper
 *    table" rule in the reference silently beat a more specific-looking one
 *    and a table could not be widened -- because how specific a rule is
 *    decides who wins, not which one is written last.
 *
 * Anything that can be pressed gives at least 40px to press, and anything
 * that cannot be pressed looks like it. A phone is a build target, not a
 * later pass (D67). Note the tick box is drawn at 22px and it is the label
 * around it that carries the 40px -- tapping the words works, which is what
 * a thumb actually hits. Said here because the sizes alone would read as a
 * target that is too small.
 */

.k-table {
  font-family: var(--font);
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}

/* -------------------------------------------------------------- toolbar */

.k-table__toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  padding: 12px;
  background: var(--surface-raised);
  border-bottom: 1px solid var(--border);
}

.k-table__search {
  flex: 1 1 240px;
  min-width: 0;
}

.k-table__search:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.k-table__filter {
  display: inline-flex;
  align-items: center;
}

.k-table__filter-line {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  /* **DOWN WITH THE BUTTONS (D143).** These sit in the same row as the search
   * and the Columns button; leaving them at 40px beside 37px is the exact 3px
   * mismatch D142 was built to remove, in the other direction. */
  min-height: 37px;
  font-size: 13px;
  color: var(--text-muted);
  cursor: pointer;
}

.k-table__filter-label {
  font-family: var(--font);
  white-space: nowrap;
}

/* Sized so it can actually be hit with a thumb. */
.k-table__filter-toggle {
  width: 22px;
  height: 22px;
  margin: 9px 0;
  accent-color: var(--brand);
  cursor: pointer;
}

/* **THE SHAPE AND THE POINTER BOTH COME FROM `k-control`.** What was here was
 * a fourth definition of a dropdown, and what was left after it went was a
 * `cursor: pointer` with no height beside it -- a target somebody can see and
 * may not be able to hit. */

.k-table__filter-range {
  width: 82px;
  padding: 6px 8px;
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
}

/* -------------------------------------------------------------- the grid
 *
 * A wide table scrolls sideways inside its own box. The page itself never
 * scrolls sideways -- a carried-over rule from the reference.
 */

.k-table__scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* **THE TABLE IS AS WIDE AS ITS CONTENTS AND SCROLLS SIDEWAYS.**
 *
 * His words on the Items tab: *"the width of the column should be such that it
 * doesn't wrap. Like, I can see brass, wire, six mm."* Squeezed to the width of
 * the screen, `Brass wire, 0.6mm` broke across three lines and every row became
 * three rows tall -- so a phone showed four items where it could have shown a
 * dozen, and none of them were quicker to read for being stacked.
 *
 * `max-content` is what stops that: the table takes the width its longest cell
 * needs and `.k-table__scroll` above it scrolls across. `min-width: 100%` keeps
 * a short table filling the screen rather than huddling on the left.
 *
 * HE ASKED FOR THIS KNOWING WHAT IT COSTS: *"the table is not accommodating in
 * mobile screen. I think that is fine because it's a very long table."*
 */
.k-table__grid {
  width: max-content;
  min-width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

/* **ONLY ONCE THE SELLER HAS SET WIDTHS.** Fixed layout ignores what is in the
 * cells and uses exactly the widths it is given, which is what makes a dragged
 * column stay where it was put. Turned on for every table it would throw away
 * the sizing above for the sake of a setting most tables never get. */
.k-table__grid--sized {
  table-layout: fixed;
  /* **AND NOTHING STRETCHES IT BACK.** `.k-table__grid` above carries
   * `min-width: 100%` so a short table fills the screen rather than huddling on
   * the left. Once the seller has set the widths himself that rule works against
   * him: narrow every column past the width of the screen and the table is
   * stretched back out to fill it, handing each column the space he just took
   * away. His widths are the answer here, even if they leave a gap on the right. */
  min-width: 0;
}

/* **ONE COLUMN ENDS WHERE THE NEXT BEGINS, AND YOU CAN SEE IT (his review).**
 *
 * *"The table does not hold two columns separately in mobile -- they collide."*
 * There was NOTHING between one column and the next: no line, just twelve pixels
 * of padding. On a wide screen that reads as roomy. On a phone, where the table
 * is scrolled sideways and the values are short, "Pieces" and "Nothing yet" sit
 * next to each other and read as one run of words.
 *
 * A hairline, not a box: a full grid makes a table look like a spreadsheet and
 * the rows are already separated by their own line underneath. The first column
 * gets none, or there is a stray edge floating at the left of the table.
 *
 * **HERE RATHER THAN IN A PHONE RULE**, because it is not a phone problem -- it
 * is only most obvious there. Two columns should be told apart on any screen. */
.k-table__cell + .k-table__cell,
.k-table__heading + .k-table__heading {
  border-left: 1px solid var(--border);
}

/* A COLUMN CLIPS ITS WORDS TO THE WIDTH IT HAS, IT DOES NOT SPILL. Without this,
 * text wider than the column simply draws over the next one and the width looks
 * ignored.
 *
 * **THE HEADING CLIPS ITS WORDS, NOT ITSELF -- AND THAT DISTINCTION IS THE WHOLE
 * REASON HE COULD NOT DRAG A COLUMN AT ALL.** The grip sits deliberately half
 * outside its heading (`right: -6px` below), straddling the edge the way a
 * column edge is grabbed everywhere else. Clipping the HEADING cut that outer
 * half off -- so the moment a table had any width saved on it, the handle was
 * 6px wide and **its own centre, where anybody aims, belonged to the sort button
 * underneath.** Measured on Bills of material: hittable from 804 to 809 only,
 * and a press at 810 re-sorted the column instead of resizing it.
 *
 * It was invisible because it only bit on a table the seller had ALREADY sized:
 * the first drag on a fresh table worked, and every drag after it was a coin
 * toss. */
.k-table__cell,
.k-table__heading-inner {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* **NO COLUMN STARTS WIDER THAN ABOUT A LINE OF TEXT, AND THAT IS HIS DECISION,
 * 2026-09-04.**
 *
 * The handle that changes a column's width lives at that column's RIGHT edge --
 * so the one column anybody ever wants to narrow, the very wide one, was the one
 * column whose handle was off the side of the screen. Measured on Bills of
 * material, cold: `Components` drawn 732px, its right edge at 1540 against a
 * visible area ending at 1248. Three columns had a reachable handle and four did
 * not. On a phone, ONE of the seven did.
 *
 * His words: cap it, *"but me being able to make it wide or narrow as needed for
 * the particular table and column"*, and *"should not be too narrow to fit the
 * screen that it is not readable"*. So this is a STARTING width and nothing more.
 *
 * **IT LIFTS THE MOMENT HE SETS A WIDTH HIMSELF** -- `:not(--sized)` is what says
 * so, and it is the half that matters. Dragging past it is how a column he wants
 * wide gets wide, and that width is remembered for that table and that column.
 *
 * **THIS NARROWS WHAT HE RULED BEFORE, IT DOES NOT CONTRADICT IT.** His earlier
 * words are above on `.k-table__grid`: a column should be wide enough not to
 * wrap, *"I can see brass, wire, six mm"*. Nothing wraps here either -- 360px
 * holds roughly forty-five characters, and what is past it ends in an ellipsis
 * rather than on a second line. */
.k-table__grid:not(.k-table__grid--sized):not(.k-table__grid--measuring) .k-table__cell,
.k-table__grid:not(.k-table__grid--sized):not(.k-table__grid--measuring) .k-table__heading {
  max-width: 360px;
}

/* **THE `--measuring` HALF OF THAT, AND WHY IT IS IN THE SAME RULE RATHER THAN A
 * SECOND ONE THAT OVERRIDES IT.**
 *
 * His instruction, 2026-09-04: a double click on the handle makes a column as
 * wide as what is in it. `fitToContents` works that out by taking the widths off
 * for one moment and reading what the browser then makes the column -- and with
 * the cap still on, the answer is 360px whatever the text says, which is not
 * fitting it to anything.
 *
 * **IT WAS WRITTEN AS A SECOND RULE SAYING `max-width: none` FIRST, AND THAT
 * QUIETLY LOST.** `.k-table__grid:not(...)  .k-table__heading` is three classes;
 * `.k-table__grid--measuring .k-table__heading` is two, so the cap won and a
 * double click on a 733px column answered 386px. Measured in the browser -- **the
 * check could not see it, because a stylesheet read as text says nothing about
 * which rule wins.** One rule with both states named cannot have that argument.
 *
 * The cap is about what a column STARTS at, so no handle begins off the side of
 * the screen. A double click is him asking for the full width on purpose, which
 * is a different question. */

.k-table__head {
  background: var(--surface-raised);
}

.k-table__body {
  background: var(--surface);
}

.k-table__head-row {
  border-bottom: 1px solid var(--border-strong);
}

.k-table__heading {
  padding: 0;
  text-align: left;
  font-weight: 600;
  white-space: nowrap;
  vertical-align: middle;
}

.k-table__heading--right {
  text-align: right;
}

/* The heading and its "i" side by side. The sorting button takes the room
 * that is left, so the "i" is never squashed out by it. */
.k-table__heading-inner {
  display: flex;
  align-items: center;
}

.k-table__heading--right .k-table__heading-inner {
  justify-content: flex-end;
}

.k-table__heading-text {
  display: inline-block;
  padding: 12px;
  font-family: var(--font);
  color: var(--text-muted);
}

/* The heading is a real button so it can be reached by keyboard, and so it is
 * obvious that the heading is the only thing that sorts. */
.k-table__sort {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 44px;
  padding: 12px;
  font-family: var(--font);
  font-size: 14px;
  font-weight: 600;
  text-align: inherit;
  color: var(--text-muted);
  background: none;
  border: 0;
  cursor: pointer;
  white-space: nowrap;
}

.k-table__sort:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.k-table__sort--on {
  color: var(--brand);
}

.k-table__sort-text {
  font-family: var(--font);
}

.k-table__sort-arrow {
  font-family: var(--font);
}

/* -------------------------------------------------------------- rows */

.k-table__row {
  border-bottom: 1px solid var(--border);
}

/* The row currently loaded into a form elsewhere on the screen. */
.k-table__row--chosen {
  background: var(--accent-bg);
  box-shadow: inset 3px 0 0 var(--accent);
}

.k-table__cell {
  /* Tightened with the buttons above -- 10px top and bottom against a 32px
   * button is padding doing nothing except making the row taller. */
  padding: 6px 12px;
  vertical-align: top;
  color: var(--text);
  /* NOTHING WRAPS. See `.k-table__grid` above for the whole of why. */
  white-space: nowrap;
}

.k-table__cell--right {
  text-align: right;
}

/* Figures line up under each other, which is the whole point of the second
 * face. Same two faces everywhere in the product (D25). */
.k-table__cell--figure {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* A figure that could not be worked out, shown as a dash rather than left
 * blank -- blank means nothing was ever recorded, which is a different thing. */
.k-table__cell--unknown {
  color: var(--text-subtle);
}

.k-table__cell--actions {
  white-space: nowrap;
  text-align: right;
}

/* THE BUTTONS SCROLL WITH THEIR ROW, LIKE EVERY OTHER COLUMN.
 *
 * **HIS DECISION 2026-08-30, holding the phone:** *"I don't want this open and
 * put aside to be frozen over there."* (His words, before the rename to Void --
 * a quotation is a record of what somebody said and is never rewritten.)
 *
 * WHAT IT USED TO DO AND WHY, kept because it is a real cost and somebody will
 * want to put it back. The buttons were held against the right edge so they
 * stayed reachable while the rest of the table scrolled under them: measured at
 * 375px the button sat at x=478 inside a 374px scroller, off the screen, on
 * every screen in the product that has an action. That was found by a review
 * walking the screens as a seller, and it was a fair finding.
 *
 * **WHAT THE REVIEW COULD NOT SEE IS WHAT HE SAW.** Held there, the column sits
 * permanently on top of whatever it is scrolled over, so on a narrow screen a
 * third of the width is spent on two buttons that never move and the columns he
 * is trying to read pass underneath them. He would rather scroll to the buttons.
 *
 * THE COST, STATED: on a phone the buttons are now off the right-hand edge until
 * the table is scrolled across. The thing that makes that bearable is the column
 * widths below -- the seller sets them, so a table can be made narrow enough
 * that the buttons are in view.
 *
 * The line down the left stays. It marks where the row's own values stop and
 * what can be done to the row starts, which is true whether or not it is held.
 */
.k-table__cell--actions,
.k-table__heading--actions {
  border-left: 1px solid var(--border);
}

.k-table__cell--actions {
  background: var(--surface);
}

.k-table__heading--actions {
  background: var(--surface-raised);
}

/* Records are opened by this button. Clicking the row does nothing, so text
 * stays selectable and nothing opens by accident (D33). */
/* **THE BUTTONS SET THE HEIGHT OF THE WHOLE ROW, so they are what shrinks.**
 * His words: reduce their height so the row gets shorter. At 40px tall inside
 * 10px of cell padding, every row was 60px whatever was in it -- so a phone
 * showed six items where it could have shown ten, and the tallest thing on the
 * row was never the thing he was reading.
 *
 * **32px, AND THAT IS A DELIBERATE DEPARTURE FROM THE 44px FLOOR (D67).** Said
 * plainly rather than left to be found: these two are not the same kind of
 * control as a Save button. They repeat on every row, so a mis-hit costs one
 * press to correct rather than anything being lost -- and BOTH of them are
 * reversible (Open just opens; Void is undone by Restore, and nothing is
 * ever erased). What buys the accuracy back is that the whole row is 40px of
 * target height and the two are 8px apart.
 *
 * THE FLOOR STILL HOLDS EVERYWHERE ELSE. Anything that saves, deletes, or is
 * the only control on a screen stays at 44px.
 */
.k-table__action {
  margin-left: 8px;
}

/* -------------------------------------------------------------- empty */

.k-table__empty {
  padding: 28px 12px;
  text-align: center;
  color: var(--text-muted);
}

.k-table__clear {
  margin: 12px auto 0;
}

/* -------------------------------------------------------------- footer */

.k-table__footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 12px;
  background: var(--surface-raised);
  border-top: 1px solid var(--border);
  font-size: 13px;
  color: var(--text-muted);
}

.k-table__count {
  font-family: var(--font);
}

.k-table__pages {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}

.k-table__page {
  min-width: 40px;
  min-height: 40px;
  padding: 8px 12px;
  font-family: var(--font);
  font-size: 13px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
}

/* Only a page you can actually go to lights up under the cursor -- and the
 * page you are already on is not one of them.
 *
 * Both exclusions are load-bearing. The current page is deliberately NOT
 * switched off (it has to stay reachable by keyboard), so ruling out only the
 * switched-off ones left this rule matching it -- and this rule counts for
 * more than the one that paints it, whatever the order. Putting the mouse on
 * the page number you are already on turned its label white on near-white.
 *
 * Fourth time this trap has been logged here. The lesson, written plainly:
 * any rule that paints a chosen, current or selected thing must be excluded
 * from every state rule that touches the same properties -- hover, focus and
 * disabled alike. Naming the class twice is not enough on its own. */
.k-table__page:hover:not(:disabled):not(.k-table__page--on) {
  background: var(--surface-raised);
}

.k-table__page:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* A page you cannot go to must not look like one you can. */
.k-table__page:disabled {
  color: var(--text-subtle);
  cursor: default;
}

/* The page you are on. Marked, not merely dimmed.
 *
 * Written with the class named twice on purpose. "Every rule is one class" is
 * the defence against a general rule quietly beating a specific one, and it
 * does not cover a state like :disabled -- which counts for as much as a
 * second class. Named once, this rule lost to the greyed-out one and the page
 * you are on was painted as though it were dead.
 *
 * Named twice the two rules count for exactly the same, and this one wins
 * ONLY because it is written further down. So the order of these two blocks
 * matters: move the greyed-out rule below this one and the bug comes back.
 * Said exactly, because a comment claiming the order does not matter is what
 * would let the next person reorder the file and undo it. */
.k-table__page.k-table__page--on {
  color: var(--on-brand);
  background: var(--brand);
  border-color: var(--brand);
  cursor: default;
}

.k-table__gap {
  padding: 0 2px;
  color: var(--text-subtle);
}

.k-table__size {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.k-table__size-label {
  font-family: var(--font);
  white-space: nowrap;
}

/* **THE SHAPE COMES FROM `k-control`.** The last of the four dropdown
 * definitions -- 40px and 13px, which meant a phone zoomed the page in the
 * moment somebody touched it. */

/* -------------------------------------------------------------- phones
 *
 * Nothing is hidden and nothing breaks on a small screen (D67). The toolbar
 * and footer stack, and the grid keeps its own sideways scroll.
 */

@media (max-width: 640px) {
  /* **THE TOOLBAR STAYS A ROW THAT WRAPS (his review).** It used to stack
   * into a column, so every control took a full row of its own -- 197 pixels
   * of toolbar before a single item, measured at 375px, and he said it read
   * as a jumble filling half the screen. Wrapping puts the search on its own
   * line, because a short search box is one nobody types in, and lets the
   * rest share the next. */
  .k-table__toolbar {
    align-items: center;
  }

  .k-table__footer {
    flex-direction: column;
    align-items: flex-start;
  }

  .k-table__search {
    flex-basis: auto;
  }

  .k-table__filter {
    display: flex;
  }

}

/* ------------------------------------------------- changing a column's width

/* The grip on a heading's right-hand edge.

 * **IT SITS ON THE EDGE ITSELF**, half in each column, because that is where a
 * person reaches for it -- and it is absolutely positioned so it takes no width
 * of its own. A grip laid out in the flow would push every heading wider by its
 * own size and the columns would no longer measure what their contents need.
 *
 * 12px WIDE, WHICH IS NOT A THUMB. It cannot be: it has to sit on the boundary
 * between two columns, and a 44px one would cover the column beside it. What
 * makes it usable on a phone instead is that it is FULL HEIGHT of the heading
 * and that the drag survives the finger sliding off it -- `setPointerCapture`
 * in table.js. This is the reason it uses `col-resize` rather than `pointer`:
 * it is a thing you pull, not a thing you press, and the product's own refusal
 * about tap targets is about the things you press.
 */
.k-table__grip {
  position: absolute;
  top: 0;
  right: -6px;
  bottom: 0;
  width: 12px;
  padding: 0;
  background: transparent;
  border: 0;
  cursor: col-resize;
  /* Above the sort button, which fills the whole heading -- otherwise the
   * heading swallows every press and the column can never be dragged. */
  z-index: 1;
  /* THE BROWSER MUST NOT TAKE THE DRAG FOR A SCROLL. Without this a sideways
   * drag on a phone scrolls the table instead of moving the column, which is
   * exactly the gesture being made. */
  touch-action: none;
}

/* THE COLUMN EDGE IS DRAWN, not left to be discovered. A grip nobody can see is
 * a grip nobody uses; the line is quiet until the heading is touched. */
.k-table__grip::before {
  content: "";
  position: absolute;
  top: 6px;
  right: 5px;
  bottom: 6px;
  width: 2px;
  background: var(--border);
  border-radius: 1px;
}

.k-table__heading:hover .k-table__grip::before,
.k-table__grip:focus-visible::before,
.k-table__grip--held::before {
  background: var(--brand);
}

.k-table__grip:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* The heading has to be the thing the grip is measured against. */
.k-table__heading {
  position: relative;
}

/* ------------------------------------ which columns this device shows

/* His words 2026-08-30: on a phone he wants to put columns away and bring
 * them back. Kept on the device, never in his database -- what a screen looks
 * like on one phone is not a fact about his business.
 *
 * IT SITS IN THE TOOLBAR beside the search and the filters, because it is the
 * same kind of thing: it changes what this screen shows him and nothing else.
 */
.k-table__columns {
  position: relative;
}

.k-table__columns-open {
  list-style: none;
}

/* Safari draws its own triangle through the summary unless this is said. */
.k-table__columns-open::-webkit-details-marker {
  display: none;
}

/* SOMETHING IS PUT AWAY, AND THE CONTROL SAYS SO WITHOUT BEING OPENED. A column
 * missing with nothing saying so is a column that looks broken -- somebody comes
 * back a week later, cannot find HSN, and has no reason to think they did it. */
/* **SAYING SOMETHING THE ORDINARY BUTTON DOES NOT ALREADY SAY.** This used to
 * set the brand colour and a brand border. `k-button--ordinary` gives the first
 * for free and its HOVER gives the second -- so "you have put columns away"
 * looked exactly like "the mouse is on this button", and half the signal was a
 * no-op. A weight is a thing no other state of this button uses. */
.k-table__columns--some-away .k-table__columns-open {
  font-weight: 700;
  border-color: var(--brand);
}

.k-table__columns-open:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ABOVE THE TABLE, NOT PUSHING IT DOWN. Laid out in the flow, opening this
 * would shove the whole table down the screen and the row somebody was
 * reading would move out from under them. */
.k-table__columns-list {
  /* **THE PADDING IS PART OF THE HEIGHT, not added to it.** `keepOnScreen`
   * works out how much room there is and sets a max-height; measured from the
   * content instead, the padding and the border push the panel back off the
   * edge it was just moved inside. */
  box-sizing: border-box;
  /* **PLACED AGAINST THE WINDOW BY `keepOnScreen`, not against the control.**
   * This table scrolls sideways, so a heading twelve columns along is off the
   * screen -- and anything hung from it is off the screen too. `fixed` is set
   * here as the starting point and the position is measured when it opens. */
  position: fixed;
  z-index: 10;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 200px;
  max-height: 60vh;
  padding: 8px;
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 6px 20px var(--shadow);
}

.k-table__columns-line {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 0 6px;
  font-family: var(--font);
  font-size: 14px;
  color: var(--text);
  border-radius: var(--radius);
  cursor: pointer;
}

.k-table__columns-line:hover {
  background: var(--surface-raised);
}

.k-table__columns-box {
  width: 18px;
  height: 18px;
  accent-color: var(--brand);
}

/* THE TWO WAYS BACK SIT TOGETHER AT THE FOOT OF THE LIST, and are drawn the
 * same, because they are the same kind of thing: each undoes something the
 * seller did to this table on this device. */
.k-table__columns-all,
.k-table__columns-widths {
  margin-top: 6px;
}

.k-table__columns-all:disabled,
.k-table__columns-widths:disabled {
  color: var(--text-muted);
  cursor: default;
}

/* -------------------------------------- a filter on each column heading

/* His words: *"there is a sort feature on each column name. What I want now, a
 * filter feature on each column name. Like how we do it in Excel?"*
 *
 * IT SITS INSIDE THE HEADING, beside the label and the help mark, because that
 * is where Excel puts it and where somebody looks for it. */
.k-table__filter-col {
  position: relative;
  display: inline-flex;
  flex: 0 0 auto;
}

/* The funnel. A glyph rather than an image: it is one character, it takes the
 * text colour, and it needs no file to be fetched. */
.k-table__filter-open {
  list-style: none;
}

.k-table__filter-open::-webkit-details-marker {
  display: none;
}

.k-table__filter-open::before {
  content: "▼";
}

/* **A NARROWED COLUMN SAYS SO WITHOUT BEING OPENED.** A table quietly hiding
 * rows because of something ticked last week is the most confusing thing a list
 * can do, and the seller has no reason to suspect it. */
.k-table__filter-col--on .k-table__filter-open {
  color: var(--on-brand);
  background: var(--brand);
}

.k-table__filter-panel {
  /* **THE PADDING IS PART OF THE HEIGHT, not added to it.** `keepOnScreen`
   * works out how much room there is and sets a max-height; measured from the
   * content instead, the padding and the border push the panel back off the
   * edge it was just moved inside. */
  box-sizing: border-box;
  /* **PLACED AGAINST THE WINDOW BY `keepOnScreen`, not against the control.**
   * This table scrolls sideways, so a heading twelve columns along is off the
   * screen -- and anything hung from it is off the screen too. `fixed` is set
   * here as the starting point and the position is measured when it opens. */
  position: fixed;
  z-index: 15;
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 240px;
  max-height: 320px;
  padding: 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 6px 20px var(--shadow);
}

.k-table__filter-find {
  box-sizing: border-box;
  width: 100%;
  min-height: 40px;
  padding: 6px 10px;
  font-family: var(--font);
  font-size: 13px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
}

.k-table__filter-list {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 2px;
  overflow-y: auto;
}

.k-table__filter-line-col {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 0 4px;
  font-family: var(--font);
  font-size: 13px;
  font-weight: 400;
  color: var(--text);
  white-space: nowrap;
  border-radius: var(--radius);
  cursor: pointer;
}

.k-table__filter-line-col:hover {
  background: var(--surface-raised);
}

.k-table__filter-box {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  accent-color: var(--brand);
}

/* The value fills the row and the count sits at the end, so a long value
 * shortens rather than pushing the count off the panel. */
.k-table__filter-word {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* HOW MANY ROWS EACH VALUE HAS. It turns the list into an answer on its own --
 * "how many of these are packaging?" is read without ticking anything. */
.k-table__filter-count {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-muted);
}

.k-table__filter-buttons {
  display: flex;
  gap: 6px;
}

.k-table__filter-all,
.k-table__filter-none {
  flex: 1;
}

/* ------------------------------------------- the toolbar, on a phone

 * **HIS REVIEW: everything above the table filled half the screen.** Measured at
 * 375px it was 197 pixels of toolbar alone -- the search, the filters and the
 * Columns button each taking a row of their own because each is wide enough to
 * refuse to share one.
 *
 * **THE SEARCH SHARES ITS ROW WITH COLUMNS (his review).** It used to take a
 * whole row to itself, on the reasoning that a short search box is one nobody
 * types in. That was written when four other controls shared the toolbar. Two
 * of them have since gone to the column headings, so all that is left beside
 * the search is one button -- and giving the search the whole row pushed that
 * button onto a row of its own for nothing.
 *
 * **AND THAT REASONING WAS OVERTAKEN, 2026-09-01.** A RANGE FILTER arrived on
 * Products after it was written -- two more boxes in the same row -- and
 * "everything but the search" then came to 270 of the 351 pixels a phone has.
 * The search was left at 81. His words: *"that stock between takes up all the
 * space and the search box is almost not usable on mobile."*
 *
 * So the search has its own row again. The sentence above is kept rather than
 * rewritten, because it is right about the case it was written for and the thing
 * that changed is what else is in the row.
 */
@media (max-width: 600px) {
  .k-table__toolbar {
    flex-wrap: wrap;
    row-gap: 8px;
    /* **EVERY GAP CLOSES**, because four things in one row on a 375px screen
     * cannot spare 36 pixels of air. */
    column-gap: 8px;
    padding: 8px;
  }

  .k-table__search {
    /* **IT TAKES WHAT IS LEFT, and everything else gives up room to make that
     * worth having.** His correction, 2026-09-01: *"all these four boxes and
     * buttons are supposed to be on a single row. Now they are appearing on two
     * rows on mobile. That should not happen."*
     *
     * Given the whole row it WAS usable and it cost a second row. So the row
     * stays one row and the width comes out of the other three instead: the
     * range's label is hidden, its two boxes go to 52, and the gaps close from
     * 12 to 8. That is 351 pixels on his phone laid out as
     * 52 + 52 + Columns + three gaps, leaving the search the rest. */
    flex: 1 1 0;
    min-width: 0;
  }

  /* Beside it, at the width of its own words -- never squeezed and never
   * wrapped under. */
  .k-table__columns {
    flex: 0 0 auto;
  }

  /* **AND THE FIFTH CONTROL, DECLARED RATHER THAN LEFT TO CHANCE.** Download
   * arrived in this row on 2026-09-05 and had no rule of its own, which a
   * reviewer caught: the budget above was written for four things and nothing
   * said what the fifth does when the row runs out.
   *
   * MEASURED, in the browser, on the busiest toolbar in the product (Products:
   * search, a range filter, Columns, Download): at 336px -- his 375px phone
   * less the page's own edges -- it is ONE ROW, both while it says `Download`
   * and while it says `Making the file`, which is the widest it ever gets. The
   * search gives up the room, which is what the sentence above says it is for.
   * Below about 330px it does wrap while the file is being made, and that is
   * accepted rather than hidden: it lasts about three seconds and the phones
   * that narrow are a decade old. */
  .k-table__download {
    flex: 0 0 auto;
  }

  /* The filters sit side by side rather than stacking. A label above its own
   * control is right on a wide screen and is two rows on a narrow one. */
  .k-table__filter {
    flex: 0 1 auto;
  }

  .k-table__filter-line {
    gap: 6px;
  }

  /* **THE RANGE'S LABEL GOES.** His instruction, 2026-09-01. Each box says what
   * it is out loud for a screen reader (`Stock from`, `Stock to`) and shows
   * `from` and `to` in itself -- so the words beside them were the one part a
   * phone could do without, and they were the widest part of the row. */
  .k-table__filter-line > .k-table__filter-label {
    display: none;
  }

  .k-table__filter-range {
    /* **AS NARROW AS THE WORD IT HOLDS.** `from` and `to` are what these say
     * when they are empty, and a stock figure is rarely more than four digits --
     * so the width these had was mostly air, paid for by the search box. */
    width: 52px;
    padding: 6px 4px;
    text-align: center;
  }
}

/* The one row that would not pack. The Type dropdown and the tickbox beside it
 * came to 341 on a 333px screen -- eight pixels over, so each took a row of its
 * own. Capping the dropdown lets them share, which is the difference between a
 * three-row toolbar and a two-row one. */
@media (max-width: 600px) {
  .k-table__filter-choice {
    max-width: 150px;
  }
}
