/* ============================================================================
   Southport Signal — WAVE 6: THE WORK SURFACE (WAVE6.md §3)
   ----------------------------------------------------------------------------
   Lane 0's stylesheet. Every class is `w6`-prefixed and every colour, duration
   and easing comes from web/styles/tokens.css, so all three modes (default /
   dark / road) come out right without a single mode-specific rule in here.

   THE RULES THIS FILE KEEPS (CONVENTIONS §9, DESIGN.md, WAVE6.md §7):
     - NO SHADOWS on content panels. Hierarchy is hairlines plus surface tints.
       The ONE exception is the drawer, a floating layer (DESIGN §7 "glass, not
       plastic"), which opts in with the shared `.floating` utility.
     - 44px rows (var(--row-h)), 56px on touch (var(--row-h-touch)); road mode
       raises both through the tokens and nothing here has to know.
     - Tabular numerals everywhere a number can change under the reader's eye.
     - Motion only through --dur-1/2/3 and --ease. No ad-hoc transitions.
     - 820px is the one breakpoint: above it the surface is a split, below it a
       push (list, then detail full-screen with a Back control).

   WHY CONTAINER QUERIES. The list is `var(--list-w)` (42%) of the surface —
   roughly 495px at 1440 — and a 44px line cannot hold rank + band + name + sub
   + status + reason + chips + right at that width. So the row shows its core
   always and REVEALS the rest as the container gets wider. It is written as
   progressive enhancement: with no container-query support at all the row still
   renders correctly, just compact.

   APPENDING (page lanes). The clearly-marked sections at the bottom are yours.
   Append page-scoped rules under your own heading; never edit another lane's
   section and never edit anything above the divider.
   ========================================================================== */

/* ====================================================== the work surface == */

.w6ws {
  display: grid;
  grid-template-columns: var(--list-w) minmax(0, 1fr);
  gap: 14px;
  align-items: start;
  min-width: 0;
}

.w6list {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 6px;
  overflow: hidden;
  min-width: 0;
  container-type: inline-size;
  container-name: w6list;
}
.w6list > * + * { border-top: 1px solid var(--line); }
.w6list:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }

.w6detail {
  position: sticky;
  top: var(--detail-top);
  max-height: calc(100vh - 80px);
  overflow: auto;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 6px;
  min-width: 0;
  scrollbar-width: thin;
}
.w6detail > .w6dbody { padding: 14px 16px 16px; }

/* The push's Back control (WAVE6 §3: "class w6back"). Above 820px there is
   nothing to go back from.

   NAMESPACE WARNING — READ BEFORE ADDING A CLASS. wave4b.css (the wave-4 record
   lane) already claims `w6back`, `w6chip(s)`, `w6comp`, `w6crow` and `w6sub` in
   the same `w6` namespace, and it LOADS FIRST, so anything it declares that a
   plain `w6.css` rule does not re-declare leaks straight through: its
   `.w6chip{height:26px}` was inflating a 44px row to 53px and its
   `.w6sub{padding:11px 13px;margin-bottom:10px}` was adding 24px more. This
   file therefore uses `w6tag(s)`, `w6note`, `w6nrow` and `w6ctx` for those four,
   and keeps only `w6back` — which WAVE6.md names outright — SCOPED to the
   detail pane. Scoping matters twice over: `.w6back` is also the company
   record's own Back button, and an unscoped `display:none` here would have made
   it vanish from #/company on every desktop. */
.w6detail > .w6back {
  display: none;
  align-items: center;
  gap: 7px;
  width: 100%;
  max-width: none;          /* wave4b.css caps its own .w6back at 190px */
  flex: none;
  overflow: visible;
  min-height: var(--row-h-touch);
  padding: 0 14px;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: var(--surf2);
  color: var(--ink2);
  font-family: var(--raj); font-weight: 600; font-size: 14px;
  cursor: pointer;
  position: sticky; top: 0; z-index: 3;
}
.w6detail > .w6back svg { width: 16px; height: 16px; flex: none; }
.w6detail > .w6back:hover { color: var(--accent); }

/* ================================================================= rows == */
/* TWO SHAPES, ONE ROW. The list is `var(--list-w)` — 42%, about 500px at 1440 —
   and 500px cannot hold rank + band + name + town·trucks·age + status + reason
   + chips + last-touch on ONE line without cutting the company name to twelve
   characters, which breaks a rule that matters far more than the line count.
   So the row is a 44px GRID of two tight lines by default, and becomes a single
   flex line the moment its container is wide enough to carry one (a wider list,
   a full-width page list, a big monitor). Both shapes are exactly `--row-h`.

   It is a CONTAINER query, not a media query: the same row has to be right in a
   500px Today list and in a 1,100px Companies list on the same screen. */

.w6row {
  display: grid;
  /* The `auto` third track lets "Plant City · 22 trucks · 7.1 yr" size to its
     own text (capped by .w6ctx's max-width) and hands everything left over to
     the reason, which is the elastic one. */
  grid-template-columns: auto auto auto minmax(0, 1fr) auto;
  grid-template-areas:
    "rank band name name   right"
    "rank band ctx  reason reason";
  align-items: center;
  column-gap: 9px;
  row-gap: 1px;
  min-height: var(--row-h);
  padding: 3px 12px 3px 14px;
  background: var(--card);
  cursor: pointer;
  min-width: 0;
  position: relative;
  font-size: 13.5px;
  transition: background var(--dur-1) var(--ease);
}
.w6row::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: transparent;
  transition: background var(--dur-1) var(--ease);
}
.w6row:hover { background: var(--surf2); }
.w6row:focus-visible { outline: 2px solid var(--accent-2); outline-offset: -2px; }
.w6row.sel { background: var(--bluetint); }
.w6row.sel::before { background: var(--accent); }
.w6row.sel .w6nm { color: var(--accent); }
/* A pinned group member — a promise made, or an account just handed over.
   Marked by a tint, never by a colour that reads as an alarm. */
.w6row.w6pin { background: var(--sand); }
.w6row.w6pin:hover { background: var(--surf2); }
.w6row.w6pin.sel { background: var(--bluetint); }

.w6rank {
  grid-area: rank; flex: none; min-width: 16px;
  font-family: var(--raj); font-weight: 700; font-size: 12.5px;
  color: var(--faint); font-variant-numeric: tabular-nums; text-align: right;
}

/* The band is the row's ONE accent. A narrow row shows the dot only (the word
   rides on the wrapper's title); a wide one shows dot + word. */
.w6band {
  grid-area: band; flex: none;
  display: inline-flex; align-items: center; overflow: hidden; width: 9px;
}
.w6band .band { font-size: 11.5px; font-weight: 600; white-space: nowrap; }

