/* brand-recolor.css - overrides the DB-injected theme.
   Primary lime #e4f221 -> #d4fb08, deep #cddb0a -> #b4d507.
   Loaded AFTER @dashboard_scripts so it wins rule-for-rule. Remove the
   <link> in vueapp.html.erb to fully revert. */

@font-face {
  font-family: 'Noto Sans Arabic';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/overview/fonts/NotoSansArabic-var-arabic.woff2') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF;
}

@font-face {
  font-family: 'Noto Sans Arabic';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/overview/fonts/Inter-var-latin.woff2') format('woff2');
}

html, body, #app, button, input, textarea, select, option, label, a, p, span, div,
h1, h2, h3, h4, h5, h6, table, th, td {
  font-family: 'Noto Sans Arabic', sans-serif !important;
}


/* ==========================================================================
   WevoCRM theme
   --------------------------------------------------------------------------
   Palette from the WevoCRM marketing site: lime #d4fb08 + ink #1d1b1c on warm
   paper neutrals.

   Built for this specific build (sendingtk/chatwoot v4.20.0), verified against
   its compiled CSS and DOM:
     - utilities are n-prefixed (bg-n-solid-2, text-n-slate-12, border-n-weak)
     - the CSS variables behind them are NOT prefixed (--solid-2, --slate-12)
     - --brand-color / --brand-color-hex are set at runtime by the fork's
       useBranding shim from BRAND_PRIMARY_COLOR; they feed .bg-n-brand, so
       both are pinned to the brand lime below (sections 2 and 3)
     - sidebar rows are div[role=button], not links

   Load order matters: this file must come after the compiled app CSS.
   ========================================================================== */
 
/* --------------------------------------------------------------------------
   1. Palette reference (documentation only)
      lime #d4fb08 | lime-deep #b4d507 | lime-soft #f3fa9b | lime-tint #fdfee9
      ink  #1d1b1c | ink-2 #0b0e12 | ink-3 #15191f | ink-4 #1c2128
      paper #f5f6f1 | paper-2 #eef0ea | line #dfe3da | muted #687078
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   2. LIGHT MODE TOKENS
   -------------------------------------------------------------------------- */
/* The brand colour has to be pinned on <body> as well as :root.

   Chatwoot writes the account's configured brand colour as an INLINE style,
   and it writes it twice — once on <html> and once on <body>. The `!important`
   below wins on <html>, but an inline declaration on <body> is not something a
   `:root` rule reaches at all: body simply has its own value, and everything
   inside inherits that one.

   The effect was that every filled brand control in light mode came out
   #bfc924, a dull olive, while :root said #d4fb08 — Apply, Schedule Message,
   the selected day in the date picker, and so on. Nothing looked broken, just
   muted, which is why it survived this long.

   Only the brand colour is restated here. The rest of the inline palette
   (--woot-*, --blue-*, --text-blue) is left as Chatwoot computed it: those
   drive text and hover tints, and #d4fb08 as a TEXT colour on white is
   unreadable. */
:root,
body {
  --brand-color: 212 251 8 !important;
  --brand-color-hex: #d4fb08 !important;
}

:root {
  /* the DB-injected theme feeds bg-n-brand through --brand-color; pin it to
     the brand lime in both modes so primary buttons never fall back to the
     old teal */
  --brand-color: 212 251 8 !important;
  --brand-color-hex: #d4fb08 !important;

  /* surfaces */
  --background-color: 245 246 241 !important;
  --card-color: 255 255 255 !important;
  --surface-1: 255 255 255 !important;
  --surface-2: 253 253 251 !important;
  --surface-active: 253 254 233 !important;
  --solid-1: 255 255 255 !important;
  --solid-2: 253 253 251 !important;
  --solid-3: 245 246 241 !important;
  --solid-active: 253 254 233 !important;

  /* borders + overlays */
  --border-weak: 223 227 218 !important;
  --border-strong: 201 207 194 !important;
  --border-container: 223 227 218 !important;
  --alpha-1: 29, 27, 28, .06 !important;
  --alpha-2: 29, 27, 28, .10 !important;
  --alpha-3: 255, 255, 255, .96 !important;
  --background-input-box: 29, 27, 28, .03 !important;
  --color-scrollbar: rgba(160, 166, 152, .40) !important;
  --color-scrollbar-hover: rgba(140, 146, 132, .55) !important;

  /* neutral ramps: 1-6 surfaces, 7-8 borders, 9-10 solids, 11-12 text */
  --gray-1: 253 253 251 !important;
  --gray-2: 249 250 246 !important;
  --gray-3: 245 246 241 !important;
  --gray-4: 238 240 234 !important;
  --gray-5: 231 234 225 !important;
  --gray-6: 223 227 218 !important;
  --gray-7: 210 216 203 !important;
  --gray-8: 187 194 180 !important;
  --gray-9: 122 130 118 !important;
  --gray-10: 108 116 104 !important;
  --gray-11: 104 112 120 !important;
  --gray-12: 29 27 28 !important;
  --slate-1: 250 251 247 !important;
  --slate-2: 248 249 245 !important;
  --slate-3: 245 246 241 !important;
  --slate-4: 238 240 234 !important;
  --slate-5: 229 233 224 !important;
  --slate-6: 223 227 218 !important;
  --slate-7: 210 216 203 !important;
  --slate-8: 168 176 160 !important;
  --slate-9: 110 118 106 !important;
  --slate-10: 88 95 85 !important;
  --slate-11: 104 112 120 !important;
  --slate-12: 29 27 28 !important;

  /* teal drives STATUS (Resolved). Kept in the lime family but a deeper,
     quieter degree than the brand lime, so Open / Pending / Resolved read as
     shades of the same yellow instead of different hues. Ink text throughout
     (see section 4b). */
  --teal-1: 252 253 235 !important;
  --teal-2: 249 251 214 !important;
  --teal-3: 244 248 176 !important;
  --teal-4: 238 244 138 !important;
  --teal-5: 230 239 100 !important;
  --teal-6: 221 233 62 !important;
  --teal-7: 180 213 7 !important;
  --teal-8: 186 199 8 !important;
  --teal-9: 168 180 5 !important; /* Resolved pill */
  --teal-10: 148 159 4 !important;
  --teal-11: 128 137 4 !important;
  --teal-12: 58 62 3 !important;
  --blue-8: 180 213 7 !important;
  --blue-9: 212 251 8 !important;
  --blue-10: 180 213 7 !important;
  --blue-11: 29 27 28 !important;
  --solid-blue: 29 27 28 !important;
  --text-blue: 29 27 28 !important;

  /* outgoing message bubble = .bg-n-solid-iris. Lime is safe here because
     section 4b forces ink text on that exact class. */
  --solid-iris: 212 251 8 !important;
  --solid-purple: 253 254 233 !important;
  --iris-9: 212 251 8 !important;
  --iris-10: 180 213 7 !important;

  /* label chips */
  --label-background: 238 240 234 !important;
  --label-border: 29, 27, 28, .10 !important;

  /* this build also carries a woot-* ramp, still teal out of the box */
  --woot-25: 253 254 233 !important;
  --woot-50: 251 253 207 !important;
  --woot-75: 247 251 168 !important;
  --woot-100: 242 249 126 !important;
  --woot-200: 236 247 79 !important;
  --woot-300: 212 251 8 !important;
  --woot-400: 180 213 7 !important;
  --woot-500: 29 27 28 !important;
  --woot-600: 19 19 20 !important;
  --woot-700: 11 14 18 !important;
  --woot-800: 8 9 11 !important;
  --woot-850: 6 7 9 !important;
  --woot-900: 5 5 6 !important;
}

/* --------------------------------------------------------------------------
   3. DARK MODE TOKENS
   -------------------------------------------------------------------------- */
:root.dark,
.dark {
  --brand-color: 212 251 8 !important;
  --brand-color-hex: #d4fb08 !important;

  --background-color: 11 14 18 !important;
  --card-color: 21 25 31 !important;
  --surface-1: 17 21 26 !important;
  --surface-2: 22 26 32 !important;
  --surface-active: 35 41 50 !important;
  --solid-1: 11 14 18 !important;
  --solid-2: 22 26 32 !important;
  --solid-3: 28 33 40 !important;
  --solid-active: 35 41 50 !important;

  --border-weak: 30 35 42 !important;
  --border-strong: 46 52 60 !important;
  --alpha-1: 21, 25, 31, .80 !important;
  --alpha-2: 255, 255, 255, .08 !important;
  --alpha-3: 22, 26, 32, .95 !important;
  --background-input-box: 255, 255, 255, .02 !important;
  --color-scrollbar: rgba(120, 130, 140, .34) !important;
  --color-scrollbar-hover: rgba(150, 160, 170, .50) !important;

  --gray-1: 11 14 18 !important;
  --gray-2: 17 21 26 !important;
  --gray-3: 22 26 32 !important;
  --gray-4: 28 33 40 !important;
  --gray-5: 35 41 50 !important;
  --gray-6: 43 50 59 !important;
  --gray-7: 55 63 73 !important;
  --gray-8: 76 86 98 !important;
  --gray-9: 112 122 134 !important;
  --gray-10: 128 138 150 !important;
  --gray-11: 160 168 178 !important;
  --gray-12: 237 239 235 !important;
  --slate-1: 11 14 18 !important;
  --slate-2: 17 21 26 !important;
  --slate-3: 22 26 32 !important;
  --slate-4: 28 33 40 !important;
  --slate-5: 35 41 50 !important;
  --slate-6: 43 50 59 !important;
  --slate-7: 55 63 73 !important;
  --slate-8: 76 86 98 !important;
  --slate-9: 112 122 134 !important;
  --slate-10: 128 138 150 !important;
  --slate-11: 160 168 178 !important;
  --slate-12: 237 239 235 !important;

  /* same lime-degree status scale in dark mode - solid pills with ink text */
  --teal-1: 20 22 10 !important;
  --teal-2: 28 31 12 !important;
  --teal-3: 42 47 14 !important;
  --teal-4: 56 62 12 !important;
  --teal-5: 72 79 12 !important;
  --teal-6: 94 102 10 !important;
  --teal-7: 124 134 8 !important;
  --teal-8: 150 161 6 !important;
  --teal-9: 168 180 5 !important; /* Resolved pill */
  --teal-10: 190 203 8 !important;
  --teal-11: 180 213 7 !important;
  --teal-12: 243 250 155 !important;
  --blue-8: 180 213 7 !important;
  --blue-9: 212 251 8 !important;
  --blue-10: 212 251 8 !important;
  --blue-11: 212 251 8 !important;
  --solid-blue: 212 251 8 !important;
  --text-blue: 212 251 8 !important;

  /* outgoing bubble: lime, with ink text forced in section 4b */
  --solid-iris: 212 251 8 !important;
  --solid-purple: 45 52 20 !important;
  --iris-9: 212 251 8 !important;
  --iris-10: 180 213 7 !important;

  --label-background: 28 33 40 !important;
  --label-border: 255, 255, 255, .06 !important;
  --button-color: 28 33 40 !important;

  --woot-25: 20 22 10 !important;
  --woot-50: 28 31 12 !important;
  --woot-75: 45 50 13 !important;
  --woot-100: 59 66 8 !important;
  --woot-200: 90 99 12 !important;
  --woot-300: 155 168 20 !important;
  --woot-400: 180 213 7 !important;
  --woot-500: 212 251 8 !important;
  --woot-600: 180 213 7 !important;
  --woot-700: 176 189 6 !important;
  --woot-800: 141 152 5 !important;
  --woot-850: 106 114 4 !important;
  --woot-900: 74 80 3 !important;
}

/* --------------------------------------------------------------------------
   4. Typography, selection, focus, scrollbars
   -------------------------------------------------------------------------- */
 
h1, h2, h3, h4 {
  letter-spacing: -.02em;
}

::selection {
  color: #1d1b1c;
  background: #d4fb08;
}

/* The brand focus ring, everywhere EXCEPT where the page asked for no ring.
 *
 * Tailwind's `outline-none` is not `outline: none` - it is `outline: 2px solid
 * transparent`, a real outline kept deliberately invisible. This rule only set
 * a COLOUR, so it painted those too, and a field whose author had explicitly
 * removed its ring got a bright lime one anyway.
 *
 * Where that showed: the canned-response box. Its search field is focused the
 * instant the box opens - nobody tabbed to it - so the whole search row was
 * framed in lime on arrival, which is why it read as a heavy selected box
 * sitting where Chatwoot has a plain row and a divider.
 *
 * Honouring `outline-none` costs nothing in accessibility: the ring still
 * appears on every control that did not ask to be rid of it. */
:focus-visible:not(.outline-none) {
  outline-color: rgba(212, 251, 8, .65);
}

/* AND NOBODY ELSE MAY PAINT IT EITHER.
 *
 * Honouring `outline-none` in our own rule was only half of it: the platform
 * has a `:focus-visible` colour of its own (#e4f221), and it paints these
 * fields for exactly the same reason - the outline is transparent, not absent,
 * so a rule setting only a colour brings it back to life.
 *
 * The canned-response box is where this is worst. Its search field takes focus
 * the instant the box opens, so the row arrives already framed in a bright
 * lime rectangle that looks like a validation error and marks nothing the
 * reader chose.
 *
 * `!important` is the point rather than a shortcut: the declaration being
 * overruled is the author's own `outline-none`, and this restores it. Controls
 * that show focus with a box-shadow instead are untouched, so nothing becomes
 * unreachable by keyboard. */
.outline-none:focus,
.outline-none:focus-visible {
  outline-color: transparent !important;
}

::-webkit-scrollbar-thumb {
  border-radius: 999px;
}

/* --------------------------------------------------------------------------
   4b. LEGIBILITY LAYER
   The app assumes its brand colour is dark: it puts white text on bg-n-brand
   and uses text-n-brand for links. With a lime brand both break, so:
     - anything filled with the brand gets ink text (Send, primary buttons)
     - brand-coloured TEXT becomes ink in light mode, lime in dark mode
   Matched with ~= so hover:/focus: variants never match.
   -------------------------------------------------------------------------- */
[class~="bg-n-brand"],
[class~="bg-n-brand"] :is(span, svg, b, small, p, div,
                          a, i, em, strong, label, li, td, th,
                          h1, h2, h3, h4, h5, h6) {
  color: #1d1b1c !important;
}

