/* The tab drawer's chrome, rearranged.

   Two search boxes and two menus were taking four lines off the top of a panel
   whose entire job is showing tabs, and ten action buttons laid across the top
   read as a wall of glyphs. Now: the four controls share ONE line and share the
   width by attention, and the actions stand on the right edge as a rail. */

/* ── the rail ────────────────────────────────────────────────────────── */
/* IT FLOATS, AND THE DRAWER LEANS AWAY FROM IT. Absolute, pinned to the top of
   the drawer's own box — anything else puts it in the flow, where it takes a
   whole row of its own and pushes the tabs down. The rows lean away with a
   margin rather than the drawer with padding: padding on the drawer moved the
   chips bodily and clipped them against the far edge. */
/* NO position HERE. The drawer is already position:absolute — anchored to the
   right edge of the board — and absolute is a positioning context of its own,
   so the rail has what it needs. Setting `relative` took the drawer OUT of that
   anchoring and dropped it into normal flow on the left of the screen, which is
   exactly what "the panel is on the left side" was. */
/* ── SLIM, AND ON THE MIDDLE OF THE EDGE ──────────────────────────────
   Pinned to the top it stood over the first group, which is where the tab
   list is busiest — the one place you least want a column of buttons. On the
   middle of the edge the top and the bottom of the panel are clear, and the
   longest reach to it is half the panel rather than the whole of it.

   `top: 50%` with a translate rather than inset-block: the rail's height
   changes with how many buttons a board's state calls for, and anything that
   assumes a height gets it wrong on the board where it matters. */
.tbar-rail {
  position: absolute; top: 50%; transform: translateY(-50%);
  inset-inline-end: 5px; z-index: 6;
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 4px 2px; border-radius: 11px;
  background: var(--panel-solid); border: 1px solid var(--border);
  box-shadow: 0 6px 20px -12px rgba(0,0,0,.55);
  /* it must never grow past the panel; if a board somehow has more buttons
     than room, the rail scrolls rather than running off the bottom */
  max-height: calc(100% - 16px); overflow-y: auto; overflow-x: visible;
  scrollbar-width: none;
}
.tbar-rail::-webkit-scrollbar { width: 0; }
/* 20px WITH A 12px GLYPH READ AS DECORATION rather than as buttons. 23 and
   13 is the middle of it: still slimmer than the 25 it started at, still
   giving the tab names their room back, and pressable again. */
.tbar-rail > button, .tbar-rail .trail-grp > button {
  position: relative; width: 23px; height: 23px; flex: none;
  display: grid; place-items: center; cursor: pointer;
  border-radius: 6px; border: 1px solid transparent;
  background: transparent; color: var(--muted);
  transition: color .14s, background .14s, border-color .14s;
}
.tbar-rail button svg { width: 13px; height: 13px; }
.tbar-rail > button:hover { color: var(--text); background: var(--hover); border-color: var(--border); }
.tbar-rail > button.on {
  color: #fff; border-color: transparent;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
}
.tbar-rail > button > i {
  position: absolute; top: -2px; inset-inline-end: -2px;
  min-width: 13px; height: 13px; padding: 0 3px; border-radius: 7px;
  font-style: normal; font-size: 9px; line-height: 13px; font-weight: 700;
  background: var(--accent); color: #fff;
}
.tbar-rail .tb-gap { width: 15px; height: 1px; margin: 2px 0; background: var(--border); flex: none; }

/* EVERYTHING LEANS AWAY, not only the top three rows. This reserved the
   rail's strip for the head, the filter row and the controls — the things
   that used to be the only ones tall enough to reach it. The rail grew when
   its buttons were put into clusters, so it now runs most of the way down the
   panel, and the tab rows underneath were sliding beneath it: "04 REFEREN…"
   with the rest of the word behind a button.

   A margin cannot do this — it adds to the width of a flex item that is
   already as wide as the drawer, so the box overflows by exactly the margin
   and the drawer grows a sideways scrollbar. And padding on the drawer cannot
   either: the rail is absolutely positioned inside it, so its offsets are
   measured from the padding box and it would walk inwards with the padding.
   The children being NARROWER is the one thing that moves the content and
   leaves the rail where it is. */
/* A MAX-WIDTH ON A BOX THAT FITS ITS CONTENTS DOES NOTHING. A group is
   `display: inline-flex` — it is already only as wide as what is in it — so
   capping it changed nothing at all: the contents did not shrink to meet the
   cap, they overflowed it and were clipped, which is "04 REFEREN" with the
   rest of the word behind a button.

   It has to be given the reserved width to FILL. Then the grid inside it has
   something definite to wrap against, and a row too long for the space breaks
   onto the next line instead of running under the rail. */
