/**
 * ERPAL CRM Cockpit — app shell styling.
 * A clean, modern, Zoho/ERPAL-style CRM front-end: fixed left sidebar,
 * sticky top bar, card + table content. Layered on top of Olivero base.
 */

/* DESIGN TOKENS live in css/erpal-tokens.css (loaded first by the app
   library) — every color/background/border below references them. Do not
   reintroduce hardcoded colors here. */

/* ---- reset the Olivero page container so our shell owns the viewport ---- */
html, body { margin: 0; padding: 0; background: var(--erpal-bg); }
body { color: var(--erpal-ink); font-size: 14px; }
.dialog-off-canvas-main-canvas { height: auto; }

/* ---- belt-and-suspenders: never show the Drupal admin toolbar / Gin admin
   navigation on the front-end (also stripped server-side in the .theme). ---- */
#toolbar-administration,
#toolbar-bar,
.toolbar-oriented .toolbar-bar,
.gin-secondary-toolbar,
.gin--vertical-toolbar #toolbar-administration,
[data-offset-top],
.toolbar-tray { display: none !important; }
body.toolbar-fixed,
body.toolbar-horizontal,
body.toolbar-vertical,
body.toolbar-tray-open { padding-top: 0 !important; }

.erpal-app {
  display: grid;
  grid-template-columns: var(--erpal-sidebar-w) 1fr;
  min-height: 100vh;
}

/* ===================== THE COLLAPSIBLE RAIL =====================
   The rail is FIXED, so the grid's first track is not holding it up — the
   track is a SPACER that reserves the width the fixed aside occupies. That is
   why collapsing is two declarations and not a layout rewrite: take the track
   to 0 and the main column (1fr) takes the width back on its own, and slide
   the aside out from under the content it would otherwise sit on top of.

   The state lives on <html>, not on .erpal-app, on purpose: js/erpal-topbar.js
   loads in <head> (header: true) and applies it BEFORE FIRST PAINT, at which
   point .erpal-app has not been parsed yet. <html> is the only element that
   exists that early — the same reason the Day/Night toggle writes data-theme
   there rather than on the shell.

   SCOPED TO ≥769px DELIBERATELY. Below that the rail is already an off-canvas
   drawer (see the 768px block at the foot of this file) with its own transform
   and its own transient .is-nav-open state, and a persisted "collapsed" must
   not leak into it — on a phone the rail is collapsed by definition and the
   toggle's job there is the opposite one. */
@media (min-width: 769px) {
  .erpal-app { transition: grid-template-columns .22s ease; }
  /* visibility, not just transform: an aside translated off-screen is still in
     the tab order, so a collapsed rail would swallow a dozen tab stops into
     nowhere. It flips AFTER the slide when collapsing (0s delayed .22s) and
     IMMEDIATELY when expanding (the rule below, 0s undelayed) — a delayed
     `visible` would animate a rail nobody can see. */
  .erpal-sidebar { transition: transform .22s ease, visibility 0s; }

  html[data-sidenav="collapsed"] .erpal-app { grid-template-columns: 0 1fr; }
  html[data-sidenav="collapsed"] .erpal-sidebar {
    transform: translateX(-100%);
    visibility: hidden;
    transition: transform .22s ease, visibility 0s linear .22s;
  }
}
/* Motion is a preference, correctness is not: the collapse still happens, it
   just happens at once. The JS fires its map-resize kick off a timeout as well
   as off transitionend precisely so this branch is not a dead end. */
@media (prefers-reduced-motion: reduce) {
  .erpal-app,
  .erpal-sidebar { transition: none !important; }
}

/* =========================== SIDEBAR =========================== */
.erpal-sidebar {
  position: fixed;
  top: 0; left: 0; bottom: 0;
  width: var(--erpal-sidebar-w);
  background: var(--erpal-sidebar-bg);
  color: var(--erpal-sidebar-ink);
  border-right: 1px solid var(--erpal-line);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  z-index: 50;
}
/* THE RAIL WORDMARK MUST STAY IN THE RAIL. page.html.twig sets the name span
   `white-space: nowrap` (a wordmark that wraps is a wordmark that misreads), and
   .erpal-sidebar is `overflow-y: auto` -- which contains nothing on the X axis.
   So a brand name longer than the rail simply painted OUT of the aside and sat
   alongside the topbar's own logotype, reading as a duplicated brand on every
   page. MEASURED on the Klamath Falls realtor tenant 2026-08-08: a 37-character
   brand name gave a 352px span in a 250px rail, ending 102px into the topbar.
   Short-name tenants never saw it, which is why it shipped.
   nowrap + overflow:hidden + ellipsis is the same idiom .erpal-topbar__right
   already uses; min-width: 0 is what lets the span shrink at all (flex children
   floor at min-content otherwise). Fix is in CSS on purpose — no template
   change, so it reaches every tenant on the library cache key alone. */
.erpal-brand {
  display: flex; align-items: center; gap: 10px;
  height: var(--erpal-topbar-h);
  padding: 0 20px;
  color: var(--erpal-ink); text-decoration: none;
  font-weight: 700; font-size: 1.1rem; letter-spacing: .2px;
  border-bottom: 1px solid var(--erpal-line);
  flex: 0 0 auto;
  min-width: 0; overflow: hidden;
}
.erpal-brand__mark { color: var(--erpal-brand); font-size: 1.2rem; flex: 0 0 auto; }
.erpal-brand__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.erpal-sidebar__nav { flex: 1 1 auto; padding: 8px 0; }
.erpal-sidebar__foot {
  flex: 0 0 auto; padding: 14px 20px;
  font-size: .72rem; color: var(--erpal-sidebar-ink-dim);
  border-top: 1px solid var(--erpal-line);
}

/* nav menu (core menu block) */
.erpal-sidebar .menu {
  list-style: none; margin: 0; padding: 0;
}
.erpal-sidebar .menu .menu { padding: 0; } /* sub-lists */

/* group header (the <nolink> parents) */
.erpal-sidebar > .erpal-sidebar__nav ul.menu > li > a,
.erpal-sidebar > .erpal-sidebar__nav ul.menu > li > span {
  display: block;
  padding: 15px 20px 5px;
  font-size: .66rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .8px; color: var(--erpal-sidebar-ink-dim);
  text-decoration: none; cursor: default;
}

/* leaf links */
.erpal-sidebar .menu .menu a {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 20px;
  color: var(--erpal-sidebar-ink); text-decoration: none;
  font-size: .9rem; font-weight: 500;
  border-left: 3px solid transparent;
  transition: background .12s, color .12s, border-color .12s;
}
.erpal-sidebar .menu .menu a:hover {
  background: var(--erpal-hover-soft); color: var(--erpal-ink);
}
.erpal-sidebar .menu .menu a.is-active {
  background: var(--erpal-sidebar-active-bg);
  color: var(--erpal-sidebar-active-ink);
  border-left-color: var(--erpal-sidebar-active-ink);
  font-weight: 600;
}