/* THE LIME THAT ARRIVES ON A STATE, NOT ON THE CLASS.
   Whole-token matching is what keeps this layer from firing on variants that
   are not painted yet - but three of those variants DO paint the lime, and
   the text under them stayed white:

     hover:bg-n-brand hover:text-white   every context-menu row (Reply, Pin,
                                         Copy, Archive, Edit) and the pinned
                                         messages button: lime on hover, white
                                         letters, nothing readable under the
                                         cursor
     !bg-n-brand                         the important-flagged fill, which
                                         `~="bg-n-brand"` never matched at all
                                         because the token carries the !
     checked:/indeterminate:             ticked boxes and radios

   Each is matched together with the state that paints it, so an element that
   is merely CAPABLE of turning lime keeps its own colour until it does. White
   on this lime measures 1.19:1 - not dim, invisible; the ink is 14.36:1. */
[class~="hover:bg-n-brand"]:hover,
[class~="hover:bg-n-brand"]:hover *,
[class~="!bg-n-brand"],
[class~="!bg-n-brand"] *,
[class~="checked:bg-n-brand"]:checked,
[class~="indeterminate:bg-n-brand"]:indeterminate,
[class~="focus-visible:bg-n-brand"]:focus-visible,
[class~="focus-visible:bg-n-brand"]:focus-visible * {
  color: #1d1b1c !important;
}

/* The ramps our palette turns lime that the first pass did not name. iris and
   blue-8 are solid lime here, teal-5 is the pale lime the Success label is
   filled with - and that label writes its text #f8f9fa. */
:is([class~="bg-n-iris-9"], [class~="bg-n-iris-10"],
    [class~="bg-n-blue-8"], [class~="bg-n-teal-5"],
    [class~="hover:bg-n-teal-5"]:hover),
:is([class~="bg-n-iris-9"], [class~="bg-n-iris-10"],
    [class~="bg-n-blue-8"], [class~="bg-n-teal-5"],
    [class~="hover:bg-n-teal-5"]:hover) * {
  color: #1d1b1c !important;
}

/* Three components that are not built from utilities at all and write white
   on the brand colour in their own scoped stylesheet: the Primary label pill
   (#f8f9fa on lime), the Primary banner, the editor's link dialog Submit, and
   the sidebar collapse handle on hover. */
.label.primary,
.banner.primary,
.banner.primary *,
.ProseMirror-prompt .ProseMirror-prompt-buttons button[type="submit"],
.sidebar-collapse-handle:hover .sidebar-collapse-handle__icon {
  color: #1d1b1c !important;
}

/* Two more of the same kind, found by scanning every compiled stylesheet for
   a rule that paints the brand colour and writes #f8f9fa/white in the same
   block (25 Sep 2026): the plain rows of the conversation card's right-click
   menu (Open in new tab, Copy conversation link, Mark as unread...) turn lime
   under the cursor with white letters, and the chosen day in the date
   picker. The menu's rule is scoped to its component, so it is matched with
   the same hash. */
.menu[data-v-ddf1dc91]:hover,
.menu[data-v-ddf1dc91]:hover *,
.mx-calendar-content .cell.active,
.mx-calendar-year-content .cell.active,
.mx-calendar-month-content .cell.active {
  color: #1d1b1c !important;
}

/* Badges, counters and status pills are filled from the woot, teal and blue
   ramps, which are lime here, while the app writes their text in white. Ink
   text on every lime-filled utility. */
:is(
  [class~="bg-woot-500"], [class~="bg-n-woot-500"],
  [class~="bg-woot-600"], [class~="bg-n-woot-600"],
  [class~="bg-woot-400"], [class~="bg-n-woot-400"],
  [class~="bg-woot-300"], [class~="bg-n-woot-300"],
  [class~="bg-woot-100"], [class~="bg-woot-50"], [class~="bg-woot-25"],
  [class~="bg-blue-500"], [class~="bg-blue-400"],
  [class~="bg-blue-100"], [class~="bg-blue-50"],
  [class~="bg-violet-500"], [class~="bg-violet-600"],
  [class~="bg-n-blue-9"], [class~="bg-n-blue-10"], [class~="bg-n-blue-11"],
  [class~="bg-n-solid-blue"],
  [class~="bg-n-teal-8"], [class~="bg-n-teal-9"],
  [class~="bg-n-teal-10"], [class~="bg-n-teal-11"],
  [class~="bg-n-amber-8"], [class~="bg-n-amber-9"],
  [class~="bg-n-amber-10"], [class~="bg-n-amber-11"],
  [class~="bg-n-solid-amber"], [class~="bg-n-solid-amber-button"]
),
:is(
  [class~="bg-woot-500"], [class~="bg-n-woot-500"],
  [class~="bg-woot-600"], [class~="bg-n-woot-600"],
  [class~="bg-woot-400"], [class~="bg-n-woot-400"],
  [class~="bg-woot-300"], [class~="bg-n-woot-300"],
  [class~="bg-woot-100"], [class~="bg-woot-50"], [class~="bg-woot-25"],
  [class~="bg-blue-500"], [class~="bg-blue-400"],
  [class~="bg-blue-100"], [class~="bg-blue-50"],
  [class~="bg-violet-500"], [class~="bg-violet-600"],
  [class~="bg-n-blue-9"], [class~="bg-n-blue-10"], [class~="bg-n-blue-11"],
  [class~="bg-n-solid-blue"],
  [class~="bg-n-teal-8"], [class~="bg-n-teal-9"],
  [class~="bg-n-teal-10"], [class~="bg-n-teal-11"],
  [class~="bg-n-amber-8"], [class~="bg-n-amber-9"],
  [class~="bg-n-amber-10"], [class~="bg-n-amber-11"],
  [class~="bg-n-solid-amber"], [class~="bg-n-solid-amber-button"]
) :is(span, svg, b, small, p, div) {
  color: #1d1b1c !important;
}

/* STATUS PILLS (Resolved / Open / Pending / Snoozed) and any yellow-family
   chip: black text, always. Two attributes give this (0,2,0) specificity, so
   it beats .text-white without relying on !important alone. The white status
   dot inside is darkened to match. */
[class~="bg-n-brand"][class*="rounded"],
[class~="bg-n-brand"][class*="rounded"] *,
[class~="bg-n-teal-8"][class*="rounded"], [class~="bg-n-teal-8"][class*="rounded"] *,
[class~="bg-n-teal-9"][class*="rounded"], [class~="bg-n-teal-9"][class*="rounded"] *,
[class~="bg-n-teal-10"][class*="rounded"], [class~="bg-n-teal-10"][class*="rounded"] *,
[class~="bg-n-teal-11"][class*="rounded"], [class~="bg-n-teal-11"][class*="rounded"] *,
[class~="bg-n-amber-8"][class*="rounded"], [class~="bg-n-amber-8"][class*="rounded"] *,
[class~="bg-n-amber-9"][class*="rounded"], [class~="bg-n-amber-9"][class*="rounded"] *,
[class~="bg-n-amber-10"][class*="rounded"], [class~="bg-n-amber-10"][class*="rounded"] *,
[class~="bg-n-amber-11"][class*="rounded"], [class~="bg-n-amber-11"][class*="rounded"] *,
[class~="bg-n-solid-amber"][class*="rounded"], [class~="bg-n-solid-amber"][class*="rounded"] *,
[class~="bg-woot-500"][class*="rounded"], [class~="bg-woot-500"][class*="rounded"] *,
[class~="bg-blue-500"][class*="rounded"], [class~="bg-blue-500"][class*="rounded"] *,
[class~="bg-violet-500"][class*="rounded"], [class~="bg-violet-500"][class*="rounded"] * {
  color: #1d1b1c !important;
}

[class~="bg-n-brand"][class*="rounded"] span[class*="bg-white"],
[class~="bg-n-teal-9"][class*="rounded"] span[class*="bg-white"],
[class~="bg-n-amber-9"][class*="rounded"] span[class*="bg-white"],
[class~="bg-woot-500"][class*="rounded"] span[class*="bg-white"],
[class~="bg-blue-500"][class*="rounded"] span[class*="bg-white"] {
  background-color: rgba(29, 27, 28, .55) !important;
}

/* Soft brand chips (Add Labels, brand tints): the fill is only ~10% lime, so
   they need lime text and a lime hairline, NOT ink text. */
/* ...but only where the element does not already define its own shape. This
   rule was written for small chips and used to hit ANY brand-tinted box - it
   turned the calendar today cell (rounded-lg, bg-n-brand/5) into a giant
   lime pill and replaced its border.

   `-z-10` is the second exclusion, and it is not a shape at all - it is how
   this build marks an element that paints BEHIND its own content. The date
   range picker bridges the 8px gap between two selected days with one of
   those: `absolute bottom-0 w-6 h-8 -right-4 bg-n-brand/15 -z-10`. Given a
   999px radius and a hairline it stopped being a bridge and became an
   outlined oval sticking out of each day, overlapping its neighbour - the
   range read as a row of overlapping eggs instead of one continuous band.
   Anything sitting behind its content is scenery, not a chip. */
[class*="bg-n-brand/"]:not([class*="rounded"]):not([class~="-z-10"]) {
  border: 1px solid rgba(180, 213, 7, .55) !important;
  border-radius: 999px !important;
}

[class*="bg-n-brand/"],
[class*="bg-n-brand/"] * {
  color: #1d1b1c !important;
}

.dark [class*="bg-n-brand/"] {
  border-color: rgba(212, 251, 8, .45) !important;
}

.dark [class*="bg-n-brand/"],
.dark [class*="bg-n-brand/"] * {
  color: #d4fb08 !important;
}

/* outgoing message bubble: exact class from the compiled CSS.
   Matched with ~= on purpose - this build also defines a
   hover:bg-n-solid-iris variant, and an earlier :not([class*="hover:"])
   guard here is what excluded the bubble and left its text white. */
[class~="bg-n-solid-iris"],
[class~="bg-n-solid-iris"] *,
[class~="bg-n-solid-iris/90"],
[class~="bg-n-solid-iris/90"] *,
[class~="bg-n-solid-purple"],
[class~="bg-n-solid-purple"] * {
  color: #1d1b1c !important;
}

[class~="bg-n-solid-iris"] svg,
[class~="bg-n-solid-iris/90"] svg {
  opacity: .8;
}

[class~="text-n-brand"] {
  color: #1d1b1c !important;
}

.dark [class~="text-n-brand"] {
  color: #d4fb08 !important;
}

/* --------------------------------------------------------------------------
   5. SIDEBAR
   Structure in this build:
     aside.bg-n-solid-2
       > section            logo tile, account switcher, search, compose
       > nav > ul > li      row = li > div > div[role=button]
                            group rows contain ul.sidebar-group-children
   Only leaf rows get the lime pill: :not(:has(> ul.sidebar-group-children))
   keeps a parent group (which also carries text-n-brand while a child is
   active) from turning into a second pill.
   Whole-token matching (~=) is used throughout so variant classes such as
   hover:text-n-brand never match.
   -------------------------------------------------------------------------- */

/* ---- rail ----
   Light values are the default; dark values are ".dark ..." descendants so
   they win wherever the .dark class actually sits in the tree. */
aside.bg-n-solid-2 {
  background-color: #f1f3ec !important;
  border-color: rgba(180, 213, 7, .45) !important; /* lime hairline */

  /* The width easing is NOT set here. It lives further down the file, in the
     one rule that owns it - a copy at this end would sit 350 lines above the
     winner and do nothing, which is exactly how the header block came to be
     44px tall while a rule up here politely asked for 24. */
}

.dark aside.bg-n-solid-2 {
  background-color: #11151a !important; /* softer on the eye than #0b0e12 */
  border-color: rgba(212, 251, 8, .30) !important;
}

@media (min-width: 768px) {
  aside.bg-n-solid-2 {
    margin: 8px !important;
    height: calc(100vh - 16px) !important;
    border-radius: 20px !important;
    border: 1px solid rgba(180, 213, 7, .45) !important;
    /* NO overflow:hidden here - it clips popups rendered inside the rail
       (the profile menu when the sidebar is collapsed). */
    overflow: visible !important;
  }

  .dark aside.bg-n-solid-2 {
    border: 1px solid rgba(212, 251, 8, .30) !important;
  }
}

/* ---- brand block ----
   Sized to the platform's own header, measured against Chatwoot: a 24px tile
   holding a 16px mark, a 1px divider, then the account name on a 28px row -
   64px for the whole block. This fork ships `size-9` (36px) where Chatwoot
   cloud ships `size-6`, and our own rules had grown it further to 44px with a
   56px name button beside it. That is what made the top of the sidebar sit so
   much heavier than everything under it. The colour stays ours; the
   proportions are the platform's. */
aside section div[class*="size-9"] {
  background-color: #d4fb08 !important;
  outline-color: #b4d507 !important;
}

#sidebar-account-switcher span:first-child {
  font-weight: 700 !important;
  letter-spacing: -.01em !important;
}

#sidebar-account-switcher:hover {
  background-color: rgba(34, 84, 242, .14) !important;
}

/* ---- search field and the compose button beside it ----
   Both drawn the way Chatwoot draws them: one quiet filled shape each, the
   same fill, the same 8px corner, no border and no outline. Measured off
   theirs, the field sits about fourteen steps lighter than the rail it is on,
   which is what the alpha fills below reproduce in either theme.

   The compose button used to be lime, on the reasoning that it is the primary
   action. Beside a grey field it read as a warning rather than an invitation,
   and the pair no longer looked like one control with two halves. The lime is
   kept for things that commit something; opening an empty composer does not.

   The button ships with `dark:!bg-n-black/30`, whose specificity beats a
   single-class rule in dark mode, so each dark variant is repeated with a
   .dark prefix to outrank it. */
aside section a[href*="/search"],
aside section span.inline-flex > button,
.dark aside section span.inline-flex > button {
  background-color: rgba(20, 26, 20, .06) !important;
  border: 0 !important;
  outline: 0 !important;
  border-radius: 8px !important;
}

.dark aside section a[href*="/search"],
.dark aside section span.inline-flex > button {
  background-color: rgba(255, 255, 255, .07) !important;
}

aside section a[href*="/search"]:hover,
aside section span.inline-flex > button:hover,
.dark aside section span.inline-flex > button:hover {
  background-color: rgba(20, 26, 20, .11) !important;
}

.dark aside section a[href*="/search"]:hover,
.dark aside section span.inline-flex > button:hover {
  background-color: rgba(255, 255, 255, .12) !important;
}