.tabbar > *:not(.tbar-rail) {
  width: calc(100% - 34px); max-width: calc(100% - 34px); box-sizing: border-box;
}
/* the two that are chips rather than rows keep their own width: a tab chip
   stretched across the drawer would be a button the size of a paragraph */
.tabbar > .tchip, .tabbar > .tloose, .tabbar > .tnew {
  width: auto; max-width: calc(100% - 34px);
}
.tabbar .twg { width: 100%; min-width: 0; }
.tabbar .tsubs, .tabbar .trow, .tabbar .tkin { min-width: 0; max-width: 100%; }

/* ── one row, sized by attention ─────────────────────────────────────── */
/* ONE ROW MEANS ONE ROW. Without nowrap the pills fall to a second line the
   moment the active one grows — which is the "they always go to the row below"
   everyone saw, and it defeats the entire point of putting them together. */
.tabbar .tbar-filt {
  display: flex; flex-wrap: nowrap; align-items: center; gap: 4px;
  padding: 6px 8px; margin-bottom: 2px;
}
.tb-one {
  display: flex; align-items: center; gap: 5px; min-width: 0;
  height: 28px; padding: 0 7px; border-radius: 9px;
  background: var(--hover); border: 1px solid var(--border);
  flex: 0 0 32px; overflow: visible;   /* visible: the caption stands outside */
  /* CENTRED WHILE SHUT. A closed pill holds one glyph and nothing else, so
     the glyph belongs in the middle of it. Open, the row starts at the left
     like any other field. */
  justify-content: center; position: relative;
  transition: flex-basis .22s cubic-bezier(.2,.9,.3,1), flex-grow .22s, border-color .16s;
}
.tb-one:focus-within, .tb-one:hover { justify-content: flex-start; }
/* the pill clips its own contents; only the caption escapes */
.tb-one > i, .tb-one > .tb-slot, .tb-one > input, .tb-one > select { overflow: hidden; }
.tb-one > i { flex: none; display: grid; place-items: center; color: var(--muted); }
.tb-one > i svg { width: 13px; height: 13px; }

/* the one you are in takes the room; the rest FADE rather than shuffle —
   they hold their place in the line and go quiet, so nothing jumps sideways
   under the pointer on the way to the thing you were aiming at */
.tb-one:focus-within, .tb-one:hover { flex: 1 1 auto; border-color: var(--accent); }
.tbar-filt:focus-within .tb-one:not(:focus-within):not(:hover),
.tbar-filt:hover .tb-one:not(:focus-within):not(:hover) {
  opacity: .34; background: transparent; border-color: transparent;
}
.tb-one { transition: flex-basis .22s cubic-bezier(.2,.9,.3,1), flex-grow .22s,
                      opacity .22s ease, background .22s, border-color .16s; }
.tb-one:focus-within > i { color: var(--accent); }
.tb-one.lit { border-color: var(--accent); }
.tb-one.lit > i { color: var(--accent); }

/* the fields themselves: invisible until their pill has room */
/* HIDING IT WITH OPACITY LEFT IT IN THE LAYOUT, which is why the glyph beside
   it sat off to one side of a pill it looked alone in. A shut field gives up
   its width as well as its ink. */
.tb-one input, .tb-one select, .tb-one .tb-slot > input {
  flex: 0 1 0; min-width: 0; width: 0; border: 0; outline: none; background: transparent;
  font: inherit; font-size: 12px; color: var(--text);
  opacity: 0; pointer-events: none; transition: opacity .16s, width .22s;
}
.tb-one:focus-within input, .tb-one:hover input,
.tb-one:focus-within select, .tb-one:hover select,
.tb-one:focus-within .tb-slot > input, .tb-one:hover .tb-slot > input {
  opacity: 1; pointer-events: auto; flex: 1 1 auto; width: 100%;
}
.tb-one .tb-slot { flex: 0 1 auto; }
.tb-one:focus-within .tb-slot, .tb-one:hover .tb-slot { flex: 1 1 auto; }
.tb-one .tb-slot { flex: 1; min-width: 0; display: flex; }
.tb-one select { cursor: pointer; appearance: none; }
/* a select must stay clickable even when collapsed, or the menu can never
   be opened — the pill is small, but it is still the handle */