/* =========================== MAIN =========================== */
.erpal-main {
  grid-column: 2;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

/* ---- top bar ---- */
.erpal-topbar {
  position: sticky; top: 0; z-index: 40;
  height: var(--erpal-topbar-h);
  background: var(--erpal-surface);
  border-bottom: 1px solid var(--erpal-line);
  display: flex; align-items: center; gap: 16px;
  padding: 0 24px;
}
/* The nav toggle. It was `display: none` here and `block` only under 768px;
   it now runs at every width, and its box, tap target and icon sizing live
   with the rest of the top-bar component in css/erpal-topbar.css. What stays
   here is the reset the control shares with the old burger. */
.erpal-topbar__burger {
  background: none; border: 0;
  cursor: pointer; color: var(--erpal-ink);
}
.erpal-search {
  flex: 1 1 auto; max-width: 540px;
  display: flex; align-items: center;
  background: var(--erpal-bg);
  border: 1px solid var(--erpal-line);
  border-radius: 8px;
  padding: 0 10px;
}
.erpal-search__input {
  flex: 1 1 auto; border: 0; background: transparent;
  padding: 9px 6px; font-size: .9rem; outline: none; color: var(--erpal-ink);
}
.erpal-search__btn {
  border: 0; background: none; cursor: pointer;
  font-size: 1.1rem; color: var(--erpal-ink-soft);
}
/* The far-right cluster. Its SHRINK behaviour (flex: 0 1 auto + min-width: 0,
   without which this element pushed the document sideways and the topbar was
   given a clipping `overflow-x: auto` to hide it) lives with the rest of the
   top-bar component in css/erpal-topbar.css. */
.erpal-topbar__right { margin-left: auto; display: flex; align-items: center; gap: 14px; }
.erpal-user { display: flex; align-items: center; gap: 10px; }
.erpal-user__name {
  font-weight: 600; font-size: .88rem; color: var(--erpal-ink); text-decoration: none;
}
.erpal-user__logout, .erpal-user__login {
  color: var(--erpal-ink-soft); text-decoration: none; font-size: 1.05rem;
}
.erpal-user__login { font-size: .9rem; font-weight: 600; color: var(--erpal-brand); }

/* ---- content ---- */
.erpal-content { padding: 26px 28px 60px; flex: 1 1 auto; }
.erpal-content__inner { max-width: 1280px; }
.erpal-breadcrumb { margin-bottom: 12px; font-size: .82rem; color: var(--erpal-ink-soft); }
/* THE LAST 18px OF SIDEWAYS SCROLL ON EVERY LIST PAGE — and it is a
   PSEUDO-ELEMENT, which is why every DOM sweep came back clean.
   Olivero paints `.breadcrumb::after`, a white-to-transparent gradient that
   fades the breadcrumb out at the right edge on narrow screens, and pins it at
   `inset-inline-end: -1.125rem` — 18px OUTSIDE its own nav. In Olivero's layout
   that lands in the page gutter; in this cockpit it lands outside the shell and
   widens the DOCUMENT. Measured on the live hub 2026-08-08 at 360px: nav
   scrollWidth 352 in a 334px box, document 358 vs a 345px client width, on
   /deals and /contacts. `document.querySelectorAll('*')` cannot see it, so the
   overflow looked like it came from nowhere; the wide views table next to it is
   innocent (erpal_tidy gives that its own scroll surface, which is the right
   answer for a table). The fade is also wrong here on its own terms: it is
   hardcoded `--color--white` over a themed surface, so in Night it would streak
   white across the crumbs.
   The side bleed on the content/list boxes goes with it — `.erpal-content`
   already owns the gutter, so there is nothing to bleed into. */
.erpal-breadcrumb .breadcrumb::after { content: none; }
.erpal-breadcrumb .breadcrumb__content,
.erpal-breadcrumb .breadcrumb__list { margin-left: 0; margin-right: 0; }
.erpal-highlighted { margin-bottom: 16px; }
.erpal-footer { padding: 16px 28px; color: var(--erpal-ink-soft); font-size: .8rem; }

/* page title */
.erpal-content h1.page-title,
.erpal-content .page-title {
  font-size: 1.6rem; font-weight: 700; margin: 0 0 18px; color: var(--erpal-ink);
}

/* =========================== CARDS / TABLES =========================== */
.erpal-content .views-element-container,
.erpal-card {
  background: var(--erpal-surface);
  border: 1px solid var(--erpal-line);
  border-radius: var(--erpal-radius);
  box-shadow: var(--erpal-shadow);
  padding: 4px 4px 0;
  margin-bottom: 22px;
}

/* exposed filter / search bar above tables */
.erpal-content form.views-exposed-form {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px;
  padding: 14px 16px; margin: 0;
}
.erpal-content form.views-exposed-form .form-item { margin: 0; }
.erpal-content form.views-exposed-form label { font-size: .76rem; font-weight: 600; color: var(--erpal-ink-soft); }
.erpal-content form.views-exposed-form input[type="text"],
.erpal-content form.views-exposed-form input[type="search"],
.erpal-content form.views-exposed-form select {
  border: 1px solid var(--erpal-line); border-radius: 7px; padding: 7px 10px; font-size: .88rem;
}

/* tables */
.erpal-content table {
  width: 100%; border-collapse: collapse; margin: 0; background: var(--erpal-surface);
  border-radius: var(--erpal-radius); overflow: hidden;
}
.erpal-content table thead th {
  background: var(--erpal-thead-bg); text-align: left;
  font-size: .72rem; text-transform: uppercase; letter-spacing: .5px;
  color: var(--erpal-ink-soft); font-weight: 700;
  padding: 9px 14px; border-bottom: 1px solid var(--erpal-line);
  white-space: nowrap;
}
/* sortable column header — click-to-sort link + arrow indicator */
.erpal-content table thead th a {
  color: var(--erpal-ink-soft); text-decoration: none; font-weight: 700;
  display: inline-flex; align-items: center; gap: 4px;
}
.erpal-content table thead th a:hover { color: var(--erpal-brand); }
.erpal-content table thead th.is-active a,
.erpal-content table thead th .is-active { color: var(--erpal-brand); }
/* THE SORT INDICATOR HAS TO BE VISIBLE (2026-09-12). Core emits
   `<span class="tablesort tablesort--asc">` carrying only visually-hidden text;
   Olivero paints it with a background image this cockpit never inherited, and a
   0.7em EMPTY inline span paints nothing at all — so the active column and its
   direction were invisible even where the sort itself worked. Draw the arrow
   from the class, and give every OTHER sortable header a resting ⇅ affordance so
   a reader can see which columns are clickable without clicking them. */
.erpal-content table thead th a .tablesort,
.erpal-content table thead th .tablesort {
  display: inline-block; width: auto; height: auto; line-height: 1; font-size: .9em;
}
.erpal-content table thead th .tablesort::after { content: "\2195"; }
.erpal-content table thead th .tablesort--asc::after { content: "\25B2"; font-size: .8em; }
.erpal-content table thead th .tablesort--desc::after { content: "\25BC"; font-size: .8em; }
.erpal-content table thead th a::after {
  content: "\21C5"; opacity: 0; margin-left: 2px; font-size: .9em; transition: opacity .12s;
}
.erpal-content table thead th a:hover::after,
.erpal-content table thead th a:focus-visible::after { opacity: .55; }
.erpal-content table thead th.is-active a::after { content: none; }
.erpal-content table thead th a { cursor: pointer; }
.erpal-content table thead th a:focus-visible {
  outline: 2px solid var(--erpal-accent); outline-offset: 2px; border-radius: 3px;
}
.erpal-content table tbody td {
  padding: 8px 14px; border-bottom: 1px solid var(--erpal-line); font-size: .88rem;
  color: var(--erpal-ink);
}
.erpal-content table tbody tr:last-child td { border-bottom: 0; }
.erpal-content table tbody tr:hover { background: var(--erpal-row-hover); }
.erpal-content table a { color: var(--erpal-accent-on-soft); text-decoration: none; font-weight: 600; }
.erpal-content table a:hover { text-decoration: underline; }

/* ================= PRINT-PAPER BLOCKS INSIDE THE CRM SHELL =================
   🔴 d-2026-09-02-048 class 3 — the customer-facing RATE CONFIRMATION.

   erpal-tms-rc-doc.html.twig opens with "DELIBERATELY ONE LOOK: this is a
   paper money document. White ground, dark ink, in every color scheme", and
   it backs that up: `.rc-paper { background:#fff; color:#111 }`. The template
   was right. THIS FILE was wrong. `.erpal-content table` above paints EVERY
   table with --erpal-surface, so in Night the document's own `.rc-grid`
   became a navy block sitting inside the white paper while the template's
   #111 / #555 print ink stayed put.

   MEASURED 2026-09-03 on demo.trial, Night, 1440 and 390, as a real seat:
   `strong` "Engineered joists — Gilchrist, OR" at 1.11:1 and `td.rc-k`
   "Load" at 2.28:1 — ink 17,17,17 and 85,85,85 on ground 22,28,44. The DOM
   walk that proved it: TD → TR → TBODY → TABLE.rc-grid bg rgb(22,28,44) →
   DIV.rc-paper bg rgb(255,255,255). This is the single most convincing
   artefact in the product and it was very nearly blank on a dark laptop.

   The rule is scoped to `.rc-paper` and repeats the template's own ink
   ladder, so the paper looks identical in Day, Night and Auto. The generic
   table rules keep applying everywhere else.

   ⚠️ OWNERSHIP: the long-term home for this is erpal_tms's own stylesheet
   next to the template it defends. It lives here today because the theme's
   table rule is what breaks it and because erpal_tms was being changed by a
   parallel worker in the same window. Fold it down when that settles. */
.erpal-content .rc-paper table,
.erpal-content .rc-paper thead th,
.erpal-content .rc-paper tbody tr,
.erpal-content .rc-paper tbody tr:hover,
.erpal-content .rc-paper tbody td { background: transparent; }
.erpal-content .rc-paper tbody td,
.erpal-content .rc-paper thead th { color: #111; }
.erpal-content .rc-paper table.rc-lines th { color: #333; }
.erpal-content .rc-paper .rc-grid .rc-k { color: #555; }

/* leading select checkbox column (theme-injected) */
.erpal-content table th.erpal-col-check,
.erpal-content table td.erpal-col-check {
  width: 34px; text-align: center; padding-left: 12px; padding-right: 6px;
}
.erpal-col-check input[type="checkbox"] { cursor: pointer; margin: 0; vertical-align: middle; }

/* full pager (right) + "Total Records N" summary (left) at the card foot */
.erpal-content .view-footer {
  padding: 10px 14px; border-top: 1px solid var(--erpal-line);
  font-size: .82rem; font-weight: 600; color: var(--erpal-ink-soft);
}
.erpal-content .pager { padding: 8px 14px 10px; margin: 0; }
.erpal-content .pager__items { display: flex; gap: 6px; list-style: none; padding: 0; margin: 0; justify-content: flex-end; }
/* 🌗 OLIVERO PAINTS THE PAGER TILE ITSELF: pager.css carries
   `.pager__item { background-color: var(--color--white); color: var(--color-text-neutral-soft) }`,
   which has no dark variant. The rules below only ever dressed the ANCHOR, so
   in Night the tiles that have no anchor — `pager__item--ellipsis` — stayed a
   white chip with a pale grey ellipsis on it, measured 2.49:1 on /leads and
   /activities (and on app.logisticsets.com, same theme). Two classes beat
   Olivero's one, and the ground is then whatever the card is. */
.erpal-content .pager__item { background: transparent; color: var(--erpal-muted); }
.erpal-content .pager__item a {
  display: inline-block; padding: 5px 11px; border: 1px solid var(--erpal-line);
  border-radius: 6px; text-decoration: none; color: var(--erpal-accent-on-soft); font-size: .82rem;
}
.erpal-content .pager__item a:hover { background: var(--erpal-hover); }
.erpal-content .pager__item.is-active a { background: var(--erpal-accent-fill); color: var(--erpal-on-accent-fill); border-color: var(--erpal-accent-fill); }

/* =========================== BUTTONS / ACTIONS ===========================
   🔵 FILLED PRIMARY CONTROLS USE THE FILL PAIR, NOT THE ACCENT PAIR
   (d-2026-09-02-048 class 1, executed 2026-09-03).

   --erpal-accent is the accent as a HUE; --erpal-accent-fill/-on-accent-fill
   are the accent as a BUTTON, and the two part company in Night: Night lifts
   the blue to #5b9bff so accent-coloured TEXT is readable on a dark canvas,
   and white ink on that lifted blue measures 2.77:1 — under the 4.5 bar on
   every filled control in the product. The fill pair flips instead of
   darkening (dark ink on the lifted blue = 6.69:1), which is the same trick
   the status chips use. Measured 2026-09-03 on demo.trial as a real seat:
   120 of 368 failing elements were this one pair of tokens on this one rule
   family.
   ⚠️ THE LAST SENTENCE OF THIS NOTE USED TO READ "--erpal-on-accent stays
   where it is because it is ALSO the ink on the DANGER ground". That was a real
   constraint and it is why a fix already understood sat unshipped for a release
   while every OTHER control painting white on the Night accent kept failing at
   2.77:1. ONE TOKEN DOING TWO JOBS WAS THE DEFECT; the answer was never a value
   that suits both grounds but a second token for the second ground.
   --erpal-on-danger now exists (erpal-tokens.css), the destructive-button rule
   further down points at it, and --erpal-on-accent is free to be dark ink in
   Night at 6.76:1. (d-2026-09-04-021, 2026-09-04.) */
.erpal-btn,
.erpal-content .button,
.erpal-content a.button,
.erpal-content input[type="submit"] {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--erpal-accent-fill); color: var(--erpal-on-accent-fill) !important;
  border: 0; border-radius: 8px; padding: 9px 16px;
  font-size: .88rem; font-weight: 600; text-decoration: none; cursor: pointer;
  box-shadow: var(--erpal-shadow);
}
.erpal-btn:hover,
.erpal-content .button:hover,
.erpal-content input[type="submit"]:hover { background: var(--erpal-brand-dark); }
.erpal-btn--ghost {
  background: var(--erpal-surface); color: var(--erpal-accent-on-soft) !important;
  border: 1px solid var(--erpal-line);
}

/* ---- FREIGHT CONTROLS THAT REPAINT THEIR OWN GROUND ----------------------
   Same trap as `.erpal-btn--danger` and `.erpal-bulk-clear` (see the note in
   erpal-listview.css): erpal_tms's Counter / Fell-off actions are SECONDARY —
   they paint themselves on --erpal-surface, not on the accent fill — and left
   their ink to the base rule. With the fill pair that ink is dark, and dark
   ink on Night's #161c2c card measures 1.06:1. The cockpit tab is the same
   shape the other way round: it paints the accent fill itself and hardcodes
   white on it (2.77:1 in Night), which erpal_tms's own comment claims is
   "contrast-safe in every theme state" — measurement says otherwise.

   ⚠️ OWNERSHIP, as with `.rc-paper` above: these belong in erpal_tms/css/
   tms.css next to the rules they correct. They are here because that module
   was being changed by a parallel worker in this window and because the
   defect is caused by this file's own !important. Fold them down. */
.erpal-content a.button.tms-counter-btn,
.erpal-content a.button.tms-falloff-btn {
  /* GROUND AND INK IN ONE RULE, or the pair splits. First cut set only the
     ink here and left the ground to tms.css's `background: var(--erpal-surface)`
     — which never won: it is (0,2,1), the generic `.erpal-content .button`
     above is also (0,2,1), and the theme aggregates after the module, so
     Counter and Fell-off have been rendering as FILLED buttons all along,
     against their own stylesheet's intent. The measured result of setting one
     half was accent ink on the accent fill: 1.00:1 in Day and 1.23:1 in Night
     on /load/1, caught by the cert on the very next run. */
  background: var(--erpal-surface);
  color: var(--erpal-accent-on-soft) !important;
  border: 1px solid var(--erpal-border);
  box-shadow: none;
}
.erpal-content .tms-cockpit__tab.is-active {
  background: var(--erpal-accent-fill); border-color: var(--erpal-accent-fill);
  color: var(--erpal-on-accent-fill);
}

/* page-level action toolbar (used by list "+ New" header + record actions) */
.erpal-pageactions {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin: 0 0 18px;
}
.erpal-pageactions .erpal-pageactions__title { font-size: 1.6rem; font-weight: 700; margin: 0; }

/* =========================== ZOHO LIST HEAD =========================== */
/* The list view header: a saved-view PILL row (left) under the page-title H1,
   with the primary "Create <Entity>" button + view-options caret floated to the
   top-right so they sit level with the H1 (which the page-title block renders). */
.erpal-content__inner { position: relative; }
/* tighten the page-title H1 so the pill row hugs it (Zoho density) */
.erpal-content h1.page-title,
.erpal-content .page-title { font-size: 1.45rem; margin: 0 0 8px; }

.erpal-listhead {
  display: flex; align-items: center; gap: 10px;
  padding: 0 0 10px; margin: 0;
}
.erpal-vpills { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.erpal-vpill {
  display: inline-block; padding: 5px 13px; border-radius: 999px;
  font-size: .82rem; font-weight: 600; color: var(--erpal-ink-soft);
  background: transparent; border: 1px solid transparent; cursor: pointer;
}
.erpal-vpill.is-active {
  /* ACCENT AS INK, NOT ACCENT AS FILL (d-2026-09-04-021's sweep). The bare
     accent on the soft tint measured 3.93:1 in Day on the hub clone — the same
     miss the sidebar's active tile was fixed for in 1.2.1, on the same pair of
     tokens, one component over. --erpal-accent-on-soft is the theme's verified
     ink for text on this ground: 5.81 Day, 6.13 Night. */
  background: var(--erpal-brand-soft); color: var(--erpal-accent-on-soft);
}
.erpal-vpill:hover { background: var(--erpal-hover); }
.erpal-vcaret, .erpal-viewmenu {
  border: 0; background: none; cursor: pointer; padding: 4px 6px;
  font-size: .9rem; color: var(--erpal-ink-soft); line-height: 1;
}
.erpal-vcaret:hover, .erpal-viewmenu:hover { color: var(--erpal-ink); }
/* Create button + view caret pinned top-right, on the H1 baseline. */
.erpal-listhead__actions {
  position: absolute; top: -2px; right: 0;
  display: flex; align-items: center; gap: 6px;
}
.erpal-listhead__actions .erpal-btn--create { padding: 8px 16px; }

/* ---- TOOLBAR: the views exposed form, reframed as one tight Filter / Sort-by /
   search bar (no standalone big search box, no Search button, no empty gaps). ---- */
.erpal-content form.views-exposed-form {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 8px 12px; margin: 0;
  border-bottom: 1px solid var(--erpal-line);
}
.erpal-content form.views-exposed-form::before {
  content: "\25BD  Filter"; font-size: .82rem; font-weight: 600;
  color: var(--erpal-ink-soft); margin-right: 2px; white-space: nowrap;
}
.erpal-content form.views-exposed-form .form-item { margin: 0; display: flex; align-items: center; gap: 6px; }
.erpal-content form.views-exposed-form label {
  font-size: .78rem; font-weight: 600; color: var(--erpal-ink-soft); margin: 0;
}
/* compact, inline search + selects */
.erpal-content form.views-exposed-form input[type="text"],
.erpal-content form.views-exposed-form input[type="search"],
.erpal-content form.views-exposed-form select {
  border: 1px solid var(--erpal-line); border-radius: 7px;
  padding: 6px 9px; font-size: .84rem; background: var(--erpal-input-bg); color: var(--erpal-ink);
}
.erpal-content form.views-exposed-form input[type="text"],
.erpal-content form.views-exposed-form input[type="search"] { min-width: 200px; }
/* the search filter sits on the right of the toolbar */
.erpal-content form.views-exposed-form .form-item-search { margin-left: auto; }
/* THE SEARCH SUBMIT IS HIDDEN, NOT REMOVED (2026-09-12, Troy: "if I change the
   per page from 50 to 100 or 20 there is no way to load the settings").
   `display: none` took the only control that could APPLY this form off the page:
   the Per-page select changed, and nothing happened, forever. Two halves fix it
   and both are needed — erpal-layout.js 1.1.0 submits the form when a select
   changes, and the button stops being `display: none` so it stays in the
   accessibility tree and in the tab order for anyone who reaches the toolbar by
   keyboard or screen reader. Visually-hidden costs the layout nothing (absolute,
   1px, clipped), which is what the old rule was actually for. */
.erpal-content form.views-exposed-form .form-actions {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; margin: -1px; padding: 0; border: 0;
}
.erpal-content form.views-exposed-form .form-actions .form-submit:focus-visible {
  position: static; width: auto; height: auto; clip-path: none; margin: 0;
  padding: 6px 12px; overflow: visible;
}

/* Entity action tabs (View / Edit / Delete / Clone) rendered as clean Zoho
   pills instead of Olivero's underline tab bar. */
.erpal-content nav.tabs { margin-bottom: 18px; }
.erpal-content ul.tabs {
  display: flex; flex-wrap: wrap; gap: 8px; list-style: none; padding: 0; margin: 0 0 20px;
  border: 0;
}
.erpal-content ul.tabs > li { margin: 0; }
.erpal-content ul.tabs > li > a {
  display: inline-block; padding: 7px 16px; text-decoration: none;
  color: var(--erpal-ink-soft); font-weight: 600; font-size: .85rem;
  background: var(--erpal-surface); border: 1px solid var(--erpal-line);
  border-radius: 999px; line-height: 1.2; transition: background .12s, color .12s, border-color .12s;
}
.erpal-content ul.tabs > li > a:hover { background: var(--erpal-hover); color: var(--erpal-ink); }
.erpal-content ul.tabs > li > a.is-active {
  background: var(--erpal-accent-fill); color: var(--erpal-on-accent-fill); border-color: var(--erpal-accent-fill);
}

/* =========================== ENTITY FORMS (Zoho record edit) =========================== */
/* The add/edit/delete form sits in the white content card with labeled fields
   in a clean stacked layout — a Zoho record edit, not raw Drupal. The list
   exposed-filter form and the top-bar search keep their own styling. */
.erpal-content form:not(.views-exposed-form):not(.erpal-search) {
  background: var(--erpal-surface);
  border: 1px solid var(--erpal-line);
  border-radius: var(--erpal-radius);
  box-shadow: var(--erpal-shadow);
  padding: 24px 26px;
  max-width: 940px;
}
.erpal-content form:not(.views-exposed-form):not(.erpal-search) .form-item,
.erpal-content form:not(.views-exposed-form):not(.erpal-search) .js-form-item {
  margin: 0 0 18px;
}
.erpal-content form:not(.views-exposed-form):not(.erpal-search) label,
.erpal-content form:not(.views-exposed-form):not(.erpal-search) .fieldset__label,
.erpal-content form:not(.views-exposed-form):not(.erpal-search) legend {
  display: block; font-size: .8rem; font-weight: 600; color: var(--erpal-ink);
  margin-bottom: 6px; padding: 0;
}
.erpal-content form:not(.views-exposed-form):not(.erpal-search) .form-required::after {
  content: " *"; color: var(--erpal-danger); font-weight: 700;
}
.erpal-content form:not(.views-exposed-form):not(.erpal-search) input[type="text"],
.erpal-content form:not(.views-exposed-form):not(.erpal-search) input[type="email"],
.erpal-content form:not(.views-exposed-form):not(.erpal-search) input[type="url"],
.erpal-content form:not(.views-exposed-form):not(.erpal-search) input[type="tel"],
.erpal-content form:not(.views-exposed-form):not(.erpal-search) input[type="number"],
.erpal-content form:not(.views-exposed-form):not(.erpal-search) input[type="date"],
.erpal-content form:not(.views-exposed-form):not(.erpal-search) input[type="datetime-local"],
.erpal-content form:not(.views-exposed-form):not(.erpal-search) input[type="password"],
.erpal-content form:not(.views-exposed-form):not(.erpal-search) select,
.erpal-content form:not(.views-exposed-form):not(.erpal-search) textarea {
  width: 100%; max-width: 520px; box-sizing: border-box;
  border: 1px solid var(--erpal-line); border-radius: 7px;
  padding: 9px 11px; font-size: .9rem; background: var(--erpal-input-bg); color: var(--erpal-ink);
  font-family: inherit;
}
.erpal-content form:not(.views-exposed-form):not(.erpal-search) textarea { min-height: 96px; }
.erpal-content form:not(.views-exposed-form):not(.erpal-search) input:focus,
.erpal-content form:not(.views-exposed-form):not(.erpal-search) select:focus,
.erpal-content form:not(.views-exposed-form):not(.erpal-search) textarea:focus {
  outline: 0; border-color: var(--erpal-brand);
  box-shadow: 0 0 0 3px var(--erpal-brand-soft);
}
.erpal-content form:not(.views-exposed-form):not(.erpal-search) .description,
.erpal-content form:not(.views-exposed-form):not(.erpal-search) .form-item__description {
  font-size: .76rem; color: var(--erpal-ink-soft); margin-top: 5px;
}
/* Nested field cards (entity reference / multi-value widgets) read as light
   sub-panels rather than heavy fieldsets. */
.erpal-content form:not(.views-exposed-form):not(.erpal-search) fieldset {
  border: 1px solid var(--erpal-line); border-radius: 7px;
  padding: 14px 16px; margin: 0 0 18px;
}
/* Action bar at the foot of the form: Save = blue primary, Delete = secondary. */
.erpal-content form:not(.views-exposed-form):not(.erpal-search) .form-actions {
  display: flex; align-items: center; gap: 12px;
  margin: 22px 0 0; padding-top: 18px; border-top: 1px solid var(--erpal-line);
}
.erpal-content .form-actions input[type="submit"],
.erpal-content .form-actions .button--primary {
  background: var(--erpal-accent-fill); color: var(--erpal-on-accent-fill) !important; border: 0;
}
.erpal-content .form-actions input[type="submit"]:hover,
.erpal-content .form-actions .button--primary:hover { background: var(--erpal-brand-dark); }
/* Secondary actions (Delete link on the edit form, Cancel on confirm forms). */
.erpal-content .form-actions a.button,
.erpal-content .form-actions .button:not(.button--primary):not(.button--danger):not([type="submit"]) {
  background: var(--erpal-surface); color: var(--erpal-ink-soft) !important;
  border: 1px solid var(--erpal-line); box-shadow: none;
}
.erpal-content .form-actions a.button:hover { background: var(--erpal-hover); color: var(--erpal-ink) !important; }
/* Destructive confirm (the delete confirmation form's Delete button). */
.erpal-content .form-actions .button--danger,
.erpal-content .form-actions input.button--danger {
  /* --erpal-on-danger, not --erpal-on-accent (d-2026-09-04-021): this button
     paints on the DANGER ground, and borrowing the accent's ink is what pinned
     that ink to white and blocked the Night accent fix. Night's dark ink on
     #e2606a is 5.45:1 where white was 3.43:1. */
  background: var(--erpal-danger); color: var(--erpal-on-danger) !important; border: 0;
}
.erpal-content .form-actions .button--danger:hover { background: var(--erpal-danger-dark); }

/* =========================== DASHBOARD =========================== */
.erpal-kpis {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 18px; margin-bottom: 24px;
}
.erpal-kpi {
  background: var(--erpal-surface); border: 1px solid var(--erpal-line);
  border-radius: var(--erpal-radius); box-shadow: var(--erpal-shadow);
  padding: 18px 20px; position: relative; overflow: hidden;
  /* The tile is its own container so the figure inside can be sized from the
     TILE's width rather than the viewport's (see .erpal-kpi__value). */
  container-type: inline-size;
}
.erpal-kpi::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--erpal-brand);
}
.erpal-kpi--green::before { background: var(--erpal-success); }
.erpal-kpi--amber::before { background: var(--erpal-warning); }
.erpal-kpi--purple::before { background: var(--erpal-purple); }
.erpal-kpi__label { font-size: .75rem; text-transform: uppercase; letter-spacing: .6px; color: var(--erpal-ink-soft); font-weight: 700; }
/* THE MONEY FIGURE NEVER WRAPS (compaction default, folded from the brand-skin
   skeleton in the d-2026-08-03-003 release batch; see
   handoffs/ERPAL_BRAND_COMPACT_STANDARD_2026-08-03.md §7).
   A flat 2rem here was the defect: four KPI tiles share the ~905px content
   column, giving ~215px per tile and ~175px usable, while "$10,498,000" needs
   ~189px -- so the last two zeros dropped to a second line on a client's
   dashboard. A figure that wraps is a figure that misreads.
   The plain font-size below is the fallback for browsers without container
   query units; the clamp that follows it wins where cqi is supported. */
.erpal-kpi__value {
  font-size: 2rem; font-weight: 800; margin-top: 6px; color: var(--erpal-ink); line-height: 1.1;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;   /* digits align, columns of figures line up */
}
/* 12.5cqi ~= 21.3px in a 171px-wide value box: "$1,234,567,890" measures 162px
   and "$100,000,000" 154px, both inside 171px and on one line. At 390px the box
   is ~316px, so the value keeps its full 2rem. Re-measure if the dashboard grid
   changes column count. Proven rendering on the CB HPR dashboard in Night,
   2026-08-03 ($10,498,000 on one line). */
.erpal-kpi__value { font-size: clamp(1rem, 12.5cqi, 2rem); }
.erpal-kpi__sub { font-size: .78rem; color: var(--erpal-ink-soft); margin-top: 4px; }

/* `minmax(0, 1fr)`, NOT `1fr`. A bare `1fr` is `minmax(auto, 1fr)`, and `auto`
   as a track MINIMUM is the item's min-content — so one wide panel (a 3-column
   views table) sets a floor the whole column cannot go below, and the grid
   grows past its own container instead. MEASURED on the live LD hub 2026-08-08
   at a 360px viewport: `.erpal-dash-grid` was 313px wide with a single
   353.888px track, every `.erpal-panel` 354px, and the document scrolled
   sideways (scrollWidth 370 vs clientWidth 345). This was the horizontal scroll
   the top bar's `overflow-x: auto` was blamed for and never fixed — no chrome
   element was ever among the offenders. */
.erpal-dash-grid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 22px;
  align-items: start;
}
.erpal-dash-grid > .erpal-panel { margin-bottom: 0; }
.erpal-panel {
  background: var(--erpal-surface); border: 1px solid var(--erpal-line);
  border-radius: var(--erpal-radius); box-shadow: var(--erpal-shadow); margin-bottom: 22px;
}
.erpal-panel__head {
  padding: 14px 18px; border-bottom: 1px solid var(--erpal-line);
  font-weight: 700; font-size: 1rem; display: flex; align-items: center; justify-content: space-between;
}
.erpal-panel__head a { font-size: .8rem; font-weight: 600; color: var(--erpal-accent-on-soft); text-decoration: none; }
.erpal-panel__body { padding: 8px 4px; }
.erpal-panel__body.is-pad { padding: 18px; }

/* deals-by-stage horizontal bars (flat, CSS-only) */
.erpal-bars { padding: 14px 18px; display: flex; flex-direction: column; gap: 12px; }
.erpal-bar {
  display: grid; grid-template-columns: 150px 1fr 34px; align-items: center; gap: 12px;
}
.erpal-bar__label {
  font-size: .82rem; color: var(--erpal-ink-soft);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.erpal-bar__track { background: var(--erpal-track); border-radius: 999px; height: 10px; overflow: hidden; }
.erpal-bar__fill { display: block; height: 100%; background: var(--erpal-brand); border-radius: 999px; }
.erpal-bar__val { font-size: .82rem; font-weight: 700; color: var(--erpal-ink); text-align: right; }

/* =========================== MISC =========================== */
.erpal-content .messages { border-radius: 8px; margin-bottom: 18px; }
.erpal-empty { padding: 26px; text-align: center; color: var(--erpal-ink-soft); }

/* status pills (rendered list_default values) */
.erpal-pill {
  display: inline-block; padding: 2px 10px; border-radius: 999px;
  font-size: .76rem; font-weight: 600; background: var(--erpal-track); color: var(--erpal-ink-soft);
}

/* =========================== STATUS TAGS =========================== */
/* Injected by erpal_crm_ui_preprocess_views_view_field() around status values. */
.erpal-tag {
  display: inline-block; padding: 3px 10px; border-radius: 4px;
  font-size: .76rem; font-weight: 600; line-height: 1.3;
  background: var(--erpal-tag-bg); color: var(--erpal-tag-ink); white-space: nowrap;
}
/* greens — won / qualified / active / paid / completed / sent */
.erpal-tag--qualified, .erpal-tag--pre-qualified, .erpal-tag--won, .erpal-tag--closed-won,
.erpal-tag--active, .erpal-tag--paid, .erpal-tag--completed, .erpal-tag--sent,
.erpal-tag--deployed, .erpal-tag--running, .erpal-tag--accepted, .erpal-tag--approved
{ background: var(--erpal-tag-green-bg); color: var(--erpal-tag-green-ink); }
/* blues — new / open / in progress / contacted */
.erpal-tag--new, .erpal-tag--open, .erpal-tag--contacted, .erpal-tag--in-progress,
.erpal-tag--proposal, .erpal-tag--price-quote, .erpal-tag--negotiation, .erpal-tag--draft,
.erpal-tag--provisioning, .erpal-tag--pending
{ background: var(--erpal-tag-blue-bg); color: var(--erpal-tag-blue-ink); }
/* ambers — warm / follow-up / on hold / overdue-ish */
.erpal-tag--warm, .erpal-tag--follow-up, .erpal-tag--on-hold, .erpal-tag--high,
.erpal-tag--scheduled, .erpal-tag--maintenance, .erpal-tag--trial
{ background: var(--erpal-tag-amber-bg); color: var(--erpal-tag-amber-ink); }
/* reds — lost / cold / cancelled / failed / overdue */
.erpal-tag--lost, .erpal-tag--closed-lost, .erpal-tag--cold, .erpal-tag--cancelled,
.erpal-tag--failed, .erpal-tag--overdue, .erpal-tag--unqualified, .erpal-tag--decommissioned,
.erpal-tag--urgent, .erpal-tag--blocked
{ background: var(--erpal-tag-red-bg); color: var(--erpal-tag-red-ink); }

/* "Total Records N" result-summary text (rendered inside .view-footer) */
.erpal-content .view-footer .views-summary,
.erpal-content .views-row-count { font-size: .82rem; color: var(--erpal-ink-soft); }

/* =========================== RECORD VIEW (Zoho record cockpit) =========================== */
/* A record page is a stack of titled SECTION cards (field_group html_element,
   format_settings.classes = "erpal-section"). Inside each card the fields lay
   out as a 2-column label:value grid (the field template emits .field /
   .field__label / .field__item). Long-text fields span the full width. */
.erpal-content .erpal-section {
  background: var(--erpal-surface);
  border: 1px solid var(--erpal-line);
  border-radius: var(--erpal-radius);
  box-shadow: var(--erpal-shadow);
  padding: 16px 22px 18px;
  margin: 0 0 18px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 36px;
  align-content: start;
}
.erpal-content .erpal-section__title {
  grid-column: 1 / -1;
  margin: 0 0 10px;
  padding: 0 0 10px;
  font-size: .98rem;
  font-weight: 700;
  color: var(--erpal-ink);
  border-bottom: 1px solid var(--erpal-line);
  letter-spacing: .2px;
}
/* one label:value pair per grid cell */
.erpal-content .erpal-section .field {
  display: flex;
  gap: 14px;
  align-items: baseline;
  padding: 7px 0;
  border-bottom: 1px solid var(--erpal-divider);
  min-width: 0;
}
.erpal-content .erpal-section .field__label {
  flex: 0 0 42%;
  max-width: 44%;
  font-weight: 600;
  color: var(--erpal-ink-soft);
  font-size: .82rem;
  line-height: 1.35;
}
.erpal-content .erpal-section .field__item,
.erpal-content .erpal-section .field__items {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--erpal-ink);
  font-size: .86rem;
  line-height: 1.4;
  word-break: break-word;
}
.erpal-content .erpal-section .field a { color: var(--erpal-accent-on-soft); text-decoration: none; font-weight: 600; }
.erpal-content .erpal-section .field a:hover { text-decoration: underline; }
/* long-text fields (notes / descriptions) span both columns and stack */
.erpal-content .erpal-section .field--type-string-long,
.erpal-content .erpal-section .field--type-text-long,
.erpal-content .erpal-section .field--type-text-with-summary {
  grid-column: 1 / -1;
  flex-direction: column;
  gap: 4px;
}
.erpal-content .erpal-section .field--type-string-long .field__label,
.erpal-content .erpal-section .field--type-text-long .field__label,
.erpal-content .erpal-section .field--type-text-with-summary .field__label {
  flex-basis: auto;
  max-width: none;
}

/* ---- Related lists: the reverse-reference view blocks (block ids start with
   "block-erpal-rel-") rendered below the record as compact, titled cards. ---- */
.erpal-content [id^="block-erpal-rel-"] {
  background: var(--erpal-surface);
  border: 1px solid var(--erpal-line);
  border-radius: var(--erpal-radius);
  box-shadow: var(--erpal-shadow);
  margin: 0 0 18px;
  overflow: hidden;
}
.erpal-content [id^="block-erpal-rel-"] > h2,
.erpal-content [id^="block-erpal-rel-"] .block__title {
  margin: 0;
  padding: 13px 18px;
  font-size: .95rem;
  font-weight: 700;
  color: var(--erpal-ink);
  border-bottom: 1px solid var(--erpal-line);
}
.erpal-content [id^="block-erpal-rel-"] .views-element-container { border: 0; box-shadow: none; margin: 0; }
.erpal-content [id^="block-erpal-rel-"] table { margin: 0; }
.erpal-content [id^="block-erpal-rel-"] .view-empty {
  padding: 16px 18px;
  color: var(--erpal-ink-soft);
  font-size: .85rem;
}

/* =========================== ACTIVITY TIMELINE ===========================
   Merged reverse-chronological stream of a record's notes/emails/activities,
   rendered by TimelineBuilder via hook_entity_view. Reuses the .erpal-section
   card + .erpal-tag chip system; overrides the section's 2-col grid back to a
   single full-width column (timeline entries are full-width rows). */
.erpal-content .erpal-section.erpal-timeline { display: block; }
.erpal-tl__count {
  display: inline-block; margin-left: 6px; padding: 1px 9px;
  border-radius: 10px; background: var(--erpal-tag-bg); color: var(--erpal-ink-soft);
  font-size: .72rem; font-weight: 700; vertical-align: middle;
}
.erpal-tl__empty { color: var(--erpal-ink-soft); font-size: .88rem; padding: 6px 0 2px; }

.erpal-tl { position: relative; margin-top: 4px; }
/* The vertical spine. */
.erpal-tl::before {
  content: ""; position: absolute; left: 7px; top: 4px; bottom: 4px;
  width: 2px; background: var(--erpal-line);
}
.erpal-tl__day {
  position: relative; margin: 14px 0 8px; padding-left: 30px;
  font-size: .76rem; font-weight: 700; letter-spacing: .02em;
  text-transform: uppercase; color: var(--erpal-ink-soft);
}
.erpal-tl__day:first-child { margin-top: 2px; }

.erpal-tl__entry { position: relative; padding: 0 0 12px 30px; }
.erpal-tl__marker {
  position: absolute; left: 1px; top: 4px; width: 14px; height: 14px;
  border-radius: 50%; background: var(--erpal-surface);
  border: 3px solid var(--erpal-ink-soft); box-sizing: border-box;
}
.erpal-tl__card {
  background: var(--erpal-bg); border: 1px solid var(--erpal-line);
  border-radius: var(--erpal-radius); padding: 9px 13px;
}
.erpal-tl__row {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
}
.erpal-tl__chip {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: 5px;
}
/* The kind glyph (TimelineBuilder::KIND_ICONS). currentColor, so it is the
   chip's own ink in both schemes and needs no per-scheme rule of its own. */
.erpal-tl__icon { flex: 0 0 auto; display: block; }
.erpal-tl__chiptext { line-height: 1; }
.erpal-tl__title {
  /* --erpal-accent-on-soft, not --erpal-brand: the brand blue measured 4.17:1
     on the timeline card's own ground in Day and 3.93:1 on the upcoming tint
     (2026-09-02). The token is verified against every ground this link lands
     on — 6.16 / 5.81 Day, 8.22 / 6.13 Night. */
  flex: 1 1 auto; min-width: 0; color: var(--erpal-accent-on-soft);
  text-decoration: none; font-weight: 600; font-size: .9rem; word-break: break-word;
}
.erpal-tl__title:hover { text-decoration: underline; }
.erpal-tl__date {
  flex: 0 0 auto; margin-left: auto; color: var(--erpal-ink-soft);
  font-size: .76rem; white-space: nowrap;
}
.erpal-tl__snippet {
  margin-top: 4px; color: var(--erpal-ink-soft);
  font-size: .82rem; line-height: 1.4; word-break: break-word;
}

/* Per-kind chip colors + marker tint (Note grey · Email purple · Call green ·
   Meeting amber · Task blue). */
.erpal-tag--note    { background: var(--erpal-tag-bg); color: var(--erpal-tag-ink); }
.erpal-tag--email   { background: var(--erpal-tag-purple-bg); color: var(--erpal-tag-purple-ink); }
.erpal-tag--call    { background: var(--erpal-tag-green-bg); color: var(--erpal-tag-green-ink); }
.erpal-tag--meeting { background: var(--erpal-tag-amber-bg); color: var(--erpal-tag-amber-ink); }
.erpal-tag--task    { background: var(--erpal-tag-blue-bg); color: var(--erpal-tag-blue-ink); }
.erpal-tl__entry--note    .erpal-tl__marker { border-color: var(--erpal-marker-dim); }
.erpal-tl__entry--email   .erpal-tl__marker { border-color: var(--erpal-tag-purple-ink); }
.erpal-tl__entry--call    .erpal-tl__marker { border-color: var(--erpal-tag-green-ink); }
.erpal-tl__entry--meeting .erpal-tl__marker { border-color: var(--erpal-tag-amber-ink); }
.erpal-tl__entry--task    .erpal-tl__marker { border-color: var(--erpal-tag-blue-ink); }
.erpal-tl__entry--sms     .erpal-tl__marker { border-color: var(--erpal-tag-purple-ink); }

/* UPCOMING: a row whose time has not happened yet is a commitment, not a
   record. It gets the accent spine, an accent-tinted card and a date that says
   the day out loud — the one thing you scan a record for is "what is next".
   Ink stays a full-strength token in both schemes; the tint carries the
   signal, which is the same idiom the rail's active tile uses and the reason a
   filled accent was rejected there (erpal_crm_ui 1.6.0). */
.erpal-tl__entry.is-upcoming .erpal-tl__marker { border-color: var(--erpal-accent); }
.erpal-tl__entry.is-upcoming .erpal-tl__card {
  background: var(--erpal-accent-soft);
  border-color: var(--erpal-accent);
}
.erpal-tl__entry.is-upcoming .erpal-tl__date {
  color: var(--erpal-accent-on-soft);
  font-weight: 700;
}

/* =========================== RECORD ACTIONS ===========================
   Zoho-style inline create affordances at the top of a record hub, rendered by
   RecordActionsBuilder via hook_entity_view: the "+ Meeting/Call/Task" quick-
   create row + the always-visible "Add a note" composer. Reuses .erpal-section
   as its card; overrides the 2-col grid to a single full-width column. */
.erpal-content .erpal-section.erpal-record-actions { display: block; }

/* MEASURED 2026-09-02 at 390px on the hub clone (d-2026-09-01-029): the panel
   handed its contents 244px of a 375px viewport. Olivero's own <details>
   chrome was taking 66px of horizontal inset in three helpings — the section's
   22px padding, `.olivero-details__wrapper`'s ~19px margin, and that wrapper's
   own 12.8px padding — none of which is visible, all of which is width. The
   quick card, the note composer and the ＋ buttons all live inside it, so this
   was 17% of a phone screen spent on nothing. The section keeps its padding at
   desktop; below 640px it and the wrapper stand down. */
@media (max-width: 640px) {
  .erpal-content .erpal-section.erpal-record-actions { padding-left: 12px; padding-right: 12px; }
  .erpal-content .erpal-section.erpal-record-actions > .olivero-details__wrapper,
  .erpal-content .erpal-section.erpal-record-actions > .details-wrapper {
    margin-left: 0; margin-right: 0; padding-left: 0; padding-right: 0;
  }
}

/* Quick-create button row (ghost buttons, tinted per activity kind). */
.erpal-record-actions__buttons {
  display: flex; flex-wrap: wrap; gap: 8px; margin: 2px 0 14px;
}
.erpal-record-actions__btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 15px; border-radius: 8px;
  background: var(--erpal-surface); border: 1px solid var(--erpal-line);
  color: var(--erpal-ink) !important; font-size: .85rem; font-weight: 600;
  text-decoration: none; cursor: pointer;
}
.erpal-record-actions__btn:hover { background: var(--erpal-hover); }
/* Per-kind accent (Call green · Meeting amber · Task blue) — colored left edge
   + label, matching the timeline chip palette. */