.w6nm {
  grid-area: name;
  font-family: var(--raj); font-weight: 700; font-size: 15px; line-height: 20px;
  letter-spacing: -.01em; color: var(--ink);
  flex: 0 1 auto; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.w6row:hover .w6nm { color: var(--accent); }

.w6ctx {
  /* No `justify-self: start`: that sizes a grid item to its own max-content and
     lets it overflow its track, so the text ran UNDER the reason chip instead
     of ellipsising. Stretch (the default) makes the cell exactly the track and
     `text-overflow` then does its job. */
  grid-area: ctx;
  flex: 0 1 auto; min-width: 0; max-width: 210px;
  font-size: 12px; line-height: 17px; color: var(--mute); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}

.w6status { grid-area: name; justify-self: end; flex: none; }
.w6status .st { font-size: 11.5px; }

.w6reason {
  grid-area: reason;
  display: flex; align-items: center; gap: 7px;
  flex: 1 1 auto; min-width: 0;
  overflow: hidden;
}
.w6rlab {
  flex: 0 1 auto; min-width: 40px;
  font-size: 10.5px; line-height: 16px; font-weight: 600;
  color: var(--ink2); background: var(--surf2);
  border: 1px solid var(--line); border-radius: 4px;
  padding: 0 6px; white-space: nowrap;
  max-width: 170px; overflow: hidden; text-overflow: ellipsis;
}
.w6rtx {
  flex: 0 1 auto; min-width: 0;
  font-size: 12.5px; line-height: 17px; color: var(--ink2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.w6tags { grid-area: reason; justify-self: end; display: none; flex: none; gap: 5px; }
.w6tag {
  font-size: 10.5px; line-height: 16px; font-weight: 600;
  color: var(--mute); background: var(--surf2);
  border: 1px solid var(--line); border-radius: 999px;
  padding: 0 7px; white-space: nowrap;
}

.w6right {
  grid-area: right; flex: none;
  font-size: 11.5px; line-height: 17px; color: var(--faint);
  font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right;
}

/* ---- one line, once there is room for one -------------------------------
   Reveal, never hide: with no container-query support at all the two-line grid
   above stands on its own and every part of the row is still on screen. */

@container w6list (min-width: 700px) {
  .w6row {
    display: flex; align-items: center; gap: 10px;
    padding: 0 12px 0 14px;
  }
  .w6nm { flex: 0 1 auto; }
  .w6ctx { max-width: none; }
  .w6band { width: auto; gap: 6px; }
  .w6tags { display: inline-flex; }
  .w6right { margin-left: auto; }
}
@container w6list (max-width: 699.98px) {
  /* Two lines: the status word and the chips are the two things a 500px row can
     do without — the status is a colour a rep already reads off the band, and
     the chips repeat what the reason says. Both come back above 700px. */
  .w6status, .w6tags, .w6clus { display: none; }
}
@container w6list (max-width: 430px) {
  /* A phone-width list (366px inside a 390px screen) cannot carry the reason
     SENTENCE as well as the town/trucks/age line, so line two swaps its
     priorities: the reason's plain type label stays whole — it is the "why
     now", and the pane one tap away has the sentence — and the context line
     becomes the elastic one, losing its tail ("… · 6.7 yr") rather than the
     label losing its meaning. */
  .w6row { grid-template-columns: auto auto minmax(0, 1fr) auto auto; }
  .w6rtx { display: none; }
  .w6ctx { max-width: none; }
}

/* ---------------------------------------------------- in-list group head */

.w6ghead {
  display: flex; align-items: baseline; gap: 8px;
  padding: 9px 14px 6px;
  background: var(--surf2);
  font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
  font-weight: 700; color: var(--faint);
}
.w6gn { font-variant-numeric: tabular-nums; letter-spacing: .04em; }
.w6gn::before { content: "\00b7"; margin-right: 7px; color: var(--rule2); }

/* ---------------------------------------------- the row's action cluster */
/* WAVE6 §2.3: actions live in ONE place. On desktop the focused row borrows
   the pane's set for as long as it is focused; it is never a per-row toolbar. */

.w6clus {
  display: none; flex: none; align-items: center; gap: 4px;
  margin-left: 8px;
}
.w6cb {
  height: 26px; padding: 0 8px;
  border: 1px solid var(--rule2); border-radius: 5px;
  background: var(--card); color: var(--ink2);
  font-family: var(--raj); font-weight: 600; font-size: 12px; line-height: 1;
  cursor: pointer; white-space: nowrap;
  transition: color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}
.w6cb:hover { background: var(--bluetint); border-color: var(--accent); color: var(--accent); }
.w6cb:disabled { opacity: .5; cursor: default; }

@media (min-width: 821px) and (hover: hover) {
  /* Hover and focus ONLY — deliberately not `.sel`. At rest exactly one outcome
     button set is on the screen (the pane's), which is WAVE6 §5's acceptance
     check; the cluster appears under the pointer, or on the row a keyboard user
     has just moved to, and it is the same set moved, not a second one.

     It takes the right column's place rather than adding width, so a row never
     changes size when the cursor crosses it. */
  .w6row:hover .w6clus,
  .w6row:focus-within .w6clus { display: inline-flex; margin-left: auto; }
  .w6row:hover .w6right,
  .w6row:focus-within .w6right { display: none; }
}
/* Lane T review: the two rules above out-specify the container query that hides the
   cluster in a list narrower than 700px (a two-line row has nowhere to put it, and it
   would be a SECOND outcome set on screen). Re-hide it at that width, at the same
   specificity, so the pointer cannot bring it back. */
@container w6list (max-width: 699.98px) {
  .w6row:hover .w6clus,
  .w6row:focus-within .w6clus { display: none; }
  .w6row:hover .w6right,
  .w6row:focus-within .w6right { display: inline; }
}

/* =============================================================== strip === */

.w6strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: 6px;
  overflow: hidden;
  margin-bottom: 12px;
}
.w6si {
  display: block; text-align: left; position: relative;
  background: var(--card);
  padding: 10px 13px 11px;
  border: 0; margin: 0;
  font: inherit; color: inherit; text-decoration: none;
  min-height: var(--row-h);
  transition: background var(--dur-1) var(--ease);
}
a.w6si, button.w6si { cursor: pointer; }
a.w6si:hover, button.w6si:hover { background: var(--surf2); }
.w6si:focus-visible { outline: 2px solid var(--accent-2); outline-offset: -2px; }
.w6si.on { background: var(--bluetint); }
/* The active filter's underline is a real element, not an inset shadow — §9's
   ban on shadows is about the paint, and an inset box-shadow is still one. */
.w6si.on::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: 2px; background: var(--accent);
}
.w6sn {
  display: block;
  font-family: var(--raj); font-weight: 700; font-size: 23px; line-height: 1.05;
  color: var(--ink); font-variant-numeric: tabular-nums;
}
.w6sl { display: block; font-size: 11.5px; line-height: 1.35; color: var(--ink-muted); margin-top: 4px; }
.w6sh { display: block; font-size: 10.5px; line-height: 1.35; color: var(--faint); margin-top: 2px; }
.w6si.on .w6sn { color: var(--accent); }
.w6si.w6pos .w6sn { color: var(--positive); }
.w6si.w6warn .w6sn { color: var(--warning); }
.w6si.w6bad .w6sn { color: var(--danger); }
.w6si.w6acc .w6sn { color: var(--accent); }
.w6si.w6dim .w6sn { color: var(--faint); }

/* =============================================================== facts === */

.w6facts {
  display: grid;
  grid-template-columns: repeat(var(--w6cols, 4), minmax(0, 1fr));
  gap: 0;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 6px;
  overflow: hidden;
  margin: 10px 0 14px;
}
.w6fact { background: var(--card); padding: 8px 11px 9px; min-width: 0; box-shadow: 1px 0 0 var(--line), 0 1px 0 var(--line); }
.w6fk {
  display: block; font-size: 9.5px; letter-spacing: .09em; text-transform: uppercase;
  font-weight: 700; color: var(--faint);
}
.w6fv {
  display: block; margin-top: 3px;
  font-family: var(--raj); font-weight: 700; font-size: 15px; line-height: 1.2;
  color: var(--ink); font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
a.w6fv { color: var(--accent); text-decoration: none; }
a.w6fv:hover { text-decoration: underline; }
.w6fs { display: block; font-size: 10.5px; color: var(--mute); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ================================================================ tabs === */

.w6tabs { min-width: 0; }
.w6tablist {
  display: flex; gap: 2px; align-items: flex-end;
  border-bottom: 1px solid var(--line);
  overflow-x: auto; scrollbar-width: none;
}
.w6tablist::-webkit-scrollbar { display: none; }
.w6tab {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 34px; padding: 0 12px;
  border: 0; border-bottom: 2px solid transparent;
  background: transparent; cursor: pointer;
  font-family: var(--raj); font-weight: 600; font-size: 13.5px;
  color: var(--mute); white-space: nowrap;
  transition: color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
.w6tab:hover { color: var(--ink); }
.w6tab.on { color: var(--accent); border-bottom-color: var(--accent); }
.w6tab:focus-visible { outline: 2px solid var(--accent-2); outline-offset: -2px; }
.w6tc {
  font-size: 10.5px; font-weight: 700; font-variant-numeric: tabular-nums;
  background: var(--surf2); border: 1px solid var(--line); border-radius: 999px;
  padding: 0 6px; line-height: 15px; color: var(--ink2);
}
.w6tab.on .w6tc { background: var(--bluetint); border-color: var(--accent); color: var(--accent); }
.w6panel { padding-top: 12px; }

/* ============================================================== drawer === */
/* The ONLY shadow in this file. A floating layer, per DESIGN §7 — one soft
   ambient shadow and a backdrop blur, both from the tokens. */

.w6drawer { position: fixed; inset: 0; z-index: 70; }
.w6dbg {
  position: absolute; inset: 0;
  background: color-mix(in srgb, var(--ink) 34%, transparent);
  backdrop-filter: blur(3px);
  animation: sig-fade-in var(--dur-2) var(--ease) both;
}
.w6dbox {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: min(440px, 100%);
  display: flex; flex-direction: column;
  background: var(--card);
  border-left: 1px solid var(--line);
  animation: w6-slide-in var(--dur-2) var(--ease) both;
}
.w6drawer.closing .w6dbox { animation: w6-slide-out var(--dur-2) var(--ease) both; }
.w6drawer.closing .w6dbg { animation: sig-fade-out var(--dur-2) var(--ease) both; }
@keyframes w6-slide-in { from { transform: translateX(24px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes w6-slide-out { from { transform: none; opacity: 1; } to { transform: translateX(24px); opacity: 0; } }

.w6dhead {
  display: flex; align-items: center; gap: 10px;
  min-height: var(--row-h-touch); padding: 0 12px 0 16px;
  border-bottom: 1px solid var(--line); background: var(--surf2);
  flex: none;
}
.w6dhead b {
  flex: 1; min-width: 0;
  font-family: var(--raj); font-weight: 700; font-size: 15px; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.w6dclose {
  display: inline-flex; align-items: center; gap: 5px;
  min-height: 30px; padding: 0 9px;
  border: 1px solid var(--rule2); border-radius: 6px;
  background: var(--card); color: var(--ink2);
  font-family: var(--raj); font-weight: 600; font-size: 12.5px; cursor: pointer;
}
.w6dclose svg { width: 13px; height: 13px; }
.w6dclose:hover { border-color: var(--accent); color: var(--accent); }
.w6dbox > .w6dbody { flex: 1; min-height: 0; overflow: auto; padding: 14px 16px 18px; }

/* ========================================================== the brief ==== */

.w6d { min-width: 0; }

.w6dh { display: flex; align-items: flex-start; gap: 12px; flex-wrap: wrap; }
.w6dhl { flex: 1 1 220px; min-width: 0; }
.w6dname {
  display: block;
  font-family: var(--raj); font-weight: 700; font-size: 20px; line-height: 1.15;
  letter-spacing: -.015em; color: var(--ink);
}
.w6dmeta { display: block; font-size: 12.5px; color: var(--mute); margin-top: 2px; }
.w6dhr { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.w6dhr .st { font-size: 12px; }

/* "Why" — the band, its word, and the basis one tap away. A <details>, so it
   is keyboard-reachable and needs no script. */
.w6why { position: relative; }
.w6why > summary {
  display: inline-flex; align-items: center; gap: 6px;
  list-style: none; cursor: pointer;
  font-size: 12px; font-weight: 600; color: var(--ink2);
}
.w6why > summary::-webkit-details-marker { display: none; }
.w6wd { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.w6wq {
  font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--accent); border-bottom: 1px dotted var(--accent);
}
.w6wb {
  position: absolute; z-index: 5; top: calc(100% + 6px); left: 0;
  width: max(240px, 100%);
  background: var(--card); border: 1px solid var(--line); border-radius: 6px;
  padding: 8px 10px;
  animation: sig-fade-in var(--dur-1) var(--ease) both;
}
.w6wr { display: flex; justify-content: space-between; gap: 12px; padding: 3px 0; font-size: 11.5px; }
.w6wr span { color: var(--mute); flex: none; }
.w6wr b { color: var(--ink2); font-weight: 600; text-align: right; min-width: 0; }

.w6av { width: 24px; height: 24px; border-radius: 50%; display: inline-grid; place-items: center;
  color: #fff; font-family: var(--raj); font-weight: 700; font-size: 10px; flex: none; }
.w6dopen, .w6ddir {
  font-family: var(--raj); font-weight: 700; font-size: 12.5px;
  color: var(--accent); text-decoration: none; white-space: nowrap;
}
.w6dopen:hover, .w6ddir:hover { text-decoration: underline; }

/* ------------------------------------------------------------ the phone */
/* §9, and it wins every conflict: the phone is the biggest thing on the pane. */

.w6phone {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  margin: 12px 0 10px;
}
.w6person { font-size: 12.5px; color: var(--mute); flex: none; }
.w6tel {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--raj); font-weight: 700; font-size: 31px; line-height: 1.05;
  letter-spacing: -.02em; color: var(--navy); text-decoration: none;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
html[data-theme="dark"] .w6tel { color: var(--ink); }
.w6tel:hover { color: var(--accent); }
.w6tel svg { width: 19px; height: 19px; color: var(--positive); flex: none; }
.w6nophone { font-family: var(--raj); font-weight: 600; font-size: 17px; color: var(--faint); }
.w6sms {
  display: inline-flex; align-items: center; gap: 5px;
  min-height: 34px; padding: 0 10px;
  border: 1px solid var(--rule2); border-radius: 6px;
  color: var(--ink2); text-decoration: none;
  font-family: var(--raj); font-weight: 600; font-size: 13px;
}
.w6sms svg { width: 14px; height: 14px; }

/* ------------------------------------------- the outcome bar, once, here */
/* kit.outcomeBar's markup, restyled for the pane. wave4a.css scopes its own
   rules to `.k4card`/`.k4today`, so nothing collides. */

.w6d .k4acts { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 0 0 14px; }
.w6d .k4b {
  min-height: 34px; padding: 0 12px;
  border: 1px solid var(--rule2); border-radius: 6px;
  background: var(--card); color: var(--ink2);
  font-family: var(--raj); font-weight: 600; font-size: 13.5px; line-height: 1;
  cursor: pointer; white-space: nowrap;
  transition: color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}
.w6d .k4b:hover { background: var(--bluetint); border-color: var(--accent); color: var(--accent); }
.w6d .k4b:disabled { opacity: .5; cursor: default; }

/* -------------------------------------------------------- section spine */

.w6sec {
  display: flex; align-items: baseline; gap: 8px;
  font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase;
  font-weight: 700; color: var(--faint);
  padding-top: 4px; margin-bottom: 6px;
}
.w6park {
  text-transform: none; letter-spacing: 0; font-size: 11px; font-weight: 600;
  color: var(--warning);
}

/* ------------------------------------------------------------- reasons */

.w6reasons { display: grid; gap: 6px; margin-bottom: 12px; }
.w6r {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  min-width: 0;
}
.w6r .w6rlab { max-width: none; }
.w6r .w6rtx { white-space: normal; font-size: 13px; line-height: 1.45; }
.w6rq { font-size: 12.5px; font-style: italic; color: var(--mute); line-height: 1.45; }
.w6more {
  display: inline-block; margin-top: 2px;
  font-size: 12.5px; color: var(--accent); text-decoration: none;
}
.w6more:hover { text-decoration: underline; }
.w6none { font-size: 12.5px; color: var(--mute); margin-bottom: 12px; }

/* ------------------------------------------------------------ timeline */

.w6tl { border: 1px solid var(--line); border-radius: 6px; overflow: hidden; margin-bottom: 8px; }
.w6tl > * + * { border-top: 1px solid var(--line); }
.w6tli {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas: "kind body" "kind meta";
  gap: 2px 9px;
  padding: 8px 11px;
  background: var(--card);
}
.w6kind {
  grid-area: kind; align-self: start;
  font-size: 9.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink2); background: var(--surf2);
  border: 1px solid var(--line); border-radius: 4px;
  padding: 1px 6px; white-space: nowrap;
}
.w6kind.call { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, var(--line)); }
.w6kind.visit { color: var(--positive); border-color: color-mix(in srgb, var(--positive) 40%, var(--line)); }
.w6kind.email { color: var(--violet); border-color: color-mix(in srgb, var(--violet) 40%, var(--line)); }
.w6tlb {
  grid-area: body; min-width: 0;
  font-size: 12.5px; line-height: 1.45; color: var(--ink2);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  line-clamp: 2; overflow: hidden;
}
.w6tlm { grid-area: meta; font-size: 11px; color: var(--faint); }

/* ------------------------------------------------------------ composer */
/* One line until it is wanted. DESIGN "invisible where it can be": a 200px
   composer sitting above the first note is what made the record 2,611px. */

.w6note {
  margin-top: 12px; padding-top: 12px;
  border-top: 1px solid var(--line);
}
.w6nrow { display: flex; align-items: flex-start; gap: 8px; }
.w6cin {
  flex: 1; min-width: 0;
  min-height: 34px; padding: 7px 10px;
  border: 1px solid var(--rule2); border-radius: 6px;
  background: var(--card); color: var(--ink);
  font: inherit; font-size: 13px; line-height: 1.4;
  resize: none; overflow: hidden;
  transition: border-color var(--dur-1) var(--ease);
}
.w6cin:focus { outline: none; border-color: var(--accent); }
.w6cin::placeholder { color: var(--faint); }
.w6cs {
  flex: none; min-height: 34px; padding: 0 14px;
  border: 1px solid var(--accent); border-radius: 6px;
  background: var(--accent); color: #fff;
  font-family: var(--raj); font-weight: 700; font-size: 13.5px; cursor: pointer;
}
.w6cs:hover { opacity: .92; }
.w6cs:disabled { opacity: .55; cursor: default; }
.w6cx {
  display: none; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 8px;
  animation: sig-fade-in var(--dur-1) var(--ease) both;
}
.w6note.w6open .w6cx { display: flex; }
.w6ckinds { display: inline-flex; gap: 4px; }
.w6ck {
  min-height: 28px; padding: 0 10px;
  border: 1px solid var(--rule2); border-radius: 999px;
  background: var(--card); color: var(--ink2);
  font-size: 12px; font-weight: 600; cursor: pointer;
}
.w6ck.on { background: var(--bluetint); border-color: var(--accent); color: var(--accent); }
.w6ctalk {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 28px; padding: 0 10px;
  border: 1px solid var(--rule2); border-radius: 6px;
  background: var(--card); color: var(--ink2);
  font-size: 12px; font-weight: 600; cursor: pointer;
}
.w6ctalk svg { width: 13px; height: 13px; }
.w6ctalk.on { background: var(--bluetint); border-color: var(--accent); color: var(--accent); }
.w6cmsg { font-size: 11.5px; color: var(--mute); }

/* --------------------------------------------------------- empty / error */

.w6err {
  display: grid; gap: 4px; padding: 22px 4px;
  text-align: center;
}
.w6err b { font-family: var(--raj); font-weight: 700; font-size: 15px; color: var(--ink); }
.w6err span { font-size: 12.5px; color: var(--mute); }

/* ============================================================== mobile === */
/* WAVE6 §2.8: under 820px the split becomes a push — the list, then the detail
   as a full screen with a Back control, the phone above the fold, and the
   outcome bar pinned above the tab bar.

   The bar is `position: sticky`, deliberately NOT `fixed`: #wrap carries the
   `.viewswap` cross-fade, and a transformed ancestor makes `fixed` position
   against that ancestor rather than the viewport (INTEGRATION_NOTES' transform
   trap). Sticky has no such rule, and needs no z-index war with the tab bar. */

@media (max-width: 820px) {
  .w6ws { grid-template-columns: 1fr; gap: 0; }
  .w6detail { display: none; }
  .w6ws.showdetail .w6list { display: none; }
  .w6ws.showdetail .w6detail {
    display: block;
    position: static; max-height: none; overflow: visible;
    border-radius: 6px;
  }
  .w6detail > .w6back { display: flex; }

  /* The two-line grid is already the base shape; a phone only needs the touch
     height and the certainty that no container width can flip it to one line. */
  .w6row {
    display: grid;
    min-height: var(--row-h-touch);
    padding: 8px 12px 8px 14px;
    row-gap: 2px;
  }
  .w6rank { font-size: 13px; }
  .w6nm { font-size: 15.5px; }
  .w6band { width: 9px; gap: 0; }
  .w6right { margin-left: 0; }
  .w6status, .w6tags, .w6clus { display: none; }

  .w6detail > .w6dbody { padding: 14px 14px 18px; }
  .w6tel { font-size: 34px; }
  .w6d .k4acts {
    position: sticky;
    bottom: calc(56px + env(safe-area-inset-bottom));
    z-index: 4;
    background: var(--card);
    border-top: 1px solid var(--line);
    margin: 0 -14px 14px;
    padding: 8px 14px;
  }
  .w6d .k4b { flex: 1 1 40%; min-height: 44px; }
  .w6facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .w6strip { grid-template-columns: repeat(auto-fit, minmax(112px, 1fr)); }
  .w6sn { font-size: 20px; }
}

/* ===================================================== reduced motion ==== */
/* tokens.css already collapses the durations; these are the two animations
   with travel in them, which read as movement even at 1ms. */

@media (prefers-reduced-motion: reduce) {
  .w6dbox, .w6drawer.closing .w6dbox { animation: none; }
  .w6wb, .w6cx { animation: none; }
}

/* ======================================================== #/styleguide === */
/* Lane 0's own page (DESIGN §10). Chrome for the specimen cases only — nothing
   here is used by the product, and no page lane should reach for it. */

.w6sgpage { max-width: 1180px; }
.w6sgbar {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 10px 12px; margin-bottom: 18px;
  background: var(--surf2); border: 1px solid var(--line); border-radius: 6px;
}
/* The rail's switcher, restated for a light surface — the same treatment
   tokens.css already gives it inside the mobile More sheet. */
.w6sgbar .themesw { margin-top: 0; background: var(--card); border: 1px solid var(--line); }
.w6sgbar .themesw button { color: var(--ink-muted); }
.w6sgbar .themesw button:hover { background: var(--surface-3); color: var(--ink); }
.w6sgbar .themesw button.on { background: var(--accent); color: #fff; }
.w6sgnote { flex: 1 1 240px; font-size: 11.5px; color: var(--mute); line-height: 1.4; }

.w6sgsec { margin-bottom: 26px; }
.w6sgbody { display: grid; gap: 16px; }
.w6sgcase { min-width: 0; }
.w6sglb {
  font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  font-weight: 700; color: var(--faint); margin-bottom: 6px;
}
.w6sginline { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 6px 0; }
/* The cluster only shows itself on a focused row, so the specimen forces it. */
.w6sginline .w6clus { display: inline-flex; }
.w6sgpane {
  background: var(--card); border: 1px solid var(--line); border-radius: 6px;
  padding: 14px 16px 16px; max-width: 640px;
}
.w6sgfill { font-size: 12.5px; color: var(--ink2); padding: 4px 0 10px; }
.w6sgnone {
  font-size: 12.5px; color: var(--mute); font-style: italic;
  border: 1px dashed var(--rule2); border-radius: 6px; padding: 12px 14px;
}

/* ==========================================================================
   PAGE-LANE SECTIONS — APPEND ONLY
   --------------------------------------------------------------------------
   Everything above this divider is Lane 0's and is frozen for wave 6. Below
   it, each page lane owns exactly one section: append your page-scoped rules
   under your own heading, keep the `w6` prefix (or your page's own `w4*`/`w5*`
   prefix where you already own one), and never edit another lane's section.
   ========================================================================== */

/* ---- Lane T: today/reasons ---- */

/* Today (rep + manager) and Reasons, on the work surface. Everything here is
   page-scoped: either a `w6t*` class this lane owns outright, or a rule that
   re-states a Lane 0 declaration for a list this lane marks with a class of its
   own. Nothing above the divider is edited.

   The wave-5 pieces these pages keep — the outcome sheet, the undo bar, the
   dialer prompt, the "Show 10 more" footer — are still styled by
   web/styles/wave4a.css, which is this lane's own stylesheet. What lands HERE is
   only what touches a shared w6 component. */

/* ------------------------------------------- the surface, on these pages */
/* `.w6tw` is the wrapper this lane puts round its work surface (today.js,
   reasons.js, manager.js all render `<div id="surface" class="w6tw">`), so every
   rule below is page-scoped without editing anything above the divider. */

/* EVERY DESKTOP-ONLY RULE LIVES IN THIS BLOCK, and the guard is the point.
   w6.css puts the phone layout in `@media (max-width: 820px)`, and a media query
   adds NO specificity — so an unguarded `.w6tw .w6detail {…}` (0,2,0) silently
   beats `.w6ws { grid-template-columns: 1fr }` (0,1,0) on a phone. That is the
   same trap that put the outcome sheet back over the tab bar; here it squeezed
   the manager's pushed detail pane into a 205px column. */
@media (min-width: 821px) {
  /* THE PANE'S HEIGHT DRIVES TODAY'S PAGE HEIGHT. Lane 0's
     `max-height: calc(100vh - 80px)` assumes the pane starts at `--detail-top`
     (64px); on these pages a summary strip sits above it, so it starts ~167px
     down and ran 87px past the fold — measured 1,067px against WAVE6 §5's
     1,000px budget for today-rep. Capping it costs nothing: the pane already
     scrolls, and the phone, the outcome bar and the reasons are all in its
     first 300px. */
  .w6tw .w6detail { max-height: calc(100vh - 175px); }

  /* 44px, exactly. The row's two tight lines add up to 45 before the hairline,
     so twenty-five of them on Reasons carried 25px of rounding into a 1,400px
     budget. The floor is still `--row-h`; only the overshoot is gone. A phone
     keeps Lane 0's touch spacing untouched. */
  .w6tw .w6list .w6row { padding-top: 2px; padding-bottom: 2px; row-gap: 0; }
}

/* THE LABEL WINS, THE SENTENCE GIVES WAY. Both were shrinking, so a 492px list
   showed "Truck o…" beside "A truck was put out of servic…" — two ellipses on
   one line, and the half that was cut was the half that names the reason. The
   type label is the "why now"; the sentence is the detail, and the pane one tap
   away has all of it. */
.w6tw .w6rlab { flex: 0 0 auto; max-width: 60%; }
@container w6list (max-width: 430px) {
  /* On a phone the row's second line is ONLY the label — w6.css drops the
     sentence at this width on purpose, "the reason's plain type label stays
     whole … it is the why now". A 60% cap against a content-sized box turned
     that into "Pro…" and "Fla…", which is the row's entire reason to exist. The
     town/trucks/age line is the elastic one here, exactly as Lane 0 intended. */
  .w6tw .w6rlab { max-width: none; }
}

/* ---- the action cluster, and the "one outcome set" rule ------------------
   w6.css hides `.w6clus` inside a list narrower than 700px — a 44px two-line row
   has nowhere to put four buttons — but the hover rule underneath it is more
   specific, so the cluster came back under the pointer, wrapped the row onto a
   third line and hid the last-touch column. It also put a SECOND company's
   outcome set on the screen whenever the pointer happened to rest on a row that
   was not the selected one, which is exactly what WAVE6 §5 forbids.

   So: no cluster where the row has no room for it, and above that width only on
   the row the pane is already showing — which is what makes it "the same set,
   moved" rather than a second one. Reported to Lane 0 as a kit patch; scoped
   here so these three pages are right either way. */
@container w6list (max-width: 699.98px) {
  .w6tw .w6row:hover .w6clus,
  .w6tw .w6row:focus-within .w6clus { display: none; }
  .w6tw .w6row:hover .w6right,
  .w6tw .w6row:focus-within .w6right { display: block; }
}
@container w6list (min-width: 700px) {
  .w6tw .w6row:not(.sel):hover .w6clus,
  .w6tw .w6row:not(.sel):focus-within .w6clus { display: none; }
  .w6tw .w6row:not(.sel):hover .w6right,
  .w6tw .w6row:not(.sel):focus-within .w6right { display: block; }
}

/* ---- the facts grid's empty tail --------------------------------------
   Lane 0 draws the grid's hairlines by letting a `--line` background show
   through 1px gaps, which also paints the unused half of a part-filled last row
   as a grey block — and "only the facts that exist" (§3.1.5) makes a part-filled
   row the normal case. Each cell paints its own line into the gap instead; the
   container's overflow:hidden clips the outer edge back to one hairline. Lane R
   found the same thing on the record and fixed it the same way. */
.w6tw .w6facts { background: var(--card); }
.w6tw .w6fact { box-shadow: 1px 0 0 var(--line), 0 1px 0 var(--line); }

/* ---- what sits under the list ----------------------------------------
   The end line, "Show 10 more" and the pager belong to the LIST, not to the
   whole page: centred under 1,180px they float in the middle of the detail
   pane's white space with nothing to do with it. */
.w6tw + .k5foot { justify-content: flex-start; margin-top: 8px; }
.w6tw + .k5foot .k5wait { flex: 0 1 auto; }
.w6tw + .k4pager { margin-top: 8px; }
@media (min-width: 821px) {
  .w6tw + .k4pager,
  .w6tw + .k4pager + .k4end { width: var(--list-w); }
}

/* ---- the mobile push is a FULL screen (§2.8) ---------------------------
   Under 820px the split becomes list -> detail, and "detail" means the phone
   number first. The strip, the brief and the tab strip are the LIST's furniture
   and they are siblings of the surface, so `.showdetail` cannot reach them from
   inside — `:has()` can, and it is scoped to this lane's own `.w6tw` wrapper so
   no other page can feel it. Measured on a 390x844 phone: the manager's phone
   sat 936px down the pushed pane with the brief still above it; with this it is
   in the first screen, which is the rule §2.8 exists to keep.

   A browser without `:has()` simply keeps the furniture and scrolls — the same
   page, one scroll longer. */
@media (max-width: 820px) {
  #wrap:has(> .w6tw > .w6ws.showdetail) > :is(.w6strip, .k4brief, .w6thd, .w6tbar, .k5foot, .k4pager, .k4end) {
    display: none;
  }
}

/* ---------------------------------------------- the pane's pinned banner */
/* A promise the rep made, or the sentence a manager wrote when he handed the
   account over, across the top of the brief. It is NOT an outcome set: "Done"
   and "Got it" move no counter (§14.1.1) and a second `data-outcome-for` here
   would break WAVE6 §5's "one outcome set at a time". */

.w6tban {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 9px 11px; margin: 0 0 12px;
  background: var(--sand); border: 1px solid var(--line); border-radius: 6px;
}
.w6tban.late { border-color: color-mix(in srgb, var(--warning) 45%, var(--line)); }
.w6tban.w6new { background: var(--bluetint); }
.w6tbi { display: inline-flex; flex: none; margin-top: 1px; }
.w6tbi svg { width: 15px; height: 15px; color: var(--warning); }
.w6tban.w6new .w6tbi svg { color: var(--accent); }
.w6tbt { flex: 1 1 auto; min-width: 0; }
.w6tbt b {
  display: block;
  font-family: var(--raj); font-weight: 700; font-size: 13.5px; line-height: 1.3;
  color: var(--ink);
}
.w6tbt small { display: block; font-size: 12px; line-height: 1.45; color: var(--ink2); margin-top: 1px; }
.w6tbb { flex: none; align-self: center; }

/* ------------------------------------------------ the sheet, in the pane */
/* WAVE6 §2.3: actions live in ONE place, so the dictated outcome sheet opens
   where the outcome buttons are — inside the detail pane, under the bar. It is
   appended to `.w6detail` (a sibling of `.w6dbody`, which is replaced wholesale
   on every selection) and sticks to the bottom of the pane's own scroll box, so
   a long brief scrolls behind it instead of pushing Save off the screen.

   Under 820px wave4a.css's `position: fixed; bottom: calc(56px + safe-area)`
   takes over untouched — the transform trap (INTEGRATION_NOTES) is cleared
   geometrically there, never with z-index, and Save stays reachable. */

/* DESKTOP ONLY, and the media query is the whole point. wave4a.css pins the
   sheet with `position: fixed; bottom: calc(56px + env(safe-area-inset-bottom))`
   under 820px — the fix for the Lane B review's blocker, where a rep aiming at
   Save hit the tab bar's Search underneath it. A sticky rule declared without a
   width guard is MORE SPECIFIC than that one (`.w6detail > .k5sheet` beats
   `.k5sheet`; a media query adds no specificity), so it silently put the sheet
   back over the tab bar. Measured before the guard: Save's bottom at 828px with
   the tab bar starting at 787. */
@media (min-width: 821px) {
  .w6detail > .k5sheet {
    position: sticky; bottom: 0; z-index: 4;
    border-top: 1px solid var(--line);
    border-radius: 0 0 6px 6px;
  }
}

/* ------------------------------------------- was this reason worth reading */
/* W5-T2-12's two taps, moved off the card and onto the top reason in the brief.
   Quiet at rest, plain on hover — wave4a.css keeps them invisible until a CARD
   is hovered, and there are no cards any more. */

.w6d .k5fb { margin-left: 6px; }
.w6d .k5fb .k5fbb { opacity: .55; }
.w6d .w6r:hover .k5fb .k5fbb, .w6d .k5fb.done .k5fbb { opacity: 1; }

/* ================================================== manager Today (§4.2) == */

/* The tab strip carries the choice; the panels are empty by design, because the
   ONE list under them is the work surface's, not a panel's. */
.w6thd { margin-bottom: 10px; position: relative; }
.w6thd .w6panel { display: none; }
/* "See all 97" rides the tab strip's right edge — the hand-out list is trimmed
   to fit the page budget and the door to the rest must be visible, not implied. */
.w6thd > .k4see { position: absolute; right: 2px; top: 9px; }

/* A WIDER LIST THAN THE REP'S. A hand-out row carries a "Hand to" select as
   well as a reason, and at Lane 0's 42% the select left ~150px for the why —
   "Truck..." beside "A t...". 56% gives the reason its sentence back and still
   leaves the brief 500px, which is more than the phone, the outcome bar and the
   facts grid need. Still under the 700px container step, so the rows keep their
   two-line shape. */
@media (min-width: 821px) { .w6tmgr .w6ws { grid-template-columns: 56% minmax(0, 1fr); } }

/* The brief itself is `.k4brief`, not a w6 component: its compaction lives in
   web/styles/wave4a.css with the rest of this lane's own rules. */

/* ---- the hand-out row -------------------------------------------------
   The "Hand to" select is the row's right-hand column. Lane 0 hides `.w6right`
   while a row is hovered so the action cluster can take its place — right for a
   list of outcomes, wrong for a list whose only control lives there, so the
   hand-out list marks itself and puts it back. Higher specificity, no
   `!important`, and no edit above the divider. */

.w6list.w6thand .w6row:hover .w6right,
.w6list.w6thand .w6row:focus-within .w6right { display: block; }
.w6list.w6thand .w6row {
  grid-template-areas:
    "rank band name name  right"
    "rank band ctx  reason right";
}
.w6list.w6thand .w6right {
  grid-row: span 2; align-self: center; margin-left: 8px;
}
.w6list.w6thand .k4sel {
  height: 30px; max-width: 148px; font-size: 12.5px;
}
.w6list.w6thand .w6rlab { max-width: none; }
/* Chosen: the rep's face where the picker was, for a beat before the row goes
   (DESIGN §9 — "the hand-out select shows the rep's avatar on choose"). */
.w6tgave {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--raj); font-weight: 700; font-size: 12.5px; color: var(--accent);
  animation: sig-fade-in var(--dur-1) var(--ease) both;
}
.w6tgave .w6av { width: 20px; height: 20px; font-size: 9px; }

/* ---- the person behind a Team row ------------------------------------- */

.w6person .w6dhr { gap: 8px; }
.w6spark { padding: 2px 0 4px; }
.w6spark .ch { width: 100%; max-width: 260px; height: 34px; display: block; }
.w6spark .sparkempty { font-size: 12.5px; color: var(--mute); }
/* A person is not a company: no band dot, no status word, and the reason slot
   carries their numbers, so it must not be clipped to a chip's width. */
.w6list.w6tteam .w6rlab { max-width: none; }

/* ===================================================== Reasons (§4.3) ==== */

/* The strip replaced the "About" chip row; what is left under it is the state
   toggle, the range and the export — one quiet line, not a filter bar. */
.w6tbar {
  margin: 0 0 7px; padding: 0 2px; min-height: 30px;
  border: 0; background: none;
}

/* ---- Lane R: record ---- */

/* The record (web/src/views/company.js, WAVE6 §4.7) uses three shared pieces:
   `factsGrid`, `tabs` and the outcome bar. Everything else it needs lives in
   `wave4b.css`, which is the record's own stylesheet. These are the only rules
   that adjust a shared w6 component, and each is scoped to `.w6rec` so no
   other page can feel them. */

/* Tabs park under the vitals header, which is sticky at 54px and writes its own
   height into --w4sumh. A 313-note timeline is a long scroll; the tab strip
   staying put is what keeps "the timeline is one click away" true at the bottom
   of it as well as the top. It is the only sticky layer inside the body — the
   timeline's dates moved into a left gutter, so nothing else competes for the
   top of the viewport. */
.w6rec .w6tablist{
  position: sticky; top: calc(54px + var(--w4sumh, 64px)); z-index: 12;
  background: var(--page);
}
.w6rec .w6panel{ padding-top: 14px; }
/* .w6panel gets display:block from the rule above; an author declaration always
   beats the UA's [hidden] { display:none }, so say it explicitly. */
.w6rec .w6panel[hidden]{ display: none; }
.w6rec .w6facts{ margin: 10px 0 12px; background: var(--card); }
/* Lane 0 draws the hairlines by letting a --line background show through the
   1px gaps. That also paints the EMPTY tail of a part-filled last row as a grey
   block — and the record's fact count is whatever this company actually has, so
   a part-filled row is the normal case. Each cell paints its own line into the
   gap instead; the container's overflow:hidden clips the edges, so the outer
   border is still a single hairline. */
.w6rec .w6fact{ box-shadow: 1px 0 0 var(--line), 0 1px 0 var(--line); }
/* A class-mix bar in a facts cell: the value slot is nowrap+ellipsis text, and
   this is a chart. */
.w6rec .w6fv .w6mix{ display: block; width: 100%; height: 9px; margin-top: 2px; border-radius: 2px; }

@media (max-width: 820px){
  /* The header is static on a phone, so the tab strip rides the app bar instead. */
  .w6rec .w6tablist{ top: 50px; }
  .w6rec .w6tab{ min-height: 40px; }
}


/* ---- Lane P: lists ---- */
/* pipeline.js / companies.js / feed.js (WAVE6.md §4.4–§4.6). Most of what
 * these three pages needed is either already-frozen kit6 markup used as-is
 * (`summaryStrip`, `listRow`, `drawer`, `detailPane`) or brand-new page-owned
 * shapes that live with the rest of each page's CSS in wave4b.css (its
 * PIPELINE / ALL ACCOUNTS / NOTES sections) — exactly where Lane R's own
 * COMPANY RECORD section keeps its page-invented markup. What belongs HERE,
 * next to Lane R's own example of the same thing just above, is the one place
 * a page adjusts an ACTUAL shared kit6 component for a need Lane 0's default
 * did not anticipate, scoped so no other page can feel it. */

/* Companies (§4.5) is `.w6row`s in a plain `.w6list` — not the split
 * `workSurface()` shape `.w6ws`/`.w6detail` bounds for free, since a fixed 42%
 * detail rail is the wrong trade at this page's width (§4.5 says so). At 50
 * rows a page (§4.5) that is roughly 2,200px of rows alone, comfortably over
 * the page's own 1,600px budget (§5) on its own — `#colist` is the one
 * adjustment this page makes to `.w6list` to fix that: bounded height, its
 * own scrollbar, same idea as Pipeline's board and `.w6detail` itself. Scoped
 * by id (companies.js's own, already unique) rather than a new wrapper class. */
#colist{
  max-height: calc(100vh - 300px);
  min-height: 360px;
  overflow-y: auto;
  scrollbar-width: thin;
}
@media (max-width: 820px){
  /* A nested scrollbar fights the page scroll on a phone, and the budget this
   * bound exists for is only asserted at 1440×900 (WAVE6.md §5) — so under
   * 820px the list goes back to flowing with the rest of the page. */
  #colist{ max-height: none; min-height: 0; overflow-y: visible; }
}

/* The drawer's `detailPane` facts grid (Pipeline §4.4 and Companies §4.5 both
 * open it): with 7 or 8 facts the last row is often part-filled, and Lane 0's
 * own hairlines — a `--line` background showing through the grid's 1px gaps —
 * paint the unused half of that row as a grey block (documented at `.w6facts`
 * in w6.css, and already fixed the same way for `.w6rec`/`.w6tw` above). Same
 * fix, scoped to the drawer rather than to a page class, since Pipeline and
 * Companies share the one drawer instead of each owning their own pane. */
.w6drawer .w6facts{ background: var(--card); }
.w6drawer .w6fact{ box-shadow: 1px 0 0 var(--line), 0 1px 0 var(--line); }

/* ---- Lane M: reports ---- */
/* Lane M's actual reports.js/w5f.css rework lives in web/styles/w5f.css (its
 * own scoped stylesheet, per WAVE6.md's file list for this lane). What lands
 * here is the density pass on Data / People / Rules (§4.9) — `.pplrow` and
 * `.w5frow` had no CSS of their own before this wave (both pages are built
 * entirely from inline `style="…"`, same tokens either way); pulling their
 * row density out to real selectors here is what "goes in w6.css" means for
 * two pages with no page-scoped stylesheet of their own. Team keeps its
 * layout untouched (WAVE6 §4.9) — its `.treprow` density is wave-4's, not
 * mine to touch — and gets only the `kit6.summaryStrip` swap in team.js
 * itself, styled entirely by Lane 0's `.w6strip` rules above this divider.
 * Rules' one density addition (`.rp-tight`, the reasons-open table) stays in
 * that page's own embedded <style> — it was already a self-contained,
 * page-scoped stylesheet before this wave, so a two-line addition there does
 * not need a second home here. */

/* #/people — one row per person; a 44px-plus dense row (WAVE6 §2.7) instead
 * of the old 16px-top-and-bottom padding. Two selects + an email input mean
 * this can never be AS short as a plain data row — 44px is a floor here, not
 * an exact height — but it is now close, and every row still fits its
 * controls without a structural change to what the row contains. */
.pplrow {
  display: flex; flex-wrap: wrap; align-items: flex-end;
  gap: 10px 14px; padding: 10px 4px; min-height: 44px;
  border-top: 1px solid var(--line);
}

/* #/data — the four-source freshness list ("Refresh the exports"). Was a
 * ~31px row (9px padding, no floor); now a real 44px row, one line, right
 * side already tabular-nums. */
.w5frow {
  display: flex; align-items: center; justify-content: space-between;
  min-height: 44px; padding: 0; border-top: 1px solid var(--line);
  font-size: 13px;
}


/* ==================================================================== */
/* ---- Review ---- (adversarial UX review, 2026-09-02)                 */
/* Appended by the wave-6 review lane. Every rule here fixes something a  */
/* screenshot showed; each carries the finding it closes.                */
/* ==================================================================== */

/* R1 — the facts grid's empty tail.
   `factsGrid` drops the pairs a company has no value for (WAVE6 §3.1.5), which
   is right, but the grid is a bordered panel: a part-filled last row was drawn
   as a fenced-off empty rectangle — an "—" wall with the dash taken out. It
   showed on the rep's pane, the manager's person pane, the record and the
   drawer, i.e. everywhere, because "whatever facts this company actually has"
   is the normal case. kit6 now marks the last cell with the span its row has
   left; CSS applies it, and re-derives it wherever CSS itself changes the
   column count (below), since an inline `span 3` in a two-column grid would
   grow an implicit third column and push the panel sideways. */
.w6facts > .w6fact { grid-column: span var(--w6span, 1); }

/* R2 — the drawer's facts grid.
   The drawer is 440px wide. Four fact columns there is a 100px cell, which
   turned "Isaac Addison" into "Isaac Addis…" and "Bought from us" into two
   lines. Two columns fit the same facts whole. The tail rule follows the new
   count: in a two-column grid the tail is at most one cell, and a last child in
   an odd position is exactly that cell. */
.w6drawer .w6facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.w6drawer .w6facts > .w6fact { grid-column: auto; }
.w6drawer .w6facts > .w6fact:last-child:nth-child(odd) { grid-column: span 2; }

@media (max-width: 820px) {
  /* Same re-derivation on a phone, where w6.css already forces two columns. */
  .w6facts > .w6fact { grid-column: auto; }
  .w6facts > .w6fact:last-child:nth-child(odd) { grid-column: span 2; }
}

/* R3 — the Companies filter bar: "one row" has to mean one baseline.
   The five dropdown chips are 48px (a label stacked on a 32px select), the
   territory pill is 32px, "+ Add company" is 30px and the "50 shown of 26,049
   matching" readout wraps to three lines at 72px — and the bar CENTRED all
   four, so its eight controls sat at four different heights (19px of top
   spread; the driver allows 16, and the eye allows less than that). Standing
   the row on one line is what makes a filter bar read as a filter bar. */
.fbar.w4cofilters { align-items: flex-end; }
.fbar.w4cofilters > .res {
  align-self: flex-end;
  flex: 0 1 auto; min-width: 0; line-height: 1.35; padding-bottom: 8px;
}

/* R4 — Companies overflowed sideways on every laptop between 821px and ~1440px.
   wave4b.css pins the filter bar to `flex-wrap: nowrap` from 821px up, but its
   eight controls need about 1,080px of content column — which a 1440px window
   has and a 1280×800 MacBook Air does not. Measured at 1024px: 323px of the bar
   hanging off the right of the page, "+ Add company" among it, with the whole
   document scrolling sideways. The drivers test 1440 and 390 and never saw it.
   Wrapping is the honest answer below the width where eight controls fit: §4.5
   asks for ONE row of dropdown chips rather than wave 5's three, and at 1440 —
   the viewport the spec and the QA budgets are written against — it is still one
   row. Under that the bar folds to two rows instead of clipping itself. */
.fbar.w4cofilters { flex-wrap: wrap; }
@media (min-width: 1400px) { .fbar.w4cofilters { flex-wrap: nowrap; } }

/* R5 — the drawer's scrim inverted in Dark mode.
   `.w6dbg` mixes `var(--ink)` at 34%, and `--ink` is the FOREGROUND colour: in
   Day it is near-black and dims the page correctly, in Dark it is #E6EEF4 and
   the scrim washed the board out to near-white behind a dark drawer — the
   opposite of "glass, not plastic", in the one look built for the demo screen.
   A modal scrim is dark in every theme, including a dark one, so it is a fixed
   value rather than a token that flips meaning. */
.w6dbg { background: color-mix(in srgb, #04121C 42%, transparent); }

/* ==========================================================================
   ---- Polish ---- (2026-09-02/03, adversarial UX review follow-up)
   --------------------------------------------------------------------------
   Every rule here fixes one of the 13 findings the polish pass worked
   through; each carries the item number it closes. Page lanes' own JS
   already dropped the reason SENTENCE for self-explanatory types and wrapped
   a context line's tail span — this section is the shared-component CSS half
   of those fixes (`.w6rtx`, `.w6ctxtail`, `.w6tags`, `.w6rlab` are kit6.js's
   classes, and per WAVE6.md §6 the page lanes' room to touch them is exactly
   here: an append-only, clearly-commented section of w6.css, never kit6.js
   itself and never another lane's section above).
   ========================================================================== */

/* Item 1 — the truncation wall, part two: `.w6rtx` (the reason sentence) had
   `flex: 0 1 auto`, so it never claimed room of its own — it only ever got
   whatever the row's other parts left over, and on a hand-out row (a "Hand
   to" select at the end) or a Reasons row that was often nothing. It is now
   `flex: 1 1 160px`, so it either gets real room or, once even 160px will not
   fit (a narrower list than 700px already drops it under the frozen rule
   above; a WIDE list that is still tight — Companies' drawer at 440px, a
   cramped hand-out column — drops it here too, at 560px). */
.w6rtx { min-width: 0; flex: 1 1 160px; }
@container w6list (max-width: 560px) { .w6rtx { display: none; } }

/* Item 2 — the mobile context line ("Tampa · 69 trucks · 7…" cut mid-number).
   The page lanes (today-parts.js, manager.js, reasons.js) wrap the LAST " · "
   segment of `sub` in `.w6ctxtail` at the call site — `listRow`'s `sub` slot
   already accepts a Raw, so kit6.js itself needed no change. This is the
   other half: hide the tail under the same width kit6.js already treats as
   "too narrow for the reason sentence", so the row drops the fraction whole
   ("7.1 yr") instead of ellipsising it in half. The existing `.w6ctx`
   overflow/ellipsis stays as the fallback for a head that is STILL too long
   (a bare long city name with nothing after it to drop). */
@container w6list (max-width: 430px) { .w6ctxtail { display: none; } }

/* Item 6 — Companies: the chips column (owner/"Customer") and the fleet
   column used to be separated by ~500px of dead flex space, because neither
   `.w6tags` nor anything before it claims the row's free width in a list with
   no `.w6reason` (Companies passes no `reason:` — there is nothing to call).
   `.w6right`'s own `margin-left: auto` was the only thing moving into that
   space, which just relocates the same blank gap rather than closing it.
   Giving `.w6tags` the growth AND right-aligning its own pills closes the gap
   against the fleet column instead of leaving it dangling after the chips. */
#colist .w6row .w6tags { flex: 1 1 auto; justify-content: flex-end; }

/* Item 9 — the manager Team tab's per-row "Calls" chip. `personRow`
   (manager.js) still passes `reason.label: 'Calls'` — `reasonLabel(undefined)`
   has no sensible fallback for a person row, and the label carries no
   information the sentence beside it ("14 today · 62 this week · 3 open
   reasons") does not already say twice. Scoped to the Team list only
   (`.w6tteam`, set by manager.js's `paintList`) — every other page's label
   chip is still the reason's own "why now" and stays exactly as kit6 draws
   it. */
.w6list.w6tteam .w6row .w6rlab { display: none; }

/* ---- Polish ---- */
/* Manager hand-out list on a phone (seen live 2026-09-03): the "Hand to" select took
   the row's right column and left "T…" of the town and half the name. Under 560px the
   select gets its own third line and the name/context get the whole width; the "See
   all N" door drops under the tabs instead of overprinting the last tab. */
@container w6list (max-width: 560px) {
  .w6list.w6thand .w6row {
    height: auto; min-height: var(--row-h-touch);
    grid-template-areas:
      "rank band name  name"
      "rank band ctx   reason"
      "rank band right right";
    padding-bottom: 6px;
  }
  .w6list.w6thand .w6right { grid-row: auto; margin: 4px 0 0; justify-self: start; }
  .w6list.w6thand .k4sel { max-width: none; width: 100%; }
}
@media (max-width: 600px) {
  .w6thd { padding-bottom: 26px; }
  .w6thd > .k4see { top: auto; bottom: 2px; }
}

/* Collapsed reasons (DESIGN rule 2): "Truck out of service ×3" — the count of events
   behind one reason, set lighter than the label so it reads as a note, not a score. */
.w6rcount { font-weight: 600; margin-left: 5px; color: var(--mute); letter-spacing: .02em; font-variant-numeric: tabular-nums; }
