/* ============================================================================
   FIX v91 — focus rings, sidebar alignment, table actions. Loaded last.
   ========================================================================== */

/* ── 1. FOCUS RING: THE WHOLE CONTROL, EVERY TIME ─────────────────────────
   The rule was `outline:2px ...; outline-offset:1px; border-radius:inherit`.
   Three things were wrong with it:
     · border-radius:inherit does nothing to an outline, so the ring kept a
       shape that did not match the field it was drawn around;
     · outline-offset:1px floats the ring off the edge, so it reads as a
       separate box rather than the field lighting up;
     · it targeted the INPUT. In a composite control the input is chrome-less
       and sits INSIDE the visible box, so the ring landed around the inner
       element and left the glyph and the "All" scope button outside it.
   One rule instead: the ring goes on the outermost visible box, hugging it. */

/* never on an inner input that has no box of its own */
body .tb-search input:focus-visible,body .tb-search input:focus,
body .list-search input:focus-visible,body .list-search input:focus,
body .hc-search input:focus-visible,body .hc-search input:focus,
body .cc-map-search input:focus-visible,body .ac-wrap input:focus-visible{
  outline:none!important;box-shadow:none!important}

/* the whole bar lights up, offset 0 so the ring IS the edge */
body .tb-search:focus-within,body .list-search:focus-within,
body .hc-search:focus-within,body .cc-map-search:focus-within,
body .ac-wrap:focus-within{
  outline:2px solid var(--accent);outline-offset:0;
  border-color:var(--accent)}

/* standalone controls: the ring follows the control's own radius, no offset */
body .input:focus-visible,body input:focus-visible,body select:focus-visible,
body textarea:focus-visible,body .btn:focus-visible,body .icon-btn:focus-visible{
  outline:2px solid var(--accent);outline-offset:0}

/* ── 2. THE GLOBAL SEARCH BAR IS ONE CONTROL ──────────────────────────────
   .tb-search holds a scope button ("All"), a glyph and an input. They were
   drawn as three separate pieces, so the bar looked broken apart. One box, one
   border, dividers between the parts instead of gaps.

   overflow:hidden USED TO BE HERE and it broke the feature. The results panel
   (.tbs-drop9) is appended INSIDE .tb-search and positioned absolutely under it,
   so clipping the pill clipped the results: the search was running correctly and
   finding records - measured 5 hits for "RAJ" in a 399x254 panel - and none of
   it could be seen. That is the reported "the universal bar doesn't even work".
   The only thing the clipping bought was keeping the scope button's hover fill
   inside the rounded right end, which the button can do with its own radius. */
body .tb-search{
  display:flex;align-items:center;gap:0;
  border:var(--hair) solid var(--line-2);background:var(--panel);
  border-radius:999px;padding:0;overflow:visible;min-height:38px}
/* the pill's right end is the scope button, so it carries that corner itself */
body .tb-scope{border-radius:0 999px 999px 0}
body .tb-search>span:first-child,body .tb-search .tb-search-ic{
  display:flex;align-items:center;justify-content:center;
  width:38px;flex:0 0 auto;opacity:.55}
body .tb-search input{
  flex:1 1 auto;min-width:0;border:0;background:none;box-shadow:none;
  padding:0 4px 0 0;height:36px;border-radius:0}
body .tb-scope{
  flex:0 0 auto;display:flex;align-items:center;gap:5px;
  height:36px;padding:0 14px 0 12px;border:0;background:none;cursor:pointer;
  border-left:var(--hair) solid var(--line-1);color:var(--muted);font-size:13px}
body .tb-scope:hover{background:var(--hover);color:var(--fg)}

/* ── 3. SIDEBAR ICONS ON ONE LINE ─────────────────────────────────
   Real structure, read off the page: a.nav-item / button.nav-grp > span.nav-ico > svg.
   Top-level icons already share x=18, but child rows are indented to 42-50. In
   the collapsed rail only icons are visible, so those indents put them on three
   different vertical axes - the staggered column in the screenshots.
   Every icon gets an identical slot, and the collapsed rail drops the indent so
   one axis is the only possible outcome. */
body .sidebar .nav-item,body .sidebar .nav-grp,body .sidebar .nav-kid{
  display:flex;align-items:center;gap:10px}
body .sidebar .nav-ico{
  flex:0 0 20px;width:20px;height:20px;
  display:inline-flex;align-items:center;justify-content:center}
body .sidebar .nav-ico svg{width:17px;height:17px;display:block}