/* The pen is a quiet glyph on that fill, not ink on lime. */
aside section span.inline-flex > button span,
.dark aside section span.inline-flex > button span,
aside section span.inline-flex > button:hover span,
.dark aside section span.inline-flex > button:hover span {
  color: #687078 !important;
  background-color: #687078 !important;   /* the icon is a masked span */
}

.dark aside section span.inline-flex > button span,
.dark aside section span.inline-flex > button:hover span {
  color: #a0a8b2 !important;
  background-color: #a0a8b2 !important;
}

aside section span.inline-flex > button:hover span,
.dark aside section span.inline-flex > button:hover span {
  color: #ffffff !important;
}

/* ---- nav rows as chips ---- */
aside nav ul li > div > div[role="button"] {
  height: 40px !important;
  gap: 10px !important;
  border-radius: 12px !important;
  padding-inline: 8px !important;
  transition: background-color .16s ease, color .16s ease !important;
}

aside nav ul li > div > div[role="button"]:hover {
  background-color: rgba(34, 84, 242, .10) !important;
}

/* icon in its own tile */
aside nav ul li > div > div[role="button"] > div.relative {
  width: 26px !important;
  height: 26px !important;
  border-radius: 8px !important;
  display: grid !important;
  place-items: center !important;
  flex: 0 0 auto !important;
  background-color: rgba(29, 27, 28, .05) !important;
}

.dark aside nav ul li > div > div[role="button"] > div.relative {
  background-color: rgba(255, 255, 255, .05) !important;
}

/* ---- guaranteed legible sidebar text and icons ----
   Explicit per-mode colours so no row, label, icon or counter can end up
   dark-on-dark or light-on-light regardless of which token feeds it. */
/* The account switcher is matched separately: an ID inside :is() would lend
   its specificity to every branch and outrank the badge rules below - that is
   what kept the counters white-on-lime. */
aside #sidebar-account-switcher span {
  color: #1d1b1c !important;
}

.dark aside #sidebar-account-switcher span {
  color: #e6e9e2 !important;
}

/* The row carries the colour and its words follow it, so a row can be faded
   while idle and full ink while it is the page on screen (crm-rail.css,
   owner 2026-09-30). */