.erpal-ra--call    { border-left: 3px solid var(--erpal-tag-green-ink); color: var(--erpal-tag-green-ink) !important; }
.erpal-ra--meeting { border-left: 3px solid var(--erpal-tag-amber-ink); color: var(--erpal-tag-amber-ink) !important; }
.erpal-ra--task    { border-left: 3px solid var(--erpal-tag-blue-ink);  color: var(--erpal-tag-blue-ink) !important; }

/* The inline "Add a note" composer. */
form.erpal-note-compose {
  display: flex; flex-direction: column; gap: 8px;
  background: var(--erpal-bg); border: 1px solid var(--erpal-line);
  border-radius: var(--erpal-radius); padding: 12px 13px;
}
form.erpal-note-compose .form-item { margin: 0; }
form.erpal-note-compose .erpal-note-compose__title,
form.erpal-note-compose .erpal-note-compose__body {
  width: 100%; box-sizing: border-box;
  border: 1px solid var(--erpal-line); border-radius: 8px;
  padding: 8px 10px; font-size: .9rem; background: var(--erpal-surface);
  color: var(--erpal-ink);
}
form.erpal-note-compose .erpal-note-compose__body { resize: vertical; min-height: 46px; }
form.erpal-note-compose .form-actions { margin: 0; }