.tb-sel select { opacity: 0; pointer-events: auto; position: absolute; inset: 0; width: 100%; }
.tb-sel { position: relative; }
.tb-sel:focus-within select, .tb-sel:hover select { opacity: 1; position: static; }

/* the widget search arrives from elsewhere and must sit flat in its pill */
#findslot > * { flex: 1; min-width: 0; border: 0 !important; background: transparent !important;
  padding: 0 !important; height: 24px; box-shadow: none !important; }

@media (max-width: 520px) {
  .tbar-rail { position: static; flex-direction: row; align-self: stretch; margin: 4px 0; }
  .tabbar > .tbar-head, .tabbar > .tbar-filt, .tabbar > .tctl-drawer { width: 100%; }
}

/* ── NOTHING IN A DRAWER MAY BE WIDER THAN THE DRAWER ────────────────────
   It scrolls vertically by design; a sideways scrollbar is always a mistake,
   and it clips the left edge of every chip so the colour dots disappear. The
   widget search arrives from another part of the UI carrying its own width,
   which is exactly the kind of thing that causes this. */
.tabbar > * { max-width: 100%; }
.tabbar .tbar-filt { max-width: 100%; box-sizing: border-box; }
#findslot { min-width: 0; }
#findslot > * { width: 100% !important; max-width: 100% !important; min-width: 0 !important; }
.tabbar { overflow-x: clip; }


/* the widget search draws its own magnifier, so its pill adds none */
.tb-one.tb-own { padding-inline-start: 4px; }
.tb-one.tb-own .tb-slot > * { opacity: 1 !important; pointer-events: auto !important; }

/* ── two adds that cannot be confused ─────────────────────────────────── */
/* A plus on its own says nothing about what it makes, and there were two of
   them side by side. Each button wears the THING it creates, with a small plus
   badged on the corner. */
