/* Brand map — the landscape as one zoomable picture. Light page, nothing under 14px
   in the chrome (the SVG keeps its own text screen-constant from JS). */

/* THE PAGE IS THE MAP. Dennis, 2026-09-01: "seems like you're underusing a lot of the
   screen space ... instead of bounding it in that white box, maybe just have it be the
   entire page, minus the navbar." Measured on the public map at 1853x992 before this:
   the stage started 281px down and `bottomPad` reserved 78 more, so the board got 64%
   of the window inside a card capped at 1720px.

   The wrap is now a fixed-height flex column whose height JS sets once from whatever
   chrome sits above it (the dashboard's page-header, the public page's sitenav), and
   the stage takes everything the two toolbar rows leave. Nothing scrolls. */
html, body { height: 100%; }
body { overflow: hidden; }
.bm-wrap { max-width: none; margin: 0; padding: 0;
           display: flex; flex-direction: column; overflow: hidden; }
/* THE DASHBOARD PILLS HAVE TO BE PINNED ONCE THE PAGE STOPS SCROLLING. Every dashboard
   page gets #health-pill-rail (the server-health pill and the View Processes pill)
   appended to the END of the body as a plain static block, which was fine while pages
   flowed. Measured here after the change: the rail sat at 685px on a 640px window, so
   both pills were off screen with no way to reach them. Pinned to the corner, and only
   on this page - the rail is shared by thirty others that still scroll. It keeps its
   inline width:100%, so it has to be pointer-transparent everywhere except over the
   pills themselves or it would swallow every click along the bottom of the board. */
#health-pill-rail { position: fixed; left: 0; bottom: 0; z-index: 7000; pointer-events: none; }
#health-pill-rail > * { pointer-events: auto; }
/* ONE LINE, NOT FOUR. The title, the live count and the click hint read as a single
   sentence across the top, so the chips can sit under them and the whole toolbar costs
   about 92px instead of 280. */