/* =========================== RESPONSIVE =========================== */
@media (max-width: 980px) {
  .erpal-dash-grid { grid-template-columns: minmax(0, 1fr); }  /* see the note above: never a bare 1fr */
  .erpal-content .erpal-section { grid-template-columns: 1fr; gap: 0; }
}
/* A TABLE MUST NOT SET A MIN-CONTENT FLOOR EITHER (the same defect as a bare
   `1fr` track or a flex item without `min-width: 0`, one box further down).
   A table's used width is max(width, min-content) — `width: 100%` above is a
   ceiling a table simply ignores — so the 3-column dashboard views table
   measured 334px of min-content inside a 311px panel at a 360px viewport and
   pushed the DOCUMENT to 355px. Measured on the live hub 2026-08-08: after the
   chrome and the dash grid were fixed, this table was the ONLY remaining
   horizontal-overflow offender.
   `table-layout: fixed` makes the table honour its own width; the header stops
   being nowrap and long values wrap, so the columns narrow. Note this is a
   SHRINK fix, not an overflow fix: nothing here becomes a scroll container, so
   nothing inside a table can be clipped the way the two nav bars were.
   Phone widths only — at desktop the auto layout sizing columns to their
   content is exactly what you want. */
@media (max-width: 800px) {
  .erpal-content table { table-layout: fixed; }
  .erpal-content table thead th { white-space: normal; }
  /* `break-word`, NOT `anywhere` (d-2026-09-13-040).
     `anywhere` collapses a cell's min-content to ONE CHARACTER, and with
     `table-layout: fixed` above letting the shrink actually happen, that is not
     a narrower column — it is a vertical column of letters. Measured on Troy's
     phone screenshot of /ops/decisions/queue: six columns of a 390px screen is
     53px each, "d-2026-08-16-062" rendered one character per line, and the
     "Mark executed" button rendered as fourteen stacked letters. The email
     reader learned this in August and was exempted below; the lesson was the
     RULE's, not the reader's. `break-word` keeps the shrink for a table that
     genuinely must stay a table and breaks a word only when it truly cannot
     fit — and every table the shell renders is now a CARD at this width
     anyway (erpal-resptable.css), where neither rule applies at all. */
  .erpal-content table thead th,
  .erpal-content table tbody td { overflow-wrap: break-word; }
  /* A table that keeps its table layout does it inside a scroll frame, where
     sizing to content is the entire point. */
  .erpal-content .erpal-scrollframe table { table-layout: auto; }

  /* EMAIL BODIES ARE NOT DASHBOARD TABLES (2026-08-17, Troy: mail on his
     phone "reads from top down like chinese"). Marketing email HTML is
     nested layout tables; `anywhere` collapses a cell's min-content to ONE
     CHARACTER and `fixed` lets the shrink happen, so every word rendered as
     a vertical 1-ch column in the reader. An email must keep the layout its
     sender built — .em-msg-body/.em-read-body already carry overflow-x:auto,
     so a 600px email scrolls sideways inside the reader instead of being
     crushed. Extra .erpal-content prefix = specificity that outranks the
     shrink rules above regardless of order. */
  .erpal-content .em-msg-body table,
  .erpal-content .em-read-body table { table-layout: auto; }
  .erpal-content .em-msg-body table thead th,
  .erpal-content .em-msg-body table tbody td,
  .erpal-content .em-read-body table thead th,
  .erpal-content .em-read-body table tbody td { overflow-wrap: break-word; }
}