/* COLLAPSED RAIL: no indent, no label, one centred column. */
body .layout.nav-collapsed .sidebar .nav-item,
body .layout.nav-collapsed .sidebar .nav-grp,
body .layout.nav-collapsed .sidebar .nav-kid,
body .sidebar.collapsed .nav-item,body .sidebar.collapsed .nav-grp,
body .sidebar.collapsed .nav-kid,
body .sidebar.is-rail .nav-item,body .sidebar.is-rail .nav-grp{
  justify-content:center;padding-left:0!important;padding-right:0!important;
  margin-left:0!important;text-indent:0}
body .layout.nav-collapsed .sidebar .nav-kids,
body .layout.nav-collapsed .sidebar .nav-sub,
body .sidebar.collapsed .nav-kids,body .sidebar.collapsed .nav-sub{
  padding-left:0!important;margin-left:0!important}
body .layout.nav-collapsed .sidebar .nav-ico,
body .sidebar.collapsed .nav-ico{margin:0 auto}

/* ── 4. ROW ACTIONS: ONLY WHEN THE ROW IS IN PLAY ─────────────────────────
   The "..." button sat visible on every row of every table, taking a full
   column of width and adding a dot of noise to each line. Every other table
   reveals it on hover or keyboard focus; this makes them all agree. */
body .dtd-menu,body .dtd:last-child>.icon-btn,body .dtr .row-more9{
  opacity:0;transition:opacity .12s}
body .dtr:hover .dtd-menu,body .dtr:hover .dtd:last-child>.icon-btn,
body .dtr:focus-within .dtd-menu,body .dtr:focus-within .dtd:last-child>.icon-btn,
body .dtr.sel .dtd-menu,body .dtr .row-more9:focus-visible{opacity:1}
@media (hover:none){ /* touch has no hover, so it must always be reachable */
  body .dtd-menu,body .dtd:last-child>.icon-btn{opacity:1}
}
body .dtd-menu,body .dth:last-child{padding-left:0;padding-right:6px}

/* ── 5. NO FLICKER ON A QUIET REFRESH ─────────────────────────────────────
   A background refresh replaces the DOM and entrance animations replay on the
   new nodes - that is the flicker this suppresses.

   THE TRANSITION HALF OF THIS RULE WAS A MISTAKE AND IT DISABLED ANIMATION IN
   THE WHOLE APP. The two classes are not equivalent:
     .soft-refreshing  is added to the layout and removed 80ms later (app.js:3088)
                       - a real window during which nothing should move.
     .mv-noanim        is added ~1s after first paint and NEVER removed
                       (app.js:2679) - it is a permanent "past the intro" flag.
   Putting `transition:none!important` behind the permanent flag killed every
   transition in the app about a second after load. That is why the fleet map
   rail opened and closed with no animation, and it was not local to the map.

   An entrance ANIMATION replays on node replacement, so suppressing that under
   the permanent flag is correct. A TRANSITION only runs when a property actually
   changes - a user collapsing the rail, hovering a row - which is the thing we
   want to keep. So the permanent flag now suppresses animation only, and the
   80ms refresh window keeps suppressing both. */
body.mv-noanim *,body.mv-noanim *::before,body.mv-noanim *::after{
  animation:none!important}
body .soft-refreshing *,body .soft-refreshing *::before{
  animation:none!important;transition:none!important}

/* ── 3b. COLLAPSED RAIL: THE REAL CLASS ───────────────────────────────────
   Measured: the collapsed state is `.layout.side-collapsed` (not .nav-collapsed,
   which was a guess and matched nothing). With the right selector the remaining
   5px stagger is visible too: .nav-item icons centre at 32, .nav-grp at 27,
   because a group is a button carrying a trailing chevron that shifts its
   content. Centre both and drop the chevron while collapsed — there is no room
   to expand a group from a 64px rail anyway. */
body .layout.side-collapsed .sidebar .nav-item,
body .layout.side-collapsed .sidebar .nav-grp,
body .layout.side-collapsed .sidebar .nav-kid{
  display:flex;align-items:center;justify-content:center;
  padding:0!important;margin:0 0 2px!important;gap:0;width:100%;position:relative}
body .layout.side-collapsed .sidebar .nav-ico{
  flex:0 0 auto;margin:0;width:20px;height:20px}