aside :is(nav ul li > div > div[role="button"], nav ul li.child-item a):not([class~="bg-n-brand"]) {
  color: var(--rail-row, #1d1b1c) !important;
}
aside :is(
  nav ul li > div > div[role="button"] span,
  nav ul li.child-item span
):not([class~="bg-n-brand"]) {
  color: inherit !important;
}

.dark aside :is(nav ul li > div > div[role="button"], nav ul li.child-item a):not([class~="bg-n-brand"]) {
  color: var(--rail-row, #e6e9e2) !important;
}

/* counters: lime chip with ink digits in BOTH modes, same as light mode.
   :not([style]) keeps label colour dots (inline background) out of this. */
aside nav span[class*="rounded"][class*="text-"]:not([style]),
.dark aside nav span[class*="rounded"][class*="text-"]:not([style]) {
  border-radius: 999px !important;
  font-weight: 700 !important;
  background-color: #d4fb08 !important;
  color: #1d1b1c !important;
}

/* active child row (All Conversations, Mentions, ... live in .child-item) */
aside nav ul li.child-item :is(a, div)[class~="text-n-brand"],
aside nav ul li.child-item[class~="text-n-brand"] span {
  color: var(--rail-row-on, #1d1b1c) !important;
  font-weight: 600 !important;
}

.dark aside nav ul li.child-item :is(a, div)[class~="text-n-brand"],
.dark aside nav ul li.child-item[class~="text-n-brand"] span {
  color: #d4fb08 !important;
  font-weight: 700 !important;
}

/* ---- active leaf row ----

   This used to be a filled lime pill with a glow. It was written as "the
   active row is unmistakable", and on its own it looked right — but it can
   only ever appear on a row that has no children, and at the top level that
   is just Overview and Flow+. Every other section (Conversations, Contacts,
   Reports, Settings…) opens a child list, and the active state lands on the
   CHILD, which Chatwoot marks with a faint film and bold text. So the rail
   had two different answers to "which page am I on", and which one you got
   depended on an implementation detail — whether that section happens to have
   sub-items — that means nothing to the person reading it.

   The two are now one. The leaf row takes the same treatment the child rows
   already had: Chatwoot's own faint film, bold label, no fill and no glow.
   The lime is not lost, it is just no longer shouted — it still marks the
   brand everywhere else in the rail.

   To go the other way instead (every active row lime, parents included),
   this is the block to change, and the `:not(:has(> ul.sidebar-group-children))`
   guard is what would have to be dropped. */
aside nav ul li:not(:has(> ul.sidebar-group-children)) > div > div[role="button"]:is(
  [class~="text-n-brand"],
  [class~="bg-n-brand"],
  [class~="active"]
) {
  background-color: rgba(29, 27, 28, .06) !important;
  font-weight: 700 !important;
  box-shadow: none !important;
}

.dark aside nav ul li:not(:has(> ul.sidebar-group-children)) > div > div[role="button"]:is(
  [class~="text-n-brand"],
  [class~="bg-n-brand"],
  [class~="active"]
) {
  /* the exact film Chatwoot puts on an active child link, so the two rows are
     indistinguishable rather than merely similar */
  background-color: rgba(255, 255, 255, .08) !important;
}

/* ---- sub rows ---- */
ul.sidebar-group-children li.child-item {
  border-radius: 10px !important;
}

ul.sidebar-group-children li.child-item:hover {
  background-color: rgba(34, 84, 242, .08) !important;
}

ul.sidebar-group-children li.child-item::before {
  background-color: rgba(212, 251, 8, .28) !important;
}

/* ---- badges ---- */
aside nav span[class*="rounded-full"] {
  border-radius: 999px !important;
  font-weight: 700 !important;
}

/* ---- collapse handle ----
   The chevron is a mask icon painted with currentColor, and the app reveals
   the handle on hover. macOS trackpads make that hard to find, so it is
   always visible here: solid chip, lime hairline, coloured chevron. */
/* the button stays an invisible hit area - only the inner wrapper is drawn */
.sidebar-collapse-handle,
.sidebar-collapse-handle--collapsed,
.sidebar-collapse-handle--expanded {
  opacity: 1 !important;
  visibility: visible !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  z-index: 60 !important;
  background: transparent !important;
  border: 0 !important;
  box-shadow: none !important;
  padding: 0 !important;
}

/* the visible chip */
.sidebar-collapse-handle__icon {
  opacity: 1 !important;
  visibility: visible !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: 22px !important;
  height: 22px !important;
  flex: 0 0 auto !important;
  border-radius: 999px !important;
  background-color: #f1f3ec !important;
  border: 1px solid rgba(180, 213, 7, .55) !important;
  color: #1d1b1c !important;
  box-shadow: 0 4px 12px rgba(29, 27, 28, .12) !important;
}

.dark .sidebar-collapse-handle__icon {
  background-color: #11151a !important;
  border-color: rgba(212, 251, 8, .45) !important;
  color: #d4fb08 !important;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .45) !important;
}

/* ONLY the chevron paints with currentColor - it is a mask icon.
   Never put this on the wrapper: it fills the whole element with colour. */
.sidebar-collapse-handle__chevron {
  opacity: 1 !important;
  visibility: visible !important;
  display: inline-block !important;
  width: 13px !important;
  height: 13px !important;
  color: inherit !important;
  background-color: currentColor !important;
}

.sidebar-collapse-handle:hover .sidebar-collapse-handle__icon,
.dark .sidebar-collapse-handle:hover .sidebar-collapse-handle__icon {
  background-color: #2254f2 !important;
  border-color: #2254f2 !important;
  color: #ffffff !important;
}

/* --------------------------------------------------------------------------
   6. Help centre portal
   -------------------------------------------------------------------------- */
#portal .prose a {
  color: #1d1b1c;
  text-decoration-color: #b4d507;
}

/* --------------------------------------------------------------------------
   7. Extending this file
   Utility-class overrides only work with the exact compiled class name, and
   variant classes keep their prefix in the class attribute - so match with
   [class~="name"], never [class*="name"], or hover:* variants will match too.
   Removed in this revision: --w-*, --n-*, .bg-woot-*, .bg-slate-* rules. They
   belong to stock Chatwoot and are inert in this build.
   -------------------------------------------------------------------------- */

/* --- conversation unread count circles -> new primary (not the Resolved pill) --- */
[class~="bg-n-teal-9"][class~="min-w-4"],
[class~="bg-n-teal-9"][class~="min-w-4"] * {
  background-color: #d4fb08 !important;
  color: #1d1b1c !important;
}

/* --- status pills: distinct hues, away from the lime primary --- */
/* Open -> Chatwoot blue */
[class~="bg-n-iris-9"][class~="rounded-full"][class~="gap-1"] {
  background-color: #1f93ff !important;
}
[class~="bg-n-iris-9"][class~="rounded-full"][class~="gap-1"],
[class~="bg-n-iris-9"][class~="rounded-full"][class~="gap-1"] * {
  color: #ffffff !important;
}
/* Resolved -> fresh green */
[class~="bg-n-teal-9"][class~="rounded-full"][class~="gap-1"] {
  background-color: #22c55e !important;
}
[class~="bg-n-teal-9"][class~="rounded-full"][class~="gap-1"],
[class~="bg-n-teal-9"][class~="rounded-full"][class~="gap-1"] * {
  color: #0b3d1e !important;
}

/* --- bigger sidebar brand logo --- */
aside section div[class*="size-9"] img {
  width: 34px !important;
  height: 34px !important;
}

/* --- empty-state logo -> faint gray watermark (was bright lime) --- */
img[class~="w-32"][class~="m-4"] {
  filter: grayscale(1) opacity(.18) !important;
}

/* smooth collapse/expand of the sidebar (added only during toggle) */
/* The sidebar's width transition is declared on the element itself, not on a
   class that gets added around a toggle.

   The class approach did not work: Vue rewrites the aside's class attribute as
   part of collapsing, which strips the added class in the same frame the width
   changes — so the sidebar snapped from 260px to 64px in a single step every
   time. Measured, not guessed: sampling the width per frame gave exactly two
   values.

   It used to be switched off for the length of a drag, on the theory that a
   drag must not lag the cursor. Chatwoot keeps its own easing running through
   the drag and, measured side by side, theirs is the one that reads as smooth:
   the rail eases toward the cursor instead of being redrawn at it. So the
   freeze is gone from sidebar-resize.js and the duration matches theirs -
   150ms, on the same curve they use.

   Only `width` is animated, which is all Chatwoot animates. Ours used to ease
   width, min-width, max-width AND flex-basis together - four properties, each
   restarting its own 150ms run on every mousemove, which is the drag feeling
   heavy even though the number said 150ms. A drag now writes `width` alone
   (see sidebar-resize.js); min and max are set once, at the end.

   120ms on a curve that leaves fast and lands gently: quick to answer, soft to
   stop. THIS IS THE ONLY RULE THAT SETS IT. */
aside.bg-n-solid-2 {
  transition: width .12s cubic-bezier(.2, .8, .2, 1),
              flex-basis .12s cubic-bezier(.2, .8, .2, 1) !important;
}

/* --- outgoing (right) message bubble -> primary lime in BOTH modes --- */
[class~="bg-n-solid-blue"][class~="right-bubble"] {
  background-color: #d4fb08 !important;
}
[class~="bg-n-solid-blue"][class~="right-bubble"],
[class~="bg-n-solid-blue"][class~="right-bubble"] * {
  color: #1d1b1c !important;
}

/* --- Private Note: blue identity (#1f93ff) instead of amber. Scoped to the
   private-note composer + note bubble, so the amber Pending pill stays amber. --- */
.reply-box.is-private {
  --amber-1: 234 243 255; --amber-2: 219 235 255; --amber-3: 201 224 255;
  --amber-4: 214 233 255; --amber-8: 120 176 235;
  --amber-9: 24 119 210; --amber-10: 22 108 196; --amber-11: 13 74 137; --amber-12: 6 42 78;
  --solid-amber: 24 119 210;
  background-color: #e3f0ff !important;
}
:root.dark .reply-box.is-private, .dark .reply-box.is-private {
  --amber-1: 16 28 44; --amber-2: 18 34 54; --amber-3: 22 42 66;
  --amber-4: 20 40 64; --amber-8: 40 92 150;
  --amber-9: 24 119 210; --amber-10: 63 165 255; --amber-11: 130 190 255; --amber-12: 200 224 255;
  --solid-amber: 24 119 210;
  background-color: #0f1f33 !important;
}
/* the solid blue Add Note button keeps white text in both modes */
.reply-box.is-private [class~="bg-n-amber-9"],
.reply-box.is-private [class~="bg-n-amber-9"] * ,
.reply-box.is-private [class~="bg-n-amber-10"],
.reply-box.is-private [class~="bg-n-amber-10"] * { color: #ffffff !important; }
/* private-note message bubble -> blue (it sits outside the composer).
   #1877d2 rather than the lighter #1f93ff it started as: white on the lighter
   blue measured 3.15:1, which is under the 4.5 body text needs. This reads the
   same at a glance and measures 5.1. */
[class~="bg-n-solid-amber"][class~="right-bubble"] { background-color: #1877d2 !important; }
[class~="bg-n-solid-amber"][class~="right-bubble"],
[class~="bg-n-solid-amber"][class~="right-bubble"] * { color: #ffffff !important; }

/* --------------------------------------------------------------------------
   8. PRIMARY BUTTON HOVER -> brand blue #2254f2
   Base stays lime #d4fb08 in both modes; hovering any primary (lime-filled)
   button turns it blue with white text. Placed last so these rules win the
   !important tie against the legibility layer above on the same specificity.
   Message bubbles (right-bubble) are excluded - they are not buttons.
   -------------------------------------------------------------------------- */
:is(button, a, [role="button"]):is(
  [class~="bg-n-brand"],
  [class~="bg-n-solid-iris"],
  [class~="bg-n-solid-iris/90"],
  [class~="hover:bg-n-brand"],
  [class~="hover:bg-n-solid-iris"]
):not(:disabled):not([class~="right-bubble"]):hover,
.dark :is(button, a, [role="button"]):is(
  [class~="bg-n-brand"],
  [class~="bg-n-solid-iris"],
  [class~="bg-n-solid-iris/90"],
  [class~="hover:bg-n-brand"],
  [class~="hover:bg-n-solid-iris"]
):not(:disabled):not([class~="right-bubble"]):hover {
  background-color: #2254f2 !important;
  color: #ffffff !important;
}

:is(button, a, [role="button"]):is(
  [class~="bg-n-brand"],
  [class~="bg-n-solid-iris"],
  [class~="bg-n-solid-iris/90"],
  [class~="hover:bg-n-brand"],
  [class~="hover:bg-n-solid-iris"]
):not(:disabled):not([class~="right-bubble"]):hover :is(span, svg, b, small, p, div),
.dark :is(button, a, [role="button"]):is(
  [class~="bg-n-brand"],
  [class~="bg-n-solid-iris"],
  [class~="bg-n-solid-iris/90"],
  [class~="hover:bg-n-brand"],
  [class~="hover:bg-n-solid-iris"]
):not(:disabled):not([class~="right-bubble"]):hover :is(span, svg, b, small, p, div) {
  color: #ffffff !important;
  opacity: 1 !important;
}


/* --------------------------------------------------------------------------
   8c. CALENDAR - today's date badge only
   The app writes the date inside the filled brand circle in white, which is
   unreadable on lime. Nothing else here: an earlier attempt also restyled the
   brand-tinted CONTAINERS and put lime rings around every cell of the date
   picker and every dropdown search box across the app.
   -------------------------------------------------------------------------- */
span[class~="bg-n-brand"][class~="rounded-full"][class~="w-7"],
.dark span[class~="bg-n-brand"][class~="rounded-full"][class~="w-7"] {
  color: #1d1b1c !important;
}

/* --------------------------------------------------------------------------
   8d. OVERVIEW, EMBEDDED
   With its stand-in sidebar suppressed the page is a single column inside the
   CRM+ frame, so the shell must not keep reserving the width that sidebar had.
   -------------------------------------------------------------------------- */
.ov-embedded .ov-shell { grid-template-columns: 1fr !important; display: block !important; }
.ov-embedded .ov-main  { margin-inline-start: 0 !important; width: 100% !important; }
.ov-embedded .ov-backdrop { display: none !important; }

/* --------------------------------------------------------------------------
   9. SIDEBAR ROWS - the Overview page's look, applied to the REAL sidebar
   Values lifted from overview.css so the platform matches the design that
   page used: 39px rows, a 12px gap, a 9px radius, a plain icon with no tile,
   and a quiet neutral hover instead of a brand tint.

   Scoped to div[role="button"] - the same anchor the rest of this file uses.
   Deliberately NOT keyed on "a row without children": collapsed groups have no
   children in the DOM either, and keying layout on that once broke every row
   in the sidebar.
   -------------------------------------------------------------------------- */
aside nav ul li > div > div[role="button"] {
  min-height: 39px !important;
  height: auto !important;
  gap: 12px !important;
  border-radius: 9px !important;
  padding-inline: 12px !important;
  font-weight: 500 !important;
}

/* The icon loses its tile and sits as a plain glyph, as it did on that page. */
aside nav ul li > div > div[role="button"] > div.relative,
.dark aside nav ul li > div > div[role="button"] > div.relative {
  width: 20px !important;
  height: 20px !important;
  border-radius: 0 !important;
  background-color: transparent !important;
}

/* Quiet hover, not a brand wash. */
aside nav ul li > div > div[role="button"]:hover {
  background-color: #f5f7fa !important;
}

.dark aside nav ul li > div > div[role="button"]:hover {
  background-color: rgba(255, 255, 255, .06) !important;
}

/* The active row keeps the brand pill, but at the new radius. */
aside nav ul li:not(:has(> ul.sidebar-group-children)) > div > div[role="button"]:is(
  [class~="text-n-brand"], [class~="bg-n-brand"], [class~="active"]
) {
  border-radius: 9px !important;
}

/* Counters: the brand lime with black digits, in both modes.
 *
 * These were muted grey chips, copied from the reference page. That was
 * overruled - the count is the one thing on the row worth looking for, and a
 * grey chip on a grey row hides it. The dark rule below carried a `.dark` of
 * its own, which outranks the plain lime rule in comments-list.css no matter
 * which file loads last, so dark mode kept the grey long after light mode had
 * stopped: this is where the two have to agree.
 */
aside nav span[class*="rounded"][class*="text-"]:not([style]),
.dark aside nav span[class*="rounded"][class*="text-"]:not([style]) {
  min-width: 21px !important;
  height: 21px !important;
  border-radius: 999px !important;
  background-color: #d4fb08 !important;
  color: #1d1b1c !important;
  font-weight: 600 !important;
}

/* On the active lime row the chip inverts so it stays legible. */
aside nav ul li > div > div[role="button"]:is(
  [class~="text-n-brand"], [class~="bg-n-brand"], [class~="active"]
) span[class*="rounded"] {
  background-color: rgba(29, 27, 28, .16) !important;
  color: #1d1b1c !important;
}

/* Sub-rows follow the same rhythm. */
ul.sidebar-group-children li.child-item {
  border-radius: 9px !important;
}

/* ==========================================================================
   10. SIDEBAR - the Overview design, applied to the real sidebar
   Every value below is lifted from overview.css so the platform's own sidebar
   matches that page rather than approximating it:

     rail      #fff, flush, 1px #e7eaf0 hairline, 14px 12px 12px padding
     brand     44px tile, 14px radius, lime, dark glyph
     workspace 56px bordered card, 11px radius
     rows      39px, 12px gap, 9px radius, weight 500, plain 18px glyph
     active    linear-gradient(100deg, #d4fb08, #e8ff6b) with #171b20 text
     hover     #f5f7fa
     counters  21px chip, 10px radius, #f0f2f6 on #475467

   Scoped to the same anchors the rest of this file uses (aside section,
   div[role="button"]). Nothing keys off "a row without children" - collapsed
   groups look identical to leaves in the DOM, and that mistake once flattened
   every row in the sidebar.
   ========================================================================== */

/* ---- rail: flush and white, not a floating card ---- */
aside.bg-n-solid-2 {
  background-color: #ffffff !important;
  border-color: #e7eaf0 !important;
  padding: 14px 12px 12px !important;
}

@media (min-width: 768px) {
  aside.bg-n-solid-2 {
    margin: 0 !important;
    height: 100vh !important;
    border-radius: 0 !important;
    border: 0 !important;
    border-right: 1px solid #e7eaf0 !important;
  }
}

.dark aside.bg-n-solid-2 {
  background-color: #16191f !important;
  border-color: rgba(255, 255, 255, .07) !important;
}

@media (min-width: 768px) {
  .dark aside.bg-n-solid-2 {
    border: 0 !important;
    border-right: 1px solid rgba(255, 255, 255, .07) !important;
  }
}

/* ---- the header block, on the platform's own proportions ----
   Measured against Chatwoot: a 24px tile holding a 16px mark, a 1px divider,
   and the account name on a 28px line - 64px for the block. This had grown to
   a 44px tile beside a 56px bordered card, 103px in all, which is why the top
   of the rail sat so much heavier than the rows under it and read as a
   different design from the rest of the product. The lime is ours and stays;
   the sizes are the platform's again. */
aside section div[class*="size-9"] {
  width: 24px !important;
  height: 24px !important;
  border-radius: 50% !important;
  background-color: #d4fb08 !important;
  outline: 0 !important;
}

aside section div[class*="size-9"] > img,
aside section div[class*="size-9"] > svg {
  width: 16px !important;
  height: 16px !important;
}

/* A name on a line, not a card. The border and the white fill were what made
   it look bolted on. */
#sidebar-account-switcher {
  height: 28px !important;
  min-height: 28px !important;
  border: 0 !important;
  border-radius: 8px !important;
  background-color: transparent !important;
  padding: 4px 8px !important;
  gap: 8px !important;
}

#sidebar-account-switcher:hover {
  background-color: #f5f7fa !important;
}

.dark #sidebar-account-switcher {
  border: 0 !important;
  background-color: transparent !important;
}

.dark #sidebar-account-switcher:hover {
  background-color: rgba(255, 255, 255, .06) !important;
}

/* ---- search field ----
   Size only. The fill and the border live in the one block further up that
   also styles the compose button beside it - the two are drawn as a pair, and
   splitting their colours across two places is how this file ended up with a
   44px logo that a rule 350 lines earlier politely asked to be 24. */
aside section a[href*="/search"] {
  height: 28px !important;
  border-radius: 8px !important;
  padding-inline: 8px !important;
}

/* ---- rows ---- */
aside nav ul li > div > div[role="button"] {
  color: #27324a !important;
}

.dark aside nav ul li > div > div[role="button"] {
  color: #cfd6e4 !important;
}

/* the glyph, muted and untiled */
aside nav ul li > div > div[role="button"] > div.relative {
  width: 18px !important;
  height: 18px !important;
  color: #667085 !important;
}

.dark aside nav ul li > div > div[role="button"] > div.relative {
  color: #98a2b3 !important;
}

/* ---- the active row ----

   This carried the Overview page's lime gradient. Section 9 states at length
   why that is now the faint film instead — the short version is that it can
   only ever land on a row with no children, which at the top level is Overview
   and Flow+ and nothing else, so the rail gave two different answers to "where
   am I".

   It is restated HERE as well because this section comes later in the file and
   would otherwise win: `background` (shorthand) also beats a `background-color`
   set earlier, so editing section 9 alone changed nothing visible. That is
   exactly what happened on the first attempt — the measured background-color
   changed while the gradient painted over it, and the row was left with dark
   ink on a dark film. One property, two rules, and only the shorthand counts.

   The label colour HAS to be restated, and that caught me out once: the
   DB-injected theme carries its own copy of this rule, fill AND ink together.
   Overriding only the fill from here left its `color: #1d1b1c` in place — dark
   ink on a dark film, 1.21:1, a row you could no longer read. Whenever a rule
   exists in two places, changing half of it produces something worse than
   either version. */
aside nav ul li:not(:has(> ul.sidebar-group-children)) > div > div[role="button"]:is(
  [class~="text-n-brand"], [class~="bg-n-brand"], [class~="active"]
) {
  background: rgba(29, 27, 28, .06) !important;
  color: var(--rail-row-on, #1d1b1c) !important;
  font-weight: 600 !important;
  box-shadow: none !important;
}

.dark aside nav ul li:not(:has(> ul.sidebar-group-children)) > div > div[role="button"]:is(
  [class~="text-n-brand"], [class~="bg-n-brand"], [class~="active"]
) {
  background: rgba(255, 255, 255, .08) !important;
  color: #e6e9e2 !important;   /* the ink an active child row already uses */
}

/* ...and the label inside it. Setting the row's own colour is not enough: the
   DB-injected copy of this rule also inks every span/svg/div inside the row,
   at a higher specificity than inheritance. That is the second half of the
   same duplicated rule, and skipping it left the row's background fixed while
   the LABEL stayed dark — the fix looked applied by measurement and was still
   unreadable on screen. */
aside nav ul li:not(:has(> ul.sidebar-group-children)) > div > div[role="button"]:is(
  [class~="text-n-brand"], [class~="bg-n-brand"], [class~="active"]
) :is(span, svg, b, small, div) {
  color: #1d1b1c !important;
}

.dark aside nav ul li:not(:has(> ul.sidebar-group-children)) > div > div[role="button"]:is(
  [class~="text-n-brand"], [class~="bg-n-brand"], [class~="active"]
) :is(span, svg, b, small, div) {
  color: #e6e9e2 !important;
}

/* ...and the chip behind the icon, which is the THIRD copy of this rule, in
   the DB-injected theme. A darker square behind the glyph was how the icon
   held its own against a bright lime plate. With the plate gone it is just a
   grey box sitting around the icon for no reason. */
aside nav ul li:not(:has(> ul.sidebar-group-children)) > div > div[role="button"]:is(
  [class~="text-n-brand"], [class~="bg-n-brand"], [class~="active"]
) > div.relative {
  background-color: transparent !important;
}

/* ---- sub-rows ---- */
ul.sidebar-group-children li.child-item:hover {
  background-color: #f5f7fa !important;
}

.dark ul.sidebar-group-children li.child-item:hover {
  background-color: rgba(255, 255, 255, .06) !important;
}

/* The compose button beside the search box.
   brand-recolor grows the search field to 39px; the button was left at
   Chatwoot's own 28px, so the row read as two unrelated controls. Squared to
   the field's height — 39px tall and only 32 wide looked stretched, and a
   square with the same corner as the field reads as part of the same row.

   The corner radius is set once, on the button's own rule above, rather than
   fought over from here. */
aside section a[href*="/search"] + span,
aside section a[href*="/search"] + span > *,
aside section a[href*="/search"] + span button {
  flex: 0 0 32px !important;
  width: 32px !important;
  min-width: 32px !important;
  height: 28px !important;
  min-height: 28px !important;
}

/* --------------------------------------------------------------------------
   The colour picker must not be cut off by the dialog it opens in.

   The picker (vue-color's `.vc-chrome`) is 239px tall and opens BELOW its
   swatch, absolutely positioned inside the dialog body. That body scrolls
   (`overflow-auto`) so long forms fit, and an overflow clip cannot be escaped
   by z-index — so on the Add label dialog the picker was sliced at 665px: the
   saturation square survived, the hue slider and the hex field did not. The
   colour was still pickable by dragging blind, which is why it reads as a
   glitch rather than a missing control.

   The clip is relaxed only while a picker is actually open. `.vc-chrome` is
   created and destroyed with it, so `:has()` turns this rule off again the
   moment the picker closes and the dialog goes back to scrolling normally.
   That matters: a tall form still needs its scrollbar.

   Written here, not in conversations.css, because pickers appear across the
   whole app — labels, teams, inbox settings, campaigns — and this file is the
   one loaded on every page.
   -------------------------------------------------------------------------- */
:is([class*="overflow-auto"], [class*="overflow-y-auto"]):has(.vc-chrome) {
  overflow: visible !important;
}

/* --------------------------------------------------------------------------
   Channel icons carry their platform's colour.

   Chatwoot ships them as CSS masks whose fill follows `currentColor`. The
   channels that have an official mark get that mark (see the block below);
   the tints here cover the rest — X, Gmail, Outlook — and stay as the fallback
   for anything the logo swap deliberately leaves alone.

   Every value below clears 3:1 against BOTH grounds (white, and the #1b1e23
   card in dark), which is the contrast floor for a non-text UI element. Where
   one value could not clear both, the mode gets its own — always another
   official colour from the same brand, never an invented one:

     WhatsApp  #128C7E / #25D366   (2.0:1 on white ruled the bright green out)
     Telegram  #1B7FAE / #229ED9
     LINE      #059748 / #06C755
     X         #0F1419 / #E7E9EA   (a black mark cannot work in both)

   Generic channels — website, e-mail, voice, api — keep the neutral ink on
   purpose: there is no brand to point at, and colouring them would say there
   is. Captain is not a channel and is left alone too.
   -------------------------------------------------------------------------- */
/* The `:where(:not(...))` guard: the SAME icon is also used to report an
   inbox's connection state, where Chatwoot colours it with `text-red-700` or
   `text-green-700`. A brand tint there would paint over a warning — a
   disconnected WhatsApp inbox would look exactly like a healthy one. State
   always outranks branding, so any icon already carrying a state colour is
   left alone. `:where()` contributes no specificity, so these stay at a single
   class and do not start an arms race with the sidebar's own colour rules. */
.i-woot-whatsapp:where(:not([class*="text-red"], [class*="text-green"], [class*="text-amber"], [class*="text-ruby"]))  { color: #128C7E !important; }
.i-woot-messenger:where(:not([class*="text-red"], [class*="text-green"], [class*="text-amber"], [class*="text-ruby"])) { color: #0084FF !important; }
.i-woot-instagram:where(:not([class*="text-red"], [class*="text-green"], [class*="text-amber"], [class*="text-ruby"])) { color: #E1306C !important; }
.i-woot-telegram:where(:not([class*="text-red"], [class*="text-green"], [class*="text-amber"], [class*="text-ruby"]))  { color: #1B7FAE !important; }
.i-woot-line:where(:not([class*="text-red"], [class*="text-green"], [class*="text-amber"], [class*="text-ruby"]))      { color: #059748 !important; }
.i-woot-tiktok:where(:not([class*="text-red"], [class*="text-green"], [class*="text-amber"], [class*="text-ruby"]))    { color: #FE2C55 !important; }
.i-woot-x:where(:not([class*="text-red"], [class*="text-green"], [class*="text-amber"], [class*="text-ruby"]))         { color: #0F1419 !important; }
.i-woot-gmail:where(:not([class*="text-red"], [class*="text-green"], [class*="text-amber"], [class*="text-ruby"]))     { color: #EA4335 !important; }
.i-woot-outlook:where(:not([class*="text-red"], [class*="text-green"], [class*="text-amber"], [class*="text-ruby"]))   { color: #0078D4 !important; }
.i-woot-sms:where(:not([class*="text-red"], [class*="text-green"], [class*="text-amber"], [class*="text-ruby"])):where(:not(aside, aside *)),
.i-woot-twilio:where(:not([class*="text-red"], [class*="text-green"], [class*="text-amber"], [class*="text-ruby"]))    { color: #F22F46 !important; }

.dark .i-woot-whatsapp:where(:not([class*="text-red"], [class*="text-green"])) { color: #25D366 !important; }
.dark .i-woot-telegram:where(:not([class*="text-red"], [class*="text-green"])) { color: #229ED9 !important; }
.dark .i-woot-line:where(:not([class*="text-red"], [class*="text-green"]))     { color: #06C755 !important; }
.dark .i-woot-x:where(:not([class*="text-red"], [class*="text-green"]))        { color: #E7E9EA !important; }

/* On a filled brand surface the icon is part of the button's label, not a
   channel marker — it goes back to inheriting the button's ink. */
[class~="bg-n-brand"] [class*="i-woot-"],
.dark [class~="bg-n-brand"] [class*="i-woot-"] {
  color: inherit !important;
}

/* --------------------------------------------------------------------------
   The real platform logos.

   These are Chatwoot's OWN shipped artwork — `public/integrations/channels/
   badges/*.png`, the same official marks the "Add inbox" screen uses. Nothing
   is redrawn here: hand-cut SVG copies of someone else's logo go subtly wrong
   (proportions, the exact Instagram gradient, Meta's blue) and every brand's
   guidelines forbid exactly that. Pointing at the shipped art also means a
   platform rebrand arrives with the next build instead of needing a redraw.

   The icons are masks, so three things have to change together: the mask goes
   away, the currentColor fill that painted it is cleared — otherwise it stays
   as a solid square behind the logo — and the artwork comes in as a background.
   The 40px source drawn into a 16px box is a 2.5x density, so it stays crisp.

   Left on the tinted glyph on purpose:
     X       - the only badge shipped is the old Twitter bird; showing a
               retired logo is worse than showing the correct monochrome mark.
     Gmail,
     Outlook - no badge ships for them at all.
   -------------------------------------------------------------------------- */
.i-woot-whatsapp:where(:not([class*="text-red"], [class*="text-green"], [class*="text-amber"], [class*="text-ruby"])):where(:not(aside, aside *)),
.i-woot-messenger:where(:not([class*="text-red"], [class*="text-green"], [class*="text-amber"], [class*="text-ruby"])):where(:not(aside, aside *)),
.i-woot-telegram:where(:not([class*="text-red"], [class*="text-green"], [class*="text-amber"], [class*="text-ruby"])):where(:not(aside, aside *)),
.i-woot-instagram:where(:not([class*="text-red"], [class*="text-green"], [class*="text-amber"], [class*="text-ruby"])):where(:not(aside, aside *)),
.i-woot-line:where(:not([class*="text-red"], [class*="text-green"], [class*="text-amber"], [class*="text-ruby"])):where(:not(aside, aside *)),
.i-woot-tiktok:where(:not([class*="text-red"], [class*="text-green"], [class*="text-amber"], [class*="text-ruby"])):where(:not(aside, aside *)),
.i-woot-sms:where(:not([class*="text-red"], [class*="text-green"], [class*="text-amber"], [class*="text-ruby"])):where(:not(aside, aside *)),
.i-woot-twilio:where(:not([class*="text-red"], [class*="text-green"], [class*="text-amber"], [class*="text-ruby"])):where(:not(aside, aside *)) {
  -webkit-mask-image: none !important;
          mask-image: none !important;
  background-color: transparent !important;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
}

.i-woot-whatsapp:where(:not([class*="text-red"], [class*="text-green"])):where(:not(aside, aside *))  { background-image: url("/integrations/channels/badges/whatsapp.png") !important; }
.i-woot-messenger:where(:not([class*="text-red"], [class*="text-green"])):where(:not(aside, aside *)) { background-image: url("/integrations/channels/badges/messenger.png") !important; }
.i-woot-telegram:where(:not([class*="text-red"], [class*="text-green"])):where(:not(aside, aside *))  { background-image: url("/integrations/channels/badges/telegram.png") !important; }
.i-woot-instagram:where(:not([class*="text-red"], [class*="text-green"])):where(:not(aside, aside *)) { background-image: url("/integrations/channels/badges/instagram-dm.png") !important; }
.i-woot-line:where(:not([class*="text-red"], [class*="text-green"])):where(:not(aside, aside *))      { background-image: url("/integrations/channels/badges/line.png") !important; }
.i-woot-tiktok:where(:not([class*="text-red"], [class*="text-green"])):where(:not(aside, aside *))    { background-image: url("/integrations/channels/badges/tiktok.png") !important; }
.i-woot-sms:where(:not([class*="text-red"], [class*="text-green"])):where(:not(aside, aside *)),
.i-woot-twilio:where(:not([class*="text-red"], [class*="text-green"])):where(:not(aside, aside *))    { background-image: url("/integrations/channels/badges/sms.png") !important; }

/* Why the sidebar is excluded outright.

   Its inbox rows use the same icon to report CONNECTION STATE - Chatwoot
   colours it `text-red-700` when the inbox is down and `text-green-700` when
   it is healthy. A full-colour logo paints straight over that, so a dead
   WhatsApp inbox would look identical to a working one.

   Excluding only the rows that carry a state class was tried first and looked
   worse than either option: the one inbox with no state to report got a bright
   logo while its neighbours stayed grey, which reads as "this one is special"
   rather than "this one has nothing to report". So the whole sidebar keeps the
   glyph. It answers "is this inbox healthy"; the conversation list answers
   "which platform is this". Two questions, two treatments, each consistent
   within itself.

   The `:not([class*="text-red"]...)` guard is kept as well, for the same icon
   wherever else a state colour is used outside the sidebar. */

/* --------------------------------------------------------------------------
   Hover links: readable in day mode.

   Chatwoot marks a hoverable name with `hover:text-n-brand`, which resolves to
   whatever --brand-color is. Its own default is a teal that reads fine on
   white. Ours is #d4fb08, and lime text on a white row measures 1.17:1 — the
   name effectively disappears at the exact moment you point at it. Every
   `hover:text-n-brand` on a light surface has this, not just the Meta
   templates list where it was noticed.

   Day mode therefore answers with ink and weight instead of hue. Weight is the
   part that actually registers: the colour barely moves, the jump from 500 to
   700 is what the eye catches, and it still works for someone who cannot
   separate lime from white. Chatwoot's own underline is left alone.

   Dark mode keeps the lime — on a dark row it measures about 11:1, so there
   the brand colour is doing its job and there is nothing to fix.
   -------------------------------------------------------------------------- */
[class*="hover:text-n-brand"]:hover {
  color: #000000 !important;
  font-weight: 700;
}

.dark [class*="hover:text-n-brand"]:hover {
  color: #d4fb08 !important;
  font-weight: 700;
}

/* The Contacts page's "Download CSV" button (contacts-export.js). Shaped like
   the page's own secondary controls rather than the lime primary: exporting is
   not the main action on that screen. */
button.crm-contacts-export {
  height: 32px;
  padding: 0 12px;
  margin-inline-end: 8px;
  border: 1px solid var(--border-weak, #dfe3da);
  border-radius: 8px;
  background: transparent;
  color: #1d1b1c;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background-color .15s ease;
}

button.crm-contacts-export:hover:not(:disabled) {
  background: rgba(29, 27, 28, .06);
}

.dark button.crm-contacts-export {
  border-color: rgba(255, 255, 255, .16);
  color: #e6e9e2;
}

.dark button.crm-contacts-export:hover:not(:disabled) {
  background: rgba(255, 255, 255, .08);
}

/* The Agents field injected into the Custom Role dialog (role-permissions.js).
   Shaped to sit with Name and Description rather than to stand out: the same
   height, radius and resting fill as the dialog's own inputs. */
.crm-agents-field { position: relative; margin-top: 14px; }

.crm-agents-caption {
  display: block;
  margin-bottom: 6px;
  font-size: 14px;
  color: #1d1b1c;
}

.crm-agents-toggle {
  width: 100%;
  min-height: 40px;
  padding: 8px 12px;
  border: 1px solid var(--border-weak, #dfe3da);
  border-radius: 12px;
  background: var(--n-solid-2, #f8f9fa);
  color: #1d1b1c;
  font-size: 14px;
  text-align: start;
  cursor: pointer;
}

.crm-agents-toggle.is-empty { color: #687078; }
.crm-agents-toggle:disabled { cursor: default; color: #687078; }

.crm-agents-panel {
  position: absolute;
  z-index: 60;
  inset-inline: 0;
  margin-top: 4px;
  max-height: 220px;
  overflow-y: auto;
  padding: 6px;
  border: 1px solid var(--border-weak, #dfe3da);
  border-radius: 12px;
  background: #ffffff;
  box-shadow: 0 12px 30px rgba(16, 24, 40, .14);
}

.crm-agents-option {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-radius: 8px;
  font-size: 14px;
  color: #1d1b1c;
  cursor: pointer;
}

.crm-agents-option:hover { background: rgba(29, 27, 28, .06); }

.dark .crm-agents-caption,
.dark .crm-agents-toggle,
.dark .crm-agents-option { color: #e6e9e2; }

.dark .crm-agents-toggle {
  background: rgba(255, 255, 255, .06);
  border-color: rgba(255, 255, 255, .16);
}

.dark .crm-agents-panel {
  background: #1b1e23;
  border-color: rgba(255, 255, 255, .16);
}

.dark .crm-agents-option:hover { background: rgba(255, 255, 255, .08); }

/* --------------------------------------------------------------------------
   Roles and permissions panel (role-manager.js).
   Built from the same pieces the settings pages use — a card on the page's
   ground, a two-column grid of permission groups — so it reads as part of the
   platform rather than as something bolted on.
   -------------------------------------------------------------------------- */
.crm-rm {
  width: 100%;
  margin-top: 18px;
  padding: 20px;
  border: 1px solid var(--border-weak, #dfe3da);
  border-radius: 14px;
  background: #ffffff;
}

/* Its second home is under the agent list, where the section has to name
   itself - on the Custom Roles page the page's own heading did that job. */
.crm-rm-band {
  width: 100%;
  margin-top: 30px;
  padding-top: 22px;
  border-top: 1px solid var(--border-weak, #dfe3da);
}

.crm-rm-title { margin: 0 0 4px; font-size: 16px; font-weight: 700; color: #1d1b1c; }
.crm-rm-sub   { margin: 0 0 16px; font-size: 13px; color: #687078; line-height: 1.6; }

.crm-rm-bar { display: flex; gap: 10px; align-items: center; margin-bottom: 16px; }

.crm-rm-picker {
  flex: 0 1 280px;
  height: 38px;
  padding: 0 10px;
  border: 1px solid var(--border-weak, #dfe3da);
  border-radius: 10px;
  background: #ffffff;
  color: #1d1b1c;
  font-size: 14px;
}

.crm-rm-delete {
  height: 38px;
  padding: 0 12px;
  border: 1px solid rgba(206, 44, 49, .35);
  border-radius: 10px;
  background: transparent;
  color: #ce2c31;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.crm-rm-field { margin-bottom: 16px; }
.crm-rm-label { display: block; margin-bottom: 6px; font-size: 14px; color: #1d1b1c; }

.crm-rm-input {
  width: 100%;
  min-height: 40px;
  padding: 8px 12px;
  border: 1px solid var(--border-weak, #dfe3da);
  border-radius: 12px;
  background: #f8f9fa;
  color: #1d1b1c;
  font-size: 14px;
}

.crm-rm-agents,
.crm-rm-card {
  padding: 10px;
  border: 1px solid var(--border-weak, #dfe3da);
  border-radius: 12px;
  background: #fbfbfa;
}

/* Permission cards: two fixed columns, one when the panel is narrow. Sized by
   the panel (container query), not the window - the panel sits in a settings
   column far narrower than the screen. */
/* The query needs a container ABOVE the grid: a container cannot query itself. */
.crm-rm-perms { container-type: inline-size; }
.crm-rm-grid { display: flex; flex-direction: column; gap: 14px; }
@container (min-width: 700px) { .crm-rm-grid { flex-direction: row; align-items: flex-start; } }
.crm-rm-col { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 14px; }

.crm-rm-can { font-size: 18px; font-weight: 700; }
.crm-rm-can-sub { margin: -2px 0 12px; font-size: 13px; color: #687078; }

.crm-rm-card { padding: 16px 16px 10px; border-color: #e6e8ec; border-radius: 14px; background: #ffffff; box-shadow: none; }
.crm-rm-card-head { display: flex; align-items: flex-start; gap: 12px; margin-bottom: 10px; }
.crm-rm-card-icon { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; width: 38px; height: 38px; border-radius: 10px; font-size: 17px; line-height: 1; }
.crm-rm-card-icon i { display: inline-flex; }
.crm-rm-card-icon.is-blue { background: #eaf0ff; color: #2f5bd3; }
.crm-rm-card-icon.is-green { background: #eaf7e6; color: #3c8a1f; }
.crm-rm-card-icon.is-purple { background: #f3ecff; color: #7a3fd6; }
.crm-rm-card-words { min-width: 0; }
.crm-rm-card h3 { margin: 1px 0 2px; font-size: 15px; font-weight: 700; color: #1d1b1c; }
.crm-rm-card-words p { margin: 0; font-size: 12.5px; color: #687078; }
.dark .crm-rm-card-icon.is-blue { background: rgba(47, 91, 211, .22); color: #9db6ff; }
.dark .crm-rm-card-icon.is-green { background: rgba(60, 138, 31, .22); color: #a8e08f; }
.dark .crm-rm-card-icon.is-purple { background: rgba(122, 63, 214, .24); color: #cdb3ff; }
.dark .crm-rm-card h3 { color: #e6e9e2; }
.dark .crm-rm-card-words p, .dark .crm-rm-can-sub { color: #98a1ad; }

.crm-rm-option {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 7px 6px;
  border-radius: 8px;
  font-size: 14px;
  color: #1d1b1c;
  cursor: pointer;
}

.crm-rm-option:hover { background: rgba(29, 27, 28, .05); }
.crm-rm-option input { margin-top: 2px; flex-shrink: 0; }
.crm-rm-empty { margin: 0; padding: 6px; font-size: 13px; color: #687078; }
/* An empty list is the section's own icon in a soft circle, one short line
   under it (owner, 2026-09-30). */
.crm-rm-none { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 64px 16px; color: #626f7f; font-size: 14px; }
.crm-rm-none p { margin: 0; }
.crm-rm-none__ic { display: grid; place-items: center; width: 64px; height: 64px; border-radius: 50%; background: #f5f6f7; color: #282e34; font-size: 28px; }
.crm-rm-none__ic > span { width: 1em; height: 1em; }
.dark .crm-rm-none { color: #9aa3af; }
.dark .crm-rm-none__ic { background: rgba(255, 255, 255, .06); color: #e8eaed; }
.crm-rm-titlerow > .crm-rm-new { flex: none; }

.crm-rm-actions { display: flex; align-items: center; gap: 12px; justify-content: flex-end; }
.crm-rm-status { font-size: 13px; color: #687078; }

.crm-rm-save {
  height: 38px;
  padding: 0 18px;
  border: 0;
  border-radius: 10px;
  background: #d4fb08;
  color: #1d1b1c;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}

.crm-rm-save:disabled { opacity: .6; cursor: progress; }

.dark .crm-rm { background: #1b1e23; border-color: rgba(255, 255, 255, .12); }
.dark .crm-rm-title, .dark .crm-rm-label, .dark .crm-rm-option { color: #e6e9e2; }
.dark .crm-rm-band { border-top-color: rgba(255, 255, 255, .12); }
.dark .crm-rm-input, .dark .crm-rm-picker {
  background: rgba(255, 255, 255, .06);
  border-color: rgba(255, 255, 255, .16);
  color: #e6e9e2;
}
.dark .crm-rm-agents, .dark .crm-rm-card {
  background: rgba(255, 255, 255, .04);
  border-color: rgba(255, 255, 255, .12);
}
.dark .crm-rm-option:hover { background: rgba(255, 255, 255, .08); }

/* Role list view (role-manager.js) */
.crm-rm-hidden { display: none !important; }

.crm-rm-back {
  display: inline-block;
  margin-bottom: 8px;
  padding: 0;
  border: 0;
  background: none;
  color: #687078;
  font-size: 13px;
  cursor: pointer;
}
.crm-rm-back:hover { color: #1d1b1c; }

.crm-rm-role {
  display: block;
  width: 100%;
  margin-bottom: 10px;
  padding: 14px;
  border: 1px solid var(--border-weak, #dfe3da);
  border-radius: 12px;
  background: #fbfbfa;
  text-align: start;
  cursor: pointer;
}
.crm-rm-role:hover { border-color: #b4d507; background: #fdfee9; }

.crm-rm-role-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.crm-rm-role-top strong { font-size: 15px; color: #1d1b1c; }
.crm-rm-count { font-size: 12px; color: #687078; }
.crm-rm-role-desc { margin: 4px 0 0; font-size: 13px; color: #687078; }

.crm-rm-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.crm-rm-chip {
  padding: 3px 8px;
  border-radius: 999px;
  background: rgba(29, 27, 28, .06);
  font-size: 11px;
  color: #1d1b1c;
}
.crm-rm-chip.is-muted { background: transparent; color: #687078; font-style: italic; }

/* The agent list on the roles screen: one person per row with the role they
   hold, so handing an existing role to someone is a dropdown rather than a
   trip through the role editor. */
.crm-rm-section {
  margin: 22px 0 10px;
  font-size: 12px;
  font-weight: 700;
  color: #687078;
}

.crm-rm-agent-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 6px;
}

.crm-rm-agent-row + .crm-rm-agent-row { border-top: 1px solid rgba(29, 27, 28, .07); }

.crm-rm-agent-who { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.crm-rm-agent-who strong { font-size: 14px; color: #1d1b1c; }
.crm-rm-agent-who span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.crm-rm-select {
  /* width stated outright: the platform styles bare `select` at width:100%,
     and with flex-shrink:0 the control kept all of it, overflowed the row and
     painted over the agent's name. */
  flex: 0 1 240px;
  width: 240px;
  max-width: 45%;
  min-width: 0;
  padding: 7px 10px;
  border: 1px solid rgba(29, 27, 28, .16);
  border-radius: 8px;
  background: #fff;
  font-size: 13px;
  color: #1d1b1c;
}

.crm-rm-select:disabled { opacity: .6; cursor: progress; }

.dark .crm-rm-section, .dark .crm-rm-agent-who span { color: #9aa4ad; }
.dark .crm-rm-agent-who strong { color: #e6e9e2; }
.dark .crm-rm-agent-row + .crm-rm-agent-row { border-top-color: rgba(255, 255, 255, .10); }
.dark .crm-rm-select {
  background: #23262c;
  border-color: rgba(255, 255, 255, .16);
  color: #e6e9e2;
}

/* "Who gets this role": a field that opens a searchable list, rather than a
   bare column of checkboxes that did not read as a field at all. */
.crm-rm-picker-wrap { position: relative; }

.crm-rm-multi {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  min-height: 40px;
  padding: 7px 12px;
  border: 1px solid rgba(29, 27, 28, .16);
  border-radius: 8px;
  background: #fff;
  text-align: start;
  cursor: pointer;
}

.crm-rm-multi:hover { border-color: #b4d507; }

.crm-rm-multi-chips { display: flex; flex-wrap: wrap; gap: 6px; flex: 1; min-width: 0; }
.crm-rm-multi-empty { font-size: 13px; color: #687078; }
.crm-rm-multi-caret { flex-shrink: 0; font-size: 11px; color: #687078; }

.crm-rm-menu {
  position: absolute;
  z-index: 30;
  inset-inline: 0;
  top: calc(100% + 4px);
  padding: 8px;
  border: 1px solid rgba(29, 27, 28, .14);
  border-radius: 10px;
  background: #fff;
  box-shadow: 0 12px 28px rgba(29, 27, 28, .14);
}

.crm-rm-menu-search { margin-bottom: 6px; }
.crm-rm-menu-list { max-height: 260px; overflow-y: auto; }

.dark .crm-rm-multi { background: #23262c; border-color: rgba(255, 255, 255, .16); }
.dark .crm-rm-menu {
  background: #23262c;
  border-color: rgba(255, 255, 255, .16);
  box-shadow: 0 12px 28px rgba(0, 0, 0, .45);
}
.dark .crm-rm-multi-empty, .dark .crm-rm-multi-caret { color: #9aa4ad; }

.crm-rm-cancel {
  height: 38px;
  padding: 0 14px;
  border: 1px solid var(--border-weak, #dfe3da);
  border-radius: 10px;
  background: transparent;
  color: #1d1b1c;
  font-size: 14px;
  cursor: pointer;
}

.dark .crm-rm-role { background: rgba(255, 255, 255, .04); border-color: rgba(255, 255, 255, .12); }
.dark .crm-rm-role:hover { background: rgba(212, 251, 8, .08); border-color: rgba(212, 251, 8, .42); }
.dark .crm-rm-role-top strong, .dark .crm-rm-chip, .dark .crm-rm-cancel { color: #e6e9e2; }
.dark .crm-rm-chip { background: rgba(255, 255, 255, .10); }
.dark .crm-rm-back:hover { color: #e6e9e2; }
.dark .crm-rm-cancel { border-color: rgba(255, 255, 255, .16); }

/* Per-page access level (role-manager.js) */
.crm-rm-perm {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 6px;
  border-radius: 8px;
}
.crm-rm-perm:hover { background: rgba(29, 27, 28, .04); }
.crm-rm-perm-name { font-size: 13.5px; color: #1d1b1c; }

.crm-rm-levels {
  display: inline-flex;
  flex-shrink: 0;
  gap: 6px;
}

/* Each level its own pill, as in the owner's design; the chosen one lime with
   black text (light mode rule), the others quiet. */
.crm-rm-level {
  min-width: 52px;
  padding: 4px 12px;
  border: 1px solid #e3e6ea;
  border-radius: 999px;
  background: #f5f6f8;
  color: #4b5563;
  font-size: 11.5px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}
.crm-rm-level:hover { border-color: #c9ced6; }
.crm-rm-level.is-on { border-color: #d4fb08; }

.crm-rm-level.is-on { background: #d4fb08; color: #1d1b1c; }

.dark .crm-rm-perm:hover { background: rgba(255, 255, 255, .06); }
.dark .crm-rm-perm-name { color: #e6e9e2; }
.dark .crm-rm-level { background: rgba(255, 255, 255, .05); border-color: rgba(255, 255, 255, .14); color: #98a1ad; }
.dark .crm-rm-level.is-on { background: #d4fb08; color: #1d1b1c; }


/* ---- top-level rows that have no sub-items ---- */
/* See the note in the deploy script: keyed to <a> because these rows are not
   div[role="button"], and appended once instead of edited into the three
   copies of the rules above. */
aside nav ul li:not(.child-item) > div > a {
  min-height: 39px !important;
  height: auto !important;
  gap: 12px !important;
  border-radius: 9px !important;
  padding-inline: 12px !important;
  font-weight: 500 !important;
  transition: background-color .16s ease, color .16s ease !important;
}

aside nav ul li:not(.child-item) > div > a:hover {
  background-color: #f5f7fa !important;
}

.dark aside nav ul li:not(.child-item) > div > a:hover {
  background-color: rgba(255, 255, 255, .06) !important;
}

/* the glyph sits plain and untiled, exactly as it does on every other row */
aside nav ul li:not(.child-item) > div > a > div.relative {
  width: 20px !important;
  height: 20px !important;
  border-radius: 0 !important;
  display: grid !important;
  place-items: center !important;
  flex: 0 0 auto !important;
  background-color: transparent !important;
}

/* label and glyph, both modes. The icon fonts paint with currentColor, so one
   colour covers the word and the picture. */
aside nav ul li:not(.child-item) > div > a { color: var(--rail-row, #1d1b1c) !important; }
aside nav ul li:not(.child-item) > div > a :is(span, svg, b, small, div) { color: inherit !important; }

.dark aside nav ul li:not(.child-item) > div > a { color: var(--rail-row, #e6e9e2) !important; }

/* active state, matching the faint film the other rows use rather than a lime
   plate — and the tile behind the glyph goes flat, same as theirs. */
aside nav ul li:not(.child-item) > div > a:is([class~="text-n-brand"], [class~="bg-n-brand"], [class~="active"], .router-link-active) {
  background: rgba(29, 27, 28, .06) !important;
  color: #1d1b1c !important;
  font-weight: 700 !important;
  border-radius: 9px !important;
  box-shadow: none !important;
}

.dark aside nav ul li:not(.child-item) > div > a:is([class~="text-n-brand"], [class~="bg-n-brand"], [class~="active"], .router-link-active) {
  background: rgba(255, 255, 255, .08) !important;
  color: var(--rail-row-on, #e6e9e2) !important;
}

aside nav ul li:not(.child-item) > div > a:is([class~="text-n-brand"], [class~="bg-n-brand"], [class~="active"], .router-link-active) > div.relative {
  background-color: transparent !important;
}

/* ==========================================================================
   Provider badges in Settings → Inboxes           [crm-provider-badge]

   The "WHATSAPP CLOUD" tag ships as green-700 on green-100 at 8px uppercase -
   3.12:1, the smallest text on the page and the hardest to read on it. The
   plate keeps its green; only the ink goes darker.
   ========================================================================== */
[class~="bg-green-100"][class~="text-green-700"],
[class~="bg-green-100"][class~="text-green-700"] * {
  color: #0b5132 !important;
}

/* ==========================================================================
   Pale-plate chips in the brand family              [crm-pale-chip-ink]

   The "Beta" chip on the Add Inbox cards ships as blue-11 text on a blue-2
   plate. This file maps the blue family onto the brand, so BOTH ends became
   lime: #d4fb08 on #f8fed6, which measured 1.14:1 - the word was there and
   nobody could read it. The plate keeps the tint; the ink goes to the near
   black used everywhere the brand colour is a background.
   ========================================================================== */
/* The two families behave differently and were measured, not assumed.
 *
 * The blue plates stay PALE in both themes - this file maps them onto a light
 * brand tint that never darkens - so their ink is forced in both. The teal
 * plates DO flip: the "Live" chip on the reports page is #f0f8c9 in light and
 * #2a2f0e in dark, so forcing black there swapped one unreadable label for
 * another, and it is corrected in light only. */
[class~="bg-n-blue-2"], [class~="bg-n-blue-2"] *,
[class~="bg-n-blue-3"], [class~="bg-n-blue-3"] * {
  color: #1d1b1c !important;
}

:root:not(.dark) [class~="bg-n-teal-2"], :root:not(.dark) [class~="bg-n-teal-2"] *,
:root:not(.dark) [class~="bg-n-teal-3"], :root:not(.dark) [class~="bg-n-teal-3"] * {
  color: #1d1b1c !important;
}

/* ==========================================================================
   Destructive text links                            [crm-ruby-text-ink]

   "Delete now" and its siblings use ruby-9, which is #e54666 - 3.82:1 on a
   white page. A label that destroys a record is the last one that should be
   hard to read, so it goes one step deeper on light backgrounds. Dark mode
   keeps the lighter ruby, where it already measures well against the panel.
   ========================================================================== */
:root:not(.dark) [class~="text-n-ruby-9"],
:root:not(.dark) [class~="text-n-ruby-9"] * {
  color: #c8203f !important;
}

/* --------------------------------------------------------------------------
   Sidebar groups and the Deals row (crm-nav.js).
   The rail was eleven rows in declaration order with nothing saying which
   belonged together, and no way at all into the pipeline board.
   -------------------------------------------------------------------------- */
.crm-nav-head {
  list-style: none;
  margin: 12px 0 2px;
  padding: 0;
  user-select: none;
}

/* A group is a row you can act on, not a caption. It reads at the same weight
   as the rows under it, which is what makes the rail feel filed rather than
   listed. */
.crm-nav-headrow {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  border: 0;
  background: transparent;
  border-radius: 8px;
  padding: 5px 8px;
  cursor: pointer;
  color: inherit;
  text-align: start;
}

.crm-nav-headrow:hover { background: var(--n-alpha-2, rgba(255, 255, 255, .05)); }

/* The group mark: a tinted tile with the group's own icon in it.
 *
 * Every heading used to carry the same folder glyph, which told the reader
 * nothing except that a group started - seven identical marks down the rail.
 * Each group now wears its own Flaticon UIcon on its own colour, so a heading
 * can be found by its mark rather than by reading down the list.
 *
 * The tint is written twice per group, as the ink and as a weak wash behind
 * it, rather than derived with color-mix(): that function is too new to be
 * safe on whatever a customer happens to be using, and the wash is faint
 * enough to sit under both the light and the dark palette unchanged. */
.crm-nav-folder {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 7px;
  flex-shrink: 0;
  color: #7c8cf8;
  background: rgba(124, 140, 248, .15);
}

.crm-nav-folder > i {
  font-size: 12px;
  line-height: 1;
  display: block;
}

/* Light mode is the base, as everywhere else in this estate.
 *
 * The inks here are darker than the tints behind them, and they were measured
 * rather than picked: an icon is a non-text graphic, which wants 3:1 against
 * what it sits on. The bright versions used in dark mode scored 1.97 to 2.84
 * over their own pale tiles on white - all seven would have failed, which is
 * the same mistake that once left this whole installation looking faded. */
[data-crm-nav="head-workspace"] .crm-nav-folder { color: #7a7bdb; background: rgba(139, 140, 249, .15); }
[data-crm-nav="head-inbox"]     .crm-nav-folder { color: #2f89ce; background: rgba(56, 163, 245, .15); }
[data-crm-nav="head-crm"]       .crm-nav-folder { color: #149659; background: rgba(24, 178, 106, .15); }
[data-crm-nav="head-marketing"] .crm-nav-folder { color: #bb7324; background: rgba(240, 147, 46, .15); }
[data-crm-nav="head-insight"]   .crm-nav-folder { color: #10939d; background: rgba(20, 184, 196, .15); }
[data-crm-nav="head-support"]   .crm-nav-folder { color: #b25cd5; background: rgba(194, 100, 232, .15); }
[data-crm-nav="head-setup"]     .crm-nav-folder { color: #7a828f; background: rgba(139, 148, 163, .18); }

/* On the dark rail the tile is nearly black, so the ink goes back up to the
   full colour - measured at 4.5 to 6.0 against it. */
:root.dark [data-crm-nav="head-workspace"] .crm-nav-folder,
.dark [data-crm-nav="head-workspace"] .crm-nav-folder { color: #8b8cf9; }
:root.dark [data-crm-nav="head-inbox"] .crm-nav-folder,
.dark [data-crm-nav="head-inbox"] .crm-nav-folder { color: #38a3f5; }
:root.dark [data-crm-nav="head-crm"] .crm-nav-folder,
.dark [data-crm-nav="head-crm"] .crm-nav-folder { color: #18b26a; }
:root.dark [data-crm-nav="head-marketing"] .crm-nav-folder,
.dark [data-crm-nav="head-marketing"] .crm-nav-folder { color: #f0932e; }
:root.dark [data-crm-nav="head-insight"] .crm-nav-folder,
.dark [data-crm-nav="head-insight"] .crm-nav-folder { color: #14b8c4; }
:root.dark [data-crm-nav="head-support"] .crm-nav-folder,
.dark [data-crm-nav="head-support"] .crm-nav-folder { color: #c264e8; }
:root.dark [data-crm-nav="head-setup"] .crm-nav-folder,
.dark [data-crm-nav="head-setup"] .crm-nav-folder { color: #8b94a3; }

/* A folded group is a quieter thing; its mark follows the label down. */
.crm-nav-head.is-shut .crm-nav-folder { opacity: .72; }

.crm-nav-title {
  flex: 1;
  min-width: 0;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: .005em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.crm-nav-caret {
  font-size: 13px;
  line-height: 1;
  opacity: .5;
  transition: transform .15s ease;
  flex-shrink: 0;
}

.crm-nav-head.is-shut .crm-nav-caret { transform: rotate(180deg); }
.crm-nav-head.is-shut .crm-nav-title { opacity: .7; }

/* Indented under the heading it belongs to. */
.crm-nav-in { padding-inline-start: 10px; }
.crm-nav-folded { display: none !important; }

/* Collapsed there is no room for the word, so the group is announced by the
   rule alone rather than by a truncated label nobody can read. */
.crm-nav-head--bare {
  margin: 10px auto 4px;
  padding: 0;
  width: 22px;
  height: 1px;
  background: currentColor;
  opacity: .18;
}

/* Our row is an <a>, so it needs the hover and current-page states the
   platform's own <div role="button"> rows get from Vue. */
aside nav ul li[data-crm-nav="deals"] a { color: inherit; text-decoration: none; }
aside nav ul li[data-crm-nav="deals"] a:hover { background: var(--n-alpha-2, rgba(255, 255, 255, .06)); }

.crm-nav-here {
  background: var(--n-alpha-2, rgba(255, 255, 255, .08)) !important;
  color: var(--n-slate-12, #e6e9e2) !important;
  font-weight: 600;
}

/* ---- the sidebar's own edge ----------------------------------------------
   Three things wanted the same sliver of screen: the round collapse button,
   the drag-to-resize grip, and the sidebar's border. Measured, the button ran
   x=251..267 and the grip x=260..270 on a sidebar ending at 267 - overlapping
   each other by 7px and both hanging outside the panel, which is why the
   button read as floating over the page rather than belonging to the rail.
   Chatwoot itself has no collapse button at all and keeps its grip 4px wide,
   inside the panel. The grip follows that; the button is pulled back in.
   -------------------------------------------------------------------------- */
.crm-resize-grip {
  width: 4px !important;
  transform: translateX(-4px);
}

/* ---- the account menu belongs to the rail, not to the page ----------------
   The menu that opens off the avatar at the foot of the sidebar is a fixed
   20rem — 320px — while the rail it hangs from is 260px. It stood 76px out
   over the dashboard on every screen, and the grip above ran straight across
   it as a bright line, because the grip is z-index 60 against the menu's 50.

   The width is the awkward half. Chatwoot anchors the menu to an empty
   absolutely-positioned wrapper that is 0px wide, so `width: 100%` on the menu
   measured nothing at all; handing that wrapper back to normal flow makes the
   rail's own full-width column the thing the percentage is measured against.
   `:has()` rather than a positional selector so this can only ever reach the
   wrapper that holds the menu — the availability dot on the avatar is
   absolutely positioned too, a few nodes away.

   The 15rem floor is for the shut rail: at 64px there is no "inside" to fit
   into, and a 64px menu would be worse than one that hangs out. */
aside.bg-n-solid-2 > section:last-of-type div.absolute:has(> div[class*="bottom-12"]) {
  position: static !important;
}

aside.bg-n-solid-2 > section:last-of-type div[class*="bottom-12"][class*="z-50"] {
  width: max(15rem, 100%) !important;
  z-index: 70 !important; /* over .crm-resize-grip, which is 60 */
}

/* The round collapse button is gone.
   Chatwoot has no such control at all - its sidebar is resized by dragging the
   edge and nothing else - and ours was a circle floating half over the page,
   fighting the grip for the same few pixels. Hidden rather than deleted:
   sidebar-resize.js reads this element's class to know whether the rail is
   collapsed, so the drag still collapses and expands exactly as before. */
.sidebar-collapse-handle {
  display: none !important;
}

/* --------------------------------------------------------------------------
   The collapse button (sidebar-resize.js).

   Open, it lives at the end of the account row. Shut, the row is 64px of logo
   and there is nowhere to put it, so it takes the logo's place and appears
   only under the pointer - the logo fades out beneath it, and a small label
   says what pressing it will do.
   -------------------------------------------------------------------------- */
.crm-side-toggle {
  flex-shrink: 0;
  margin-inline-start: auto;
  display: grid;
  place-content: center;
  width: 28px;
  height: 28px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: #687078;
  cursor: pointer;
  padding: 0;
  transition: background-color .12s ease, color .12s ease, opacity .12s ease;
}

/* The icon is an <i> drawn 1em wide, so its size is the <i>'s font size;
   ".crm-ico > svg" outranks a width set on the svg alone. */
.crm-side-toggle svg { width: 20px; height: 20px; }
.crm-side-toggle > .fi { font-size: 20px; line-height: 0; }
.crm-side-toggle:hover { background: rgba(20, 26, 20, .09); color: #1d1b1c; }
.dark .crm-side-toggle { color: #a0a8b2; }
.dark .crm-side-toggle:hover { background: rgba(255, 255, 255, .12); color: #edefeb; }

/* ---- shut: the button stands where the logo was ---- */

/* ---- the mark, shut ----

   Open, the tile is 24px to match the platform's own header. Shut, that same
   24px sits in a 64px rail directly above the search and compose buttons,
   which are 32px wide - so the one thing that identifies the product was the
   smallest thing in the column. It takes their width here: a number the stack
   already uses, rather than a bigger one picked by eye. */
aside.crm-rail-shut section div[class*="size-9"] {
  width: 32px !important;
  height: 32px !important;
}

aside.crm-rail-shut section div[class*="size-9"] > img,
aside.crm-rail-shut section div[class*="size-9"] > svg {
  width: 21px !important;
  height: 21px !important;
}

/* The row shrinks to the mark when the rail closes - 39px wide inside a 64px
   rail, tight against the top corner. The button overflows it on both axes so
   the target is the full width of the rail and the height of a row. */
aside.crm-rail-shut section > div:first-child {
  position: relative;
  width: 100% !important;
  min-height: 40px;
}

/* Faded, never disabled.

   This used to carry `pointer-events: none` until the row was hovered, and
   that made the only way of reopening the rail unreliable: a press that
   arrived before the hover state had painted hit the mark underneath and
   nothing happened, so a shut sidebar could look permanently stuck. Nothing
   else lives here when the rail is shut - Vue takes the account switcher out
   of the row, leaving a plain div holding the mark, with no click of its own
   to steal - so the button can stay pressable the whole time and let opacity
   be the only thing the hover changes. */
aside.crm-rail-shut .crm-side-toggle {
  position: absolute;
  inset: -4px -12px;
  width: auto;
  height: auto;
  margin: 0;
  opacity: 0;
  pointer-events: auto;
  /* The box is a hit area, not a shape. What is drawn is the circle below. */
  background: transparent !important;
}

/* The circle, exactly where the mark was and exactly its size.

   The button's box was left large so the whole width of the rail is pressable,
   but a hover fill on that box is a 63x48 slab in a 64px column - it reads as a
   panel opening, not as a control being pointed at. The fill is moved onto a
   pseudo-element sized to the 32px mark it replaces, so the thing that lights
   up is round and sits exactly where the eye already is. */
aside.crm-rail-shut .crm-side-toggle::before {
  content: '';
  position: absolute;
  top: 50%;
  inset-inline-start: 50%;
  width: 32px;
  height: 32px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: transparent;
  transition: background-color .12s ease;
}

html[dir="rtl"] aside.crm-rail-shut .crm-side-toggle::before {
  transform: translate(50%, -50%);
}

aside.crm-rail-shut .crm-side-toggle:hover::before {
  background: rgba(20, 26, 20, .09);
}

.dark aside.crm-rail-shut .crm-side-toggle:hover::before {
  background: rgba(255, 255, 255, .12);
}

/* The glyph rides above the circle: the pseudo-element is positioned and the
   svg is not, so without this the fill paints over the icon. */
aside.crm-rail-shut .crm-side-toggle svg {
  position: relative;
  z-index: 1;
}

aside.crm-rail-shut section > div:first-child:hover .crm-side-toggle,
aside.crm-rail-shut .crm-side-toggle:focus-visible {
  opacity: 1;
}

/* The mark steps aside rather than sitting behind the button. */
aside.crm-rail-shut section > div:first-child:hover > div[class*="size-9"],
aside.crm-rail-shut section > div:first-child:has(.crm-side-toggle:focus-visible) > div[class*="size-9"] {
  opacity: 0;
}

aside.crm-rail-shut section > div:first-child > div[class*="size-9"] {
  transition: opacity .12s ease;
}

/* ---- the frame between the two states ----

   A toggle is not one change but two, and they land ~130ms apart. Vue swaps
   the header row to the other state's markup the moment the state flips,
   while the rail's width is held still for the length of that re-render, so
   one state's layout is painted at the other state's width.

   Shutting, the collapsed row carries `justify-center` - and centred in a
   260px sidebar the mark leaves x=12, appears at x=114, holds there for eight
   frames and slides back to x=16 as the width finally catches up. That jump
   is the flash. Opening does it in reverse: the open row is laid out at 152px
   inside a 64px rail, and nothing in this subtree clips, so the account name
   and the button spill across the conversation list until the width arrives.

   For the length of the move the contents are held to the start edge and the
   section clips. The rail's edge travels; what is inside it stays put. */
aside.crm-rail-moving section > div:first-child {
  justify-content: flex-start !important;
}

aside.crm-rail-moving section {
  overflow: hidden;
}

/* The button is mid-fade in both directions - out across the full 260px on
   the way shut, in at x=128 outside a 64px rail on the way open. Neither is
   worth showing, and it is not pressable mid-animation anyway (smoothToggle
   refuses while `animating`), so it waits for the rail to arrive. */
aside.crm-rail-moving .crm-side-toggle {
  opacity: 0 !important;
  transition: none !important;
}

/* ---- the label, only while the rail is shut ---- */
aside.crm-rail-shut .crm-side-toggle::after {
  content: attr(data-tip);
  position: absolute;
  inset-inline-start: calc(100% + 10px);
  top: 50%;
  transform: translateY(-50%);
  padding: 5px 9px;
  border-radius: 7px;
  background: #1d1b1c;
  color: #ffffff;
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity .12s ease;
  z-index: 70;
}

aside.crm-rail-shut .crm-side-toggle:hover::after { opacity: 1; }
.dark aside.crm-rail-shut .crm-side-toggle::after { background: #2b3138; }

/* The shut rail's rows sit in its middle (owner, 27 Sep 2026). The nav's one
   40px column is wider than the 31px left inside its padding, and a grid puts
   an overflowing column at the start - so every icon sat 4px right of centre.
   Centring the column splits the overflow evenly. Only while shut: open, the
   column is `auto`, and centring it would shrink every row to its text. */
aside.crm-rail-shut nav.grid { justify-content: center; }

/* ---- a field with choices in it says so --------------------------------
 *
 * The platform's reset sets `appearance: none` on form controls, and that
 * takes the native arrow with it - so every <select> we draw was a box with a
 * word in it, identical to a text field, and the only way to discover it was a
 * menu was to click it and see. On the deal drawer that is four fields in a
 * row (Stage, Owner, Priority, the price list) and none of them looked
 * pickable.
 *
 * One rule for all of them across every overlay, keyed on the element and our
 * own class prefix rather than written out eight times in eight stylesheets
 * and left to drift. The `:focus` selector is not decoration: the overlays set
 * `background` (the shorthand, which clears background-image) on focus at a
 * higher specificity than a single class, so without it the arrow vanished the
 * moment the field was used.
 *
 * THE SECOND SELECTOR is for the dialogs. Those build their selects with
 * `document.createElement('select')` and style them by descent - the elements
 * carry NO class of their own, so the prefix rule could never see them, and
 * the invoice screens' menus have looked like text boxes since they were
 * written. `body > [class*="crm-"]` reaches them and nothing else: our dialogs
 * are appended to <body> directly, and no child of body inside the Vue app
 * carries our prefix. It is scoped to direct children on purpose - a bare
 * `[class*="crm-"] select` would match every select on the conversations
 * screen, because that one puts `crm-convo` on <body> itself.
 */
select[class*="crm-"]:not([multiple]),
select[class*="crm-"]:not([multiple]):focus,
select[class*="crm-"]:not([multiple]):hover,
body > [class*="crm-"] select:not([multiple]),
body > [class*="crm-"] select:not([multiple]):focus,
body > [class*="crm-"] select:not([multiple]):hover {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23687078' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-inline-end: 30px;
  /* WITHOUT THIS THE CARET FLOATS IN THE MIDDLE OF THE FIELD. The dashboard's
     own compiled stylesheet carries `select { background-origin: content-box }`
     - an element selector, so it loses every specificity contest, but nothing
     here ever set the property, so it applied by default. "10px from the
     right" was then measured from the CONTENT edge, which the 30px of padding
     had already pushed 30px in: the arrow sat 40px from the border, in open
     space, looking like it belonged to nothing. Measured on screen 23 Sep 2026
     (computed `content-box`, caret 49px in on a 36px-padded field). */
  background-origin: padding-box;
}

/* `html.crm-rtl` beside `html[dir]`, because this installation never sets the
   document's own dir — our screens carry their direction in that class instead
   (crm-i18n.js), so without it the chevron stayed on the right in Arabic. */
html[dir="rtl"] select[class*="crm-"]:not([multiple]),
html[dir="rtl"] select[class*="crm-"]:not([multiple]):focus,
html[dir="rtl"] select[class*="crm-"]:not([multiple]):hover,
html.crm-rtl select[class*="crm-"]:not([multiple]),
html.crm-rtl select[class*="crm-"]:not([multiple]):focus,
html.crm-rtl select[class*="crm-"]:not([multiple]):hover,
html.crm-rtl body > [class*="crm-"] select:not([multiple]),
html.crm-rtl body > [class*="crm-"] select:not([multiple]):focus,
html.crm-rtl body > [class*="crm-"] select:not([multiple]):hover {
  background-position: left 10px center;
}

:root.dark select[class*="crm-"]:not([multiple]),
:root.dark select[class*="crm-"]:not([multiple]):focus,
.dark select[class*="crm-"]:not([multiple]),
.dark select[class*="crm-"]:not([multiple]):focus,
[data-theme="dark"] select[class*="crm-"]:not([multiple]),
[data-theme="dark"] select[class*="crm-"]:not([multiple]):focus,
:root.dark body > [class*="crm-"] select:not([multiple]),
:root.dark body > [class*="crm-"] select:not([multiple]):focus,
.dark body > [class*="crm-"] select:not([multiple]),
.dark body > [class*="crm-"] select:not([multiple]):focus,
[data-theme="dark"] body > [class*="crm-"] select:not([multiple]),
[data-theme="dark"] body > [class*="crm-"] select:not([multiple]):focus {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2398a1ad' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}

/* A list you scroll is not a menu you open.
 *
 * The arrow above is drawn on every `crm-` select, and `size`/`multiple` turns a
 * select into a scrolling LIST BOX - which renders the chevron over the first
 * row instead of beside it, so the first option reads with a triangle stuck
 * through its first letter. `:not([multiple])` in the selectors above keeps the
 * arrow where it belongs; this restores the padding a list box should have, and
 * gives a chosen row the brand tint so a multi-select shows its selection the
 * way the rest of the platform does.
 */
select[class*="crm-"][multiple] {
  padding-inline-end: 12px;
  background-image: none;
}

select[class*="crm-"][multiple] option {
  padding: 5px 8px;
  border-radius: 6px;
}

/* ==========================================================================
   [hidden] means hidden
   The framework's reset carries `[hidden] { display: none }`, and every
   `display` utility - `.flex`, `.grid`, `.block` - is declared AFTER it at the
   same specificity, so any element that carries one and the attribute together
   stays on screen. Nothing in this build wants a hidden element visible, and
   several overlays fold panels away by setting the attribute, so the attribute
   is made to mean what it says.
   ========================================================================== */
[hidden] { display: none !important; }

/* ==========================================================================
   Waiting bones — the shape of a card before its data arrives
   Shared by the two cards injected into the conversation sidebar
   (contact-panel.js, deal-panel.js). They live here because both need them and
   neither owns the other's stylesheet.

   The point is not decoration. Those cards need up to five API answers before
   there is anything to write in them, and until this they were simply absent:
   the platform's own panels painted at 2.0s and ours dropped in on top at 3.8s
   and 4.7s, shoving them down the page. A box that arrives late does not read
   as part of the screen. Now the box is there from the first paint, at its own
   size, and only its contents change.
   ========================================================================== */
.crm-bone {
  display: block;
  border-radius: 5px;
  background: currentColor;
  opacity: .11;
  animation: crm-bone-pulse 1.4s ease-in-out infinite;
}

.crm-bone--mark { width: 34px; height: 34px; border-radius: 9px; }
.crm-bone--title { width: 128px; height: 13px; }
.crm-bone--line { width: 100%; height: 11px; }
.crm-bone--line:nth-child(2) { width: 78%; }
.crm-bone--line:nth-child(3) { width: 54%; }
.crm-bone--row { width: 100%; height: 42px; border-radius: 9px; }
.crm-bone--btn { width: 100%; height: 30px; border-radius: 8px; opacity: .07; }

@keyframes crm-bone-pulse {
  0%, 100% { opacity: .11; }
  50%      { opacity: .05; }
}

/* Someone who has asked for less movement gets a still box rather than none. */
@media (prefers-reduced-motion: reduce) {
  .crm-bone { animation: none; }
}

/* ==========================================================================
   CONVERSATION SIDE-PANEL SWITCH (contact / Captain)
   The platform marks the open Captain panel with `!text-n-iris-9`, and iris-9
   is lime here - a lime mark on the pill's pale fill, which disappears. The
   selected button becomes a lime disc with the ink mark instead, in both
   themes, so "which panel is open" reads at a glance. The contact button's
   selected state gets the same disc so the two never look different.
   ========================================================================== */
[class~="rounded-full"][class~="backdrop-blur-lg"] button:is([class~="!text-n-iris-9"], [class~="bg-n-alpha-2"]):has(:is(.i-woot-captain, .i-ph-user-bold)) {
  background-color: #d4fb08 !important;
  color: #1d1b1c !important;
}
[class~="rounded-full"][class~="backdrop-blur-lg"] button:is([class~="!text-n-iris-9"], [class~="bg-n-alpha-2"]):has(:is(.i-woot-captain, .i-ph-user-bold)) :is(span, svg) {
  color: #1d1b1c !important;
}

/* ==========================================================================
   THE LABEL LIST HIDES ITSELF
   The sidebar caps the Channels and Labels lists at 14rem AND sets
   `scrollbar-width: none` on them, so an account with 24 labels shows six and
   gives no sign at all that eighteen more exist - which is exactly how the
   owner met it: "the Labels hidden under the menu". Measured on account 13 on
   2026-09-21: a 240px window over an 866px list, and nothing on screen saying
   so.
   Two changes, both small. The window gets taller, but bounded by the screen
   rather than by a constant - the rail is already 1,800px long and must not
   grow without limit. And the list is allowed to look like a list: a thin
   scrollbar it was explicitly denied. The cap itself stays, because a rail
   that scrolls twice is worse than one that scrolls once.
   ========================================================================== */
aside nav [class*="max-h-[calc(14rem"] {
  max-height: min(42vh, 420px) !important;
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, currentColor 25%, transparent) transparent;
}
aside nav [class*="max-h-[calc(14rem"]::-webkit-scrollbar {
  display: block;
  width: 6px;
}
aside nav [class*="max-h-[calc(14rem"]::-webkit-scrollbar-thumb {
  border-radius: 999px;
  background: color-mix(in srgb, currentColor 25%, transparent);
}
aside nav [class*="max-h-[calc(14rem"]::-webkit-scrollbar-track { background: transparent; }

/* ---------------------------------------------- "Live updates paused", 23 Sep 2026
 *
 * THE BANNER WAS BEING PAINTED OVER, NOT CLIPPED BY ITS OWN BOX. The platform
 * pins it at `top-2 left-2` with `z-50`, and the sidebar next to it sits at
 * `z-index: 65` - measured on the live page. So the sidebar drew on top of it
 * and the owner saw a banner with its left half missing, on every screen.
 *
 * Raising it alone would leave it lying across the sidebar rail, so it moves
 * to the top centre as well: a message about the whole app belongs across the
 * top of the whole app, clear of every rail at any sidebar width. 10000 is one
 * above the highest z-index anything on the page uses.
 */
[class*="fixed"][class*="z-50"][class*="top-2"][class*="left-2"]:has(> [class*="bg-n-amber"]) {
  z-index: 10000 !important;
  inset-inline-start: 50% !important;
  transform: translateX(-50%);
  top: 10px !important;
  width: max-content;
  max-width: min(560px, calc(100vw - 32px));
}
[dir="rtl"] [class*="fixed"][class*="z-50"][class*="top-2"][class*="left-2"]:has(> [class*="bg-n-amber"]),
html.crm-rtl [class*="fixed"][class*="z-50"][class*="top-2"][class*="left-2"]:has(> [class*="bg-n-amber"]) {
  transform: translateX(50%);
}


/* ==========================================================================
   Few colours (owner, 2026-09-29, after respond.io)          [crm-calm-ink]
   The two neutrals that replaced the old accent blues and violets in the
   screens' own stylesheets: ink for words, icons and links, and one quiet
   grey for any tint behind them. Tokens, so a rule written once for the light
   page still reads on the dark one.
   ========================================================================== */
:root { --crm-ink: #282e34; --crm-tint: #f2f2f3; }
:root.dark, .dark { --crm-ink: #e8eaed; --crm-tint: rgba(255, 255, 255, .06); }

/* ---- inner screens: white, the boxes flat -----------------------------------
   Owner, 2026-09-30: a pale grey page was tried (respond.io's) and compared
   side by side with white in the same tab; white won ("white is much nicer").
   The page stays white; boxes keep their hairline and have no shadow under them
   (the card shadow tokens are `none` in their own files). Don't grey it again
   without asking.
   -------------------------------------------------------------------------- */
/* Screens that painted their own off-white page (#f5f6f1 - #fbfcfe) are white
   like the rest (owner, 2026-09-30: "why isn't this screen white like the
   others"). Measured screen by screen: the platform's page layer straight under
   main (Scheduled messages, Activities) and our own roots. Light mode only;
   the conversation screen keeps its look. A new screen with its own page
   colour goes in this list. */
:root:not(.dark) body:not(.dark):not(.crm-convo) main.bg-n-surface-1 > .bg-n-background,
:root:not(.dark) body:not(.dark):not(.crm-convo) main :is(
  .crm-adc, .ovx-spa, .crm-iv, .crm-out, .crm-cb-pagebox, .cpo, .crm-co
) { background-color: #fff !important; }