/* THE VIEWPORT CANNOT SEE THE RAIL (Troy ruling d-2026-08-13-014, `container_query`).
   The rule above is keyed on the VIEWPORT, and that stopped being the same thing as
   the available width the moment the navigation rail became collapsible in 1.2.3.
   MEASURED on the live hub 2026-08-13 at 1024x1366 with the rail EXPANDED: the rail
   eats 248px, so each `.erpal-dash-grid > .erpal-panel` is 236px — while the panels'
   3-column views tables measure 315px, 323px and 382px of min-content. Document
   scrollWidth 1026 in a 1009px viewport, 17 overflowing elements, and the page
   scrolled sideways. The 800px rule never fired because the viewport was 1024.
   Collapsing the rail cleared it completely (1009 == 1009) — but the DEFAULT state on
   first load is the overflowing one, so a workaround is not a fix.

   PROVEN PRE-EXISTING, not caused by the 1.2.3/1.2.4 rail work: hiding the new toggle
   and restoring the old bar padding left the measurement byte-identical at 1026 with
   the same 17 offenders. The topbar itself fits with room to spare (761 == 761).

   WHY A CONTAINER QUERY AND NOT ANOTHER BREAKPOINT. The panel's own width is the thing
   that actually matters and it is what the rail changes; a viewport breakpoint cannot
   see the rail, which is exactly how the 800px rule missed this. Raising that
   breakpoint to ~1100px would have covered the measured case by applying a phone rule
   to every tablet and small-desktop width where the auto layout is what you want.

   Scoped deliberately: `container-type: inline-size` applies `contain: layout style
   inline-size`, which makes the element a containing block for absolutely positioned
   descendants. That is fine on the content shell and on the four dashboard panels;
   it is not something to impose on every `.erpal-panel` in the theme. Same
   SHRINK-not-scroll behaviour as the 800px rule above — nothing becomes a scroll
   container, so nothing inside a table can be clipped.

   TWO LEVELS, because two different things were keyed on the viewport.

   LEVEL 1 — the GRID. `@media (max-width: 980px)` drops the dashboard to one column,
   and that threshold assumed the content area IS the viewport. With the rail out at
   1024 the content shell is 705px and the grid inside it only 493px, so each of the
   two columns is 236px: a 3-column data table cannot be read there at all, let alone
   fit. Below a 760px SHELL the grid goes single-column, which hands each panel the
   full 493px — wide enough that the tables render with their natural column widths
   and no shrink rule is needed. That is the real fix for the reported case.

   LEVEL 2 — the PANEL, as the floor. Wherever a panel still ends up narrower than
   420px (two-up at 1024-collapsed = 324px, at 1440 = 384px; one-up on a phone =
   343px) the table takes `table-layout: fixed` so it can never paint outside its own
   card. Threshold from measurement: 420px is above the widest observed table
   min-content (382px) and below the narrowest panel that comfortably holds it.
   `overflow-wrap: break-word`, NOT `anywhere`: with a fixed layout the min-content
   size no longer has to shrink, so words break only when a single word genuinely
   does not fit — `anywhere` chopped "Oregon Institute of Technology" into
   "Orego/n Institut/e of" at 236px, which is the phone rule showing up on a
   desktop. */