/* labels, counts and the group chevron have nothing to sit next to at this width */
body .layout.side-collapsed .sidebar .nav-item>:not(.nav-ico),
body .layout.side-collapsed .sidebar .nav-grp>:not(.nav-ico),
body .layout.side-collapsed .sidebar .nav-kid>:not(.nav-ico){display:none!important}
body .layout.side-collapsed .sidebar .nav-sec,
body .layout.side-collapsed .sidebar .nav-kids,
body .layout.side-collapsed .sidebar .nav{
  padding-left:0!important;margin-left:0!important}
/* ── 3c. WHY THE RAIL ICONS STILL STAGGERED ───────────────────────────────
   justify-content:center was applying correctly all along. The rows were not
   the same WIDTH, so centring each one produced a different axis. Measured in
   the collapsed rail:
       .nav-grp  in .nav-sec   left 0  width 20  -> centre 10
       .nav-item in .nav       left 0  width 55  -> centre 28
       .nav-item in .nav-foot  left 8  width 47  -> centre 32
       .nav-help in .nav-foot  left 8  width 20  -> centre 18
   The containers are flex columns that let their children shrink to content, and
   .nav-foot adds 8px of its own padding. Centring is only meaningful once every
   row spans the same box, so stretch the children and drop the stray padding. */
body .layout.side-collapsed .sidebar .nav,
body .layout.side-collapsed .sidebar .nav-sec,
body .layout.side-collapsed .sidebar .nav-kids,
body .layout.side-collapsed .sidebar .nav-foot{
  display:flex;flex-direction:column;align-items:stretch;
  padding-left:0!important;padding-right:0!important;
  margin-left:0!important;margin-right:0!important}
body .layout.side-collapsed .sidebar .nav-item,
body .layout.side-collapsed .sidebar .nav-grp,
body .layout.side-collapsed .sidebar .nav-kid{
  width:100%!important;max-width:none!important;box-sizing:border-box;
  align-self:stretch}
/* ── 6. CHECKBOX BESIDE ITS LABEL ─────────────────────────────────────────
   Measured on the contact form: the label sits ~80px to the LEFT of its own
   checkbox (gapToLabel -78 and -90). The row is flex, but the label is allowed
   to grow and pushes the box to the far edge, so the two read as unrelated.
   A checkbox and its label are one object: box first, label immediately after,
   neither of them stretching. */
body .form-row:has(>input[type=checkbox]),
body .field-wrap:has(>input[type=checkbox]),
body .form-row.form-row-half:has(>input[type=checkbox]){
  display:flex!important;flex-direction:row-reverse;justify-content:flex-end;
  align-items:center;gap:9px;flex-wrap:nowrap}
body .form-row:has(>input[type=checkbox])>.field-label,
body .field-wrap:has(>input[type=checkbox])>.field-label{
  flex:0 1 auto;margin:0!important;font-weight:520;cursor:pointer}
body .form-row:has(>input[type=checkbox])>input[type=checkbox],
body .field-wrap:has(>input[type=checkbox])>input[type=checkbox]{
  flex:0 0 16px;width:16px;height:16px;margin:0!important;accent-color:var(--accent)}
/* the hint belongs under the pair, not squeezed between them */
body .form-row:has(>input[type=checkbox])>.field-hint,
body .field-wrap:has(>input[type=checkbox])>.field-hint{
  flex:1 0 100%;order:3;margin:5px 0 0}
/* ── 7. THE GLOBAL SEARCH WAS UNUSABLE — MY REGRESSION ────────────────────
   Measured: .tb-search is 91px wide holding 122px of chrome (scope button 61px +
   icon span 37px), which squeezed the input to FOUR PIXELS. You could not see it
   or type into it, which is "the universal bar doesn't even work". Pressing Enter
   did navigate, so the search logic was fine the whole time - it was the box.

   Two mistakes of mine:
     · .tb-search was left at flex 0 1 auto, so it never grew into the topbar.
     · I styled `>span:first-child` as the icon slot, but the real child order is
       button.tb-scope -> span(icon) -> input. first-child is the SCOPE button, so
       the rule never applied and the icon kept its natural 37px.
   The input now has a floor it cannot shrink past, and on a narrow topbar the
   scope refinement gives up its space rather than the search field. */
body .topbar .tb-search{flex:1 1 auto;min-width:0;max-width:620px}
body .tb-search>span{flex:0 0 34px;width:34px;height:34px;
  display:inline-flex;align-items:center;justify-content:center;opacity:.55}