.tbar-rail > button > u {
  position: absolute; bottom: -1px; inset-inline-end: -1px;
  width: 11px; height: 11px; border-radius: 50%;
  font-size: 9px; line-height: 11px; font-weight: 800; text-decoration: none;
  background: var(--accent); color: #fff; text-align: center;
}
.tbar-rail > button.tadd-tab { color: var(--accent); }
.tbar-rail > button.tgnew > u { background: var(--accent-2); color: #04202020; color: #06202a; }

/* ── WHAT THIS PILL IS, ABOVE IT ───────────────────────────────────────────
   "Find a tab…" written inside a pill competing with three others for one
   narrow row is always going to read "Find a ta". The name does not belong
   inside the pill; it belongs above it, where there is a drawer's width of
   room and nothing using it. Full words, never clipped, gone when the pointer
   leaves. The placeholder stays for the moment the field is open and you are
   typing in it — the one moment it is not competing for space. */
.tb-one[data-tip]::after {
  content: attr(data-tip);
  position: absolute; bottom: calc(100% + 6px); inset-inline-start: 50%;
  transform: translateX(-50%) translateY(3px);
  padding: 3px 8px; border-radius: 7px; white-space: nowrap;
  background: var(--text); color: var(--canvas-bg, #fff);
  font-size: 10.5px; font-weight: 700; letter-spacing: .01em; line-height: 1.5;
  opacity: 0; pointer-events: none;
  transition: opacity .14s ease, transform .14s ease;
  z-index: 60;
}
.tb-one[data-tip]:hover::after { opacity: .96; transform: translateX(-50%) translateY(0); }
/* once you are typing in it the field says what it is; a caption over your own
   text would be the second thing in the way */
.tb-one[data-tip]:focus-within::after { opacity: 0; }
/* the row must not clip the caption, and the pills must still not wrap */
.tabbar .tbar-filt { overflow: visible; }

/* ── OUT-SPECIFIED BY THE OLD LAYOUT ──────────────────────────────────────
   Two rules in app.css reach these fields with a longer selector than mine —
   `.tabbar .tbar-filt .tfind { flex: 1 1 100% }` and `.tfind { min-width:
   40px }` — so a shut pill kept a 40px field in it and pushed its glyph 22px
   to the left of a box it looked alone in. The widget search does the same
   through `.board-find { min-width: 120px }`, which is the right number where
   that component normally lives and the wrong one inside a 32px pill.

   Measured, not guessed: sort and group sat at 0px off centre and the other
   two at -22px and -1px, which is what sent me looking. */
.tabbar .tbar-filt .tb-one:not(:hover):not(:focus-within) .tfind,
.tabbar .tbar-filt .tb-one:not(:hover):not(:focus-within) .tb-slot > input {
  flex: 0 0 0 !important; width: 0 !important; min-width: 0 !important;
  padding: 0 !important; border-color: transparent !important; margin: 0 !important;
}
/* FLEX-GROW BEATS WIDTH inside a flex row, so `width: 15px` on a child with
   `flex: 1` does nothing at all — the flex basis has to be the thing that is
   pinned. The first attempt set width and measured 245px, unchanged. */
.tabbar .tbar-filt .tb-one:not(:hover):not(:focus-within) .tb-slot,
.tabbar .tbar-filt .tb-one:not(:hover):not(:focus-within) .tb-slot > * {
  flex: 0 0 15px !important; min-width: 0 !important; width: 15px !important;
  max-width: 15px !important; overflow: hidden;
}
/* AND THE GAP IS STILL A GAP when the thing beside it is zero wide: 5px of
   nothing between the glyph and an empty field pushed the glyph 3px off
   centre, which is exactly the amount that looks wrong without looking
   broken. */
.tb-one:not(:hover):not(:focus-within) { gap: 0; }
/* the widget search draws its magnifier as an absolutely-placed glyph 10px in
   from its own start edge — which centres nothing when the box around it has
   shrunk to the glyph. Shut, it sits in the flow like every other icon. */
.tabbar .tbar-filt .tb-one:not(:hover):not(:focus-within) .tb-slot > .board-find {
  display: grid; place-items: center; width: 15px !important; gap: 0;
}
.tabbar .tbar-filt .tb-one:not(:hover):not(:focus-within) .tb-slot > .board-find > svg {
  position: static; inset: auto;
}
.tabbar .tbar-filt .tb-one:not(:hover):not(:focus-within) .tb-slot > .board-find > kbd {
  display: none;
}

/* ── THE RAIL, IN CLUSTERS ────────────────────────────────────────────────
   Fourteen glyphs in a column with hairline gaps between them said nothing
   about which of them did what — you learned it by pressing things, and a
   rail you learn by pressing is a rail you press wrong. Each job stands on
   its own ground with real space around it: make something, change how the
   drawer shows what is there, tidy the list, keep the panel. */
.tbar-rail .trail-grp {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 2px 1px; border-radius: 8px;
  background: color-mix(in srgb, var(--text) 5%, transparent);
}
.tbar-rail .tb-gap { display: none; }   /* the clusters are the separation now */

/* ── THE HINT, AS A CARD ──────────────────────────────────────────────────
   These sentences are worth reading — "removing a group removes the SET only:
   no tab and no card is touched" is the difference between pressing a button
   and knowing what it will do. A native tooltip delivers that as a grey slab
   in the OS font, after half a second, wrapping wherever it likes. */
/* A PANEL IS A PANEL. It was painted var(--text) on var(--canvas-bg) — dark
   on a light board, light on a dark one — which is what a native tooltip does
   and exactly why those always look like they belong to the operating system
   rather than to the app. White on a white board, dark on a dark one, with the
   same border and shadow as every other floating thing here. */
.trail-tip {
  position: fixed; z-index: 90; max-width: 248px; pointer-events: none;
  padding: 8px 11px; border-radius: 11px;
  background: var(--panel-solid, var(--panel)); color: var(--text);
  border: 1px solid var(--border);
  box-shadow: 0 16px 38px -14px rgba(0,0,0,.42);
  font-family: var(--font); line-height: 1.45;
  animation: trailTipIn .12s ease;
}
@keyframes trailTipIn { from { opacity: 0; transform: translateY(3px); } }
.trail-tip b { display: block; font-size: 11.5px; font-weight: 800; letter-spacing: .01em; }
/* the sentence is the point, so it is not made small enough to skip */
.trail-tip span { display: block; font-size: 11px; font-weight: 500;
  color: var(--muted); margin-top: 2px; }
/* a button that only ever had a title has no name to put above the line, so
   the line is the whole card and carries the full ink */
.trail-tip.one span { margin-top: 0; color: var(--text); font-weight: 600; font-size: 11.5px; }
.trail-tip.one b { display: none; }

/* the plus rides on the corner of what it makes, not beside it */
.tbar-rail button { position: relative; }
.tbar-rail button > u {
  position: absolute; inset-inline-end: 1px; top: 0px; font-size: 10px; font-weight: 900;
  line-height: 1; text-decoration: none; color: var(--accent);
}