.erpal-content__inner { container-type: inline-size; container-name: erpal-shell; }
@container erpal-shell (max-width: 760px) {
  .erpal-dash-grid { grid-template-columns: minmax(0, 1fr); }
}
.erpal-dash-grid > .erpal-panel {
  container-type: inline-size;
  container-name: erpal-panel;
}
@container erpal-panel (max-width: 420px) {
  .erpal-content table { table-layout: fixed; }
  .erpal-content table thead th { white-space: normal; }
  .erpal-content table thead th,
  .erpal-content table tbody td { overflow-wrap: break-word; }
}

@media (max-width: 768px) {
  .erpal-app { grid-template-columns: 1fr; }
  .erpal-sidebar { transform: translateX(-100%); transition: transform .2s ease; }
  .erpal-app.is-nav-open .erpal-sidebar { transform: translateX(0); }
  /* THE OPEN DRAWER USED TO BURY ITS OWN CONTROL. The rail is fixed at
     z-index 50 and the top bar is sticky at 40, so an open drawer painted
     straight over the toggle: MEASURED at 390px and 768px on the dev stack,
     elementFromPoint at the button's centre returned the sidebar and
     Playwright's click timed out. The drawer opened and nothing could close
     it — pre-existing, since the burger has always been the only control, and
     it matters more now that this button is the nav control at every width.
     Raising the BAR (not the button — .erpal-topbar is a sticky positioned
     element with a z-index, so it is its own stacking context and a child
     cannot escape it) puts the drawer under the header, which is where a
     drawer belongs anyway. Nothing is lost behind it: the rail's top 56px is
     its brand row, and the bar above it is already showing the same logo and
     wordmark. */
  .erpal-app.is-nav-open .erpal-topbar { z-index: 60; }
  .erpal-main { grid-column: 1; }
  /* the toggle is visible at every width now — see css/erpal-topbar.css */
  .erpal-content { padding: 18px 16px 48px; }
}