body .tb-search>span svg{width:16px;height:16px;display:block}
body .tb-search>input{flex:1 1 auto;min-width:80px;width:auto}
body .tb-scope{flex:0 0 auto}
@media (max-width:760px){
  /* the scope filter is a refinement; the field itself is the feature */
  body .tb-scope{display:none}
  body .tb-search>input{min-width:60px}
}
/* ── 8. LIST TOOLBAR: ONE ROW, ONE HEIGHT, ONE SHAPE ─────────────────────
   Measured on the vehicle list: the search box is 36px tall with a 6px radius
   while the filter pills beside it are 32px with a 999px radius. Two heights and
   two shapes on a single row is what reads as "bad spacing" - the eye sees a
   row that does not line up rather than a set of related controls. */
body #content .list-search,
body #content .wv-fpill,
body #content .dt-tools>.btn,
body #content .list-toolbar .btn{
  height:34px;min-height:34px;border-radius:999px}
body #content .list-search{padding:0 12px}
body #content .list-search>input{height:32px}
body #content .wv-fpill{padding:0 12px;font-size:13px}
/* the row itself: one baseline, one gap, wraps instead of overflowing */
body #content .list-toolbar,body #content .wv-filters,body #content .dt-bar{
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;row-gap:8px}
body #content .list-toolbar>*,body #content .wv-filters>*{margin:0}
/* the count sits apart from the controls, not jammed against the last pill */
body #content .dt-pager-n,body #content .list-count9{margin-left:auto;padding-left:10px;
  font-size:12.5px;color:var(--muted);white-space:nowrap}

/* ── 9. TABLE DENSITY ─────────────────────────────────────────────────────
   Rows measured 49px. A data table is for scanning many records at once; the
   reference product runs nearer 40. Tighter rows without shrinking the type,
   so more of the fleet is visible without a scroll. */
/* MEASURED AGAINST THE REFERENCE, NOT ASSUMED: Fleetio's vehicle rows are 49px,
   which is what ours already were. An earlier version of this block tightened
   them to 44px on the belief that denser is better - it made us diverge from the
   thing we are matching, so it is gone. The height comes from cell padding, and
   the leading icon stays small inside it (theirs is 16px). */
body .dtable-body .dtr{min-height:48px}
body .dtd{padding-top:13px;padding-bottom:13px;display:flex;align-items:center}
body .dthr .dth{padding-top:10px;padding-bottom:10px}
body .dtable-body .dtr .dtd>*{min-width:0}
/* the compact density option still wins when the user picks it */
body .dt-dense .dtable-body .dtr{min-height:34px}
body .dt-dense .dtd{padding-top:6px;padding-bottom:6px}

/* the top-plan billing button must not read as a primary action */
body .btn-plan9{font-weight:560}
/* ── 9b. WHAT ACTUALLY SET THE ROW HEIGHT ─────────────────────────────────
   Not the padding. Measured per cell: actions 48px (a 32px "..." button + 8+8),
   label 44px (a 28px vehicle icon + padding), everything else 33px. A grid row is
   as tall as its tallest cell, so the two chrome elements were setting the density
   for the whole table. Capping them is what brings the row down - reducing text
   padding alone could never have worked. */
/* the row-action button: modest, and it must not set the row height */
body .dtd-menu,body .dtd[data-k="actions"]{padding-top:6px;padding-bottom:6px}
body .dtd-menu>*,body .dtd[data-k="actions"]>*{height:28px;min-height:0}
body .dtd-menu .icon-btn,body .dtd[data-k="actions"] .icon-btn{
  width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center}
/* the leading vehicle / record icon */
body .dtd[data-k="label"] img,body .dtd[data-k="label"] svg,
body .dtd .dt-avatar,body .dtd .veh-ic9{
  width:24px;height:24px;flex:0 0 24px;object-fit:cover}
body .dtd[data-k="label"]{gap:9px}
/* status chips must not inflate a row either */
body .dtd .badge{padding:2px 8px;line-height:1.45}
/* the icon WRAPPER is .dt-veh-ic at 28px; capping the inner svg left the span
   setting the height. 26px wrapper + 14px padding lands the row at 40. */
/* Their row icon is 16px; ours was 28px and crowded the name beside it. 20px
   keeps it legible at our stroke weight. !important because a more specific rule
   upstream was pinning 28px and out-classing it is not worth the selector. */
body .dt-veh-ic{width:20px!important;height:20px!important;flex:0 0 20px!important;
  display:inline-flex;align-items:center;justify-content:center;border-radius:6px}
body .dt-veh-ic svg,body .dt-veh-ic img{width:18px!important;height:18px!important}
body .dt-veh{display:flex;align-items:center;gap:9px;min-width:0}
body .dt-veh>span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}