.bm-top { display: flex; align-items: baseline; gap: 14px; margin: 0; padding: 8px 18px 6px; }
.bm-top > div { display: flex; flex-wrap: wrap; align-items: baseline; gap: 12px; min-width: 0; }
.bm-h1 { margin: 0; font-size: 18px; }
.bm-say, .bm-hint { font-size: 13.5px; color: #52514e; }
/* THIS SENTENCE MAY NOT CHANGE THE HEIGHT OF THE BOARD. Dennis, 2026-09-04: "maybe
   don't move the entire boxes around when I play around with the filters because it
   just creates too much movement."

   Making the boxes ignore the filters was not enough on its own, and this is why. The
   unfiltered sentence runs to two lines and a filtered one to one, so ticking a chip
   gave 18px back to the stage - and the WORLD'S ASPECT is measured off the stage, so
   the treemap was rebuilt at a different shape and all eighteen rectangles moved, up
   to 739px on the worst one. The filter was moving the board through the paragraph
   describing it.

   So the line stands at exactly two lines whatever it says. Nothing is lost to the
   clamp: the full sentence is on the element's own title, put there by the same code
   that writes the text. Related: rule 244, where a status sentence growing a line was
   pushing the bottom of a board off the window. Same cause, opposite symptom. */
.bm-say { min-height: 2.7em; max-height: 2.7em; overflow: hidden; }
/* The separator belongs to the LINE and not to the words, so the dashboard shell -
   which carries no hint - reads correctly instead of ending on a dangling dot. */
.bm-top > div > * + *::before { content: "·"; color: #a8a59c; margin-right: 12px; }
.bm-search { width: 240px; padding: 6px 11px; font-size: 14.5px; border: 1px solid #8f8d86;
             border-radius: 8px; background: #fff; margin-left: auto; flex: 0 0 auto; }
.bm-search:focus { outline: 2px solid #2a78d6; outline-offset: 0; }
/* A RING ON EVERY CONTROL, NOT ON TWO OF THEM. Measured on the live page
   2026-09-04: 55 tabstops and exactly two :focus rules on the whole stylesheet, the
   search box and the size picker. Everything else - all 40 filter chips, the fold
   button, the focus bar, the kinds buttons and the drawer's close - took the browser
   default, a 1px near-black ring, which is invisible on precisely the chips that
   matter most: the ones that are ON and therefore filled #0b0b0b. The offset puts the
   ring on the page ground instead of on the fill, so it reads the same on a white
   chip and a black one. :focus-visible, so a mouse click never draws it. */
.bm-chip:focus-visible, .bm-more:focus-visible, .bm-sub:focus-visible,
.bm-fbtn:focus-visible, .bm-dclose:focus-visible, .bm-dchip.act:focus-visible,
.bm-fold:focus-visible, .bm-search:focus-visible, select.bm-pick:focus-visible {
  outline: 2px solid #2a78d6; outline-offset: 2px; }

/* Filters: one bar, groups combine (AND across groups, OR inside one). */
/* The border under it is what makes the title line and the chips read as ONE toolbar
   rather than as loose controls floating above a board. */
.bm-filterbar { display: flex; flex-wrap: wrap; gap: 5px 7px; align-items: center;
                margin: 0; padding: 0 18px 8px; border-bottom: 1px solid #e1e0d9; }
.bm-fgroup { display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
             padding-right: 10px; margin-right: 2px; border-right: 1px solid #e6e3da; }
.bm-fgroup:last-child { border-right: 0; }
/* THE EDGE OF A CONTROL IS THE ONLY THING MARKING IT, SO IT HAS TO CLEAR 3:1.
   Measured on the live page 2026-09-04: every chip, the search box, the focus-bar
   buttons, the kinds buttons and the drawer's close button were outlined in
   #d5d2c9 or #cfcdc3 on white, which is 1.43:1 - the contrast of a decorative
   hairline, doing the job of a boundary. The page already knew the right grey:
   #8f8d86 (3.32:1) was its HOVER colour, so the resting state was fainter than the
   same control a moment later under the pointer. Resting takes the hover grey and
   hover steps down again. */
.bm-chip { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px; font-size: 13px;
           border: 1px solid #8f8d86; border-radius: 999px; background: #fff; color: #2c3440;
           cursor: pointer; user-select: none; white-space: nowrap; }
.bm-chip .n { font-size: 12px; color: #77746d; }   /* 3.59:1 was under the 4.5 floor */
.bm-chip .dot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; }
.bm-chip.on { background: #0b0b0b; border-color: #0b0b0b; color: #fff; }
.bm-chip.on .n { color: #c9c9c9; }
.bm-chip.faint { opacity: 0.4; }        /* would leave nothing, still clickable */
/* The hover's last line, set apart from the facts above it: it is an instruction,
   not another thing we know about the brand. */
.bm-tclick { margin-top: 5px; padding-top: 5px; border-top: 1px solid rgba(255,255,255,.18);
             opacity: .8; }
.bm-more { font-size: 14px; border: 0; background: none; color: #52514e; cursor: pointer;
           text-decoration: underline; padding: 6px 4px; }
/* The button carries a count when something inside the fold is on, so it has to look
   different in the two states rather than only reading differently (rule 116). */
.bm-more.on { color: #0b0b0b; font-weight: 600; }
/* A hard row break inside the wrapping bar, so the colour chips and the who-pays
   chips are always two rows and never reflow into one crowded one at a wide window. */
.bm-fbreak { flex-basis: 100%; height: 0; margin: 0; }
/* ONLY THE FIRST ONE. The bar carried three breaks and so always drew three rows:
   avatars, then who-pays, then "Boxes =" and "Size =" on a row of their own. Two rows
   is 28px of board back and, more to the point, the two chips that change what the
   board MEANS now sit beside the ones that change what is on it, which is where a
   reader looking for them would go first. The fold panel still breaks itself
   (flex-basis:100%) and is display:none while closed, so a closed bar is two rows. */
.bm-fbreak ~ .bm-fbreak { display: none; }
/* The folded half. Full width so it starts on its own row when it opens. */
.bm-foldpanel { display: flex; flex-wrap: wrap; gap: 6px 8px; align-items: center;
                flex-basis: 100%; padding-top: 2px; }
.bm-foldpanel[hidden] { display: none; }

/* The focus bar: what a box you clicked into says about itself.

   It is a BAR and not another chip because it reports a state, and a control that
   reports a state has to look different in each state (rule 116). Sitting between
   the filters and the board, it is unmissable in the one situation it exists for
   and absent in every other. */
/* 8px to 6px, and the gap 12 to 10. Small on its own; this bar carries two rows and
   sits between the title and the board on every drill-down, so the padding is paid
   four times over. Measured, not guessed: it is 10px of board. */
.bm-focusbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
               margin: 0 0 8px; padding: 6px 12px; border-radius: 10px;
               background: #efeee7; border: 1px solid #dedcd2; }
.bm-focusbar .bm-fname { font-weight: 650; font-size: 15px; color: #0b0b0b; }
.bm-focusbar .bm-fcount { font-size: 14px; color: #52514e; }
.bm-focusbar .bm-fnote { font-size: 14px; color: #6d6b64; }
.bm-focusbar .bm-fkey { margin-left: auto; font-size: 12px; color: #6d6b64;
                        border: 1px solid #cfcdc3; border-radius: 5px; padding: 1px 6px; }
.bm-fbtn { font-size: 14px; cursor: pointer; border-radius: 999px; padding: 6px 12px;
           border: 1px solid #8f8d86; background: #fff; color: #0b0b0b; }
.bm-fbtn:hover { border-color: #5f5d57; }
.bm-fbtn.all { background: #0b0b0b; color: #fff; border-color: #0b0b0b; }
.bm-fbtn.all:hover { background: #333; }

/* The audience card. It reuses the drawer's own sections, tiles and faces, so it
   cannot drift away from how a brand's card looks; only these four are new. */
.bm-dwords { font-size: 14px; line-height: 1.5; color: #2b2a27; margin-top: 8px; }
.bm-avniche { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.bm-jumpcat { font-size: 13px; cursor: pointer; border-radius: 999px; padding: 5px 11px;
              border: 1px solid #dedcd2; background: #fff; color: #2b2a27; }
.bm-jumpcat:hover { border-color: #8f8d86; }
.bm-jumpcat b { font-weight: 650; margin-left: 4px; }
a.bm-face { text-decoration: none; color: inherit; }
a.bm-face:hover .who { text-decoration: underline; }

/* No card, no rounded corner, no cap: the board is the rest of the page. JS sets the
   WRAP's height and flex hands the remainder here, so this rule never names a height. */
.bm-stage { position: relative; flex: 1 1 auto; min-height: 240px;
            background: #fcfcfb; border: 0; border-radius: 0; overflow: hidden; }
#bm-svg { width: 100%; height: 100%; display: block; cursor: grab; }
#bm-svg:active { cursor: grabbing; }

/* SVG marks (world-space; font sizes are set from JS so they stay screen-constant) */
/* CONTRAST, MEASURED against this page's own #f7f6f1 rather than judged by eye. The
   four values below were 2.36:1 for the axis captions (text, and it fails), 1.15:1 for
   the guide lines and 1.20:1 for the cell edges - which is not a light grid, it is an
   invisible one, and the grid is what tells a reader which category they are looking
   at. The captions now clear 4.5:1 and the two line weights sit at about 2.5:1 and
   2.0:1, dark enough to see and light enough that 18 category boxes do not shout over
   the bubbles inside them. */
.bm-cell { fill: #f7f6f1; stroke: #b3b0a7; stroke-width: 1; }
.bm-guide { stroke: #c9c6bc; }
.bm-axcap { fill: #716e67; font-weight: 600; pointer-events: none;
            paint-order: stroke; stroke: #f7f6f1; stroke-width: 3.5px; stroke-linejoin: round; }
.bm-cellname { fill: #52514e; font-weight: 700; cursor: pointer;
               paint-order: stroke; stroke: #f6f5f0; stroke-width: 4px; stroke-linejoin: round; }
.bm-cellname:hover { fill: #0b0b0b; }
.bm-node circle.core { stroke: #ffffff; }
.bm-node.talky circle.core { stroke: #0b0b0b; }
/* Size unknown. It was WHITE dashes on a near-white page, which is a mark nobody has
   ever been able to see; the dash pattern itself is set from JS in screen pixels. */
.bm-node circle.unknown { stroke: #8f8d86; }
.bm-node .ring { fill: none; stroke: #52514e; opacity: 0.55; }
/* Every mark sits on a white coin (see addMark) so a dark logo on a dark bubble reads.
   The coloured rim around it still carries the avatar. */
.bm-node circle.plate { fill: #ffffff; }
.bm-node text.mono { font-weight: 700; pointer-events: none; }
/* THESE THREE ARE DELIBERATELY UNSCOPED. The labels live in their own layer
   above every bubble, not inside .bm-node, so a `.bm-node text.bname` rule
   matches nothing - which is exactly what happened: for as long as the layer
   has existed every brand name has rendered as unstyled 400-weight black text
   with NO halo, which is most of why a crowded shelf read as clutter.
   The plate below is only worn by a label that had nowhere clear to go, so it reads as a caption over a
   bubble instead of ink on a colour. Nearly opaque on purpose: a see-through plate
   over a saturated circle is the same unreadable label with an extra edge on it. */
rect.lplate { fill: #fcfcfb; fill-opacity: 0.94; stroke: #e4e2da;
              pointer-events: none; }
text.bname { fill: #0b0b0b; font-weight: 600; paint-order: stroke; stroke: #fcfcfb;
             stroke-width: 4.5px; stroke-linejoin: round; pointer-events: none; }
/* The count sits under the name and is the fact most readers came for, so it is dark
   enough to read on a busy shelf. Same halo, so it survives landing on a bubble. */
text.bvids { fill: #1c1c1a; font-weight: 600; paint-order: stroke; stroke: #fcfcfb;
             stroke-width: 4.5px; stroke-linejoin: round; pointer-events: none; }
/* Who owns the brand, one line under the count. LIGHTER than the two lines above it
   on purpose: it is a fact about the company behind the bubble rather than about the
   bubble, and at the same weight three dark lines under one circle read as a
   paragraph. Same halo, so it survives landing on a busy shelf. */
text.bown { fill: #5c5a54; font-weight: 500; paint-order: stroke; stroke: #fcfcfb;
            stroke-width: 4px; stroke-linejoin: round; pointer-events: none; }
/* A brand the filters removed is GONE, not faded. Until 2026-08-31 filtering only
   set .dim, so narrowing to 532 brands still drew 1,850 circles at the same size
   in the same rectangles - the filter bar could not buy a single pixel of room.
   .dim stays for the SEARCH box, which highlights without reflowing. */
.bm-node.gone { display: none; }
/* The two pickers: what the boxes are, and what the size means. They wear the chip's
   own shape so the bar reads as one row of controls, and they say their current choice
   in words on their own face (rule 144) - which is also what makes them one control
   each instead of the five lit-one-of chips that used to force a third toolbar row.
   Dark, because a control that CHANGES the picture should not look like one of the
   filters that only narrows it. */
select.bm-pick { -webkit-appearance: none; appearance: none;
                 background: #2f2c26; color: #fff; border-color: #2f2c26;
                 padding-right: 24px; font-family: inherit;
                 background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='7'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23fff' stroke-width='1.6'/%3E%3C/svg%3E");
                 background-repeat: no-repeat; background-position: right 9px center; }
select.bm-pick:hover { background-color: #45413a; }
select.bm-pick:focus { outline: 2px solid #2a78d6; outline-offset: 1px; }
/* A dropdown's own menu is drawn by the OS in its own colours, so the options have to
   be set back to dark-on-white or they inherit white-on-white in some browsers. */
select.bm-pick option { background: #fff; color: #2c3440; }
.bm-node.dim { opacity: 0.10; pointer-events: none; }
.bm-node { cursor: pointer; transition: opacity 0.25s ease; }
/* The target, never drawn. `fill: none` alone takes no pointer, which is the whole
   point of the pair - the circle has to be hit-testable and invisible at once. Its
   radius is set in screen pixels by relabel(). */
.bm-node circle.hit { fill: none; pointer-events: all; }
.bm-node:hover circle.core { stroke: #0b0b0b; }
/* SELECTED IS NOT HOVER. Both of these said #0b0b0b, so the brand whose panel was open
   looked exactly like whatever the cursor was passing over, and after a click there was
   nothing on the board saying which bubble you were reading about. Selection wears the
   page's own blue - the same blue the drawer's links and key figure use - and the
   heavier edge is set in relabel() because stroke widths here are in map units. */
.bm-node.sel circle.core { stroke: #2a78d6; }
.bm-node.sel circle.ring { stroke: #2a78d6; opacity: 1; }
.bm-badge rect { rx: 9px; }
.bm-badge text { fill: #fff; font-weight: 700; }
.bm-badge.mail rect { fill: #0b0b0b; }
.bm-badge.li rect { fill: #0a66c2; }

/* Overlays */
.bm-legend { position: absolute; left: 14px; bottom: 14px; background: rgba(255,255,255,0.95);
             border: 1px solid #e1e0d9; border-radius: 10px; padding: 12px 14px; font-size: 14px;
             color: #2c3440; max-width: 300px; }
.bm-legend h4 { margin: 0 0 6px; font-size: 14px; color: #52514e; }
.bm-lhead { border: 0; background: none; font-size: 14px; font-weight: 700; color: #52514e;
            cursor: pointer; padding: 0; margin-bottom: 6px; }
.bm-lbody[hidden] { display: none; }
.bm-lrow { display: flex; align-items: center; gap: 8px; margin: 3px 0; }
.bm-lrow .dot { width: 12px; height: 12px; border-radius: 50%; flex: 0 0 auto; }
.bm-lrow .n { color: #6f6c66; margin-left: auto; padding-left: 10px; }
/* The three edges that carry meaning, said in the always-open half of the key. */
.bm-shapes { margin-top: 9px; padding-top: 8px; border-top: 1px solid #eceae3; }
.bm-srow { display: flex; align-items: center; gap: 8px; margin: 4px 0;
           font-size: 13.5px; color: #52514e; }
.bm-srow svg { flex: 0 0 auto; }
.bm-lsizes { display: flex; align-items: flex-end; gap: 10px; margin: 8px 0 2px; }
.bm-lsizes .szc { border: 1.6px solid #52514e; border-radius: 50%; background: #eceae3; }
.bm-lsizes .szc.unk { border-style: dashed; }
.bm-lnote { color: #6f6c66; font-size: 13.5px; margin-top: 6px; }
.bm-fold { border: 0; background: none; font-size: 14px; color: #52514e; cursor: pointer;
           text-decoration: underline; padding: 0; margin-top: 8px; }

.bm-tip { position: fixed; z-index: 60; background: #0b0b0b; color: #fff; border-radius: 9px;
          padding: 11px 14px; font-size: 15px; max-width: 360px; pointer-events: none;
          box-shadow: 0 6px 24px rgba(0,0,0,0.25); }
.bm-tip .t { font-weight: 700; font-size: 17px; }
.bm-tip .s { color: #e6e4de; margin-top: 3px; }
.bm-tip .k { color: #9ec5f4; }
/* The number the bubble is drawn on. White and heavier than everything round it, so
   the one fact a reader is comparing between two circles is the one they land on. */
.bm-tip .big { color: #fff; font-weight: 600; font-size: 17px; margin-top: 5px; }

/* ---------- who they share creators with (/shared-creators-map/ only) ----------

   The faces and the lines live in their own layer on top of the board, and every rule
   here is inert on the brand map, which never bloats one. Two levels of quiet, not one:
   a brand that has nothing to do with the open creator web goes almost out (weboff),
   and a brand that is IN the web but not under the cursor goes half out (webquiet), so
   hovering one face answers "and who else pays this person" without losing where the
   rest of the web was. */
.bm-webface circle { fill: #ffffff; stroke: #4a3aa7; stroke-width: 2.4; }
/* The photograph is square and the frame is round. clip-path on the image rather than a
   per-face clipPath element: 24 of those get made and torn down on every click. */
.bm-webface image { clip-path: circle(50%); }
.bm-webface text { fill: #4a3aa7; font-weight: 700; }
.bm-webface { cursor: pointer; }
.bm-webface:hover circle { stroke: #0b0b0b; }
.bm-webline { stroke: #4a3aa7; opacity: 0.5; }
.bm-node.weboff { opacity: 0.08; pointer-events: none; }
.bm-node.webquiet { opacity: 0.3; }
/* While one face is hovered, everything that is not it steps back. `.lit` is put on the
   ones that stay, so the rule is written once and the default state needs no class. */
.bm-web.one .bm-webface:not(.lit) { opacity: 0.18; }
.bm-web.one .bm-webline:not(.lit) { opacity: 0.08; }

.bm-error { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
            font-size: 16px; color: #b3261e; padding: 40px; text-align: center; background: #fcfcfb; }

/* Drawer — the dash on the right. */
/* This panel is where a reader actually reads, and it was 14.5px set solid in a
   440px column with section headings only a point larger than the body, so every
   block looked like every other block. Wider, larger, and with real air between
   the sections.

   THE SHELL IS NOT THE PANEL. That pass set this rule to 15.5px and stopped, but
   the nine content blocks below carry their OWN sizes and were left at 11-13.5px,
   so the drawer advertised 15.5 while every line a reader actually reads was 12 or
   13. Nothing in here goes under 14px now; a tag riding on something else may go to
   12.5 and no lower. Check that floor when adding a block, because the default a
   new panel inherits is this rule and not the small print around it. */
/* WIDER, AND WITH AN EDGE YOU CAN SEE. Dennis, 2026-09-01: "the bar on the side is kind
   of hard to see ... it's very narrow if you look at the entire screen size space." At
   560px on an 1853px window it was 30% of the screen, white on a near-white board behind
   a 1px hairline and a shadow at 8% - so it read as more page rather than as a panel
   that had opened. 720px, a darker edge and a real shadow. */
/* AND BACK IN AGAIN, Dennis 2026-09-04: "it expands the screen way too wide ... the part
   on the right is very hard to read." 720 was content-box, so with 26px of padding a side
   the panel actually drew 773px - 41% of an 1890px window - and the prose inside ran at 91
   characters a line, well past the 45-75 a person reads comfortably. The 2026-09-01 problem
   was that the panel was hard to SEE, and the border and the shadow below are what fixed
   that; the extra width was never what made it visible. box-sizing is now stated, so 600
   means 600 on screen: 32% of the window and a 548px column, about 72 characters. */
.bm-drawer { position: absolute; top: 0; right: 0; bottom: 0;
             box-sizing: border-box; width: min(38vw, 600px);
             max-width: 94%;
             background: #ffffff; border-left: 1px solid #cfcdc3; box-shadow: -18px 0 44px rgba(0,0,0,0.14);
             overflow-y: auto; padding: 0 26px 26px; font-size: 15.5px; line-height: 1.5;
             color: #2c3440; }
/* The key sits bottom-right on the public page and a 720px panel lands on top of it.
   One of the two has to go while the other is open, and it is the one the reader did
   not just ask for. */
.bm-stage:has(.bm-drawer:not([hidden])) .bm-legend { display: none; }
/* The brand's name, its domain, its numbers and the way out never scroll away. */
.bm-dtop { position: sticky; top: 0; z-index: 6; background: #fff; padding: 16px 0 10px;
           border-bottom: 1px solid #eceae3; margin-bottom: 10px; }
/* The tiles sit immediately under that block, so they need to hang together with it
   rather than float in the body: no top margin, and the head's own margin below. */
.bm-dtop + .bm-nums { margin: 0 0 4px; }
.bm-drawer h2 { margin: 0; font-size: 23px; line-height: 1.2; display: flex;
                align-items: center; gap: 10px; letter-spacing: -0.015em; }
.bm-drawer h2 img { width: 34px; height: 34px; border-radius: 8px; object-fit: contain;
                    border: 1px solid #eceae3; background: #fff; }
/* .dom LIVES IN .bm-dtop, NOT IN .bm-dhead. It moved there when the header was made
   sticky and these two rules did not follow it, so the brand's own domain - the first
   link in the panel - has been drawing in raw #0000EE browser blue, underlined. The
   selector is now the drawer rather than either block, so it survives the next move. */
.bm-drawer .dom { margin: 4px 0 8px; }
.bm-drawer .dom a { color: #2a78d6; text-decoration: none; font-size: 14.5px; }
/* Same fault, one layer down: a link dropped into a sentence (the LinkedIn one under
   the team size) carries no class of its own and inherits nothing. Every link in the
   panel that is not already a styled component gets the house blue. */
.bm-drawer a:not([class]) { color: #2a78d6; text-decoration: none; }
.bm-drawer a:not([class]):hover { text-decoration: underline; }
.bm-dchips { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0; }
.bm-dchip { font-size: 14px; padding: 3px 9px; border-radius: 999px; background: #f2efe9; color: #52514e; }
/* `.av` used to carry the audience hue as an inline background with white text on it.
   The hue is gone (see brand_map.js), so this rule had to go with it - left behind it
   was white text on the pale chip ground, which is a label nobody can read. The chip
   now looks like every other chip and says the audience in words.

   The class itself was emitted for another day after the rule went, and brand_map.js
   went on setting the fill inline, so the chip kept its hue and took the plain chip's
   grey: 1.08:1 in the AG1 drawer. Both are gone now, so there is no `.av` to style and
   nothing here to keep in step with (rule 182). */
/* A chip that DOES something has to look different from one that just labels, or the
   only way to find out is to click every chip on the card (rule 116). */
.bm-dchip.act { border: 0; font: inherit; font-size: 14px; cursor: pointer; }
.bm-dchip.act:hover { background: #e4e0d6; }
/* The revenue chip is the only one on the row that LEAVES the page, when we hold the
   source it came from, so it wears the house blue rather than looking like the label
   beside it (rule 116). Without a source to point at it stays a plain chip, because
   then there is nothing to press. */
a.bm-dchip.rev { color: #2a78d6; text-decoration: none; }
a.bm-dchip.rev:hover { background: #e4e0d6; text-decoration: underline; }
/* Who owns them. Same shape as the revenue chip and the same blue when it carries a
   page to click, because they are the same kind of thing: a fact about the company
   rather than about its creators, with its source one press away. */
a.bm-dchip.own { color: #2a78d6; text-decoration: none; }
a.bm-dchip.own:hover { background: #e4e0d6; text-decoration: underline; }
.bm-dblurb { color: #52514e; margin: 8px 0 2px; }
.bm-dsec { margin-top: 24px; border-top: 1px solid #eceae3; padding-top: 16px; }
/* A heading has to WIN against the body text under it, or a wall of facts reads as
   one undifferentiated block, which is what this panel was doing. */
.bm-dsec h3 { margin: 0 0 10px; font-size: 17px; font-weight: 700; letter-spacing: -0.01em; }
.bm-dsec h3 .n { color: #6f6c66; font-weight: 400; }
.bm-person { padding: 8px 0; border-bottom: 1px dashed #eceae3; }
.bm-person:last-child { border-bottom: 0; }
.bm-person .who { font-weight: 600; }
.bm-person .who a { color: #0a66c2; text-decoration: none; }
.bm-person .meta { color: #5a5751; font-size: 14px; margin-top: 1px; }
.bm-person .snip { color: #52514e; font-size: 14px; margin-top: 3px; font-style: italic; }
.bm-pill { display: inline-block; font-size: 13px; font-weight: 700; padding: 2px 8px;
           border-radius: 999px; margin-left: 6px; vertical-align: 1px; }
.bm-pill.live { background: #c9e7cd; color: #14431c; }
.bm-pill.cold { background: #fdf0c2; color: #5c4a05; }
.bm-pill.quiet { background: #eceae3; color: #52514e; }
.bm-none { color: #6f6c66; }
.bm-dwhy { color: #52514e; }
.bm-dmeta { color: #52514e; margin-top: 3px; }
.bm-dsub { margin: 18px 0 10px; font-size: 16px; font-weight: 700; }
/* WHAT THEY SAY THEY ARE TRYING TO DO. A quotation, and it has to LOOK like one, or a
   sentence the company wrote reads as a sentence we wrote about them: the left rule and
   the larger size are what separate their voice from the facts underneath.
   16.5px against the panel's 14px, because this is the line somebody opened the card
   for and the rest of the panel is reference. The source line under it stays quiet at
   13px - it qualifies the quote rather than competing with it. */
.bm-goal { margin: 4px 0 12px; padding: 2px 0 2px 12px; border-left: 3px solid #2a78d6;
           font-size: 16.5px; line-height: 1.42; color: #0b0b0b; }
.bm-goal .src { display: block; margin-top: 5px; font-size: 13px; color: #52514e; }
.bm-goal .src a { color: #2a78d6; }

/* Who they paid: real faces, named, never counted (rule 126). */
.bm-faces { display: flex; flex-wrap: wrap; gap: 10px; }
.bm-face { width: 88px; text-align: center; }
.bm-face img, .bm-face .ini { width: 52px; height: 52px; border-radius: 50%; object-fit: cover;
                              background: #f2efe9; display: inline-flex; align-items: center;
                              justify-content: center; font-weight: 700; color: #6f6c66; }
.bm-face .who { display: block; font-size: 14px; margin-top: 4px; line-height: 1.25;
                overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.bm-face .cnt { display: block; font-size: 14px; color: #5a5751; }

/* The videos themselves, biggest first. */
.bm-vids { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.bm-vid { text-decoration: none; color: #2c3440; }
.bm-vid img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-radius: 7px;
              background: #f2efe9; display: block; }
.bm-vid .t { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
             overflow: hidden; font-size: 14px; line-height: 1.3; margin-top: 4px; }
.bm-vid .m { display: block; font-size: 14px; color: #5a5751; margin-top: 2px; }
/* ══ the brand's own file ══ Everything below draws data the drawer was already
   fetching and throwing away. Faces widened to 104px because a name now carries the
   other brands paying that person under it, and two lines of brand names in 88px
   wrapped to one word a line. */

/* The stat row. `key` is the one figure that separates brands on the same shelf,
   so it gets the weight - the rest are context for it. */
.bm-nums { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 8px; }
/* 88px of basis fitted all five tiles on one line while the panel was 773px wide. In a
   600px panel it wraps 4 + 1, and the orphan stretches the full width of the drawer,
   which reads as a mistake rather than as a row. 145px wraps five as 3 + 2 and four
   as 2 + 2, so no tile is ever left alone on a line of its own. */
.bm-num { flex: 1 1 145px; background: #f6f4ef; border-radius: 8px; padding: 8px 10px; }
.bm-num b { display: block; font-size: 17px; line-height: 1.15; }
.bm-num span { display: block; font-size: 14px; color: #5a5751; margin-top: 2px; }
.bm-num.key { background: #eef3fb; }
.bm-num.key b { color: #2a78d6; }

.bm-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0; }

/* A face's other brands. These are real buttons because they DO something - they fly
   the map - so they have to look pressable and take a pointer. */
.bm-faces .bm-face { width: 112px; }
.bm-face .alsob { display: block; font-size: 14px; color: #5a5751; margin-top: 3px;
                  line-height: 1.5; }
.bm-jump { font: inherit; font-size: 14px; border: 1px solid #d5d2c9; background: #fff;
           color: #2c3440; border-radius: 999px; padding: 1px 7px; cursor: pointer;
           max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
           vertical-align: bottom; }
.bm-jump:hover { border-color: #2a78d6; color: #2a78d6; }
/* One canonical shade per meaning (rule 41): the amber that marks a direct rival here
   is the same amber the rivals list uses below. */
.bm-jump.rival { border-color: #eda100; background: #fdf6e3; }
.bm-jump.rival:hover { border-color: #b87c00; color: #7a5300; }
.bm-jump.nope { opacity: .5; cursor: default; border-style: dashed; }

/* Video rows carry what was SOLD, not just what the video was called. */
.bm-vid .o { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
             overflow: hidden; font-size: 14px; color: #52514e; margin-top: 3px;
             line-height: 1.35; }
.bm-vid .code, .bm-vid .hear { display: inline-block; font-size: 13px; margin-top: 4px;
                               padding: 1px 7px; border-radius: 999px; }
.bm-vid .code { background: #f2efe9; color: #52514e; }
.bm-vid .hear { background: #eef3fb; color: #2a78d6; margin-left: 4px; }
.bm-vid .vtag { font-style: normal; font-size: 12.5px; background: #f2efe9; color: #5a5751;
                border-radius: 4px; padding: 0 5px; }

/* Twelve quarters. Deliberately unlabelled between the ends: this is the SHAPE of a
   programme, and a number on every bar would invite reading it as a measurement. */
.bm-spark { display: flex; align-items: flex-end; gap: 3px; height: 46px; margin: 8px 0 2px; }
.bm-spark i { flex: 1; background: #c3cfe0; border-radius: 2px 2px 0 0; min-height: 2px; }
.bm-spark i:last-child { background: #2a78d6; }
.bm-sparkx { display: flex; justify-content: space-between; font-size: 13px; color: #5a5751; }

/* Who else is on the shelf. Every row flies the map, so the whole row is the button. */
.bm-rivals { display: flex; flex-direction: column; gap: 4px; }
.bm-rival { display: flex; align-items: baseline; gap: 8px; width: 100%; text-align: left;
            font: inherit; border: 1px solid #eceae3; background: #fff; border-radius: 8px;
            padding: 7px 10px; cursor: pointer; }
.bm-rival:hover { border-color: #2a78d6; background: #fafcff; }
.bm-rival .rn { font-weight: 600; font-size: 14.5px; }
.bm-rival .rm { font-size: 14px; color: #5a5751; flex: 1; }
.bm-rival .rlive { color: #14875f; font-size: 12.5px; }

/* The gap list sits in the same face grid, tinted so it cannot be mistaken for the
   creators this brand actually pays - which is the one misreading that would matter. */
.bm-faces.gap { background: #fdf6e3; border-radius: 10px; padding: 10px; }

/* The fold that hides it on the public page. A real bordered target rather than the
   legend's underlined text, because this is the control that stands in for a whole
   panel and it has to look pressable on sight (rule 145). */
.bm-gapfold { display: inline-block; border: 1px solid #d5d2c9; background: #fff;
              border-radius: 999px; padding: 5px 13px; margin-top: 2px; color: #2c3440;
              text-decoration: none; }
.bm-gapfold:hover { border-color: #2a78d6; color: #2a78d6; }
.bm-gapbody[hidden] { display: none; }

.bm-camps { display: flex; flex-direction: column; gap: 8px; }
.bm-camp { border-left: 3px solid #eceae3; padding-left: 9px; }
.bm-camp .cn { font-size: 14.5px; font-weight: 600; }
.bm-camp .cn a { color: #2c3440; text-decoration: none; }
.bm-camp .cn a:hover { color: #2a78d6; }
.bm-camp .cm { font-size: 14px; color: #5a5751; }
.bm-dmeta .asof { color: #5a5751; font-size: 14px; }

/* What the videos could not show. A LABEL AND ITS ANSWER, stacked rather than side
   by side: the answers run to a couple of lines each and a label column would leave
   the sentences reading in a 300px gutter inside an already 532px panel. The left
   rule is the only decoration, and it is there to say these three lines are a
   different KIND of thing from the recorded figures above them - read off the web
   this morning, not counted out of our own tables. */
.bm-ready { margin: 2px 0 8px; }
.bm-rrow { border-left: 3px solid #e4e0d6; padding: 0 0 0 10px; margin: 0 0 9px; }
.bm-rrow:last-child { margin-bottom: 4px; }
.bm-rrow b { display: block; font-size: 14px; font-weight: 650; color: #6d6b64; }
.bm-rrow span { display: block; font-size: 15px; line-height: 1.45; color: #2c3440; }

.bm-iglist { display: flex; flex-direction: column; gap: 6px; }
.bm-ig { display: flex; gap: 8px; align-items: baseline; text-decoration: none; color: #2c3440;
         font-size: 14.5px; }
.bm-ig:hover .who { color: #2a78d6; }
.bm-ig .m { font-size: 14px; color: #5a5751; }

/* One Meta ad. Same card as .bm-cel below, because an ad's opening line is read the
   same way a celebrity's quoted line is: a name, some dry facts, then the words. */
.bm-adlist { display: flex; flex-direction: column; gap: 6px; }
.bm-ad { background: #f6f4ef; border-radius: 8px; padding: 9px 12px; font-size: 14.5px; }
.bm-ad .m { font-size: 14px; color: #5a5751; }
.bm-ad .q { display: block; color: #52514e; font-style: italic; margin-top: 3px; }
.bm-ad a { color: #2a78d6; display: inline-block; margin-top: 3px; font-size: 14px; }

.bm-cel { background: #f6f4ef; border-radius: 8px; padding: 10px 12px; margin: 8px 0;
          font-size: 14.5px; }
.bm-cel .q { display: block; color: #52514e; font-style: italic; margin-top: 3px; }
.bm-cel a { color: #2a78d6; }
/* ONE column, not two. In two columns each cell was ~221px wide, so "owned by PepsiCo
   (public, NASDAQ: PEP)" broke over three lines beside a label with nothing under it.
   Down the page the label sits left and its answer right, which is the shape a reader
   already scans for, and a long owner line gets the whole width before it wraps. */
.bm-facts { display: grid; grid-template-columns: 1fr; gap: 7px; margin-top: 8px; }
.bm-facts div { display: flex; justify-content: space-between; gap: 14px; font-size: 14.5px;
                border-bottom: 1px dotted #eceae3; padding-bottom: 5px; }
/* The label, and it is the half a reader skips - so it stays quieter than its answer
   while still clearing 4.5:1 at this size. */
.bm-facts span { color: #5a5751; flex: 0 0 auto; }
.bm-facts div > :last-child { text-align: right; }

.bm-dclose { position: sticky; top: 0; float: right; border: 1px solid #8f8d86; background: #fff;
             border-radius: 8px; font-size: 15px; padding: 4px 11px; cursor: pointer; }
/* It sits under the tags and the mission line now rather than at the foot of the panel,
   so it needs room below it as well as above: it is a link with sections under it, not
   the last thing in the drawer. */
.bm-dlink { display: inline-block; margin: 10px 0 2px; color: #2a78d6; text-decoration: none; }
/* The brand list's pop-up, in a frame over the whole map. Above the site nav (sticky,
   z 9000) and the corner badge (8000) that _sitenav.py puts on every public page. The
   frame's document is transparent and carries its own scrim, so the map shows through
   dimmed; .loading carries that dim itself until the frame has painted. */
.bm-embed { position: fixed; inset: 0; z-index: 9500; }
.bm-embed.loading { background: rgba(10, 10, 10, .5); }
.bm-embed iframe { width: 100%; height: 100%; border: 0; display: block; }
.bm-embed-note { position: absolute; inset: 0; display: grid; place-items: center; color: #fff;
                 font-size: 18px; pointer-events: none; }
.bm-embed-note:empty { display: none; }
.bm-embed[hidden] { display: none; }
.bm-skel { color: #6f6c66; padding: 30px 0; text-align: center; }

/* An author display rule on anything that also uses [hidden] needs this guard,
   or the attribute silently loses (see the /manus-library modal lesson). */
.bm-legend[hidden], .bm-tip[hidden], .bm-drawer[hidden], .bm-error[hidden] { display: none; }

@media (max-width: 900px) {
  .bm-top { flex-direction: column; align-items: stretch; }
  /* THE SEPARATOR IS A JOIN, AND DOWN HERE NOTHING IS JOINED. The dot is drawn by
     `* + *::before` on a wrapping row, so at 700px, where the count sentence and the
     click hint each take their own line, both lines opened on a grey bullet with a
     12px gap after it - which reads as a bulleted list somebody forgot to finish. */
  .bm-top > div > * + *::before { content: none; }
  .bm-search { width: 100%; margin-left: 0; }
  /* 42vw of a small window is too narrow to read, and 720px is the whole screen, so
     neither half of the min() is right down here. */
  .bm-drawer { width: min(94vw, 520px); padding: 0 18px 20px; }
  /* No height override here any more: the stage is a flex item and takes what the
     toolbar leaves, which on a phone is most of the screen either way. */
}

/* The sub-niche drill-down, on its own line under the focus bar. It is a second row
   rather than more pills in the same row because it answers a different question:
   the row above says which box you are in, this one says what kinds are inside it. */
/* ONE LINE THAT SCROLLS, NOT TWO THAT WRAP. Eleven kinds plus the label plus the
   "and 14 smaller" note wrapped to a second line, and this strip only exists once you
   have drilled into a box - which is the moment the board needs the room, not the
   moment to spend another 28px of it on chrome (rule 244). Measured at 1389x868:
   57px to 29px, and the stage grew by every pixel of it.

   `min-width: 0` IS LOAD-BEARING and is the whole reason this works. A flex item's
   min-width:auto only collapses when its own overflow is not visible; without it the
   strip would grow to fit all eleven chips and push them off the edge of the screen
   instead of scrolling - an element that OVERFLOWS is not an element that SCROLLS
   (rule 228). The landscape page's tab strip broke exactly this way today.
   Every child is flex:none, or they would squash to fit rather than scroll. */
/* Stands in for the who-pays row when a growth state has already pinned it. Quiet,
   and the same height as the chips it replaces so the bar does not change shape. */
.bm-fnote-row { font-size: 13px; color: #6d6b64; padding: 5px 2px; align-self: center; }
/* `el.hidden = true` does NOT hide a flex container: [hidden] carries display:none at
   the user-agent level and .bm-fgroup's display:flex is an author rule, so it wins.
   Measured: the row stayed on screen and the note appeared UNDER it, which added a
   whole row to the bar, shrank the stage and moved all eighteen boxes - the exact
   thing this session is here to stop. */
.bm-fgroup[hidden] { display: none; }
.bm-subswrap { flex-basis: 100%; min-width: 0; position: relative;
               margin-top: 6px; padding-top: 6px; border-top: 1px solid #dedcd2; }
/* Only drawn when there IS more, and it fades to the bar's own ground rather than to
   white, or it reads as a white smear over a cream panel. */
.bm-subswrap::after { content: ''; position: absolute; right: 0; top: 6px; bottom: 0;
                      width: 46px; pointer-events: none; opacity: 0; transition: opacity .15s;
                      background: linear-gradient(to right, rgba(239,238,231,0), #efeee7); }
.bm-subswrap.more::after { opacity: 1; }
.bm-subs { min-width: 0; display: flex; flex-wrap: nowrap; gap: 6px;
           align-items: center; overflow-x: auto; scrollbar-width: none; }
.bm-subs::-webkit-scrollbar { display: none; }
.bm-subs > * { flex: none; }
.bm-subs-lab { font-size: 13px; color: #6d6b64; margin-right: 2px; }
.bm-sub { font-size: 13px; cursor: pointer; border-radius: 999px; padding: 4px 10px;
          border: 1px solid #8f8d86; background: #fff; color: #2b2a27; }
.bm-sub:hover { border-color: #5f5d57; }
.bm-sub b { font-weight: 650; margin-left: 3px; color: #6d6b64; }
.bm-sub.on { background: #0b0b0b; color: #fff; border-color: #0b0b0b; }
.bm-sub.on b { color: #cfcdc3; }
.bm-sub.faint { opacity: 0.45; }

/* The interviews we hold in full. One row per interview, the title doing the work
   and the show, date, length and point count in the quiet line under it. A row is
   a LINK to the video, so the panel is a way into the thing rather than a list of
   things that exist. */
.bm-ivs{display:flex;flex-direction:column;gap:6px;margin:6px 0 2px}
.bm-iv{display:block;padding:7px 9px;border:1px solid #e6e3dd;border-radius:7px;
       background:#fbfaf8;text-decoration:none;color:inherit}
.bm-iv:hover{background:#f4f2ee;border-color:#d8d4cc}
.bm-iv-t{display:block;font-weight:600;font-size:13px;line-height:1.35}
.bm-iv-m{display:block;margin-top:2px;font-size:11.5px;color:#898781}