/* --------------------------------------------------------------------------
 * FULL-BLEED CALENDAR (Troy 2026-08-22): the calendar is an APP surface —
 * the month grid earns the whole viewport width; breadcrumb and the duplicate
 * page title above it were dead space. Events open in a core modal (the
 * fullcalendar_view dialogWindow/dialogModal options), so the page itself is
 * the whole workflow now.
 * ------------------------------------------------------------------------ */
body.path-calendar .erpal-content { padding: 8px 10px 0; }
body.path-calendar .erpal-content__inner { max-width: none; }
/* --------------------------------------------------------------------------
 * OLIVERO'S 14-COLUMN CONTENT GRID IS NOT THIS APP'S LAYOUT.
 *
 * MEASURED 2026-09-02, hub vs Logic TMS tenant, same theme, same viewport:
 *
 *   hub    .region--content  display:block  ->  listing main 1168px, rows 44px
 *   tenant .region--content  display:grid   ->  listing main  801px, rows ~180px
 *
 * Olivero's `grid.css` gives `.grid-full` a `repeat(14, minmax(0,1fr))` grid and
 * its content-medium pass places the main block at column 3, spanning ten of the
 * fourteen. Inside a 1136px app shell that is 801px of usable width with 335px of
 * dead gutter — which is where "325px of dead gutter while the table hyphenates
 * 'Mixed pro-duce'" came from. It was read as a views container that would not
 * stretch. It is not: the container is doing exactly what it is told, one level up.
 *
 * THE HUB ESCAPED IT BY ACCIDENT. The neutralising rule lived in erpal_tidy's
 * tidy-list.css — a module the hub has and NO client or edition tenant does. So
 * the single most visible layout difference between the flagship and every
 * product built from it was a side effect of an optional UI module, which is the
 * same finding as the record cockpits: hub polish that no module shipped.
 *
 * It belongs HERE. This is app-shell layout, not a "Columns" feature, and the
 * declaration is byte-identical to erpal_tidy's, so on a site that has both the
 * result is unchanged.
 * ------------------------------------------------------------------------ */
.erpal-app .erpal-content .region--content,
.erpal-app .erpal-content .region--content.grid-full {
  display: block;
  max-width: none;
  margin-bottom: 0;
}

body.path-calendar .region--content { display: block; }
body.path-calendar nav.breadcrumb,
body.path-calendar .block-page-title-block { display: none; }

/* --------------------------------------------------------------------------
 * EDGE-TO-EDGE — the calendar idiom above, extended to the LISTS and the
 * RECORDS (Troy 2026-08-26: "I want calendars, views and records pages edge to
 * edge, I see too much wasted space").
 *
 * MEASURED on the live hub at 1440×900 before this block, logged in as the
 * staff seat:
 *   /leads    content col 1177 (l=248) · table 921 starting at x=490
 *             → 504px of a 1425px document spent on chrome
 *   /deal/90  content col 1177 · card 1121, 28px of side padding
 *             → 319px, and 72px of breadcrumb above an H1 that REPEATS the
 *               record name already printed in .rec-header__name below it
 *
 * The classes are ENUMERATED, never `body[class*="path-"]`. This cockpit
 * hosts more than the CRM — the hub dashboard (path-frontpage), the guides,
 * the agreements shell — and a full-bleed rule that leaked onto a client-
 * facing hub page would be a regression nobody would connect back to here.
 * Everything in this block is scoped to a route the CRM owns.
 *
 * The breadcrumb goes on every one of them because on this site it renders
 * exactly one crumb — "Home" — behind a contextual-links wrapper (verified
 * live on /leads and /deal/90 2026-08-26). It costs 18px on a list and 72px
 * on a record and it has never once told anyone where they are.
 *
 * The duplicate H1 goes on the RECORD routes ONLY. There the page title is a
 * verbatim repeat of .rec-header__name in the header card immediately below
 * it (measured: identical strings on /deal/90). On the LISTS it is the only
 * thing on the page that says "Leads" — the toolbar shows saved-view pills,
 * not the list's name — so it stays and merely loses its 18px bottom margin.
 * ------------------------------------------------------------------------ */
body.path-leads .erpal-content,
body.path-contacts .erpal-content,
body.path-accounts .erpal-content,
body.path-deals .erpal-content,
body.path-tasks .erpal-content,
body.path-activities .erpal-content,
body.path-calls .erpal-content,
body.path-meetings .erpal-content,
body.path-notes .erpal-content,
body.path-lead .erpal-content,
body.path-individual .erpal-content,
body.path-organization .erpal-content,
body.path-deal .erpal-content { padding: 12px 12px 40px; }

body.path-leads .erpal-content__inner,
body.path-contacts .erpal-content__inner,
body.path-accounts .erpal-content__inner,
body.path-deals .erpal-content__inner,
body.path-tasks .erpal-content__inner,
body.path-activities .erpal-content__inner,
body.path-calls .erpal-content__inner,
body.path-meetings .erpal-content__inner,
body.path-notes .erpal-content__inner,
body.path-lead .erpal-content__inner,
body.path-individual .erpal-content__inner,
body.path-organization .erpal-content__inner,
body.path-deal .erpal-content__inner { max-width: none; }

/* The breadcrumb: one crumb, on every CRM surface. */
body.path-leads .erpal-breadcrumb,
body.path-contacts .erpal-breadcrumb,
body.path-accounts .erpal-breadcrumb,
body.path-deals .erpal-breadcrumb,
body.path-tasks .erpal-breadcrumb,
body.path-activities .erpal-breadcrumb,
body.path-calls .erpal-breadcrumb,
body.path-meetings .erpal-breadcrumb,
body.path-notes .erpal-breadcrumb,
body.path-lead .erpal-breadcrumb,
body.path-individual .erpal-breadcrumb,
body.path-organization .erpal-breadcrumb,
body.path-deal .erpal-breadcrumb { display: none; }

/* --------------------------------------------------------------------------
 * THE SAME LIST, AGAIN, IN CSS (2026-09-02).
 *
 * The three blocks above are a HARDCODED LUCKY DUCK ROUTE LIST — the identical
 * mistake `_erpal_crm_ui_listing_views()` made in PHP and that 1.8.0 fixed with
 * hook_erpal_listing_views_alter(). An edition's board is not `path-leads`, so
 * it fell outside all three and paid for it, measured on the Logic TMS demo:
 *
 *              .erpal-content pad   __inner cap   breadcrumb   h1 top
 *   /leads          12px             none          hidden        84px
 *   /loads          26px            1280px         54px tall    164px
 *
 * 80px of chrome above the heading, on the surface the product is demonstrated
 * from, for no reason a user could name — the rail already says which board
 * they are on.
 *
 * KEY IT OFF THE SHELL, NOT THE PATH. `:has(.erpal-listing)` is true exactly
 * when the listing template rendered, so every view an edition declares to the
 * hook inherits the CRM's own density with nothing to remember. The path list
 * above stays: it also covers the RECORD routes, which are not listings, and it
 * is the fallback anywhere `:has()` is unavailable.
 * ------------------------------------------------------------------------ */
.erpal-content:has(.erpal-listing) { padding: 12px 12px 40px; }
.erpal-content:has(.erpal-listing) .erpal-content__inner { max-width: none; }
.erpal-content:has(.erpal-listing) .erpal-breadcrumb { display: none; }

/* --------------------------------------------------------------------------
 * AN EXPOSED MULTI-SELECT IS NOT A DROPDOWN.
 *
 * A CRM listing puts its exposed filters in the 244px rail; a board has no rail,
 * so the raw exposed form lands in the toolbar and a `<select multiple size=8>`
 * renders as a 120px OPEN LIST floating over the page — measured on /loads (one)
 * and /trucks (two), and it reads as a stuck-open dropdown, not a control. Cap
 * it and let it scroll: same options, same form, two rows of height.
 * ------------------------------------------------------------------------ */
.erpal-listing__toolbar select[multiple] {
  max-height: 64px;
  overflow-y: auto;
  min-width: 9rem;
}
.erpal-listing__toolbar .views-exposed-form { align-items: center; }

/* The duplicate record title — RECORD ROUTES ONLY (see the note above). */
body.path-lead .block-page-title-block,
body.path-individual .block-page-title-block,
body.path-organization .block-page-title-block,
body.path-deal .block-page-title-block { display: none; }

/* The list title stays; it just stops reserving a paragraph of air under it. */
body.path-leads .erpal-content .page-title,
body.path-contacts .erpal-content .page-title,
body.path-accounts .erpal-content .page-title,
body.path-deals .erpal-content .page-title,
body.path-tasks .erpal-content .page-title,
body.path-activities .erpal-content .page-title,
body.path-calls .erpal-content .page-title,
body.path-meetings .erpal-content .page-title,
body.path-notes .erpal-content .page-title { font-size: 1.35rem; margin-bottom: 6px; }

/* --------------------------------------------------------------------------
 * THE LIST FILTER RAIL BECOMES A DRAWER.
 *
 * `.erpal-listing__body` is a `244px minmax(0,1fr)` grid, and the rail track
 * is the single biggest piece of the 504px: 216px of aside plus a 16px gap,
 * pushing the table from x=261 to x=490. Collapsing the TRACK is the whole
 * fix — the main column is already `minmax(0, 1fr)` and takes the width back
 * on its own, exactly as the nav rail's own collapse does.
 *
 * State lives on <html> as `data-listfilters`, written pre-paint by
 * js/erpal-layout.js. That attribute selector is also what makes these rules
 * work FROM THIS FILE at all: `.erpal-listing__body` is styled in
 * css/erpal-listview.css, a separately-attached library whose load order
 * relative to this one is not something a stylesheet gets to assume, and
 * `html[data-listfilters="collapsed"] .erpal-listing__body` outranks it on
 * specificity no matter which file wins the cascade.
 *
 * `visibility: hidden` alongside the size collapse, for the reason the nav
 * rail's own comment gives: a zero-width aside is still in the tab order, and
 * a collapsed drawer must not swallow a dozen tab stops into nowhere.
 * ------------------------------------------------------------------------ */
/*
 * SCOPED TO A BODY THAT ACTUALLY HAS A RAIL (2026-09-02, v4). Unscoped, this
 * rule gave an EDITION BOARD — which renders no `<aside>`, because
 * erpal_crm_filter_sidebar() is keyed to the five CRM entity types — a two-track
 * grid whose first track is zero. With no aside to occupy it, the LIST
 * auto-placed into the zero track: `.erpal-listing__main` measured 2px (its own
 * borders), the table inside it 0px, clipped by main's `overflow: hidden`. The
 * board rendered as an empty white column on a page that returned 200 with the
 * full table in the DOM. `:has()` keeps the drawer behaviour identical wherever
 * a rail exists and takes this rule out of the boards' way entirely.
 */
html[data-listfilters="collapsed"] .erpal-listing__body:has(> .erpal-listing__filters) {
  grid-template-columns: 0 minmax(0, 1fr);
  gap: 0;
}
html[data-listfilters="collapsed"] .erpal-listing__filters {
  visibility: hidden;
  overflow: hidden;
  width: 0;
  padding: 0;
  border: 0;
  box-shadow: none;
}

.erpal-listtoggle {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--erpal-border, var(--erpal-line));
  border-radius: 7px;
  background: var(--erpal-surface); color: var(--erpal-muted, var(--erpal-ink-soft));
  padding: 6px 12px; font-size: .82rem; font-weight: 600;
  cursor: pointer; min-height: 34px; flex: 0 0 auto;
}
.erpal-listtoggle:hover { color: var(--erpal-accent); border-color: var(--erpal-accent); }
.erpal-listtoggle.is-open { color: var(--erpal-accent); border-color: var(--erpal-accent); }
.erpal-listtoggle__glyph { font-size: .95rem; line-height: 1; }
.erpal-listtoggle .erpal-fcount { margin-left: 2px; }

/* --------------------------------------------------------------------------
 * ONE SEARCH ON A PHONE.
 *
 * MEASURED on /leads at 390×844: THREE search inputs on one screen — the
 * topbar's global search (y=1), the view's exposed `search` (y=326, empty
 * placeholder, a 4-point "Search" label above it) and the filter rail's
 * "Search by name…" (y=515). None of them sticky. Three boxes that look the
 * same and search different things is not three times the search.
 *
 * Below 768px the topbar search is THE search: it travels with the user (the
 * bar is sticky) and it is now wide enough to type in. The view's exposed one
 * stands down — the WRAPPER only, tagged by js/erpal-layout.js, because the
 * same form carries Sort by / Order / Per page and those must stay. The rail's
 * search goes with the rail, which is collapsed by default.
 *
 * Above 768px it stays and merely gains a name: the same JS writes a real
 * placeholder ("Search leads…") in place of the empty one every CRM view
 * ships, so the box says what it does without a config change in 296 views.
 * ------------------------------------------------------------------------ */
@media (max-width: 768px) {
  /* Selector written LONG on purpose: the rule it has to beat is
     `.erpal-content form.views-exposed-form .form-item { display: flex }`
     earlier in this same file (0,3,1). A bare `.erpal-exposed-search` is
     (0,1,0) and loses — measured on the hub, computed `display: flex` at
     390px with the class correctly applied. Matching the specificity and
     coming later in the cascade is what makes it stick; `!important` would
     have hidden the reason. */
  .erpal-content form.views-exposed-form .erpal-exposed-search { display: none; }
}

/* --------------------------------------------------------------------------
 * THE DEAL STAGE BAR FITS ITS CARD.
 *
 * MEASURED on /deal/90 at 1440: `.rec-stagebar__track` is 1566px inside an
 * 1121px card (scrollWidth 1586 vs clientWidth 1119). The bar is not broken —
 * erpal_record/css/record.css gives it `overflow-x: auto`, so the late stages
 * ARE reachable — but the container has no visible scrollbar of its own on a
 * trackpad/overlay-scrollbar desktop, so what the user sees is a pipeline
 * that stops at "Proposal" with no indication that anything follows. A
 * control whose affordance is invisible is a control nobody uses.
 *
 * Wrapping is the fix rather than a prettier scrollbar: at desktop widths the
 * whole pipeline then paints at once, which is the entire point of a stage
 * bar. `min-width: max-content` on the track is what forbids that today, so
 * it is released and the track is allowed to be a wrapping flex row. The
 * chevron clip-paths are per-item and survive wrapping untouched.
 *
 * Scoped from the theme rather than edited in the module: the module ships to
 * every tenant on its own release cadence and this is a cockpit-layout
 * decision. `body` prefix carries the specificity (0,1,1 vs the module's
 * 0,1,0) so it wins regardless of which stylesheet loads last.
 *
 * Below 800px record.css already stacks the cockpit into one column; there
 * the bar keeps its horizontal scroll, because 10 wrapped stages on a 343px
 * phone would be a wall of chevrons above the record it describes.
 * ------------------------------------------------------------------------ */
@media (min-width: 801px) {
  body .rec-stagebar { overflow-x: visible; }
  body .rec-stagebar__track {
    min-width: 0;
    flex-wrap: wrap;
    row-gap: 4px;
  }
}

/* Money columns never wrap mid-number (found 2026-08-26: currency formatting
   grew the string two chars and $3,584.40 broke across lines on /deals). */
.views-field-field-amount,
td.views-field-field-amount { white-space: nowrap; }

/* ============= OLIVERO FIELDSET CARDS FOLLOW THE THEME MODE ============
   Olivero (our base theme) paints .fieldset with a hardcoded
   `--color--white` card and never defines a dark variant, while our token
   layer flips text light under Night/prefers-dark — so every webform
   fieldset rendered light-gray-on-white in dark mode (found by Troy
   2026-08-26 on the Digital PCS mailbox form: the "Identification
   documents" section was unreadable). Re-base the card on OUR tokens so it
   follows Day/Night/Auto exactly like every other surface. */
.fieldset {
  background-color: var(--erpal-surface, #fff);
  color: var(--erpal-text, inherit);
  border-color: var(--erpal-border, #e6e9ee);
}
/* 🟠 THE LEGEND BAR AND ITS LABEL ARE ONE PAIR (measured 2026-09-03,
   d-2026-09-02-048 class 4). Olivero paints `.fieldset__legend` with
   `--color--gray-45` (#5f7581, a mid-grey bar) and its `.fieldset__label`
   with `--color--white`, which is Olivero's own matched pair. Re-basing only
   the LABEL on --erpal-text — which is what this block used to do — broke the
   pair in BOTH schemes at once: Day put #1f2733 on that grey at 3.11:1 and
   Night put #e8ecf4 on it at 4.08:1, so "Special requirements" and "Truck
   availability" were the rare defect that fails light mode too. Ground and
   ink now come from the same token set, which is the whole rule this file
   exists to enforce (feedback_dark_mode_contrast_check_required). Measured
   after: #1f2733 on #eef1f6 = 13.28:1 Day, #e8ecf4 on #202942 = 12.17:1 Night. */
.fieldset .fieldset__legend {
  background-color: var(--erpal-hover, #eef1f6);
}
.fieldset .fieldset__legend,
.fieldset .fieldset__label,
.fieldset .fieldset__description,
.fieldset .form-item__description {
  color: var(--erpal-text, inherit);
}
.fieldset .fieldset__description,
.fieldset .form-item__description {
  color: var(--erpal-muted, #5f6b7a);
}
